diff --git a/Config/DefaultEditor.ini b/Config/DefaultEditor.ini new file mode 100644 index 0000000..8f207b7 --- /dev/null +++ b/Config/DefaultEditor.ini @@ -0,0 +1,10 @@ +[/Script/UnrealEd.AssetViewerSettings] +-Profiles=(ProfileName="Default",DirectionalLightIntensity=2.620000,DirectionalLightColor=(R=0.990000,G=0.839850,B=0.732600,A=1.000000),SkyLightIntensity=0.880000,bRotateLightingRig=False,bShowEnvironment=True,bShowFloor=True,EnvironmentCubeMapPath="/Engine/EditorMaterials/AssetViewer/EpicQuadPanorama_CC+EV1.EpicQuadPanorama_CC+EV1",PostProcessingSettings=(bOverride_WhiteTemp=True,bOverride_WhiteTint=False,bOverride_ColorSaturation=True,bOverride_ColorContrast=True,bOverride_ColorGamma=True,bOverride_ColorGain=True,bOverride_ColorOffset=True,bOverride_ColorSaturationShadows=False,bOverride_ColorContrastShadows=False,bOverride_ColorGammaShadows=False,bOverride_ColorGainShadows=False,bOverride_ColorOffsetShadows=False,bOverride_ColorSaturationMidtones=False,bOverride_ColorContrastMidtones=False,bOverride_ColorGammaMidtones=False,bOverride_ColorGainMidtones=False,bOverride_ColorOffsetMidtones=False,bOverride_ColorSaturationHighlights=False,bOverride_ColorContrastHighlights=False,bOverride_ColorGammaHighlights=False,bOverride_ColorGainHighlights=False,bOverride_ColorOffsetHighlights=False,bOverride_ColorCorrectionShadowsMax=False,bOverride_ColorCorrectionHighlightsMin=False,bOverride_FilmWhitePoint=False,bOverride_FilmSaturation=False,bOverride_FilmChannelMixerRed=False,bOverride_FilmChannelMixerGreen=False,bOverride_FilmChannelMixerBlue=False,bOverride_FilmContrast=False,bOverride_FilmDynamicRange=False,bOverride_FilmHealAmount=False,bOverride_FilmToeAmount=False,bOverride_FilmShadowTint=False,bOverride_FilmShadowTintBlend=False,bOverride_FilmShadowTintAmount=False,bOverride_FilmSlope=True,bOverride_FilmToe=True,bOverride_FilmShoulder=True,bOverride_FilmBlackClip=True,bOverride_FilmWhiteClip=True,bOverride_SceneColorTint=False,bOverride_SceneFringeIntensity=False,bOverride_AmbientCubemapTint=False,bOverride_AmbientCubemapIntensity=False,bOverride_BloomIntensity=True,bOverride_BloomThreshold=False,bOverride_Bloom1Tint=False,bOverride_Bloom1Size=False,bOverride_Bloom2Size=False,bOverride_Bloom2Tint=False,bOverride_Bloom3Tint=False,bOverride_Bloom3Size=False,bOverride_Bloom4Tint=False,bOverride_Bloom4Size=False,bOverride_Bloom5Tint=False,bOverride_Bloom5Size=False,bOverride_Bloom6Tint=False,bOverride_Bloom6Size=False,bOverride_BloomSizeScale=False,bOverride_BloomDirtMaskIntensity=False,bOverride_BloomDirtMaskTint=False,bOverride_BloomDirtMask=False,bOverride_AutoExposureMethod=True,bOverride_AutoExposureLowPercent=False,bOverride_AutoExposureHighPercent=False,bOverride_AutoExposureMinBrightness=True,bOverride_AutoExposureMaxBrightness=True,bOverride_AutoExposureSpeedUp=False,bOverride_AutoExposureSpeedDown=False,bOverride_AutoExposureBias=True,bOverride_HistogramLogMin=True,bOverride_HistogramLogMax=True,bOverride_LensFlareIntensity=False,bOverride_LensFlareTint=False,bOverride_LensFlareTints=False,bOverride_LensFlareBokehSize=False,bOverride_LensFlareBokehShape=False,bOverride_LensFlareThreshold=False,bOverride_VignetteIntensity=True,bOverride_GrainIntensity=False,bOverride_GrainJitter=False,bOverride_AmbientOcclusionIntensity=True,bOverride_AmbientOcclusionStaticFraction=True,bOverride_AmbientOcclusionRadius=True,bOverride_AmbientOcclusionFadeDistance=False,bOverride_AmbientOcclusionFadeRadius=False,bOverride_AmbientOcclusionDistance=False,bOverride_AmbientOcclusionRadiusInWS=False,bOverride_AmbientOcclusionPower=True,bOverride_AmbientOcclusionBias=True,bOverride_AmbientOcclusionQuality=True,bOverride_AmbientOcclusionMipBlend=True,bOverride_AmbientOcclusionMipScale=True,bOverride_AmbientOcclusionMipThreshold=True,bOverride_LPVIntensity=False,bOverride_LPVDirectionalOcclusionIntensity=False,bOverride_LPVDirectionalOcclusionRadius=False,bOverride_LPVDiffuseOcclusionExponent=False,bOverride_LPVSpecularOcclusionExponent=False,bOverride_LPVDiffuseOcclusionIntensity=False,bOverride_LPVSpecularOcclusionIntensity=False,bOverride_LPVSize=False,bOverride_LPVSecondaryOcclusionIntensity=False,bOverride_LPVSecondaryBounceIntensity=False,bOverride_LPVGeometryVolumeBias=False,bOverride_LPVVplInjectionBias=False,bOverride_LPVEmissiveInjectionIntensity=False,bOverride_IndirectLightingColor=False,bOverride_IndirectLightingIntensity=False,bOverride_ColorGradingIntensity=True,bOverride_ColorGradingLUT=True,bOverride_DepthOfFieldFocalDistance=False,bOverride_DepthOfFieldFstop=False,bOverride_DepthOfFieldSensorWidth=False,bOverride_DepthOfFieldDepthBlurRadius=False,bOverride_DepthOfFieldDepthBlurAmount=False,bOverride_DepthOfFieldFocalRegion=False,bOverride_DepthOfFieldNearTransitionRegion=False,bOverride_DepthOfFieldFarTransitionRegion=False,bOverride_DepthOfFieldScale=True,bOverride_DepthOfFieldMaxBokehSize=False,bOverride_DepthOfFieldNearBlurSize=False,bOverride_DepthOfFieldFarBlurSize=False,bOverride_DepthOfFieldMethod=True,bOverride_MobileHQGaussian=False,bOverride_DepthOfFieldBokehShape=False,bOverride_DepthOfFieldOcclusion=False,bOverride_DepthOfFieldColorThreshold=False,bOverride_DepthOfFieldSizeThreshold=False,bOverride_DepthOfFieldSkyFocusDistance=False,bOverride_DepthOfFieldVignetteSize=False,bOverride_MotionBlurAmount=False,bOverride_MotionBlurMax=False,bOverride_MotionBlurPerObjectSize=False,bOverride_ScreenPercentage=False,bOverride_ScreenSpaceReflectionIntensity=True,bOverride_ScreenSpaceReflectionQuality=True,bOverride_ScreenSpaceReflectionMaxRoughness=True,bOverride_ScreenSpaceReflectionRoughnessScale=False,WhiteTemp=6700.000000,WhiteTint=0.000000,ColorSaturation=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrast=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGamma=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGain=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffset=(X=0.005000,Y=0.005000,Z=0.005000,W=0.000000),ColorSaturationShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetShadows=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorCorrectionShadowsMax=0.090000,ColorSaturationMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetMidtones=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorSaturationHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetHighlights=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorCorrectionHighlightsMin=0.500000,FilmWhitePoint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),FilmShadowTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),FilmShadowTintBlend=0.500000,FilmShadowTintAmount=0.000000,FilmSaturation=1.000000,FilmChannelMixerRed=(R=1.000000,G=0.000000,B=0.000000,A=1.000000),FilmChannelMixerGreen=(R=0.000000,G=1.000000,B=0.000000,A=1.000000),FilmChannelMixerBlue=(R=0.000000,G=0.000000,B=1.000000,A=1.000000),FilmContrast=0.030000,FilmToeAmount=1.000000,FilmHealAmount=1.000000,FilmDynamicRange=4.000000,FilmSlope=0.880000,FilmToe=0.550000,FilmShoulder=0.260000,FilmBlackClip=0.000000,FilmWhiteClip=0.040000,SceneColorTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),SceneFringeIntensity=0.000000,BloomIntensity=0.675000,BloomThreshold=-1.000000,BloomSizeScale=4.000000,Bloom1Size=0.300000,Bloom2Size=1.000000,Bloom3Size=2.000000,Bloom4Size=10.000000,Bloom5Size=30.000000,Bloom6Size=64.000000,Bloom1Tint=(R=0.346500,G=0.346500,B=0.346500,A=1.000000),Bloom2Tint=(R=0.138000,G=0.138000,B=0.138000,A=1.000000),Bloom3Tint=(R=0.117600,G=0.117600,B=0.117600,A=1.000000),Bloom4Tint=(R=0.066000,G=0.066000,B=0.066000,A=1.000000),Bloom5Tint=(R=0.066000,G=0.066000,B=0.066000,A=1.000000),Bloom6Tint=(R=0.061000,G=0.061000,B=0.061000,A=1.000000),BloomDirtMaskIntensity=0.000000,BloomDirtMaskTint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),BloomDirtMask=None,AmbientCubemapTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),AmbientCubemapIntensity=1.000000,AmbientCubemap=None,AutoExposureMethod=AEM_Histogram,AutoExposureLowPercent=80.000000,AutoExposureHighPercent=98.300003,AutoExposureMinBrightness=1.000000,AutoExposureMaxBrightness=1.000000,AutoExposureSpeedUp=3.000000,AutoExposureSpeedDown=1.000000,AutoExposureBias=0.330000,HistogramLogMin=-8.000000,HistogramLogMax=4.000000,LensFlareIntensity=1.000000,LensFlareTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),LensFlareBokehSize=3.000000,LensFlareThreshold=8.000000,LensFlareBokehShape=None,LensFlareTints[0]=(R=1.000000,G=0.800000,B=0.400000,A=0.600000),LensFlareTints[1]=(R=1.000000,G=1.000000,B=0.600000,A=0.530000),LensFlareTints[2]=(R=0.800000,G=0.800000,B=1.000000,A=0.460000),LensFlareTints[3]=(R=0.500000,G=1.000000,B=0.400000,A=0.390000),LensFlareTints[4]=(R=0.500000,G=0.800000,B=1.000000,A=0.310000),LensFlareTints[5]=(R=0.900000,G=1.000000,B=0.800000,A=0.270000),LensFlareTints[6]=(R=1.000000,G=0.800000,B=0.400000,A=0.220000),LensFlareTints[7]=(R=0.900000,G=0.700000,B=0.700000,A=0.150000),VignetteIntensity=0.161468,GrainJitter=0.000000,GrainIntensity=0.000000,AmbientOcclusionIntensity=1.000000,AmbientOcclusionStaticFraction=1.000000,AmbientOcclusionRadius=73.477997,AmbientOcclusionRadiusInWS=False,AmbientOcclusionFadeDistance=8000.000000,AmbientOcclusionFadeRadius=5000.000000,AmbientOcclusionDistance=80.000000,AmbientOcclusionPower=1.200000,AmbientOcclusionBias=3.000000,AmbientOcclusionQuality=100.000000,AmbientOcclusionMipBlend=0.600000,AmbientOcclusionMipScale=1.700000,AmbientOcclusionMipThreshold=0.010000,IndirectLightingColor=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),IndirectLightingIntensity=1.000000,ColorGradingIntensity=0.000000,ColorGradingLUT=Texture2D'/Engine/EditorResources/RGBTable16x1_AssetViewer.RGBTable16x1_AssetViewer',DepthOfFieldMethod=DOFM_BokehDOF,bMobileHQGaussian=False,DepthOfFieldFstop=4.000000,DepthOfFieldSensorWidth=24.576000,DepthOfFieldFocalDistance=1000.000000,DepthOfFieldDepthBlurAmount=1.000000,DepthOfFieldDepthBlurRadius=0.000000,DepthOfFieldFocalRegion=0.000000,DepthOfFieldNearTransitionRegion=300.000000,DepthOfFieldFarTransitionRegion=500.000000,DepthOfFieldScale=0.000000,DepthOfFieldMaxBokehSize=15.000000,DepthOfFieldNearBlurSize=15.000000,DepthOfFieldFarBlurSize=15.000000,DepthOfFieldBokehShape=None,DepthOfFieldOcclusion=0.400000,DepthOfFieldColorThreshold=1.000000,DepthOfFieldSizeThreshold=0.080000,DepthOfFieldSkyFocusDistance=0.000000,DepthOfFieldVignetteSize=200.000000,MotionBlurAmount=0.500000,MotionBlurMax=5.000000,MotionBlurPerObjectSize=0.500000,LPVIntensity=1.000000,LPVVplInjectionBias=0.640000,LPVSize=5312.000000,LPVSecondaryOcclusionIntensity=0.000000,LPVSecondaryBounceIntensity=0.000000,LPVGeometryVolumeBias=0.384000,LPVEmissiveInjectionIntensity=1.000000,LPVDirectionalOcclusionIntensity=0.000000,LPVDirectionalOcclusionRadius=8.000000,LPVDiffuseOcclusionExponent=1.000000,LPVSpecularOcclusionExponent=7.000000,LPVDiffuseOcclusionIntensity=1.000000,LPVSpecularOcclusionIntensity=1.000000,ScreenSpaceReflectionIntensity=100.000000,ScreenSpaceReflectionQuality=100.000000,ScreenSpaceReflectionMaxRoughness=1.000000,ScreenPercentage=100.000000,WeightedBlendables=(Array=),Blendables=),bPostProcessingEnabled=True,LightingRigRotation=109.389069,RotationSpeed=2.000000,DirectionalLightRotation=(Pitch=-39.999985,Yaw=-67.500015,Roll=0.000000)) +-Profiles=(ProfileName="Default",DirectionalLightIntensity=2.620000,DirectionalLightColor=(R=0.990000,G=0.839850,B=0.732600,A=1.000000),SkyLightIntensity=0.880000,bRotateLightingRig=False,bShowEnvironment=True,bShowFloor=True,EnvironmentCubeMapPath="/Engine/EditorMaterials/AssetViewer/EpicQuadPanorama_CC+EV1.EpicQuadPanorama_CC+EV1",PostProcessingSettings=(bOverride_WhiteTemp=True,bOverride_WhiteTint=False,bOverride_ColorSaturation=True,bOverride_ColorContrast=True,bOverride_ColorGamma=True,bOverride_ColorGain=True,bOverride_ColorOffset=True,bOverride_ColorSaturationShadows=False,bOverride_ColorContrastShadows=False,bOverride_ColorGammaShadows=False,bOverride_ColorGainShadows=False,bOverride_ColorOffsetShadows=False,bOverride_ColorSaturationMidtones=False,bOverride_ColorContrastMidtones=False,bOverride_ColorGammaMidtones=False,bOverride_ColorGainMidtones=False,bOverride_ColorOffsetMidtones=False,bOverride_ColorSaturationHighlights=False,bOverride_ColorContrastHighlights=False,bOverride_ColorGammaHighlights=False,bOverride_ColorGainHighlights=False,bOverride_ColorOffsetHighlights=False,bOverride_ColorCorrectionShadowsMax=False,bOverride_ColorCorrectionHighlightsMin=False,bOverride_FilmWhitePoint=False,bOverride_FilmSaturation=False,bOverride_FilmChannelMixerRed=False,bOverride_FilmChannelMixerGreen=False,bOverride_FilmChannelMixerBlue=False,bOverride_FilmContrast=False,bOverride_FilmDynamicRange=False,bOverride_FilmHealAmount=False,bOverride_FilmToeAmount=False,bOverride_FilmShadowTint=False,bOverride_FilmShadowTintBlend=False,bOverride_FilmShadowTintAmount=False,bOverride_FilmSlope=True,bOverride_FilmToe=True,bOverride_FilmShoulder=True,bOverride_FilmBlackClip=True,bOverride_FilmWhiteClip=True,bOverride_SceneColorTint=False,bOverride_SceneFringeIntensity=False,bOverride_AmbientCubemapTint=False,bOverride_AmbientCubemapIntensity=False,bOverride_BloomIntensity=True,bOverride_BloomThreshold=False,bOverride_Bloom1Tint=False,bOverride_Bloom1Size=False,bOverride_Bloom2Size=False,bOverride_Bloom2Tint=False,bOverride_Bloom3Tint=False,bOverride_Bloom3Size=False,bOverride_Bloom4Tint=False,bOverride_Bloom4Size=False,bOverride_Bloom5Tint=False,bOverride_Bloom5Size=False,bOverride_Bloom6Tint=False,bOverride_Bloom6Size=False,bOverride_BloomSizeScale=False,bOverride_BloomDirtMaskIntensity=False,bOverride_BloomDirtMaskTint=False,bOverride_BloomDirtMask=False,bOverride_AutoExposureMethod=True,bOverride_AutoExposureLowPercent=False,bOverride_AutoExposureHighPercent=False,bOverride_AutoExposureMinBrightness=True,bOverride_AutoExposureMaxBrightness=True,bOverride_AutoExposureSpeedUp=False,bOverride_AutoExposureSpeedDown=False,bOverride_AutoExposureBias=True,bOverride_HistogramLogMin=True,bOverride_HistogramLogMax=True,bOverride_LensFlareIntensity=False,bOverride_LensFlareTint=False,bOverride_LensFlareTints=False,bOverride_LensFlareBokehSize=False,bOverride_LensFlareBokehShape=False,bOverride_LensFlareThreshold=False,bOverride_VignetteIntensity=True,bOverride_GrainIntensity=False,bOverride_GrainJitter=False,bOverride_AmbientOcclusionIntensity=True,bOverride_AmbientOcclusionStaticFraction=True,bOverride_AmbientOcclusionRadius=True,bOverride_AmbientOcclusionFadeDistance=False,bOverride_AmbientOcclusionFadeRadius=False,bOverride_AmbientOcclusionDistance=False,bOverride_AmbientOcclusionRadiusInWS=False,bOverride_AmbientOcclusionPower=True,bOverride_AmbientOcclusionBias=True,bOverride_AmbientOcclusionQuality=True,bOverride_AmbientOcclusionMipBlend=True,bOverride_AmbientOcclusionMipScale=True,bOverride_AmbientOcclusionMipThreshold=True,bOverride_LPVIntensity=False,bOverride_LPVDirectionalOcclusionIntensity=False,bOverride_LPVDirectionalOcclusionRadius=False,bOverride_LPVDiffuseOcclusionExponent=False,bOverride_LPVSpecularOcclusionExponent=False,bOverride_LPVDiffuseOcclusionIntensity=False,bOverride_LPVSpecularOcclusionIntensity=False,bOverride_LPVSize=False,bOverride_LPVSecondaryOcclusionIntensity=False,bOverride_LPVSecondaryBounceIntensity=False,bOverride_LPVGeometryVolumeBias=False,bOverride_LPVVplInjectionBias=False,bOverride_LPVEmissiveInjectionIntensity=False,bOverride_IndirectLightingColor=False,bOverride_IndirectLightingIntensity=False,bOverride_ColorGradingIntensity=True,bOverride_ColorGradingLUT=True,bOverride_DepthOfFieldFocalDistance=False,bOverride_DepthOfFieldFstop=False,bOverride_DepthOfFieldSensorWidth=False,bOverride_DepthOfFieldDepthBlurRadius=False,bOverride_DepthOfFieldDepthBlurAmount=False,bOverride_DepthOfFieldFocalRegion=False,bOverride_DepthOfFieldNearTransitionRegion=False,bOverride_DepthOfFieldFarTransitionRegion=False,bOverride_DepthOfFieldScale=True,bOverride_DepthOfFieldMaxBokehSize=False,bOverride_DepthOfFieldNearBlurSize=False,bOverride_DepthOfFieldFarBlurSize=False,bOverride_DepthOfFieldMethod=True,bOverride_MobileHQGaussian=False,bOverride_DepthOfFieldBokehShape=False,bOverride_DepthOfFieldOcclusion=False,bOverride_DepthOfFieldColorThreshold=False,bOverride_DepthOfFieldSizeThreshold=False,bOverride_DepthOfFieldSkyFocusDistance=False,bOverride_DepthOfFieldVignetteSize=False,bOverride_MotionBlurAmount=False,bOverride_MotionBlurMax=False,bOverride_MotionBlurPerObjectSize=False,bOverride_ScreenPercentage=False,bOverride_ScreenSpaceReflectionIntensity=True,bOverride_ScreenSpaceReflectionQuality=True,bOverride_ScreenSpaceReflectionMaxRoughness=True,bOverride_ScreenSpaceReflectionRoughnessScale=False,WhiteTemp=6700.000000,WhiteTint=0.000000,ColorSaturation=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrast=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGamma=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGain=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffset=(X=0.005000,Y=0.005000,Z=0.005000,W=0.000000),ColorSaturationShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetShadows=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorCorrectionShadowsMax=0.090000,ColorSaturationMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetMidtones=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorSaturationHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetHighlights=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorCorrectionHighlightsMin=0.500000,FilmWhitePoint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),FilmShadowTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),FilmShadowTintBlend=0.500000,FilmShadowTintAmount=0.000000,FilmSaturation=1.000000,FilmChannelMixerRed=(R=1.000000,G=0.000000,B=0.000000,A=1.000000),FilmChannelMixerGreen=(R=0.000000,G=1.000000,B=0.000000,A=1.000000),FilmChannelMixerBlue=(R=0.000000,G=0.000000,B=1.000000,A=1.000000),FilmContrast=0.030000,FilmToeAmount=1.000000,FilmHealAmount=1.000000,FilmDynamicRange=4.000000,FilmSlope=0.880000,FilmToe=0.550000,FilmShoulder=0.260000,FilmBlackClip=0.000000,FilmWhiteClip=0.040000,SceneColorTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),SceneFringeIntensity=0.000000,BloomIntensity=0.675000,BloomThreshold=-1.000000,BloomSizeScale=4.000000,Bloom1Size=0.300000,Bloom2Size=1.000000,Bloom3Size=2.000000,Bloom4Size=10.000000,Bloom5Size=30.000000,Bloom6Size=64.000000,Bloom1Tint=(R=0.346500,G=0.346500,B=0.346500,A=1.000000),Bloom2Tint=(R=0.138000,G=0.138000,B=0.138000,A=1.000000),Bloom3Tint=(R=0.117600,G=0.117600,B=0.117600,A=1.000000),Bloom4Tint=(R=0.066000,G=0.066000,B=0.066000,A=1.000000),Bloom5Tint=(R=0.066000,G=0.066000,B=0.066000,A=1.000000),Bloom6Tint=(R=0.061000,G=0.061000,B=0.061000,A=1.000000),BloomDirtMaskIntensity=0.000000,BloomDirtMaskTint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),BloomDirtMask=None,AmbientCubemapTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),AmbientCubemapIntensity=1.000000,AmbientCubemap=None,AutoExposureMethod=AEM_Histogram,AutoExposureLowPercent=80.000000,AutoExposureHighPercent=98.300003,AutoExposureMinBrightness=1.000000,AutoExposureMaxBrightness=1.000000,AutoExposureSpeedUp=3.000000,AutoExposureSpeedDown=1.000000,AutoExposureBias=0.330000,HistogramLogMin=-8.000000,HistogramLogMax=4.000000,LensFlareIntensity=1.000000,LensFlareTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),LensFlareBokehSize=3.000000,LensFlareThreshold=8.000000,LensFlareBokehShape=None,LensFlareTints[0]=(R=1.000000,G=0.800000,B=0.400000,A=0.600000),LensFlareTints[1]=(R=1.000000,G=1.000000,B=0.600000,A=0.530000),LensFlareTints[2]=(R=0.800000,G=0.800000,B=1.000000,A=0.460000),LensFlareTints[3]=(R=0.500000,G=1.000000,B=0.400000,A=0.390000),LensFlareTints[4]=(R=0.500000,G=0.800000,B=1.000000,A=0.310000),LensFlareTints[5]=(R=0.900000,G=1.000000,B=0.800000,A=0.270000),LensFlareTints[6]=(R=1.000000,G=0.800000,B=0.400000,A=0.220000),LensFlareTints[7]=(R=0.900000,G=0.700000,B=0.700000,A=0.150000),VignetteIntensity=0.161468,GrainJitter=0.000000,GrainIntensity=0.000000,AmbientOcclusionIntensity=1.000000,AmbientOcclusionStaticFraction=1.000000,AmbientOcclusionRadius=73.477997,AmbientOcclusionRadiusInWS=False,AmbientOcclusionFadeDistance=8000.000000,AmbientOcclusionFadeRadius=5000.000000,AmbientOcclusionDistance=80.000000,AmbientOcclusionPower=1.200000,AmbientOcclusionBias=3.000000,AmbientOcclusionQuality=100.000000,AmbientOcclusionMipBlend=0.600000,AmbientOcclusionMipScale=1.700000,AmbientOcclusionMipThreshold=0.010000,IndirectLightingColor=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),IndirectLightingIntensity=1.000000,ColorGradingIntensity=0.000000,ColorGradingLUT=Texture2D'/Engine/EditorResources/RGBTable16x1_AssetViewer.RGBTable16x1_AssetViewer',DepthOfFieldMethod=DOFM_BokehDOF,bMobileHQGaussian=False,DepthOfFieldFstop=4.000000,DepthOfFieldSensorWidth=24.576000,DepthOfFieldFocalDistance=1000.000000,DepthOfFieldDepthBlurAmount=1.000000,DepthOfFieldDepthBlurRadius=0.000000,DepthOfFieldFocalRegion=0.000000,DepthOfFieldNearTransitionRegion=300.000000,DepthOfFieldFarTransitionRegion=500.000000,DepthOfFieldScale=0.000000,DepthOfFieldMaxBokehSize=15.000000,DepthOfFieldNearBlurSize=15.000000,DepthOfFieldFarBlurSize=15.000000,DepthOfFieldBokehShape=None,DepthOfFieldOcclusion=0.400000,DepthOfFieldColorThreshold=1.000000,DepthOfFieldSizeThreshold=0.080000,DepthOfFieldSkyFocusDistance=0.000000,DepthOfFieldVignetteSize=200.000000,MotionBlurAmount=0.500000,MotionBlurMax=5.000000,MotionBlurPerObjectSize=0.500000,LPVIntensity=1.000000,LPVVplInjectionBias=0.640000,LPVSize=5312.000000,LPVSecondaryOcclusionIntensity=0.000000,LPVSecondaryBounceIntensity=0.000000,LPVGeometryVolumeBias=0.384000,LPVEmissiveInjectionIntensity=1.000000,LPVDirectionalOcclusionIntensity=0.000000,LPVDirectionalOcclusionRadius=8.000000,LPVDiffuseOcclusionExponent=1.000000,LPVSpecularOcclusionExponent=7.000000,LPVDiffuseOcclusionIntensity=1.000000,LPVSpecularOcclusionIntensity=1.000000,ScreenSpaceReflectionIntensity=100.000000,ScreenSpaceReflectionQuality=100.000000,ScreenSpaceReflectionMaxRoughness=1.000000,ScreenPercentage=100.000000,WeightedBlendables=(Array=),Blendables=),bPostProcessingEnabled=True,LightingRigRotation=109.389069,RotationSpeed=2.000000,DirectionalLightRotation=(Pitch=-39.999985,Yaw=-67.500015,Roll=0.000000)) +-Profiles=(ProfileName="Default",DirectionalLightIntensity=2.620000,DirectionalLightColor=(R=0.990000,G=0.839850,B=0.732600,A=1.000000),SkyLightIntensity=0.880000,bRotateLightingRig=False,bShowEnvironment=True,bShowFloor=True,EnvironmentCubeMapPath="",PostProcessingSettings=(bOverride_WhiteTemp=True,bOverride_WhiteTint=False,bOverride_ColorSaturation=True,bOverride_ColorContrast=True,bOverride_ColorGamma=True,bOverride_ColorGain=True,bOverride_ColorOffset=True,bOverride_ColorSaturationShadows=False,bOverride_ColorContrastShadows=False,bOverride_ColorGammaShadows=False,bOverride_ColorGainShadows=False,bOverride_ColorOffsetShadows=False,bOverride_ColorSaturationMidtones=False,bOverride_ColorContrastMidtones=False,bOverride_ColorGammaMidtones=False,bOverride_ColorGainMidtones=False,bOverride_ColorOffsetMidtones=False,bOverride_ColorSaturationHighlights=False,bOverride_ColorContrastHighlights=False,bOverride_ColorGammaHighlights=False,bOverride_ColorGainHighlights=False,bOverride_ColorOffsetHighlights=False,bOverride_ColorCorrectionShadowsMax=False,bOverride_ColorCorrectionHighlightsMin=False,bOverride_FilmWhitePoint=False,bOverride_FilmSaturation=False,bOverride_FilmChannelMixerRed=False,bOverride_FilmChannelMixerGreen=False,bOverride_FilmChannelMixerBlue=False,bOverride_FilmContrast=False,bOverride_FilmDynamicRange=False,bOverride_FilmHealAmount=False,bOverride_FilmToeAmount=False,bOverride_FilmShadowTint=False,bOverride_FilmShadowTintBlend=False,bOverride_FilmShadowTintAmount=False,bOverride_FilmSlope=True,bOverride_FilmToe=True,bOverride_FilmShoulder=True,bOverride_FilmBlackClip=True,bOverride_FilmWhiteClip=True,bOverride_SceneColorTint=False,bOverride_SceneFringeIntensity=False,bOverride_AmbientCubemapTint=False,bOverride_AmbientCubemapIntensity=False,bOverride_BloomIntensity=True,bOverride_BloomThreshold=False,bOverride_Bloom1Tint=False,bOverride_Bloom1Size=False,bOverride_Bloom2Size=False,bOverride_Bloom2Tint=False,bOverride_Bloom3Tint=False,bOverride_Bloom3Size=False,bOverride_Bloom4Tint=False,bOverride_Bloom4Size=False,bOverride_Bloom5Tint=False,bOverride_Bloom5Size=False,bOverride_Bloom6Tint=False,bOverride_Bloom6Size=False,bOverride_BloomSizeScale=False,bOverride_BloomDirtMaskIntensity=False,bOverride_BloomDirtMaskTint=False,bOverride_BloomDirtMask=False,bOverride_AutoExposureMethod=True,bOverride_AutoExposureLowPercent=False,bOverride_AutoExposureHighPercent=False,bOverride_AutoExposureMinBrightness=True,bOverride_AutoExposureMaxBrightness=True,bOverride_AutoExposureSpeedUp=False,bOverride_AutoExposureSpeedDown=False,bOverride_AutoExposureBias=True,bOverride_HistogramLogMin=True,bOverride_HistogramLogMax=True,bOverride_LensFlareIntensity=False,bOverride_LensFlareTint=False,bOverride_LensFlareTints=False,bOverride_LensFlareBokehSize=False,bOverride_LensFlareBokehShape=False,bOverride_LensFlareThreshold=False,bOverride_VignetteIntensity=True,bOverride_GrainIntensity=False,bOverride_GrainJitter=False,bOverride_AmbientOcclusionIntensity=True,bOverride_AmbientOcclusionStaticFraction=True,bOverride_AmbientOcclusionRadius=True,bOverride_AmbientOcclusionFadeDistance=False,bOverride_AmbientOcclusionFadeRadius=False,bOverride_AmbientOcclusionDistance=False,bOverride_AmbientOcclusionRadiusInWS=False,bOverride_AmbientOcclusionPower=True,bOverride_AmbientOcclusionBias=True,bOverride_AmbientOcclusionQuality=True,bOverride_AmbientOcclusionMipBlend=True,bOverride_AmbientOcclusionMipScale=True,bOverride_AmbientOcclusionMipThreshold=True,bOverride_LPVIntensity=False,bOverride_LPVDirectionalOcclusionIntensity=False,bOverride_LPVDirectionalOcclusionRadius=False,bOverride_LPVDiffuseOcclusionExponent=False,bOverride_LPVSpecularOcclusionExponent=False,bOverride_LPVDiffuseOcclusionIntensity=False,bOverride_LPVSpecularOcclusionIntensity=False,bOverride_LPVSize=False,bOverride_LPVSecondaryOcclusionIntensity=False,bOverride_LPVSecondaryBounceIntensity=False,bOverride_LPVGeometryVolumeBias=False,bOverride_LPVVplInjectionBias=False,bOverride_LPVEmissiveInjectionIntensity=False,bOverride_IndirectLightingColor=False,bOverride_IndirectLightingIntensity=False,bOverride_ColorGradingIntensity=True,bOverride_ColorGradingLUT=True,bOverride_DepthOfFieldFocalDistance=False,bOverride_DepthOfFieldFstop=False,bOverride_DepthOfFieldSensorWidth=False,bOverride_DepthOfFieldDepthBlurRadius=False,bOverride_DepthOfFieldDepthBlurAmount=False,bOverride_DepthOfFieldFocalRegion=False,bOverride_DepthOfFieldNearTransitionRegion=False,bOverride_DepthOfFieldFarTransitionRegion=False,bOverride_DepthOfFieldScale=True,bOverride_DepthOfFieldMaxBokehSize=False,bOverride_DepthOfFieldNearBlurSize=False,bOverride_DepthOfFieldFarBlurSize=False,bOverride_DepthOfFieldMethod=True,bOverride_MobileHQGaussian=False,bOverride_DepthOfFieldBokehShape=False,bOverride_DepthOfFieldOcclusion=False,bOverride_DepthOfFieldColorThreshold=False,bOverride_DepthOfFieldSizeThreshold=False,bOverride_DepthOfFieldSkyFocusDistance=False,bOverride_DepthOfFieldVignetteSize=False,bOverride_MotionBlurAmount=False,bOverride_MotionBlurMax=False,bOverride_MotionBlurPerObjectSize=False,bOverride_ScreenPercentage=False,bOverride_ScreenSpaceReflectionIntensity=True,bOverride_ScreenSpaceReflectionQuality=True,bOverride_ScreenSpaceReflectionMaxRoughness=True,bOverride_ScreenSpaceReflectionRoughnessScale=False,WhiteTemp=6700.000000,WhiteTint=0.000000,ColorSaturation=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrast=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGamma=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGain=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffset=(X=0.005000,Y=0.005000,Z=0.005000,W=0.000000),ColorSaturationShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetShadows=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorCorrectionShadowsMax=0.090000,ColorSaturationMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetMidtones=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorSaturationHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetHighlights=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorCorrectionHighlightsMin=0.500000,FilmWhitePoint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),FilmShadowTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),FilmShadowTintBlend=0.500000,FilmShadowTintAmount=0.000000,FilmSaturation=1.000000,FilmChannelMixerRed=(R=1.000000,G=0.000000,B=0.000000,A=1.000000),FilmChannelMixerGreen=(R=0.000000,G=1.000000,B=0.000000,A=1.000000),FilmChannelMixerBlue=(R=0.000000,G=0.000000,B=1.000000,A=1.000000),FilmContrast=0.030000,FilmToeAmount=1.000000,FilmHealAmount=0.180000,FilmDynamicRange=4.000000,FilmSlope=0.880000,FilmToe=0.550000,FilmShoulder=0.260000,FilmBlackClip=0.000000,FilmWhiteClip=0.040000,SceneColorTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),SceneFringeIntensity=0.000000,BloomIntensity=1.000000,BloomThreshold=1.000000,BloomSizeScale=4.000000,Bloom1Size=1.000000,Bloom2Size=4.000000,Bloom3Size=16.000000,Bloom4Size=32.000000,Bloom5Size=64.000000,Bloom6Size=64.000000,Bloom1Tint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),Bloom2Tint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),Bloom3Tint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),Bloom4Tint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),Bloom5Tint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),Bloom6Tint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),BloomDirtMaskIntensity=1.000000,BloomDirtMaskTint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),BloomDirtMask=None,AmbientCubemapTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),AmbientCubemapIntensity=1.000000,AmbientCubemap=None,AutoExposureMethod=AEM_Histogram,AutoExposureLowPercent=80.000000,AutoExposureHighPercent=98.300003,AutoExposureMinBrightness=1.000000,AutoExposureMaxBrightness=1.000000,AutoExposureSpeedUp=3.000000,AutoExposureSpeedDown=1.000000,AutoExposureBias=0.330000,HistogramLogMin=-8.000000,HistogramLogMax=4.000000,LensFlareIntensity=1.000000,LensFlareTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),LensFlareBokehSize=3.000000,LensFlareThreshold=8.000000,LensFlareBokehShape=None,LensFlareTints[0]=(R=1.000000,G=0.800000,B=0.400000,A=0.600000),LensFlareTints[1]=(R=1.000000,G=1.000000,B=0.600000,A=0.530000),LensFlareTints[2]=(R=0.800000,G=0.800000,B=1.000000,A=0.460000),LensFlareTints[3]=(R=0.500000,G=1.000000,B=0.400000,A=0.390000),LensFlareTints[4]=(R=0.500000,G=0.800000,B=1.000000,A=0.310000),LensFlareTints[5]=(R=0.900000,G=1.000000,B=0.800000,A=0.270000),LensFlareTints[6]=(R=1.000000,G=0.800000,B=0.400000,A=0.220000),LensFlareTints[7]=(R=0.900000,G=0.700000,B=0.700000,A=0.150000),VignetteIntensity=0.161468,GrainJitter=0.000000,GrainIntensity=0.000000,AmbientOcclusionIntensity=1.000000,AmbientOcclusionStaticFraction=1.000000,AmbientOcclusionRadius=73.477997,AmbientOcclusionRadiusInWS=False,AmbientOcclusionFadeDistance=8000.000000,AmbientOcclusionFadeRadius=5000.000000,AmbientOcclusionDistance=80.000000,AmbientOcclusionPower=1.200000,AmbientOcclusionBias=3.000000,AmbientOcclusionQuality=100.000000,AmbientOcclusionMipBlend=0.600000,AmbientOcclusionMipScale=1.700000,AmbientOcclusionMipThreshold=0.010000,IndirectLightingColor=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),IndirectLightingIntensity=1.000000,ColorGradingIntensity=0.000000,ColorGradingLUT=Texture2D'/Engine/EditorResources/RGBTable16x1_AssetViewer.RGBTable16x1_AssetViewer',DepthOfFieldMethod=DOFM_BokehDOF,bMobileHQGaussian=False,DepthOfFieldFstop=4.000000,DepthOfFieldSensorWidth=24.576000,DepthOfFieldFocalDistance=1000.000000,DepthOfFieldDepthBlurAmount=1.000000,DepthOfFieldDepthBlurRadius=0.000000,DepthOfFieldFocalRegion=0.000000,DepthOfFieldNearTransitionRegion=300.000000,DepthOfFieldFarTransitionRegion=500.000000,DepthOfFieldScale=0.000000,DepthOfFieldMaxBokehSize=15.000000,DepthOfFieldNearBlurSize=15.000000,DepthOfFieldFarBlurSize=15.000000,DepthOfFieldBokehShape=None,DepthOfFieldOcclusion=0.400000,DepthOfFieldColorThreshold=1.000000,DepthOfFieldSizeThreshold=0.080000,DepthOfFieldSkyFocusDistance=0.000000,DepthOfFieldVignetteSize=200.000000,MotionBlurAmount=0.500000,MotionBlurMax=5.000000,MotionBlurPerObjectSize=0.500000,LPVIntensity=1.000000,LPVVplInjectionBias=0.640000,LPVSize=5312.000000,LPVSecondaryOcclusionIntensity=0.000000,LPVSecondaryBounceIntensity=0.000000,LPVGeometryVolumeBias=0.384000,LPVEmissiveInjectionIntensity=1.000000,LPVDirectionalOcclusionIntensity=0.000000,LPVDirectionalOcclusionRadius=8.000000,LPVDiffuseOcclusionExponent=1.000000,LPVSpecularOcclusionExponent=7.000000,LPVDiffuseOcclusionIntensity=1.000000,LPVSpecularOcclusionIntensity=1.000000,ScreenSpaceReflectionIntensity=100.000000,ScreenSpaceReflectionQuality=100.000000,ScreenSpaceReflectionMaxRoughness=1.000000,ScreenPercentage=100.000000,WeightedBlendables=(Array=),Blendables=),bPostProcessingEnabled=True,LightingRigRotation=109.389069,RotationSpeed=2.000000,DirectionalLightRotation=(Pitch=-39.999985,Yaw=-67.500015,Roll=0.000000)) ++Profiles=(ProfileName="Default",DirectionalLightIntensity=2.620000,DirectionalLightColor=(R=0.990000,G=0.839850,B=0.732600,A=1.000000),SkyLightIntensity=0.880000,bRotateLightingRig=False,bShowEnvironment=True,bShowFloor=True,EnvironmentCubeMapPath="/Engine/EditorMaterials/AssetViewer/EpicQuadPanorama_CC+EV1.EpicQuadPanorama_CC+EV1",PostProcessingSettings=(bOverride_WhiteTemp=True,bOverride_WhiteTint=False,bOverride_ColorSaturation=True,bOverride_ColorContrast=True,bOverride_ColorGamma=True,bOverride_ColorGain=True,bOverride_ColorOffset=True,bOverride_ColorSaturationShadows=False,bOverride_ColorContrastShadows=False,bOverride_ColorGammaShadows=False,bOverride_ColorGainShadows=False,bOverride_ColorOffsetShadows=False,bOverride_ColorSaturationMidtones=False,bOverride_ColorContrastMidtones=False,bOverride_ColorGammaMidtones=False,bOverride_ColorGainMidtones=False,bOverride_ColorOffsetMidtones=False,bOverride_ColorSaturationHighlights=False,bOverride_ColorContrastHighlights=False,bOverride_ColorGammaHighlights=False,bOverride_ColorGainHighlights=False,bOverride_ColorOffsetHighlights=False,bOverride_ColorCorrectionShadowsMax=False,bOverride_ColorCorrectionHighlightsMin=False,bOverride_FilmWhitePoint=False,bOverride_FilmSaturation=False,bOverride_FilmChannelMixerRed=False,bOverride_FilmChannelMixerGreen=False,bOverride_FilmChannelMixerBlue=False,bOverride_FilmContrast=False,bOverride_FilmDynamicRange=False,bOverride_FilmHealAmount=False,bOverride_FilmToeAmount=False,bOverride_FilmShadowTint=False,bOverride_FilmShadowTintBlend=False,bOverride_FilmShadowTintAmount=False,bOverride_FilmSlope=True,bOverride_FilmToe=True,bOverride_FilmShoulder=True,bOverride_FilmBlackClip=True,bOverride_FilmWhiteClip=True,bOverride_SceneColorTint=False,bOverride_SceneFringeIntensity=False,bOverride_AmbientCubemapTint=False,bOverride_AmbientCubemapIntensity=False,bOverride_BloomIntensity=True,bOverride_BloomThreshold=False,bOverride_Bloom1Tint=False,bOverride_Bloom1Size=False,bOverride_Bloom2Size=False,bOverride_Bloom2Tint=False,bOverride_Bloom3Tint=False,bOverride_Bloom3Size=False,bOverride_Bloom4Tint=False,bOverride_Bloom4Size=False,bOverride_Bloom5Tint=False,bOverride_Bloom5Size=False,bOverride_Bloom6Tint=False,bOverride_Bloom6Size=False,bOverride_BloomSizeScale=False,bOverride_BloomDirtMaskIntensity=False,bOverride_BloomDirtMaskTint=False,bOverride_BloomDirtMask=False,bOverride_AutoExposureMethod=True,bOverride_AutoExposureLowPercent=False,bOverride_AutoExposureHighPercent=False,bOverride_AutoExposureMinBrightness=True,bOverride_AutoExposureMaxBrightness=True,bOverride_AutoExposureSpeedUp=False,bOverride_AutoExposureSpeedDown=False,bOverride_AutoExposureBias=True,bOverride_HistogramLogMin=True,bOverride_HistogramLogMax=True,bOverride_LensFlareIntensity=False,bOverride_LensFlareTint=False,bOverride_LensFlareTints=False,bOverride_LensFlareBokehSize=False,bOverride_LensFlareBokehShape=False,bOverride_LensFlareThreshold=False,bOverride_VignetteIntensity=True,bOverride_GrainIntensity=False,bOverride_GrainJitter=False,bOverride_AmbientOcclusionIntensity=True,bOverride_AmbientOcclusionStaticFraction=True,bOverride_AmbientOcclusionRadius=True,bOverride_AmbientOcclusionFadeDistance=False,bOverride_AmbientOcclusionFadeRadius=False,bOverride_AmbientOcclusionDistance=False,bOverride_AmbientOcclusionRadiusInWS=False,bOverride_AmbientOcclusionPower=True,bOverride_AmbientOcclusionBias=True,bOverride_AmbientOcclusionQuality=True,bOverride_AmbientOcclusionMipBlend=True,bOverride_AmbientOcclusionMipScale=True,bOverride_AmbientOcclusionMipThreshold=True,bOverride_LPVIntensity=False,bOverride_LPVDirectionalOcclusionIntensity=False,bOverride_LPVDirectionalOcclusionRadius=False,bOverride_LPVDiffuseOcclusionExponent=False,bOverride_LPVSpecularOcclusionExponent=False,bOverride_LPVDiffuseOcclusionIntensity=False,bOverride_LPVSpecularOcclusionIntensity=False,bOverride_LPVSize=False,bOverride_LPVSecondaryOcclusionIntensity=False,bOverride_LPVSecondaryBounceIntensity=False,bOverride_LPVGeometryVolumeBias=False,bOverride_LPVVplInjectionBias=False,bOverride_LPVEmissiveInjectionIntensity=False,bOverride_IndirectLightingColor=False,bOverride_IndirectLightingIntensity=False,bOverride_ColorGradingIntensity=True,bOverride_ColorGradingLUT=True,bOverride_DepthOfFieldFocalDistance=False,bOverride_DepthOfFieldFstop=False,bOverride_DepthOfFieldSensorWidth=False,bOverride_DepthOfFieldDepthBlurRadius=False,bOverride_DepthOfFieldDepthBlurAmount=False,bOverride_DepthOfFieldFocalRegion=False,bOverride_DepthOfFieldNearTransitionRegion=False,bOverride_DepthOfFieldFarTransitionRegion=False,bOverride_DepthOfFieldScale=True,bOverride_DepthOfFieldMaxBokehSize=False,bOverride_DepthOfFieldNearBlurSize=False,bOverride_DepthOfFieldFarBlurSize=False,bOverride_DepthOfFieldMethod=True,bOverride_MobileHQGaussian=False,bOverride_DepthOfFieldBokehShape=False,bOverride_DepthOfFieldOcclusion=False,bOverride_DepthOfFieldColorThreshold=False,bOverride_DepthOfFieldSizeThreshold=False,bOverride_DepthOfFieldSkyFocusDistance=False,bOverride_DepthOfFieldVignetteSize=False,bOverride_MotionBlurAmount=False,bOverride_MotionBlurMax=False,bOverride_MotionBlurPerObjectSize=False,bOverride_ScreenPercentage=False,bOverride_ScreenSpaceReflectionIntensity=True,bOverride_ScreenSpaceReflectionQuality=True,bOverride_ScreenSpaceReflectionMaxRoughness=True,bOverride_ScreenSpaceReflectionRoughnessScale=False,WhiteTemp=6700.000000,WhiteTint=0.000000,ColorSaturation=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrast=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGamma=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGain=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffset=(X=0.005000,Y=0.005000,Z=0.005000,W=0.000000),ColorSaturationShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetShadows=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorCorrectionShadowsMax=0.090000,ColorSaturationMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetMidtones=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorSaturationHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetHighlights=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorCorrectionHighlightsMin=0.500000,FilmWhitePoint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),FilmShadowTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),FilmShadowTintBlend=0.500000,FilmShadowTintAmount=0.000000,FilmSaturation=1.000000,FilmChannelMixerRed=(R=1.000000,G=0.000000,B=0.000000,A=1.000000),FilmChannelMixerGreen=(R=0.000000,G=1.000000,B=0.000000,A=1.000000),FilmChannelMixerBlue=(R=0.000000,G=0.000000,B=1.000000,A=1.000000),FilmContrast=0.030000,FilmToeAmount=1.000000,FilmHealAmount=1.000000,FilmDynamicRange=4.000000,FilmSlope=0.880000,FilmToe=0.550000,FilmShoulder=0.260000,FilmBlackClip=0.000000,FilmWhiteClip=0.040000,SceneColorTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),SceneFringeIntensity=0.000000,BloomIntensity=0.675000,BloomThreshold=-1.000000,BloomSizeScale=4.000000,Bloom1Size=0.300000,Bloom2Size=1.000000,Bloom3Size=2.000000,Bloom4Size=10.000000,Bloom5Size=30.000000,Bloom6Size=64.000000,Bloom1Tint=(R=0.346500,G=0.346500,B=0.346500,A=1.000000),Bloom2Tint=(R=0.138000,G=0.138000,B=0.138000,A=1.000000),Bloom3Tint=(R=0.117600,G=0.117600,B=0.117600,A=1.000000),Bloom4Tint=(R=0.066000,G=0.066000,B=0.066000,A=1.000000),Bloom5Tint=(R=0.066000,G=0.066000,B=0.066000,A=1.000000),Bloom6Tint=(R=0.061000,G=0.061000,B=0.061000,A=1.000000),BloomDirtMaskIntensity=0.000000,BloomDirtMaskTint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),BloomDirtMask=None,AmbientCubemapTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),AmbientCubemapIntensity=1.000000,AmbientCubemap=None,AutoExposureMethod=AEM_Histogram,AutoExposureLowPercent=80.000000,AutoExposureHighPercent=98.300003,AutoExposureMinBrightness=1.000000,AutoExposureMaxBrightness=1.000000,AutoExposureSpeedUp=3.000000,AutoExposureSpeedDown=1.000000,AutoExposureBias=0.330000,HistogramLogMin=-8.000000,HistogramLogMax=4.000000,LensFlareIntensity=1.000000,LensFlareTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),LensFlareBokehSize=3.000000,LensFlareThreshold=8.000000,LensFlareBokehShape=None,LensFlareTints[0]=(R=1.000000,G=0.800000,B=0.400000,A=0.600000),LensFlareTints[1]=(R=1.000000,G=1.000000,B=0.600000,A=0.530000),LensFlareTints[2]=(R=0.800000,G=0.800000,B=1.000000,A=0.460000),LensFlareTints[3]=(R=0.500000,G=1.000000,B=0.400000,A=0.390000),LensFlareTints[4]=(R=0.500000,G=0.800000,B=1.000000,A=0.310000),LensFlareTints[5]=(R=0.900000,G=1.000000,B=0.800000,A=0.270000),LensFlareTints[6]=(R=1.000000,G=0.800000,B=0.400000,A=0.220000),LensFlareTints[7]=(R=0.900000,G=0.700000,B=0.700000,A=0.150000),VignetteIntensity=0.161468,GrainJitter=0.000000,GrainIntensity=0.000000,AmbientOcclusionIntensity=1.000000,AmbientOcclusionStaticFraction=1.000000,AmbientOcclusionRadius=73.477997,AmbientOcclusionRadiusInWS=False,AmbientOcclusionFadeDistance=8000.000000,AmbientOcclusionFadeRadius=5000.000000,AmbientOcclusionDistance=80.000000,AmbientOcclusionPower=1.200000,AmbientOcclusionBias=3.000000,AmbientOcclusionQuality=100.000000,AmbientOcclusionMipBlend=0.600000,AmbientOcclusionMipScale=1.700000,AmbientOcclusionMipThreshold=0.010000,IndirectLightingColor=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),IndirectLightingIntensity=1.000000,ColorGradingIntensity=0.000000,ColorGradingLUT=Texture2D'/Engine/EditorResources/RGBTable16x1_AssetViewer.RGBTable16x1_AssetViewer',DepthOfFieldMethod=DOFM_BokehDOF,bMobileHQGaussian=False,DepthOfFieldFstop=4.000000,DepthOfFieldSensorWidth=24.576000,DepthOfFieldFocalDistance=1000.000000,DepthOfFieldDepthBlurAmount=1.000000,DepthOfFieldDepthBlurRadius=0.000000,DepthOfFieldFocalRegion=0.000000,DepthOfFieldNearTransitionRegion=300.000000,DepthOfFieldFarTransitionRegion=500.000000,DepthOfFieldScale=0.000000,DepthOfFieldMaxBokehSize=15.000000,DepthOfFieldNearBlurSize=15.000000,DepthOfFieldFarBlurSize=15.000000,DepthOfFieldBokehShape=None,DepthOfFieldOcclusion=0.400000,DepthOfFieldColorThreshold=1.000000,DepthOfFieldSizeThreshold=0.080000,DepthOfFieldSkyFocusDistance=0.000000,DepthOfFieldVignetteSize=200.000000,MotionBlurAmount=0.500000,MotionBlurMax=5.000000,MotionBlurPerObjectSize=0.500000,LPVIntensity=1.000000,LPVVplInjectionBias=0.640000,LPVSize=5312.000000,LPVSecondaryOcclusionIntensity=0.000000,LPVSecondaryBounceIntensity=0.000000,LPVGeometryVolumeBias=0.384000,LPVEmissiveInjectionIntensity=1.000000,LPVDirectionalOcclusionIntensity=0.000000,LPVDirectionalOcclusionRadius=8.000000,LPVDiffuseOcclusionExponent=1.000000,LPVSpecularOcclusionExponent=7.000000,LPVDiffuseOcclusionIntensity=1.000000,LPVSpecularOcclusionIntensity=1.000000,ScreenSpaceReflectionIntensity=100.000000,ScreenSpaceReflectionQuality=100.000000,ScreenSpaceReflectionMaxRoughness=1.000000,ScreenPercentage=100.000000,WeightedBlendables=(Array=),Blendables=),bPostProcessingEnabled=True,LightingRigRotation=109.389069,RotationSpeed=2.000000,DirectionalLightRotation=(Pitch=-39.999985,Yaw=-67.500015,Roll=0.000000)) ++Profiles=(ProfileName="Default",DirectionalLightIntensity=2.620000,DirectionalLightColor=(R=0.990000,G=0.839850,B=0.732600,A=1.000000),SkyLightIntensity=0.880000,bRotateLightingRig=False,bShowEnvironment=True,bShowFloor=True,EnvironmentCubeMapPath="/Engine/EditorMaterials/AssetViewer/EpicQuadPanorama_CC+EV1.EpicQuadPanorama_CC+EV1",PostProcessingSettings=(bOverride_WhiteTemp=True,bOverride_WhiteTint=False,bOverride_ColorSaturation=True,bOverride_ColorContrast=True,bOverride_ColorGamma=True,bOverride_ColorGain=True,bOverride_ColorOffset=True,bOverride_ColorSaturationShadows=False,bOverride_ColorContrastShadows=False,bOverride_ColorGammaShadows=False,bOverride_ColorGainShadows=False,bOverride_ColorOffsetShadows=False,bOverride_ColorSaturationMidtones=False,bOverride_ColorContrastMidtones=False,bOverride_ColorGammaMidtones=False,bOverride_ColorGainMidtones=False,bOverride_ColorOffsetMidtones=False,bOverride_ColorSaturationHighlights=False,bOverride_ColorContrastHighlights=False,bOverride_ColorGammaHighlights=False,bOverride_ColorGainHighlights=False,bOverride_ColorOffsetHighlights=False,bOverride_ColorCorrectionShadowsMax=False,bOverride_ColorCorrectionHighlightsMin=False,bOverride_FilmWhitePoint=False,bOverride_FilmSaturation=False,bOverride_FilmChannelMixerRed=False,bOverride_FilmChannelMixerGreen=False,bOverride_FilmChannelMixerBlue=False,bOverride_FilmContrast=False,bOverride_FilmDynamicRange=False,bOverride_FilmHealAmount=False,bOverride_FilmToeAmount=False,bOverride_FilmShadowTint=False,bOverride_FilmShadowTintBlend=False,bOverride_FilmShadowTintAmount=False,bOverride_FilmSlope=True,bOverride_FilmToe=True,bOverride_FilmShoulder=True,bOverride_FilmBlackClip=True,bOverride_FilmWhiteClip=True,bOverride_SceneColorTint=False,bOverride_SceneFringeIntensity=False,bOverride_AmbientCubemapTint=False,bOverride_AmbientCubemapIntensity=False,bOverride_BloomIntensity=True,bOverride_BloomThreshold=False,bOverride_Bloom1Tint=False,bOverride_Bloom1Size=False,bOverride_Bloom2Size=False,bOverride_Bloom2Tint=False,bOverride_Bloom3Tint=False,bOverride_Bloom3Size=False,bOverride_Bloom4Tint=False,bOverride_Bloom4Size=False,bOverride_Bloom5Tint=False,bOverride_Bloom5Size=False,bOverride_Bloom6Tint=False,bOverride_Bloom6Size=False,bOverride_BloomSizeScale=False,bOverride_BloomDirtMaskIntensity=False,bOverride_BloomDirtMaskTint=False,bOverride_BloomDirtMask=False,bOverride_AutoExposureMethod=True,bOverride_AutoExposureLowPercent=False,bOverride_AutoExposureHighPercent=False,bOverride_AutoExposureMinBrightness=True,bOverride_AutoExposureMaxBrightness=True,bOverride_AutoExposureSpeedUp=False,bOverride_AutoExposureSpeedDown=False,bOverride_AutoExposureBias=True,bOverride_HistogramLogMin=True,bOverride_HistogramLogMax=True,bOverride_LensFlareIntensity=False,bOverride_LensFlareTint=False,bOverride_LensFlareTints=False,bOverride_LensFlareBokehSize=False,bOverride_LensFlareBokehShape=False,bOverride_LensFlareThreshold=False,bOverride_VignetteIntensity=True,bOverride_GrainIntensity=False,bOverride_GrainJitter=False,bOverride_AmbientOcclusionIntensity=True,bOverride_AmbientOcclusionStaticFraction=True,bOverride_AmbientOcclusionRadius=True,bOverride_AmbientOcclusionFadeDistance=False,bOverride_AmbientOcclusionFadeRadius=False,bOverride_AmbientOcclusionDistance=False,bOverride_AmbientOcclusionRadiusInWS=False,bOverride_AmbientOcclusionPower=True,bOverride_AmbientOcclusionBias=True,bOverride_AmbientOcclusionQuality=True,bOverride_AmbientOcclusionMipBlend=True,bOverride_AmbientOcclusionMipScale=True,bOverride_AmbientOcclusionMipThreshold=True,bOverride_LPVIntensity=False,bOverride_LPVDirectionalOcclusionIntensity=False,bOverride_LPVDirectionalOcclusionRadius=False,bOverride_LPVDiffuseOcclusionExponent=False,bOverride_LPVSpecularOcclusionExponent=False,bOverride_LPVDiffuseOcclusionIntensity=False,bOverride_LPVSpecularOcclusionIntensity=False,bOverride_LPVSize=False,bOverride_LPVSecondaryOcclusionIntensity=False,bOverride_LPVSecondaryBounceIntensity=False,bOverride_LPVGeometryVolumeBias=False,bOverride_LPVVplInjectionBias=False,bOverride_LPVEmissiveInjectionIntensity=False,bOverride_IndirectLightingColor=False,bOverride_IndirectLightingIntensity=False,bOverride_ColorGradingIntensity=True,bOverride_ColorGradingLUT=True,bOverride_DepthOfFieldFocalDistance=False,bOverride_DepthOfFieldFstop=False,bOverride_DepthOfFieldSensorWidth=False,bOverride_DepthOfFieldDepthBlurRadius=False,bOverride_DepthOfFieldDepthBlurAmount=False,bOverride_DepthOfFieldFocalRegion=False,bOverride_DepthOfFieldNearTransitionRegion=False,bOverride_DepthOfFieldFarTransitionRegion=False,bOverride_DepthOfFieldScale=True,bOverride_DepthOfFieldMaxBokehSize=False,bOverride_DepthOfFieldNearBlurSize=False,bOverride_DepthOfFieldFarBlurSize=False,bOverride_DepthOfFieldMethod=True,bOverride_MobileHQGaussian=False,bOverride_DepthOfFieldBokehShape=False,bOverride_DepthOfFieldOcclusion=False,bOverride_DepthOfFieldColorThreshold=False,bOverride_DepthOfFieldSizeThreshold=False,bOverride_DepthOfFieldSkyFocusDistance=False,bOverride_DepthOfFieldVignetteSize=False,bOverride_MotionBlurAmount=False,bOverride_MotionBlurMax=False,bOverride_MotionBlurPerObjectSize=False,bOverride_ScreenPercentage=False,bOverride_ScreenSpaceReflectionIntensity=True,bOverride_ScreenSpaceReflectionQuality=True,bOverride_ScreenSpaceReflectionMaxRoughness=True,bOverride_ScreenSpaceReflectionRoughnessScale=False,WhiteTemp=6700.000000,WhiteTint=0.000000,ColorSaturation=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrast=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGamma=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGain=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffset=(X=0.005000,Y=0.005000,Z=0.005000,W=0.000000),ColorSaturationShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetShadows=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorCorrectionShadowsMax=0.090000,ColorSaturationMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetMidtones=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorSaturationHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetHighlights=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorCorrectionHighlightsMin=0.500000,FilmWhitePoint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),FilmShadowTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),FilmShadowTintBlend=0.500000,FilmShadowTintAmount=0.000000,FilmSaturation=1.000000,FilmChannelMixerRed=(R=1.000000,G=0.000000,B=0.000000,A=1.000000),FilmChannelMixerGreen=(R=0.000000,G=1.000000,B=0.000000,A=1.000000),FilmChannelMixerBlue=(R=0.000000,G=0.000000,B=1.000000,A=1.000000),FilmContrast=0.030000,FilmToeAmount=1.000000,FilmHealAmount=1.000000,FilmDynamicRange=4.000000,FilmSlope=0.880000,FilmToe=0.550000,FilmShoulder=0.260000,FilmBlackClip=0.000000,FilmWhiteClip=0.040000,SceneColorTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),SceneFringeIntensity=0.000000,BloomIntensity=0.675000,BloomThreshold=-1.000000,BloomSizeScale=4.000000,Bloom1Size=0.300000,Bloom2Size=1.000000,Bloom3Size=2.000000,Bloom4Size=10.000000,Bloom5Size=30.000000,Bloom6Size=64.000000,Bloom1Tint=(R=0.346500,G=0.346500,B=0.346500,A=1.000000),Bloom2Tint=(R=0.138000,G=0.138000,B=0.138000,A=1.000000),Bloom3Tint=(R=0.117600,G=0.117600,B=0.117600,A=1.000000),Bloom4Tint=(R=0.066000,G=0.066000,B=0.066000,A=1.000000),Bloom5Tint=(R=0.066000,G=0.066000,B=0.066000,A=1.000000),Bloom6Tint=(R=0.061000,G=0.061000,B=0.061000,A=1.000000),BloomDirtMaskIntensity=0.000000,BloomDirtMaskTint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),BloomDirtMask=None,AmbientCubemapTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),AmbientCubemapIntensity=1.000000,AmbientCubemap=None,AutoExposureMethod=AEM_Histogram,AutoExposureLowPercent=80.000000,AutoExposureHighPercent=98.300003,AutoExposureMinBrightness=1.000000,AutoExposureMaxBrightness=1.000000,AutoExposureSpeedUp=3.000000,AutoExposureSpeedDown=1.000000,AutoExposureBias=0.330000,HistogramLogMin=-8.000000,HistogramLogMax=4.000000,LensFlareIntensity=1.000000,LensFlareTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),LensFlareBokehSize=3.000000,LensFlareThreshold=8.000000,LensFlareBokehShape=None,LensFlareTints[0]=(R=1.000000,G=0.800000,B=0.400000,A=0.600000),LensFlareTints[1]=(R=1.000000,G=1.000000,B=0.600000,A=0.530000),LensFlareTints[2]=(R=0.800000,G=0.800000,B=1.000000,A=0.460000),LensFlareTints[3]=(R=0.500000,G=1.000000,B=0.400000,A=0.390000),LensFlareTints[4]=(R=0.500000,G=0.800000,B=1.000000,A=0.310000),LensFlareTints[5]=(R=0.900000,G=1.000000,B=0.800000,A=0.270000),LensFlareTints[6]=(R=1.000000,G=0.800000,B=0.400000,A=0.220000),LensFlareTints[7]=(R=0.900000,G=0.700000,B=0.700000,A=0.150000),VignetteIntensity=0.161468,GrainJitter=0.000000,GrainIntensity=0.000000,AmbientOcclusionIntensity=1.000000,AmbientOcclusionStaticFraction=1.000000,AmbientOcclusionRadius=73.477997,AmbientOcclusionRadiusInWS=False,AmbientOcclusionFadeDistance=8000.000000,AmbientOcclusionFadeRadius=5000.000000,AmbientOcclusionDistance=80.000000,AmbientOcclusionPower=1.200000,AmbientOcclusionBias=3.000000,AmbientOcclusionQuality=100.000000,AmbientOcclusionMipBlend=0.600000,AmbientOcclusionMipScale=1.700000,AmbientOcclusionMipThreshold=0.010000,IndirectLightingColor=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),IndirectLightingIntensity=1.000000,ColorGradingIntensity=0.000000,ColorGradingLUT=Texture2D'/Engine/EditorResources/RGBTable16x1_AssetViewer.RGBTable16x1_AssetViewer',DepthOfFieldMethod=DOFM_BokehDOF,bMobileHQGaussian=False,DepthOfFieldFstop=4.000000,DepthOfFieldSensorWidth=24.576000,DepthOfFieldFocalDistance=1000.000000,DepthOfFieldDepthBlurAmount=1.000000,DepthOfFieldDepthBlurRadius=0.000000,DepthOfFieldFocalRegion=0.000000,DepthOfFieldNearTransitionRegion=300.000000,DepthOfFieldFarTransitionRegion=500.000000,DepthOfFieldScale=0.000000,DepthOfFieldMaxBokehSize=15.000000,DepthOfFieldNearBlurSize=15.000000,DepthOfFieldFarBlurSize=15.000000,DepthOfFieldBokehShape=None,DepthOfFieldOcclusion=0.400000,DepthOfFieldColorThreshold=1.000000,DepthOfFieldSizeThreshold=0.080000,DepthOfFieldSkyFocusDistance=0.000000,DepthOfFieldVignetteSize=200.000000,MotionBlurAmount=0.500000,MotionBlurMax=5.000000,MotionBlurPerObjectSize=0.500000,LPVIntensity=1.000000,LPVVplInjectionBias=0.640000,LPVSize=5312.000000,LPVSecondaryOcclusionIntensity=0.000000,LPVSecondaryBounceIntensity=0.000000,LPVGeometryVolumeBias=0.384000,LPVEmissiveInjectionIntensity=1.000000,LPVDirectionalOcclusionIntensity=0.000000,LPVDirectionalOcclusionRadius=8.000000,LPVDiffuseOcclusionExponent=1.000000,LPVSpecularOcclusionExponent=7.000000,LPVDiffuseOcclusionIntensity=1.000000,LPVSpecularOcclusionIntensity=1.000000,ScreenSpaceReflectionIntensity=100.000000,ScreenSpaceReflectionQuality=100.000000,ScreenSpaceReflectionMaxRoughness=1.000000,ScreenPercentage=100.000000,WeightedBlendables=(Array=),Blendables=),bPostProcessingEnabled=True,LightingRigRotation=109.389069,RotationSpeed=2.000000,DirectionalLightRotation=(Pitch=-39.999985,Yaw=-67.500015,Roll=0.000000)) ++Profiles=(ProfileName="Default",DirectionalLightIntensity=2.620000,DirectionalLightColor=(R=0.990000,G=0.839850,B=0.732600,A=1.000000),SkyLightIntensity=0.880000,bRotateLightingRig=False,bShowEnvironment=True,bShowFloor=True,EnvironmentCubeMapPath="",PostProcessingSettings=(bOverride_WhiteTemp=True,bOverride_WhiteTint=False,bOverride_ColorSaturation=True,bOverride_ColorContrast=True,bOverride_ColorGamma=True,bOverride_ColorGain=True,bOverride_ColorOffset=True,bOverride_ColorSaturationShadows=False,bOverride_ColorContrastShadows=False,bOverride_ColorGammaShadows=False,bOverride_ColorGainShadows=False,bOverride_ColorOffsetShadows=False,bOverride_ColorSaturationMidtones=False,bOverride_ColorContrastMidtones=False,bOverride_ColorGammaMidtones=False,bOverride_ColorGainMidtones=False,bOverride_ColorOffsetMidtones=False,bOverride_ColorSaturationHighlights=False,bOverride_ColorContrastHighlights=False,bOverride_ColorGammaHighlights=False,bOverride_ColorGainHighlights=False,bOverride_ColorOffsetHighlights=False,bOverride_ColorCorrectionShadowsMax=False,bOverride_ColorCorrectionHighlightsMin=False,bOverride_FilmWhitePoint=False,bOverride_FilmSaturation=False,bOverride_FilmChannelMixerRed=False,bOverride_FilmChannelMixerGreen=False,bOverride_FilmChannelMixerBlue=False,bOverride_FilmContrast=False,bOverride_FilmDynamicRange=False,bOverride_FilmHealAmount=False,bOverride_FilmToeAmount=False,bOverride_FilmShadowTint=False,bOverride_FilmShadowTintBlend=False,bOverride_FilmShadowTintAmount=False,bOverride_FilmSlope=True,bOverride_FilmToe=True,bOverride_FilmShoulder=True,bOverride_FilmBlackClip=True,bOverride_FilmWhiteClip=True,bOverride_SceneColorTint=False,bOverride_SceneFringeIntensity=False,bOverride_AmbientCubemapTint=False,bOverride_AmbientCubemapIntensity=False,bOverride_BloomIntensity=True,bOverride_BloomThreshold=False,bOverride_Bloom1Tint=False,bOverride_Bloom1Size=False,bOverride_Bloom2Size=False,bOverride_Bloom2Tint=False,bOverride_Bloom3Tint=False,bOverride_Bloom3Size=False,bOverride_Bloom4Tint=False,bOverride_Bloom4Size=False,bOverride_Bloom5Tint=False,bOverride_Bloom5Size=False,bOverride_Bloom6Tint=False,bOverride_Bloom6Size=False,bOverride_BloomSizeScale=False,bOverride_BloomDirtMaskIntensity=False,bOverride_BloomDirtMaskTint=False,bOverride_BloomDirtMask=False,bOverride_AutoExposureMethod=True,bOverride_AutoExposureLowPercent=False,bOverride_AutoExposureHighPercent=False,bOverride_AutoExposureMinBrightness=True,bOverride_AutoExposureMaxBrightness=True,bOverride_AutoExposureSpeedUp=False,bOverride_AutoExposureSpeedDown=False,bOverride_AutoExposureBias=True,bOverride_HistogramLogMin=True,bOverride_HistogramLogMax=True,bOverride_LensFlareIntensity=False,bOverride_LensFlareTint=False,bOverride_LensFlareTints=False,bOverride_LensFlareBokehSize=False,bOverride_LensFlareBokehShape=False,bOverride_LensFlareThreshold=False,bOverride_VignetteIntensity=True,bOverride_GrainIntensity=False,bOverride_GrainJitter=False,bOverride_AmbientOcclusionIntensity=True,bOverride_AmbientOcclusionStaticFraction=True,bOverride_AmbientOcclusionRadius=True,bOverride_AmbientOcclusionFadeDistance=False,bOverride_AmbientOcclusionFadeRadius=False,bOverride_AmbientOcclusionDistance=False,bOverride_AmbientOcclusionRadiusInWS=False,bOverride_AmbientOcclusionPower=True,bOverride_AmbientOcclusionBias=True,bOverride_AmbientOcclusionQuality=True,bOverride_AmbientOcclusionMipBlend=True,bOverride_AmbientOcclusionMipScale=True,bOverride_AmbientOcclusionMipThreshold=True,bOverride_LPVIntensity=False,bOverride_LPVDirectionalOcclusionIntensity=False,bOverride_LPVDirectionalOcclusionRadius=False,bOverride_LPVDiffuseOcclusionExponent=False,bOverride_LPVSpecularOcclusionExponent=False,bOverride_LPVDiffuseOcclusionIntensity=False,bOverride_LPVSpecularOcclusionIntensity=False,bOverride_LPVSize=False,bOverride_LPVSecondaryOcclusionIntensity=False,bOverride_LPVSecondaryBounceIntensity=False,bOverride_LPVGeometryVolumeBias=False,bOverride_LPVVplInjectionBias=False,bOverride_LPVEmissiveInjectionIntensity=False,bOverride_IndirectLightingColor=False,bOverride_IndirectLightingIntensity=False,bOverride_ColorGradingIntensity=True,bOverride_ColorGradingLUT=True,bOverride_DepthOfFieldFocalDistance=False,bOverride_DepthOfFieldFstop=False,bOverride_DepthOfFieldSensorWidth=False,bOverride_DepthOfFieldDepthBlurRadius=False,bOverride_DepthOfFieldDepthBlurAmount=False,bOverride_DepthOfFieldFocalRegion=False,bOverride_DepthOfFieldNearTransitionRegion=False,bOverride_DepthOfFieldFarTransitionRegion=False,bOverride_DepthOfFieldScale=True,bOverride_DepthOfFieldMaxBokehSize=False,bOverride_DepthOfFieldNearBlurSize=False,bOverride_DepthOfFieldFarBlurSize=False,bOverride_DepthOfFieldMethod=True,bOverride_MobileHQGaussian=False,bOverride_DepthOfFieldBokehShape=False,bOverride_DepthOfFieldOcclusion=False,bOverride_DepthOfFieldColorThreshold=False,bOverride_DepthOfFieldSizeThreshold=False,bOverride_DepthOfFieldSkyFocusDistance=False,bOverride_DepthOfFieldVignetteSize=False,bOverride_MotionBlurAmount=False,bOverride_MotionBlurMax=False,bOverride_MotionBlurPerObjectSize=False,bOverride_ScreenPercentage=False,bOverride_ScreenSpaceReflectionIntensity=True,bOverride_ScreenSpaceReflectionQuality=True,bOverride_ScreenSpaceReflectionMaxRoughness=True,bOverride_ScreenSpaceReflectionRoughnessScale=False,WhiteTemp=6700.000000,WhiteTint=0.000000,ColorSaturation=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrast=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGamma=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGain=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffset=(X=0.005000,Y=0.005000,Z=0.005000,W=0.000000),ColorSaturationShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainShadows=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetShadows=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorCorrectionShadowsMax=0.090000,ColorSaturationMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainMidtones=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetMidtones=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorSaturationHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorContrastHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGammaHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorGainHighlights=(X=1.000000,Y=1.000000,Z=1.000000,W=1.000000),ColorOffsetHighlights=(X=0.000000,Y=0.000000,Z=0.000000,W=0.000000),ColorCorrectionHighlightsMin=0.500000,FilmWhitePoint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),FilmShadowTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),FilmShadowTintBlend=0.500000,FilmShadowTintAmount=0.000000,FilmSaturation=1.000000,FilmChannelMixerRed=(R=1.000000,G=0.000000,B=0.000000,A=1.000000),FilmChannelMixerGreen=(R=0.000000,G=1.000000,B=0.000000,A=1.000000),FilmChannelMixerBlue=(R=0.000000,G=0.000000,B=1.000000,A=1.000000),FilmContrast=0.030000,FilmToeAmount=1.000000,FilmHealAmount=0.180000,FilmDynamicRange=4.000000,FilmSlope=0.880000,FilmToe=0.550000,FilmShoulder=0.260000,FilmBlackClip=0.000000,FilmWhiteClip=0.040000,SceneColorTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),SceneFringeIntensity=0.000000,BloomIntensity=1.000000,BloomThreshold=1.000000,BloomSizeScale=4.000000,Bloom1Size=1.000000,Bloom2Size=4.000000,Bloom3Size=16.000000,Bloom4Size=32.000000,Bloom5Size=64.000000,Bloom6Size=64.000000,Bloom1Tint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),Bloom2Tint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),Bloom3Tint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),Bloom4Tint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),Bloom5Tint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),Bloom6Tint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),BloomDirtMaskIntensity=1.000000,BloomDirtMaskTint=(R=0.500000,G=0.500000,B=0.500000,A=1.000000),BloomDirtMask=None,AmbientCubemapTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),AmbientCubemapIntensity=1.000000,AmbientCubemap=None,AutoExposureMethod=AEM_Histogram,AutoExposureLowPercent=80.000000,AutoExposureHighPercent=98.300003,AutoExposureMinBrightness=1.000000,AutoExposureMaxBrightness=1.000000,AutoExposureSpeedUp=3.000000,AutoExposureSpeedDown=1.000000,AutoExposureBias=0.330000,HistogramLogMin=-8.000000,HistogramLogMax=4.000000,LensFlareIntensity=1.000000,LensFlareTint=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),LensFlareBokehSize=3.000000,LensFlareThreshold=8.000000,LensFlareBokehShape=None,LensFlareTints[0]=(R=1.000000,G=0.800000,B=0.400000,A=0.600000),LensFlareTints[1]=(R=1.000000,G=1.000000,B=0.600000,A=0.530000),LensFlareTints[2]=(R=0.800000,G=0.800000,B=1.000000,A=0.460000),LensFlareTints[3]=(R=0.500000,G=1.000000,B=0.400000,A=0.390000),LensFlareTints[4]=(R=0.500000,G=0.800000,B=1.000000,A=0.310000),LensFlareTints[5]=(R=0.900000,G=1.000000,B=0.800000,A=0.270000),LensFlareTints[6]=(R=1.000000,G=0.800000,B=0.400000,A=0.220000),LensFlareTints[7]=(R=0.900000,G=0.700000,B=0.700000,A=0.150000),VignetteIntensity=0.161468,GrainJitter=0.000000,GrainIntensity=0.000000,AmbientOcclusionIntensity=1.000000,AmbientOcclusionStaticFraction=1.000000,AmbientOcclusionRadius=73.477997,AmbientOcclusionRadiusInWS=False,AmbientOcclusionFadeDistance=8000.000000,AmbientOcclusionFadeRadius=5000.000000,AmbientOcclusionDistance=80.000000,AmbientOcclusionPower=1.200000,AmbientOcclusionBias=3.000000,AmbientOcclusionQuality=100.000000,AmbientOcclusionMipBlend=0.600000,AmbientOcclusionMipScale=1.700000,AmbientOcclusionMipThreshold=0.010000,IndirectLightingColor=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),IndirectLightingIntensity=1.000000,ColorGradingIntensity=0.000000,ColorGradingLUT=Texture2D'/Engine/EditorResources/RGBTable16x1_AssetViewer.RGBTable16x1_AssetViewer',DepthOfFieldMethod=DOFM_BokehDOF,bMobileHQGaussian=False,DepthOfFieldFstop=4.000000,DepthOfFieldSensorWidth=24.576000,DepthOfFieldFocalDistance=1000.000000,DepthOfFieldDepthBlurAmount=1.000000,DepthOfFieldDepthBlurRadius=0.000000,DepthOfFieldFocalRegion=0.000000,DepthOfFieldNearTransitionRegion=300.000000,DepthOfFieldFarTransitionRegion=500.000000,DepthOfFieldScale=0.000000,DepthOfFieldMaxBokehSize=15.000000,DepthOfFieldNearBlurSize=15.000000,DepthOfFieldFarBlurSize=15.000000,DepthOfFieldBokehShape=None,DepthOfFieldOcclusion=0.400000,DepthOfFieldColorThreshold=1.000000,DepthOfFieldSizeThreshold=0.080000,DepthOfFieldSkyFocusDistance=0.000000,DepthOfFieldVignetteSize=200.000000,MotionBlurAmount=0.500000,MotionBlurMax=5.000000,MotionBlurPerObjectSize=0.500000,LPVIntensity=1.000000,LPVVplInjectionBias=0.640000,LPVSize=5312.000000,LPVSecondaryOcclusionIntensity=0.000000,LPVSecondaryBounceIntensity=0.000000,LPVGeometryVolumeBias=0.384000,LPVEmissiveInjectionIntensity=1.000000,LPVDirectionalOcclusionIntensity=0.000000,LPVDirectionalOcclusionRadius=8.000000,LPVDiffuseOcclusionExponent=1.000000,LPVSpecularOcclusionExponent=7.000000,LPVDiffuseOcclusionIntensity=1.000000,LPVSpecularOcclusionIntensity=1.000000,ScreenSpaceReflectionIntensity=100.000000,ScreenSpaceReflectionQuality=100.000000,ScreenSpaceReflectionMaxRoughness=1.000000,ScreenPercentage=100.000000,WeightedBlendables=(Array=),Blendables=),bPostProcessingEnabled=True,LightingRigRotation=109.389069,RotationSpeed=2.000000,DirectionalLightRotation=(Pitch=-39.999985,Yaw=-67.500015,Roll=0.000000)) + +[/Script/AdvancedPreviewScene.SharedProfiles] + diff --git a/Config/DefaultEngine.ini b/Config/DefaultEngine.ini new file mode 100644 index 0000000..c7a0d00 --- /dev/null +++ b/Config/DefaultEngine.ini @@ -0,0 +1,466 @@ +[ConsoleVariables] +p.Chaos.ImmPhys.Joint.UsePBDDrives=0 + +[HMDPluginPriority] +OpenXRHMD=60 +WindowsMixedRealityHMD=40 +OculusHMD=70 +SteamVR=10 + +[/Script/Engine.GameEngine] ++NetDriverDefinitions=(DefName="GameNetDriver2",DriverClassName="OnlineSubsystemUtils.IpNetDriver",DriverClassNameFallback="OnlineSubsystemUtils.IpNetDriver") ++NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="OnlineSubsystemSteam.SteamNetDriver",DriverClassNameFallback="OnlineSubsystemUtils.IpNetDriver") + +[/Script/OnlineSubsystemSteam.SteamNetDriver] +NetConnectionClassName=OnlineSubsystemSteam.SteamNetConnection + +[Voice] +bEnabled=true + +[OnlineSubsystem] +bHasVoiceEnabled=true +DefaultPlatformService=Steam + +[OnlineSubsystemSteam] +bEnabled=True +SteamDevAppId=480 + +[/Script/OnlineSubsystemUtils.IpNetDriver] +MaxClientRate=15000 +MaxInternetClientRate=15000 + +[/Script/Engine.Player] +ConfiguredInternetSpeed=15000 +ConfiguredLanSpeed=20000 + +[SystemSettings] +net.IsPushModelEnabled=1 + +[/Script/EngineSettings.GameMapsSettings] +EditorStartupMap=/Game/Senseglove/Maps/SensegloveDemoMap.SensegloveDemoMap +LocalMapOptions= +TransitionMap= +bUseSplitscreen=False +TwoPlayerSplitscreenLayout=Horizontal +ThreePlayerSplitscreenLayout=FavorTop +GameInstanceClass=/Game/VRE/Core/VRGameInstance.VRGameInstance_C +GameDefaultMap=/Game/Senseglove/Maps/SensegloveDemoMap.SensegloveDemoMap +ServerDefaultMap=/Engine/Maps/Entry +GlobalDefaultGameMode=/Game/VRE/Core/VRGameMode.VRGameMode_C +GlobalDefaultServerGameMode=None + +[/Script/Engine.Engine] ++ActiveGameNameRedirects=(OldGameName="TP_VirtualRealityBP",NewGameName="/Script/SGVRETemplate") ++ActiveGameNameRedirects=(OldGameName="/Script/TP_VirtualRealityBP",NewGameName="/Script/SGVRETemplate") ++ActiveGameNameRedirects=(OldGameName="TP_FirstPersonBP",NewGameName="/Script/VRTemplate") ++ActiveGameNameRedirects=(OldGameName="/Script/TP_FirstPersonBP",NewGameName="/Script/VRTemplate") +bSmoothFrameRate=False +GameViewportClientClassName=/Script/VRExpansionPlugin.VRGameViewportClient +NearClipPlane=2.000000 +LocalPlayerClassName=/Game/VRE/Core/CustomLocalPlayer.CustomLocalPlayer_C + +[/Script/HardwareTargeting.HardwareTargetingSettings] +TargetedHardwareClass=Desktop +TargetedHardwareClass=Desktop +AppliedTargetedHardwareClass=Desktop +DefaultGraphicsPerformance=Maximum +DefaultGraphicsPerformance=Maximum +AppliedDefaultGraphicsPerformance=Maximum + +[/Script/Engine.RendererSettings] +r.Nanite=0 +r.DefaultFeature.AmbientOcclusion=False +r.DefaultFeature.AmbientOcclusionStaticFraction=False +vr.InstancedStereo=False +r.SeparateTranslucency=0 +r.HZBOcclusion=0 +r.EyeAdaptionQuality=0 +r.SSR.MaxRoughness=0 +r.rhicmdbypass=0 +r.TiledReflectionEnvironmentMinimumCount=10 +r.ForwardShading=True +r.DefaultFeature.AntiAliasing=3 +r.AllowStaticLighting=True +r.DefaultFeature.MotionBlur=False +r.DefaultFeature.Bloom=True +r.DefaultFeature.AutoExposure=False +r.CustomDepth=3 +r.CustomDepthTemporalAAJitter=True +r.EarlyZPass=3 +r.EarlyZPassMovable=True +r.GBufferFormat=1 +r.Mobile.UseHWsRGBEncoding=True +r.MobileMSAA=4 +r.MobileHDR=True +r.AntiAliasingMethod=3 +r.Mobile.AntiAliasing=3 +vr.VRS.HMDFixedFoveationDynamic=False +vr.VRS.HMDFixedFoveationLevel=0 +vr.MobileMultiView=True +r.Mobile.ShadingPath=0 +r.Lumen.Reflections.HardwareRayTracing.Translucent.Refraction.EnableForProject=False +r.RayTracing=False +r.Nanite.ProjectEnabled=False +r.NormalMapsForStaticLighting=False + +[/Script/NavigationSystem.NavigationSystemV1] +bAutoCreateNavigationData=True +bAllowClientSideNavigation=True +bInitialBuildingLocked=False +bSkipAgentHeightCheckWhenPickingNavData=False +DataGatheringMode=Instant +bGenerateNavigationOnlyAroundNavigationInvokers=False +ActiveTilesUpdateInterval=1.000000 +DirtyAreasUpdateFreq=60.000000 + +[/Script/Engine.UserInterfaceSettings] +RenderFocusRule=NavigationOnly +DefaultCursor=None +TextEditBeamCursor=None +CrosshairsCursor=None +HandCursor=None +GrabHandCursor=None +GrabHandClosedCursor=None +SlashedCircleCursor=None +ApplicationScale=1.000000 +UIScaleRule=ShortestSide +CustomScalingRuleClass=None +UIScaleCurve=(EditorCurveData=(PreInfinityExtrap=RCCE_Constant,PostInfinityExtrap=RCCE_Constant,Keys=((Time=480.000000,Value=0.444000),(Time=720.000000,Value=0.666000),(Time=1080.000000,Value=1.000000),(Time=8640.000000,Value=8.000000)),DefaultValue=340282346638528859811704183484516925440.000000),ExternalCurve=None) + +[/Script/Engine.EndUserSettings] +bSendAnonymousUsageDataToEpic=False + +[/Script/OculusXRHMD.OculusXRHMDRuntimeSettings] ++SupportedDevices=Quest3 ++SupportedDevices=Quest2 ++SupportedDevices=QuestPro +SuggestedCpuPerfLevel=SustainedLow +SuggestedGpuPerfLevel=SustainedHigh +FoveatedRenderingMethod=FixedFoveatedRendering +FoveatedRenderingLevel=Off +bDynamicFoveatedRendering=True +bSupportEyeTrackedFoveatedRendering=False +bCompositeDepthMobile=False +bFocusAware=True +bLateLatching=False +bRequiresSystemKeyboard=False +bInsightPassthroughEnabled=False +bAnchorSupportEnabled=False +bAnchorSharingEnabled=False +bSceneSupportEnabled=False +bBoundaryVisibilitySupportEnabled=False +bDefaultBoundaryVisibilitySuppressed=False +bBodyTrackingEnabled=False +bEyeTrackingEnabled=False +bFaceTrackingEnabled=False +FaceTrackingDataSource=() +bDeploySoToDevice=False +bIterativeCookOnTheFly=False +bSupportExperimentalFeatures=False +ProcessorFavor=FavorEqually +bTileTurnOffEnabled=True +HandTrackingSupport=HandsOnly +HandTrackingVersion=V2 +HandTrackingFrequency=HIGH + +[/Script/Engine.CollisionProfile] +-Profiles=(Name="NoCollision",CollisionEnabled=NoCollision,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="No collision",bCanModify=False) +-Profiles=(Name="BlockAll",CollisionEnabled=QueryAndPhysics,ObjectTypeName="WorldStatic",CustomResponses=,HelpMessage="WorldStatic object that blocks all actors by default. All new custom channels will use its own default response. ",bCanModify=False) +-Profiles=(Name="OverlapAll",CollisionEnabled=QueryOnly,ObjectTypeName="WorldStatic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ",bCanModify=False) +-Profiles=(Name="BlockAllDynamic",CollisionEnabled=QueryAndPhysics,ObjectTypeName="WorldDynamic",CustomResponses=,HelpMessage="WorldDynamic object that blocks all actors by default. All new custom channels will use its own default response. ",bCanModify=False) +-Profiles=(Name="OverlapAllDynamic",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that overlaps all actors by default. All new custom channels will use its own default response. ",bCanModify=False) +-Profiles=(Name="IgnoreOnlyPawn",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that ignores Pawn and Vehicle. All other channels will be set to default.",bCanModify=False) +-Profiles=(Name="OverlapOnlyPawn",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that overlaps Pawn, Camera, and Vehicle. All other channels will be set to default. ",bCanModify=False) +-Profiles=(Name="Pawn",CollisionEnabled=QueryAndPhysics,ObjectTypeName="Pawn",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object. Can be used for capsule of any playerable character or AI. ",bCanModify=False) +-Profiles=(Name="Spectator",CollisionEnabled=QueryOnly,ObjectTypeName="Pawn",CustomResponses=((Channel="WorldStatic",Response=ECR_Block),(Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore),(Channel="PhysicsBody",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Destructible",Response=ECR_Ignore)),HelpMessage="Pawn object that ignores all other actors except WorldStatic.",bCanModify=False) +-Profiles=(Name="CharacterMesh",CollisionEnabled=QueryOnly,ObjectTypeName="Pawn",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object that is used for Character Mesh. All other channels will be set to default.",bCanModify=False) +-Profiles=(Name="PhysicsActor",CollisionEnabled=QueryAndPhysics,ObjectTypeName="PhysicsBody",CustomResponses=,HelpMessage="Simulating actors",bCanModify=False) +-Profiles=(Name="Destructible",CollisionEnabled=QueryAndPhysics,ObjectTypeName="Destructible",CustomResponses=,HelpMessage="Destructible actors",bCanModify=False) +-Profiles=(Name="InvisibleWall",CollisionEnabled=QueryAndPhysics,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldStatic object that is invisible.",bCanModify=False) +-Profiles=(Name="InvisibleWallDynamic",CollisionEnabled=QueryAndPhysics,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that is invisible.",bCanModify=False) +-Profiles=(Name="Trigger",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that is used for trigger. All other channels will be set to default.",bCanModify=False) +-Profiles=(Name="Ragdoll",CollisionEnabled=QueryAndPhysics,ObjectTypeName="PhysicsBody",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Simulating Skeletal Mesh Component. All other channels will be set to default.",bCanModify=False) +-Profiles=(Name="Vehicle",CollisionEnabled=QueryAndPhysics,ObjectTypeName="Vehicle",CustomResponses=,HelpMessage="Vehicle object that blocks Vehicle, WorldStatic, and WorldDynamic. All other channels will be set to default.",bCanModify=False) +-Profiles=(Name="UI",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Block),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ",bCanModify=False) ++Profiles=(Name="NoCollision",CollisionEnabled=NoCollision,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="No collision") ++Profiles=(Name="BlockAll",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=,HelpMessage="WorldStatic object that blocks all actors by default. All new custom channels will use its own default response. ") ++Profiles=(Name="OverlapAll",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ") ++Profiles=(Name="BlockAllDynamic",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=,HelpMessage="WorldDynamic object that blocks all actors by default. All new custom channels will use its own default response. ") ++Profiles=(Name="OverlapAllDynamic",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that overlaps all actors by default. All new custom channels will use its own default response. ") ++Profiles=(Name="IgnoreOnlyPawn",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that ignores Pawn and Vehicle. All other channels will be set to default.") ++Profiles=(Name="OverlapOnlyPawn",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that overlaps Pawn, Camera, and Vehicle. All other channels will be set to default. ") ++Profiles=(Name="Pawn",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object. Can be used for capsule of any playerable character or AI. ") ++Profiles=(Name="Spectator",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="WorldStatic"),(Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore),(Channel="PhysicsBody",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Destructible",Response=ECR_Ignore)),HelpMessage="Pawn object that ignores all other actors except WorldStatic.") ++Profiles=(Name="CharacterMesh",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object that is used for Character Mesh. All other channels will be set to default.") ++Profiles=(Name="PhysicsActor",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="PhysicsBody",CustomResponses=,HelpMessage="Simulating actors") ++Profiles=(Name="Destructible",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Destructible",CustomResponses=,HelpMessage="Destructible actors") ++Profiles=(Name="InvisibleWall",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldStatic object that is invisible.") ++Profiles=(Name="InvisibleWallDynamic",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that is invisible.") ++Profiles=(Name="Trigger",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that is used for trigger. All other channels will be set to default.") ++Profiles=(Name="Ragdoll",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="PhysicsBody",CustomResponses=((Channel="Pawn",Response=ECR_Ignore)),HelpMessage="Simulating Skeletal Mesh Component. All other channels will be set to default.") ++Profiles=(Name="Vehicle",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Vehicle",CustomResponses=,HelpMessage="Vehicle object that blocks Vehicle, WorldStatic, and WorldDynamic. All other channels will be set to default.") ++Profiles=(Name="UI",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility"),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ") ++Profiles=(Name="WaterBodyCollision",CollisionEnabled=QueryOnly,bCanModify=True,ObjectTypeName="",CustomResponses=,HelpMessage="For Water Plugin") ++DefaultChannelResponses=(Channel=ECC_GameTraceChannel1,DefaultResponse=ECR_Block,bTraceType=True,bStaticObject=False,Name="VRTraceChannel") ++DefaultChannelResponses=(Channel=ECC_GameTraceChannel2,DefaultResponse=ECR_Ignore,bTraceType=True,bStaticObject=False,Name="FloorTrace") ++DefaultChannelResponses=(Channel=ECC_GameTraceChannel3,DefaultResponse=ECR_Ignore,bTraceType=False,bStaticObject=False,Name="PawnWalking") ++EditProfiles=(Name="PhysicsActor",CustomResponses=((Channel="VRTraceChannel"))) ++EditProfiles=(Name="BlockAllDynamic",CustomResponses=((Channel="VRTraceChannel"))) +-ProfileRedirects=(OldName="BlockingVolume",NewName="InvisibleWall") +-ProfileRedirects=(OldName="InterpActor",NewName="IgnoreOnlyPawn") +-ProfileRedirects=(OldName="StaticMeshComponent",NewName="BlockAllDynamic") +-ProfileRedirects=(OldName="SkeletalMeshActor",NewName="PhysicsActor") +-ProfileRedirects=(OldName="InvisibleActor",NewName="InvisibleWallDynamic") ++ProfileRedirects=(OldName="BlockingVolume",NewName="InvisibleWall") ++ProfileRedirects=(OldName="InterpActor",NewName="IgnoreOnlyPawn") ++ProfileRedirects=(OldName="StaticMeshComponent",NewName="BlockAllDynamic") ++ProfileRedirects=(OldName="SkeletalMeshActor",NewName="PhysicsActor") ++ProfileRedirects=(OldName="InvisibleActor",NewName="InvisibleWallDynamic") +-CollisionChannelRedirects=(OldName="Static",NewName="WorldStatic") +-CollisionChannelRedirects=(OldName="Dynamic",NewName="WorldDynamic") +-CollisionChannelRedirects=(OldName="VehicleMovement",NewName="Vehicle") +-CollisionChannelRedirects=(OldName="PawnMovement",NewName="Pawn") ++CollisionChannelRedirects=(OldName="Static",NewName="WorldStatic") ++CollisionChannelRedirects=(OldName="Dynamic",NewName="WorldDynamic") ++CollisionChannelRedirects=(OldName="VehicleMovement",NewName="Vehicle") ++CollisionChannelRedirects=(OldName="PawnMovement",NewName="Pawn") + +[/Script/NavigationSystem.RecastNavMesh] +RuntimeGeneration=Dynamic + +[/Script/VRExpansionPlugin.VRGlobalSettings] +DefaultGrippableCharacterMeshComponentClass=/Script/CoreUObject.Class'/Script/VRExpansionPlugin.GrippableSkeletalMeshComponent' +bUseCollisionModificationForCollisionIgnore=False +CollisionIgnoreSubsystemUpdateRate=1.000000 +bUseChaosTranslationScalers=False +bSetEngineChaosScalers=False +LinearDriveStiffnessScale=1.500000 +LinearDriveDampingScale=0.700000 +AngularDriveStiffnessScale=0.300000 +AngularDriveDampingScale=0.300000 +JointStiffness=1.000000 +SoftLinearStiffnessScale=1.500000 +SoftLinearDampingScale=1.200000 +SoftAngularStiffnessScale=100000.000000 +SoftAngularDampingScale=1000.000000 +JointLinearBreakScale=1.000000 +JointAngularBreakScale=1.000000 +bLerpHybridWithSweepGrips=True +bOnlyLerpHybridRotation=False +bHybridWithSweepUseDistanceBasedLerp=True +HybridWithSweepLerpDuration=0.660000 +bUseGlobalLerpToHand=False +bSkipLerpToHandIfHeld=False +MinDistanceForLerp=10.000000 +LerpDuration=0.250000 +MinSpeedForLerp=100.000000 +MaxSpeedForLerp=500.000000 +LerpInterpolationMode=QuatInterp +bUseCurve=False +OptionalCurveToFollow=(EditorCurveData=(Keys=,DefaultValue=340282346638528859811704183484516925440.000000,PreInfinityExtrap=RCCE_Constant,PostInfinityExtrap=RCCE_Constant),ExternalCurve=None) ++MeleeSurfaceSettings=(bSurfaceAllowsPenetration=True,BluntDamageScaler=1.000000,SharpDamageScaler=1.000000,StabVelocityScaler=1.000000,SurfaceType=SurfaceType2) ++MeleeSurfaceSettings=(bSurfaceAllowsPenetration=True,BluntDamageScaler=1.000000,SharpDamageScaler=1.000000,StabVelocityScaler=2.000000,SurfaceType=SurfaceType1) +VirtualStockSettings=(bUseDistanceBasedStockSnapping=True,StockSnapDistance=35.000000,StockSnapLerpThreshold=20.000000,StockLerpValue=0.000000,StockSnapOffset=(X=0.000000,Y=0.000000,Z=0.000000),bAdjustZOfStockToPrimaryHand=True,bSmoothStockHand=True,SmoothingValueForStock=1.000000,StockHandSmoothing=(MinCutoff=0.100000,DeltaCutoff=10.000000,CutoffSlope=10.000000),bDebugDrawVirtualStock=False) +OneEuroMinCutoff=0.100000 +OneEuroCutoffSlope=10.000000 +OneEuroDeltaCutoff=10.000000 ++ControllerProfiles=(ControllerName="Oculus_Touch_Steam",SocketOffsetTransform=(Rotation=(X=0.000000,Y=-0.000000,Z=0.000000,W=1.000000),Translation=(X=0.000000,Y=0.000000,Z=0.000000),Scale3D=(X=1.000000,Y=1.000000,Z=1.000000)),bUseSeperateHandOffsetTransforms=False,SocketOffsetTransformRightHand=(Rotation=(X=0.000000,Y=0.000000,Z=0.000000,W=1.000000),Translation=(X=0.000000,Y=0.000000,Z=0.000000),Scale3D=(X=1.000000,Y=1.000000,Z=1.000000))) ++ControllerProfiles=(ControllerName="Oculus_Touch_Home",SocketOffsetTransform=(Rotation=(X=0.000000,Y=-0.000000,Z=0.000000,W=1.000000),Translation=(X=0.000000,Y=0.000000,Z=0.000000),Scale3D=(X=1.000000,Y=1.000000,Z=1.000000)),bUseSeperateHandOffsetTransforms=False,SocketOffsetTransformRightHand=(Rotation=(X=0.000000,Y=0.000000,Z=0.000000,W=1.000000),Translation=(X=0.000000,Y=0.000000,Z=0.000000),Scale3D=(X=1.000000,Y=1.000000,Z=1.000000))) ++ControllerProfiles=(ControllerName="Vive_Wands",SocketOffsetTransform=(Rotation=(X=0.000000,Y=0.000000,Z=0.000000,W=1.000000),Translation=(X=0.000000,Y=0.000000,Z=0.000000),Scale3D=(X=1.000000,Y=1.000000,Z=1.000000)),bUseSeperateHandOffsetTransforms=False,SocketOffsetTransformRightHand=(Rotation=(X=0.000000,Y=0.000000,Z=0.000000,W=1.000000),Translation=(X=0.000000,Y=0.000000,Z=0.000000),Scale3D=(X=1.000000,Y=1.000000,Z=1.000000))) ++ControllerProfiles=(ControllerName="Windows_MR",SocketOffsetTransform=(Rotation=(X=0.000000,Y=-0.000000,Z=0.000000,W=1.000000),Translation=(X=0.000000,Y=0.000000,Z=0.000000),Scale3D=(X=1.000000,Y=1.000000,Z=1.000000)),bUseSeperateHandOffsetTransforms=True,SocketOffsetTransformRightHand=(Rotation=(X=0.000000,Y=-0.000000,Z=0.000000,W=1.000000),Translation=(X=0.000000,Y=0.000000,Z=0.000000),Scale3D=(X=1.000000,Y=1.000000,Z=1.000000))) ++ControllerProfiles=(ControllerName="FPS_Pawn",SocketOffsetTransform=(Rotation=(X=0.000000,Y=-0.573576,Z=0.000000,W=0.819152),Translation=(X=0.000000,Y=0.000000,Z=0.000000),Scale3D=(X=1.000000,Y=1.000000,Z=1.000000)),bUseSeperateHandOffsetTransforms=False,SocketOffsetTransformRightHand=(Rotation=(X=0.000000,Y=0.000000,Z=0.000000,W=1.000000),Translation=(X=0.000000,Y=0.000000,Z=0.000000),Scale3D=(X=1.000000,Y=1.000000,Z=1.000000))) ++ControllerProfiles=(ControllerName="KnucklesEV2",SocketOffsetTransform=(Rotation=(X=-0.000000,Y=-0.000000,Z=0.000000,W=1.000000),Translation=(X=0.000000,Y=0.000000,Z=0.000000),Scale3D=(X=1.000000,Y=1.000000,Z=1.000000)),bUseSeperateHandOffsetTransforms=True,SocketOffsetTransformRightHand=(Rotation=(X=0.000000,Y=-0.000000,Z=0.000000,W=1.000000),Translation=(X=0.000000,Y=0.000000,Z=0.000000),Scale3D=(X=1.000000,Y=1.000000,Z=1.000000))) ++ControllerProfiles=(ControllerName="SenseGlove_HandTracking",SocketOffsetTransform=(Rotation=(X=-0.892539,Y=-0.157379,Z=-0.416198,W=0.073387),Translation=(X=-4.000000,Y=-11.000000,Z=2.000000),Scale3D=(X=1.000000,Y=1.000000,Z=1.000000)),bUseSeperateHandOffsetTransforms=True,SocketOffsetTransformRightHand=(Rotation=(X=-0.892539,Y=0.157379,Z=-0.416198,W=-0.073387),Translation=(X=-4.000000,Y=11.000000,Z=2.000000),Scale3D=(X=1.000000,Y=1.000000,Z=1.000000))) + +[/Script/Engine.PhysicsSettings] +DefaultGravityZ=-980.000000 +DefaultTerminalVelocity=4000.000000 +DefaultFluidFriction=0.300000 +SimulateScratchMemorySize=262144 +RagdollAggregateThreshold=4 +TriangleMeshTriangleMinAreaThreshold=5.000000 +bEnableShapeSharing=False +bEnablePCM=True +bEnableStabilization=False +bWarnMissingLocks=True +bEnable2DPhysics=False +PhysicErrorCorrection=(PingExtrapolation=0.100000,PingLimit=100.000000,ErrorPerLinearDifference=1.000000,ErrorPerAngularDifference=1.000000,MaxRestoredStateError=1.000000,MaxLinearHardSnapDistance=400.000000,PositionLerp=0.000000,AngleLerp=0.400000,LinearVelocityCoefficient=100.000000,AngularVelocityCoefficient=10.000000,ErrorAccumulationSeconds=0.500000,ErrorAccumulationDistanceSq=15.000000,ErrorAccumulationSimilarity=100.000000) +DefaultDegreesOfFreedom=Full3D +BounceThresholdVelocity=200.000000 +FrictionCombineMode=Average +RestitutionCombineMode=Average +MaxAngularVelocity=3600.000000 +MaxDepenetrationVelocity=0.000000 +ContactOffsetMultiplier=0.020000 +MinContactOffset=2.000000 +MaxContactOffset=8.000000 +bSimulateSkeletalMeshOnDedicatedServer=True +DefaultShapeComplexity=CTF_UseSimpleAndComplex +bSuppressFaceRemapTable=False +bSupportUVFromHitResults=False +bDisableActiveActors=False +bDisableKinematicStaticPairs=False +bDisableKinematicKinematicPairs=False +bDisableCCD=False +bEnableEnhancedDeterminism=False +AnimPhysicsMinDeltaTime=0.000000 +bSimulateAnimPhysicsAfterReset=False +MaxPhysicsDeltaTime=0.033333 +bSubstepping=True +bSubsteppingAsync=False +MaxSubstepDeltaTime=0.016667 +MaxSubsteps=6 +SyncSceneSmoothingFactor=0.000000 +InitialAverageFrameRate=0.016667 +PhysXTreeRebuildRate=10 ++PhysicalSurfaces=(Type=SurfaceType1,Name="Flesh") ++PhysicalSurfaces=(Type=SurfaceType2,Name="Wood") +DefaultBroadphaseSettings=(bUseMBPOnClient=False,bUseMBPOnServer=False,bUseMBPOuterBounds=False,MBPBounds=(Min=(X=0.000000,Y=0.000000,Z=0.000000),Max=(X=0.000000,Y=0.000000,Z=0.000000),IsValid=0),MBPOuterBounds=(Min=(X=0.000000,Y=0.000000,Z=0.000000),Max=(X=0.000000,Y=0.000000,Z=0.000000),IsValid=0),MBPNumSubdivs=2) +ChaosSettings=(DefaultThreadingModel=SingleThread,DedicatedThreadTickMode=VariableCapped,DedicatedThreadBufferMode=Double) +SolverOptions=(Iterations=8,CollisionPairIterations=1,PushOutIterations=4,CollisionPushOutPairIterations=4,CollisionMarginFraction=0.050000,CollisionMarginMax=10.000000,CollisionCullDistance=3.000000,CollisionMaxPushOutVelocity=100000.000000,JointPairIterations=1,JointPushOutPairIterations=1,ClusterConnectionFactor=1.000000,ClusterUnionConnectionType=DelaunayTriangulation,bGenerateCollisionData=False,CollisionFilterSettings=(FilterEnabled=False,MinMass=0.000000,MinSpeed=0.000000,MinImpulse=0.000000),bGenerateBreakData=False,BreakingFilterSettings=(FilterEnabled=False,MinMass=0.000000,MinSpeed=0.000000,MinVolume=0.000000),bGenerateTrailingData=False,TrailingFilterSettings=(FilterEnabled=False,MinMass=0.000000,MinSpeed=0.000000,MinVolume=0.000000),bGenerateContactGraph=True) + +[/Script/AndroidRuntimeSettings.AndroidRuntimeSettings] +PackageName=com.YourCompany.[PROJECT] +StoreVersion=1 +StoreVersionOffsetArm64=0 +StoreVersionOffsetX8664=0 +ApplicationDisplayName= +VersionDisplayName=1.0 +MinSDKVersion=32 +TargetSDKVersion=33 +InstallLocation=InternalOnly +bEnableLint=False +bPackageDataInsideApk=False +bCreateAllPlatformsInstall=False +bDisableVerifyOBBOnStartUp=False +bForceSmallOBBFiles=False +bAllowLargeOBBFiles=False +bAllowPatchOBBFile=False +bAllowOverflowOBBFiles=False +bUseExternalFilesDir=False +bPublicLogFiles=True +Orientation=SensorLandscape +MaxAspectRatio=2.100000 +bUseDisplayCutout=False +bRestoreNotificationsOnReboot=False +bFullScreen=True +bEnableNewKeyboard=True +DepthBufferPreference=Default +bValidateTextureFormats=True +bForceCompressNativeLibs=False +bEnableAdvancedBinaryCompression=True +bEnableBundle=False +bEnableUniversalAPK=False +bBundleABISplit=True +bBundleLanguageSplit=True +bBundleDensitySplit=True +ExtraApplicationSettings= +ExtraActivitySettings= +bAndroidVoiceEnabled=False +bEnableMulticastSupport=False +bPackageForMetaQuest=True +bRemoveOSIG=True +KeyStore= +KeyAlias= +KeyStorePassword= +KeyPassword= +bBuildForArm64=True +bBuildForX8664=False +bBuildForES31=False +bSupportsVulkan=True +bSupportsVulkanSM5=False +DebugVulkanLayerDirectory=(Path="") +bAndroidOpenGLSupportsBackbufferSampling=False +bDetectVulkanByDefault=True +bBuildWithHiddenSymbolVisibility=False +bDisableStackProtector=False +bDisableLibCppSharedDependencyValidation=False +bSaveSymbols=False +bStripShaderReflection=True +bEnableGooglePlaySupport=False +bUseGetAccounts=False +GamesAppID= +bEnableSnapshots=False +bSupportAdMob=True +AdMobAppID= +TagForChildDirectedTreatment=TAG_FOR_CHILD_DIRECTED_TREATMENT_UNSPECIFIED +TagForUnderAgeOfConsent=TAG_FOR_UNDER_AGE_OF_CONSENT_UNSPECIFIED +MaxAdContentRating=MAX_AD_CONTENT_RATING_G +AdMobAdUnitID= +GooglePlayLicenseKey= +GCMClientSenderID= +bShowLaunchImage=True +bAllowIMU=True +bAllowControllers=True +bBlockAndroidKeysOnControllers=False +bControllersBlockDeviceFeedback=False +AndroidAudio=Default +AudioSampleRate=44100 +AudioCallbackBufferFrameSize=1024 +AudioNumBuffersToEnqueue=4 +AudioMaxChannels=0 +AudioNumSourceWorkers=0 +SpatializationPlugin= +SourceDataOverridePlugin= +ReverbPlugin= +OcclusionPlugin= +CompressionOverrides=(bOverrideCompressionTimes=False,DurationThreshold=5.000000,MaxNumRandomBranches=0,SoundCueQualityIndex=0) +CacheSizeKB=0 +MaxChunkSizeOverrideKB=0 +bResampleForDevice=False +SoundCueCookQualityIndex=-1 +MaxSampleRate=0.000000 +HighSampleRate=0.000000 +MedSampleRate=0.000000 +LowSampleRate=0.000000 +MinSampleRate=0.000000 +CompressionQualityModifier=0.000000 +AutoStreamingThreshold=0.000000 +AndroidGraphicsDebugger=None +MaliGraphicsDebuggerPath=(Path="") +bEnableMaliPerfCounters=False +bMultiTargetFormat_ETC2=True +bMultiTargetFormat_DXT=True +bMultiTargetFormat_ASTC=True +TextureFormatPriority_ETC2=0.200000 +TextureFormatPriority_DXT=0.600000 +TextureFormatPriority_ASTC=0.900000 +SDKAPILevelOverride= +NDKAPILevelOverride= +BuildToolsOverride= +bStreamLandscapeMeshLODs=False +bEnableDomStorage=False + +[/Script/OculusHMD.OculusHMDRuntimeSettings] +FFRLevel=FFR_Medium +HandTrackingSupport=ControllersAndHands + +[/Script/LinuxTargetPlatform.LinuxTargetSettings] +SpatializationPlugin= +ReverbPlugin= +OcclusionPlugin= +SoundCueCookQualityIndex=-1 +-TargetedRHIs=SF_VULKAN_SM5 ++TargetedRHIs=SF_VULKAN_SM5 ++TargetedRHIs=SF_VULKAN_ES31 + +[/Script/AndroidFileServerEditor.AndroidFileServerRuntimeSettings] +bEnablePlugin=True +bAllowNetworkConnection=True +SecurityToken=A20E6C4847E893682C3EDFA6620C12B0 +bIncludeInShipping=False +bAllowExternalStartInShipping=False +bCompileAFSProject=False +bUseCompression=False +bLogFiles=False +bReportStats=False +ConnectionType=USBOnly +bUseManualIPAddress=False +ManualIPAddress= + +[/Script/WindowsTargetPlatform.WindowsTargetSettings] +DefaultGraphicsRHI=DefaultGraphicsRHI_DX12 + +[URL] +GameName=SGVRETemplate + diff --git a/Config/DefaultGame.ini b/Config/DefaultGame.ini new file mode 100644 index 0000000..038038c --- /dev/null +++ b/Config/DefaultGame.ini @@ -0,0 +1,53 @@ +[/Script/EngineSettings.GeneralProjectSettings] +ProjectID=567B108A44C2B2D804F0208CBFD47729 +ProjectName=Senseglove VRExpansion Demo +bStartInVR=True +CopyrightNotice=Copyright (c) 2024 Senseglove. All rights reserved. + +[/Script/Engine.GameNetworkManager] +TotalNetBandwidth=64000 +MaxDynamicBandwidth=15000 +MinDynamicBandwidth=4000 + +[/Script/Engine.GameSession] +bRequiresPushToTalk=true + +[/Script/UnrealEd.ProjectPackagingSettings] +Build=IfProjectHasCode +BuildConfiguration=PPBC_Development +BuildTarget= +StagingDirectory=(Path="E:/DESKTOP/VRExpPluginTestMulti") +FullRebuild=False +ForDistribution=False +IncludeDebugFiles=False +bExcludeMonolithicEngineHeadersInNativizedCode=False +UsePakFile=True +bUseIoStore=False +bGenerateChunks=False +bGenerateNoChunks=False +bChunkHardReferencesOnly=False +bForceOneChunkPerFile=False +MaxChunkSize=0 +bBuildHttpChunkInstallData=False +HttpChunkInstallDataDirectory=(Path="") +PakFileCompressionFormats= +PakFileAdditionalCompressionOptions= +HttpChunkInstallDataVersion= +IncludePrerequisites=True +IncludeAppLocalPrerequisites=False +bShareMaterialShaderCode=False +bDeterministicShaderCodeOrder=False +bSharedMaterialNativeLibraries=False +ApplocalPrerequisitesDirectory=(Path="") +IncludeCrashReporter=True +InternationalizationPreset=English +-CulturesToStage=en ++CulturesToStage=en +LocalizationTargetCatchAllChunkId=0 +bCookAll=False +bCookMapsOnly=True +bCompressed=True +bSkipEditorContent=False +bSkipMovies=False ++DirectoriesToAlwaysCook=(Path="/Game/VRE") + diff --git a/Config/DefaultGameplayTags.ini b/Config/DefaultGameplayTags.ini new file mode 100644 index 0000000..6b861de --- /dev/null +++ b/Config/DefaultGameplayTags.ini @@ -0,0 +1,11 @@ + +[/Script/GameplayTags.GameplayTagsSettings] +ImportTagsFromConfig=False +WarnOnInvalidTags=True +FastReplication=True ++GameplayTagTableList=/Game/VRE/Core/DefaultGameplayTags.DefaultGameplayTags +NumBitsForContainerSize=6 +NetIndexFirstBitSegment=16 + + + diff --git a/Config/DefaultInput.ini b/Config/DefaultInput.ini new file mode 100644 index 0000000..b4e868f --- /dev/null +++ b/Config/DefaultInput.ini @@ -0,0 +1,204 @@ + + +[/Script/Engine.InputSettings] +-AxisConfig=(AxisKeyName="Gamepad_LeftX",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f)) +-AxisConfig=(AxisKeyName="Gamepad_LeftY",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f)) +-AxisConfig=(AxisKeyName="Gamepad_RightX",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f)) +-AxisConfig=(AxisKeyName="Gamepad_RightY",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f)) +-AxisConfig=(AxisKeyName="MouseX",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f)) +-AxisConfig=(AxisKeyName="MouseY",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f)) +-AxisConfig=(AxisKeyName="Mouse2D",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f)) ++AxisConfig=(AxisKeyName="Mouse2D",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_RightY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MouseX",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MouseY",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MouseWheelAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_LeftTriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_RightTriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MotionController_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MotionController_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MotionController_Left_TriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MotionController_Left_Grip1Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MotionController_Left_Grip2Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MotionController_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MotionController_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MotionController_Right_TriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MotionController_Right_Grip1Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MotionController_Right_Grip2Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_Special_Left_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_Special_Left_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_FaceButton1",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_Trigger",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_FaceButton2",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_IndexPointing",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_ThumbUp",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_FaceButton1",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_Trigger",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_FaceButton2",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_IndexPointing",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_ThumbUp",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_LeftX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_LeftY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_RightX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Daydream_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Daydream_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Daydream_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Daydream_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusGo_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusGo_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusGo_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusGo_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Grip_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Touch",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Grip_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) +bAltEnterTogglesFullscreen=True +bF11TogglesFullscreen=True +bUseMouseForTouch=False +bEnableMouseSmoothing=True +bEnableFOVScaling=True +bCaptureMouseOnLaunch=True +bEnableLegacyInputScales=True +bEnableMotionControls=True +bFilterInputByPlatformUser=False +bShouldFlushPressedKeysOnViewportFocusLost=True +bEnableDynamicComponentInputBinding=True +bAlwaysShowTouchInterface=False +bShowConsoleOnFourFingerTap=True +bEnableGestureRecognizer=False +bUseAutocorrect=False +DefaultViewportMouseCaptureMode=CapturePermanently_IncludingInitialMouseDown +DefaultViewportMouseLockMode=LockOnCapture +FOVScale=0.011110 +DoubleClickTime=0.200000 ++ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=SpaceBar) ++ActionMappings=(ActionName="TeleportLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=T) ++ActionMappings=(ActionName="TeleportRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Right_Thumbstick_Touch) ++ActionMappings=(ActionName="TeleportRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Right_Trackpad_Touch) ++ActionMappings=(ActionName="TeleportRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Right_Thumbstick_Click) ++ActionMappings=(ActionName="TeleportRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Right_Thumbstick_Click) ++ActionMappings=(ActionName="AlternateGripRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Right_Grip_Click) ++ActionMappings=(ActionName="AlternateGripRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Right_A_Click) ++ActionMappings=(ActionName="AlternateGripRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Right_A_Click) ++ActionMappings=(ActionName="AlternateGripRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Right_Grip_Click) ++ActionMappings=(ActionName="AlternateGripLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Left_Grip_Click) ++ActionMappings=(ActionName="AlternateGripLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Left_Grip_Click) ++ActionMappings=(ActionName="AlternateGripLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Left_X_Click) ++ActionMappings=(ActionName="AlternateGripLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Left_A_Click) ++ActionMappings=(ActionName="PrimaryGripLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Left_Trigger_Click) ++ActionMappings=(ActionName="PrimaryGripLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Left_Trigger_Click) ++ActionMappings=(ActionName="PrimaryGripLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Left_Grip_Click) ++ActionMappings=(ActionName="PrimaryGripLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Left_Grip_Force) ++ActionMappings=(ActionName="PrimaryGripRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Right_Trigger_Click) ++ActionMappings=(ActionName="PrimaryGripRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Right_Trigger_Click) ++ActionMappings=(ActionName="PrimaryGripRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Right_Grip_Click) ++ActionMappings=(ActionName="PrimaryGripRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Right_Grip_Force) ++ActionMappings=(ActionName="TeleportLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Left_Thumbstick_Click) ++ActionMappings=(ActionName="TeleportLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Left_Thumbstick_Click) ++ActionMappings=(ActionName="TeleportLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Left_Thumbstick_Touch) ++ActionMappings=(ActionName="TeleportLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Left_Trackpad_Touch) ++ActionMappings=(ActionName="LaserBeamRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Right_Menu_Click) ++ActionMappings=(ActionName="LaserBeamRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Right_B_Click) ++ActionMappings=(ActionName="LaserBeamRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Right_Thumbstick_Down) ++ActionMappings=(ActionName="LaserBeamRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Right_B_Click) ++ActionMappings=(ActionName="LaserBeamLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Left_Menu_Click) ++ActionMappings=(ActionName="LaserBeamLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Left_B_Click) ++ActionMappings=(ActionName="LaserBeamLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Left_Y_Click) ++ActionMappings=(ActionName="LaserBeamLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Left_Thumbstick_Down) ++ActionMappings=(ActionName="LaserBeamLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=L) ++ActionMappings=(ActionName="LaserBeamRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=L) ++ActionMappings=(ActionName="PrimaryGripRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=RightMouseButton) ++ActionMappings=(ActionName="PrimaryGripLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=LeftMouseButton) ++ActionMappings=(ActionName="UseHeldObjectLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Left_Trigger_Click) ++ActionMappings=(ActionName="UseHeldObjectRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Right_Trigger_Click) ++ActionMappings=(ActionName="UseHeldObjectLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Left_Trigger_Click) ++ActionMappings=(ActionName="UseHeldObjectLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Left_Trigger_Click) ++ActionMappings=(ActionName="UseHeldObjectLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Left_Trigger_Click) ++ActionMappings=(ActionName="UseHeldObjectRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Right_Trigger_Click) ++ActionMappings=(ActionName="UseHeldObjectRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Right_Trigger_Click) ++ActionMappings=(ActionName="UseHeldObjectRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Right_Trigger_Click) ++ActionMappings=(ActionName="UseHeldObjectLeft",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=LeftMouseButton) ++ActionMappings=(ActionName="UseHeldObjectRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=RightMouseButton) ++ActionMappings=(ActionName="TeleportRight",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=T) ++AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=W) ++AxisMappings=(AxisName="MoveForward",Scale=-1.000000,Key=S) ++AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=D) ++AxisMappings=(AxisName="MoveRight",Scale=-1.000000,Key=A) ++AxisMappings=(AxisName="TurnRate",Scale=-1.000000,Key=Left) ++AxisMappings=(AxisName="TurnRate",Scale=1.000000,Key=Right) ++AxisMappings=(AxisName="LookUp",Scale=-1.000000,Key=MouseY) ++AxisMappings=(AxisName="Turn",Scale=1.000000,Key=MouseX) ++AxisMappings=(AxisName="TeleportDirectionUp",Scale=1.000000,Key=Gamepad_LeftY) ++AxisMappings=(AxisName="TeleportDirectionRight",Scale=1.000000,Key=Gamepad_LeftX) ++AxisMappings=(AxisName="MotionControllerThumbLeft_Y",Scale=1.000000,Key=ValveIndex_Left_Thumbstick_Y) ++AxisMappings=(AxisName="MotionControllerThumbLeft_Y",Scale=1.000000,Key=Vive_Left_Trackpad_Y) ++AxisMappings=(AxisName="MotionControllerThumbLeft_Y",Scale=1.000000,Key=OculusTouch_Left_Thumbstick_Y) ++AxisMappings=(AxisName="MotionControllerThumbLeft_Y",Scale=1.000000,Key=MixedReality_Left_Thumbstick_Y) ++AxisMappings=(AxisName="MotionControllerThumbLeft_X",Scale=1.000000,Key=ValveIndex_Left_Thumbstick_X) ++AxisMappings=(AxisName="MotionControllerThumbLeft_X",Scale=1.000000,Key=Vive_Left_Trackpad_X) ++AxisMappings=(AxisName="MotionControllerThumbLeft_X",Scale=1.000000,Key=OculusTouch_Left_Thumbstick_X) ++AxisMappings=(AxisName="MotionControllerThumbLeft_X",Scale=1.000000,Key=MixedReality_Left_Thumbstick_X) ++AxisMappings=(AxisName="MotionControllerThumbRight_Y",Scale=1.000000,Key=ValveIndex_Right_Thumbstick_Y) ++AxisMappings=(AxisName="MotionControllerThumbRight_Y",Scale=1.000000,Key=Vive_Right_Trackpad_Y) ++AxisMappings=(AxisName="MotionControllerThumbRight_Y",Scale=1.000000,Key=OculusTouch_Right_Thumbstick_Y) ++AxisMappings=(AxisName="MotionControllerThumbRight_Y",Scale=1.000000,Key=MixedReality_Right_Thumbstick_Y) ++AxisMappings=(AxisName="MotionControllerThumbRight_X",Scale=1.000000,Key=ValveIndex_Right_Thumbstick_X) ++AxisMappings=(AxisName="MotionControllerThumbRight_X",Scale=1.000000,Key=Vive_Right_Trackpad_X) ++AxisMappings=(AxisName="MotionControllerThumbRight_X",Scale=1.000000,Key=OculusTouch_Right_Thumbstick_X) ++AxisMappings=(AxisName="MotionControllerThumbRight_X",Scale=1.000000,Key=MixedReality_Right_Thumbstick_X) ++AxisMappings=(AxisName="ControllerMovementLeft",Scale=1.000000,Key=Vive_Left_Trackpad_Click) ++AxisMappings=(AxisName="ControllerMovementLeft",Scale=1.000000,Key=ValveIndex_Left_Thumbstick_Touch) ++AxisMappings=(AxisName="ControllerMovementLeft",Scale=1.000000,Key=OculusTouch_Left_Thumbstick_Touch) ++AxisMappings=(AxisName="ControllerMovementLeft",Scale=1.000000,Key=MixedReality_Left_Thumbstick_Click) ++AxisMappings=(AxisName="ControllerMovementRight",Scale=1.000000,Key=ValveIndex_Right_Thumbstick_Touch) ++AxisMappings=(AxisName="ControllerMovementRight",Scale=1.000000,Key=Vive_Right_Trackpad_Click) ++AxisMappings=(AxisName="ControllerMovementRight",Scale=1.000000,Key=OculusTouch_Right_Thumbstick_Touch) ++AxisMappings=(AxisName="ControllerMovementRight",Scale=1.000000,Key=MixedReality_Right_Thumbstick_Click) +DefaultPlayerInputClass=/Script/EnhancedInput.EnhancedPlayerInput +DefaultInputComponentClass=/Script/EnhancedInput.EnhancedInputComponent +DefaultTouchInterface=None +-ConsoleKeys=Tilde ++ConsoleKeys=Tilde + +[/Script/OpenXRInput.OpenXRInputSettings] +MappableInputConfig=/Game/VRE/Input/VREInputConfig.VREInputConfig + diff --git a/Config/DefaultScalability.ini b/Config/DefaultScalability.ini new file mode 100644 index 0000000..1107172 --- /dev/null +++ b/Config/DefaultScalability.ini @@ -0,0 +1,90 @@ + +[AntiAliasingQuality@0] +r.PostProcessAAQuality=0 + +[AntiAliasingQuality@1] +r.PostProcessAAQuality=2 + +[AntiAliasingQuality@2] +r.PostProcessAAQuality=3 + +[AntiAliasingQuality@3] +r.PostProcessAAQuality=3 + +;----------------------------------------------------------------------------------------------------------------- + +[PostProcessQuality@0] +r.MotionBlurQuality=0 +r.AmbientOcclusionLevels=0 +r.LensFlareQuality=0 +r.SceneColorFringeQuality=0 +r.DepthOfFieldQuality=0 +r.BloomQuality=1 +r.FastBlurThreshold=0 + +[PostProcessQuality@1] +r.MotionBlurQuality=0 +r.AmbientOcclusionLevels=0 +r.LensFlareQuality=0 +r.SceneColorFringeQuality=0 +r.DepthOfFieldQuality=0 +r.BloomQuality=1 +r.FastBlurThreshold=0 + +[PostProcessQuality@2] +r.MotionBlurQuality=0 +r.AmbientOcclusionLevels=0 +r.LensFlareQuality=0 +r.SceneColorFringeQuality=0 +r.DepthOfFieldQuality=0 +r.BloomQuality=1 +r.FastBlurThreshold=0 + +[PostProcessQuality@3] +r.MotionBlurQuality=0 +r.AmbientOcclusionLevels=0 +r.LensFlareQuality=0 +r.SceneColorFringeQuality=0 +r.DepthOfFieldQuality=0 +r.BloomQuality=1 +r.FastBlurThreshold=0 + +;----------------------------------------------------------------------------------------------------------------- + +[TextureQuality@0] +r.MaxAnisotropy=0 + +[TextureQuality@1] +r.MaxAnisotropy=2 + +[TextureQuality@2] +r.MaxAnisotropy=4 + +[TextureQuality@3] +r.MaxAnisotropy=8 + +;----------------------------------------------------------------------------------------------------------------- + +[EffectsQuality@0] +r.TranslucencyVolumeBlur=0 +r.TranslucencyLightingVolumeDim=4 +r.SceneColorFormat=2 +r.SSR.Quality=0 + +[EffectsQuality@1] +r.TranslucencyVolumeBlur=0 +r.TranslucencyLightingVolumeDim=4 +r.SceneColorFormat=2 +r.SSR.Quality=0 + +[EffectsQuality@2] +r.TranslucencyVolumeBlur=0 +r.TranslucencyLightingVolumeDim=4 +r.SceneColorFormat=2 +r.SSR.Quality=0 + +[EffectsQuality@3] +r.TranslucencyVolumeBlur=0 +r.TranslucencyLightingVolumeDim=4 +r.SceneColorFormat=2 +r.SSR.Quality=0 \ No newline at end of file diff --git a/Config/DefaultSenseGloveSettings.ini b/Config/DefaultSenseGloveSettings.ini new file mode 100644 index 0000000..e5ee688 --- /dev/null +++ b/Config/DefaultSenseGloveSettings.ini @@ -0,0 +1,5 @@ + + +[/Script/SenseGloveSettings.SGSettings] +TrackingSettings=(bFallbackToHandTrackingIfNoGloveDetected=False,GloveTrackingSettings=(GloveConnectivityCheckInterval=16.666666),HandTrackingSettings=(bUseMoreSpecificMotionSourceNames=False,bSupportLegacyControllerMotionSources=True),HMDTrackingSettings=(ViveHMDDetectionPriority=HtcViveFocus3First),WristTrackingSettings=(TrackingHardware=Quest3Controller,TrackingHardwareLocationOffsetLeftHand=(X=0.000000,Y=0.000000,Z=0.000000),TrackingHardwareLocationOffsetRightHand=(X=0.000000,Y=0.000000,Z=0.000000),TrackingHardwareRotationOffsetLeftHand=(Pitch=0.000000,Yaw=0.000000,Roll=0.000000),TrackingHardwareRotationOffsetRightHand=(Pitch=0.000000,Yaw=0.000000,Roll=0.000000),LeftHandMotionSource=Left,RightHandMotionSource=Right,DebuggingSettings=(bDrawDebugWristTracker=False,DebugWristTrackerSettings=(Length=4.000000,XAxisColor=(B=0,G=0,R=255,A=255),YAxisColor=(B=0,G=255,R=0,A=255),ZAxisColor=(B=255,G=0,R=0,A=255),bPersistentLines=False,LifeTimeModifier=1.100000,DepthPriority=0,Thickness=0.400000)))) + diff --git a/Config/HoloLens/HoloLensEngine.ini b/Config/HoloLens/HoloLensEngine.ini new file mode 100644 index 0000000..fa8a9a8 --- /dev/null +++ b/Config/HoloLens/HoloLensEngine.ini @@ -0,0 +1,31 @@ + + +[/Script/HoloLensPlatformEditor.HoloLensTargetSettings] +bBuildForEmulation=False +bBuildForDevice=True +bUseNameForLogo=True +bBuildForRetailWindowsStore=False +bAutoIncrementVersion=False +bShouldCreateAppInstaller=False +AppInstallerInstallationURL= +HoursBetweenUpdateChecks=0 +bEnablePIXProfiling=False +TileBackgroundColor=(B=64,G=0,R=0,A=255) +SplashScreenBackgroundColor=(B=64,G=0,R=0,A=255) ++PerCultureResources=(CultureId="",Strings=(PackageDisplayName="",PublisherDisplayName="",PackageDescription="",ApplicationDisplayName="",ApplicationDescription=""),Images=()) +TargetDeviceFamily=Windows.Holographic +MinimumPlatformVersion= +MaximumPlatformVersionTested=10.0.19041.0 +MaxTrianglesPerCubicMeter=500.000000 +SpatialMeshingVolumeSize=20.000000 +CompilerVersion=Default +Windows10SDKVersion=10.0.18362.0 ++CapabilityList=internetClientServer ++CapabilityList=privateNetworkClientServer ++Uap2CapabilityList=spatialPerception +bSetDefaultCapabilities=False +SpatializationPlugin= +ReverbPlugin= +OcclusionPlugin= +SoundCueCookQualityIndex=-1 + diff --git a/Config/SteamVRBindings/gamepad.json b/Config/SteamVRBindings/gamepad.json new file mode 100644 index 0000000..fff7db7 --- /dev/null +++ b/Config/SteamVRBindings/gamepad.json @@ -0,0 +1,13 @@ +{ + "name": "Default bindings for Gamepads", + "controller_type": "gamepad", + "last_edited_by": "UnrealEngine", + "bindings": + { + "/actions/main": + { + "sources": [] + } + }, + "description": "Virtual Reality BP Game Template-11100242" +} \ No newline at end of file diff --git a/Config/SteamVRBindings/holographic_controller.json b/Config/SteamVRBindings/holographic_controller.json new file mode 100644 index 0000000..b0267cd --- /dev/null +++ b/Config/SteamVRBindings/holographic_controller.json @@ -0,0 +1,229 @@ +{ + "name": "Default bindings for MixedReality", + "controller_type": "holographic_controller", + "last_edited_by": "UnrealEngine", + "bindings": + { + "/actions/main": + { + "sources": [ + { + "mode": "joystick", + "path": "/user/hand/left/input/joystick", + "inputs": + { + "click": + { + "output": "/actions/main/in/TeleportLeft" + } + } + }, + { + "mode": "joystick", + "path": "/user/hand/right/input/joystick", + "inputs": + { + "click": + { + "output": "/actions/main/in/TeleportRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/grip", + "inputs": + { + "click": + { + "output": "/actions/main/in/AlternateGripRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/grip", + "inputs": + { + "click": + { + "output": "/actions/main/in/AlternateGripLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/PrimaryGripLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/PrimaryGripRight" + } + } + }, + { + "mode": "dpad", + "path": "/user/hand/right/input/joystick", + "parameters": + { + "sub_mode": "touch" + }, + "inputs": + { + "south": + { + "output": "/actions/main/in/LaserBeamRight" + } + } + }, + { + "mode": "dpad", + "path": "/user/hand/left/input/joystick", + "parameters": + { + "sub_mode": "touch" + }, + "inputs": + { + "south": + { + "output": "/actions/main/in/LaserBeamLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/UseHeldObjectLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/UseHeldObjectRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/TriggerInteractionLEft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/TriggerInteractionRight" + } + } + }, + { + "mode": "joystick", + "path": "/user/hand/left/input/joystick", + "inputs": + { + "position": + { + "output": "/actions/main/in/MotionControllerThumbLeft_X,MotionControllerThumbLeft_Y X Y_axis2d" + } + } + }, + { + "mode": "joystick", + "path": "/user/hand/right/input/joystick", + "inputs": + { + "position": + { + "output": "/actions/main/in/MotionControllerThumbRight_X,MotionControllerThumbRight_Y X Y_axis2d" + } + } + }, + { + "mode": "scalar_constant", + "path": "/user/hand/left/input/joystick", + "inputs": + { + "value": + { + "output": "/actions/main/in/ControllerMovementLeft axis" + } + } + }, + { + "mode": "scalar_constant", + "path": "/user/hand/right/input/joystick", + "inputs": + { + "value": + { + "output": "/actions/main/in/ControllerMovementRight axis" + } + } + } + ], + "poses": [ + { + "output": "/actions/main/in/controllerleft", + "path": "/user/hand/left/pose/raw", + "requirement": "optional" + }, + { + "output": "/actions/main/in/controllerright", + "path": "/user/hand/right/pose/raw" + } + ], + "skeleton": [ + { + "output": "/actions/main/in/skeletonleft", + "path": "/user/hand/left/input/skeleton/left" + }, + { + "output": "/actions/main/in/skeletonright", + "path": "/user/hand/right/input/skeleton/right" + } + ], + "haptics": [ + { + "output": "/actions/main/out/vibrateleft", + "path": "/user/hand/left/output/haptic" + }, + { + "output": "/actions/main/out/vibrateright", + "path": "/user/hand/right/output/haptic" + } + ] + } + }, + "description": "Virtual Reality BP Game Template-11100242" +} \ No newline at end of file diff --git a/Config/SteamVRBindings/indexhmd.json b/Config/SteamVRBindings/indexhmd.json new file mode 100644 index 0000000..91f92fd --- /dev/null +++ b/Config/SteamVRBindings/indexhmd.json @@ -0,0 +1,13 @@ +{ + "name": "Default bindings for Valve Index Headset", + "controller_type": "indexhmd", + "last_edited_by": "UnrealEngine", + "bindings": + { + "/actions/main": + { + "sources": [] + } + }, + "description": "Virtual Reality BP Game Template-11100242" +} \ No newline at end of file diff --git a/Config/SteamVRBindings/knuckles.json b/Config/SteamVRBindings/knuckles.json new file mode 100644 index 0000000..efee109 --- /dev/null +++ b/Config/SteamVRBindings/knuckles.json @@ -0,0 +1,200 @@ +{ + "action_manifest_version" : 0, + "alias_info" : {}, + "app_key" : "application.generated.ue.virtual-reality-bp-game-template-14627614.ue4editor-win64-debuggame.exe", + "bindings" : { + "/actions/main" : { + "haptics" : [ + { + "output" : "/actions/main/out/vibrateleft", + "path" : "/user/hand/left/output/haptic" + }, + { + "output" : "/actions/main/out/vibrateright", + "path" : "/user/hand/right/output/haptic" + } + ], + "poses" : [ + { + "output" : "/actions/main/in/controllerleft", + "path" : "/user/hand/left/pose/raw", + "requirement" : "optional" + }, + { + "output" : "/actions/main/in/controllerright", + "path" : "/user/hand/right/pose/raw" + } + ], + "skeleton" : [ + { + "output" : "/actions/main/in/skeletonleft", + "path" : "/user/hand/left/input/skeleton/left" + }, + { + "output" : "/actions/main/in/skeletonright", + "path" : "/user/hand/right/input/skeleton/right" + } + ], + "sources" : [ + { + "inputs" : { + "east" : { + "output" : "/actions/main/in/teleportleft" + }, + "north" : { + "output" : "/actions/main/in/teleportleft" + }, + "south" : { + "output" : "/actions/main/in/teleportleft" + }, + "west" : { + "output" : "/actions/main/in/TeleportLeft" + } + }, + "mode" : "dpad", + "parameters" : { + "sub_mode" : "touch" + }, + "path" : "/user/hand/left/input/thumbstick" + }, + { + "inputs" : { + "east" : { + "output" : "/actions/main/in/teleportright" + }, + "north" : { + "output" : "/actions/main/in/teleportright" + }, + "south" : { + "output" : "/actions/main/in/teleportright" + }, + "west" : { + "output" : "/actions/main/in/teleportright" + } + }, + "mode" : "dpad", + "parameters" : { + "sub_mode" : "touch" + }, + "path" : "/user/hand/right/input/thumbstick" + }, + { + "inputs" : { + "click" : { + "output" : "/actions/main/in/AlternateGripRight" + } + }, + "mode" : "button", + "path" : "/user/hand/right/input/a" + }, + { + "inputs" : { + "click" : { + "output" : "/actions/main/in/AlternateGripLeft" + } + }, + "mode" : "button", + "path" : "/user/hand/left/input/a" + }, + { + "inputs" : { + "click" : { + "output" : "/actions/main/in/LaserBeamRight" + } + }, + "mode" : "button", + "path" : "/user/hand/right/input/b" + }, + { + "inputs" : { + "click" : { + "output" : "/actions/main/in/LaserBeamLeft" + } + }, + "mode" : "button", + "path" : "/user/hand/left/input/b" + }, + { + "inputs" : { + "click" : { + "output" : "/actions/main/in/UseHeldObjectLeft" + } + }, + "mode" : "trigger", + "path" : "/user/hand/left/input/trigger" + }, + { + "inputs" : { + "click" : { + "output" : "/actions/main/in/UseHeldObjectRight" + } + }, + "mode" : "trigger", + "path" : "/user/hand/right/input/trigger" + }, + { + "inputs" : { + "position" : { + "output" : "/actions/main/in/motioncontrollerthumbleft_x,motioncontrollerthumbleft_y x y_axis2d" + }, + "touch" : { + "output" : "/actions/main/in/controllermovementleft axis" + } + }, + "mode" : "joystick", + "parameters" : { + "deadzone_pct" : "10" + }, + "path" : "/user/hand/left/input/thumbstick" + }, + { + "inputs" : { + "position" : { + "output" : "/actions/main/in/MotionControllerThumbRight_X,MotionControllerThumbRight_Y X Y_axis2d" + }, + "touch" : { + "output" : "/actions/main/in/controllermovementright axis" + } + }, + "mode" : "joystick", + "parameters" : { + "deadzone_pct" : "10" + }, + "path" : "/user/hand/right/input/thumbstick" + }, + { + "inputs" : { + "click" : { + "output" : "/actions/main/in/primarygripleft" + } + }, + "mode" : "button", + "parameters" : { + "click_activate_threshold" : "1", + "click_deactivate_threshold" : "1" + }, + "path" : "/user/hand/left/input/grip" + }, + { + "inputs" : { + "click" : { + "output" : "/actions/main/in/primarygripright" + } + }, + "mode" : "button", + "parameters" : { + "click_activate_threshold" : "1", + "click_deactivate_threshold" : "1" + }, + "path" : "/user/hand/right/input/grip" + } + ] + } + }, + "category" : "steamvr_input", + "controller_type" : "knuckles", + "description" : "Virtual Reality BP Game Template-14627614", + "name" : "Default bindings for ValveIndex", + "options" : {}, + "simulated_actions" : [] +} diff --git a/Config/SteamVRBindings/oculus_touch.json b/Config/SteamVRBindings/oculus_touch.json new file mode 100644 index 0000000..22353e3 --- /dev/null +++ b/Config/SteamVRBindings/oculus_touch.json @@ -0,0 +1,221 @@ +{ + "name": "Default bindings for OculusTouch", + "controller_type": "oculus_touch", + "last_edited_by": "UnrealEngine", + "bindings": + { + "/actions/main": + { + "sources": [ + { + "mode": "joystick", + "path": "/user/hand/left/input/joystick", + "inputs": + { + "touch": + { + "output": "/actions/main/in/TeleportLeft" + } + } + }, + { + "mode": "joystick", + "path": "/user/hand/right/input/joystick", + "inputs": + { + "touch": + { + "output": "/actions/main/in/TeleportRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/a", + "inputs": + { + "click": + { + "output": "/actions/main/in/AlternateGripRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/x", + "inputs": + { + "click": + { + "output": "/actions/main/in/AlternateGripLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/grip", + "inputs": + { + "click": + { + "output": "/actions/main/in/PrimaryGripLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/grip", + "inputs": + { + "click": + { + "output": "/actions/main/in/PrimaryGripRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/b", + "inputs": + { + "touch": + { + "output": "/actions/main/in/LaserBeamRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/y", + "inputs": + { + "click": + { + "output": "/actions/main/in/LaserBeamLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/UseHeldObjectLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/UseHeldObjectRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/TriggerInteractionLEft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/TriggerInteractionRight" + } + } + }, + { + "mode": "joystick", + "path": "/user/hand/left/input/joystick", + "inputs": + { + "position": + { + "output": "/actions/main/in/MotionControllerThumbLeft_X,MotionControllerThumbLeft_Y X Y_axis2d" + } + } + }, + { + "mode": "joystick", + "path": "/user/hand/right/input/joystick", + "inputs": + { + "position": + { + "output": "/actions/main/in/MotionControllerThumbRight_X,MotionControllerThumbRight_Y X Y_axis2d" + } + } + }, + { + "mode": "scalar_constant", + "path": "/user/hand/left/input/joystick", + "inputs": + { + "value": + { + "output": "/actions/main/in/ControllerMovementLeft axis" + } + } + }, + { + "mode": "scalar_constant", + "path": "/user/hand/right/input/joystick", + "inputs": + { + "value": + { + "output": "/actions/main/in/ControllerMovementRight axis" + } + } + } + ], + "poses": [ + { + "output": "/actions/main/in/controllerleft", + "path": "/user/hand/left/pose/raw", + "requirement": "optional" + }, + { + "output": "/actions/main/in/controllerright", + "path": "/user/hand/right/pose/raw" + } + ], + "skeleton": [ + { + "output": "/actions/main/in/skeletonleft", + "path": "/user/hand/left/input/skeleton/left" + }, + { + "output": "/actions/main/in/skeletonright", + "path": "/user/hand/right/input/skeleton/right" + } + ], + "haptics": [ + { + "output": "/actions/main/out/vibrateleft", + "path": "/user/hand/left/output/haptic" + }, + { + "output": "/actions/main/out/vibrateright", + "path": "/user/hand/right/output/haptic" + } + ] + } + }, + "description": "Virtual Reality BP Game Template-11100242" +} \ No newline at end of file diff --git a/Config/SteamVRBindings/rift.json b/Config/SteamVRBindings/rift.json new file mode 100644 index 0000000..d1af9fe --- /dev/null +++ b/Config/SteamVRBindings/rift.json @@ -0,0 +1,13 @@ +{ + "name": "Default bindings for Rift Headset", + "controller_type": "rift", + "last_edited_by": "UnrealEngine", + "bindings": + { + "/actions/main": + { + "sources": [] + } + }, + "description": "Virtual Reality BP Game Template-11100242" +} \ No newline at end of file diff --git a/Config/SteamVRBindings/steamvr_manifest.json b/Config/SteamVRBindings/steamvr_manifest.json new file mode 100644 index 0000000..63a7eb7 --- /dev/null +++ b/Config/SteamVRBindings/steamvr_manifest.json @@ -0,0 +1,270 @@ +{ + "actions": [ + { + "name": "/actions/main/in/controllerleft", + "type": "pose", + "requirement": "optional" + }, + { + "name": "/actions/main/in/controllerright", + "type": "pose", + "requirement": "optional" + }, + { + "name": "/actions/main/in/special1", + "type": "pose", + "requirement": "optional" + }, + { + "name": "/actions/main/in/special2", + "type": "pose", + "requirement": "optional" + }, + { + "name": "/actions/main/in/special3", + "type": "pose", + "requirement": "optional" + }, + { + "name": "/actions/main/in/special4", + "type": "pose", + "requirement": "optional" + }, + { + "name": "/actions/main/in/special5", + "type": "pose", + "requirement": "optional" + }, + { + "name": "/actions/main/in/special6", + "type": "pose", + "requirement": "optional" + }, + { + "name": "/actions/main/in/special7", + "type": "pose", + "requirement": "optional" + }, + { + "name": "/actions/main/in/special8", + "type": "pose", + "requirement": "optional" + }, + { + "name": "/actions/main/in/skeletonleft", + "type": "skeleton", + "skeleton": "/skeleton/hand/left", + "requirement": "optional" + }, + { + "name": "/actions/main/in/skeletonright", + "type": "skeleton", + "skeleton": "/skeleton/hand/right", + "requirement": "optional" + }, + { + "name": "/actions/main/in/open_console", + "type": "boolean", + "requirement": "optional" + }, + { + "name": "/actions/main/out/vibrateleft", + "type": "vibration", + "requirement": "optional" + }, + { + "name": "/actions/main/out/vibrateright", + "type": "vibration", + "requirement": "optional" + }, + { + "name": "/actions/main/in/TeleportLeft", + "type": "boolean" + }, + { + "name": "/actions/main/in/TeleportRight", + "type": "boolean" + }, + { + "name": "/actions/main/in/AlternateGripRight", + "type": "boolean" + }, + { + "name": "/actions/main/in/AlternateGripLeft", + "type": "boolean" + }, + { + "name": "/actions/main/in/PrimaryGripLeft", + "type": "boolean" + }, + { + "name": "/actions/main/in/PrimaryGripRight", + "type": "boolean" + }, + { + "name": "/actions/main/in/LaserBeamRight", + "type": "boolean" + }, + { + "name": "/actions/main/in/LaserBeamLeft", + "type": "boolean" + }, + { + "name": "/actions/main/in/UseHeldObjectLeft", + "type": "boolean" + }, + { + "name": "/actions/main/in/UseHeldObjectRight", + "type": "boolean" + }, + { + "name": "/actions/main/in/MotionControllerThumbLeft_X,MotionControllerThumbLeft_Y X Y_axis2d", + "type": "vector2" + }, + { + "name": "/actions/main/in/MotionControllerThumbRight_X,MotionControllerThumbRight_Y X Y_axis2d", + "type": "vector2" + }, + { + "name": "/actions/main/in/ControllerMovementLeft axis", + "type": "vector1" + }, + { + "name": "/actions/main/in/ControllerMovementRight axis", + "type": "vector1" + } + ], + "action_sets": [ + { + "name": "/actions/main", + "usage": "leftright" + } + ], + "default_bindings": [ + { + "controller_type": "gamepad", + "binding_url": "gamepad.json" + }, + { + "controller_type": "holographic_controller", + "binding_url": "holographic_controller.json" + }, + { + "controller_type": "indexhmd", + "binding_url": "indexhmd.json" + }, + { + "controller_type": "knuckles", + "binding_url": "knuckles.json" + }, + { + "controller_type": "oculus_touch", + "binding_url": "oculus_touch.json" + }, + { + "controller_type": "rift", + "binding_url": "rift.json" + }, + { + "controller_type": "vive", + "binding_url": "vive.json" + }, + { + "controller_type": "vive_controller", + "binding_url": "vive_controller.json" + }, + { + "controller_type": "vive_cosmos_controller", + "binding_url": "vive_cosmos_controller.json" + }, + { + "controller_type": "vive_pro", + "binding_url": "vive_pro.json" + }, + { + "controller_type": "vive_tracker_camera", + "binding_url": "vive_tracker_camera.json" + }, + { + "controller_type": "knuckles", + "binding_url": "knuckles.json" + }, + { + "controller_type": "vive_controller", + "binding_url": "vive_controller.json" + }, + { + "controller_type": "vive_cosmos_controller", + "binding_url": "vive_cosmos_controller.json" + }, + { + "controller_type": "oculus_touch", + "binding_url": "oculus_touch.json" + }, + { + "controller_type": "holographic_controller", + "binding_url": "holographic_controller.json" + }, + { + "controller_type": "indexhmd", + "binding_url": "indexhmd.json" + }, + { + "controller_type": "vive", + "binding_url": "vive.json" + }, + { + "controller_type": "vive_pro", + "binding_url": "vive_pro.json" + }, + { + "controller_type": "rift", + "binding_url": "rift.json" + }, + { + "controller_type": "vive_tracker_camera", + "binding_url": "vive_tracker_camera.json" + }, + { + "controller_type": "gamepad", + "binding_url": "gamepad.json" + } + ], + "localization": [ + { + "language_tag": "en_us", + "/actions/main/in/controllerleft": "Left Controller [Pose]", + "/actions/main/in/controllerright": "Right Controller [Pose]", + "/actions/main/in/special1": "Special 1 [Tracker]", + "/actions/main/in/special2": "Special 2 [Tracker]", + "/actions/main/in/special3": "Special 3 [Tracker]", + "/actions/main/in/special4": "Special 4 [Tracker]", + "/actions/main/in/special5": "Special 5 [Tracker]", + "/actions/main/in/special6": "Special 6 [Tracker]", + "/actions/main/in/special7": "Special 7 [Tracker]", + "/actions/main/in/special8": "Special 8 [Tracker]", + "/actions/main/in/skeletonleft": "Skeleton (Left)", + "/actions/main/in/skeletonright": "Skeleton (Right)", + "/actions/main/in/open_console": "Open Console", + "/actions/main/out/vibrateleft": "Haptic (Left)", + "/actions/main/out/vibrateright": "Haptic (Right)", + "/actions/main/in/TeleportLeft": "TeleportLeft", + "/actions/main/in/TeleportRight": "TeleportRight", + "/actions/main/in/AlternateGripRight": "AlternateGripRight", + "/actions/main/in/AlternateGripLeft": "AlternateGripLeft", + "/actions/main/in/PrimaryGripLeft": "PrimaryGripLeft", + "/actions/main/in/PrimaryGripRight": "PrimaryGripRight", + "/actions/main/in/LaserBeamRight": "LaserBeamRight", + "/actions/main/in/LaserBeamLeft": "LaserBeamLeft", + "/actions/main/in/UseHeldObjectLeft": "UseHeldObjectLeft", + "/actions/main/in/UseHeldObjectRight": "UseHeldObjectRight", + "/actions/main/in/TriggerInteractionLEft": "TriggerInteractionLEft", + "/actions/main/in/TriggerInteractionRight": "TriggerInteractionRight", + "/actions/main/in/MotionControllerThumbLeft_X,MotionControllerThumbLeft_Y X Y_axis2d": "MotionControllerThumbLeft", + "/actions/main/in/MotionControllerThumbRight_X,MotionControllerThumbRight_Y X Y_axis2d": "MotionControllerThumbRight", + "/actions/main/in/ControllerMovementLeft axis": "ControllerMovementLeft", + "/actions/main/in/ControllerMovementRight axis": "ControllerMovementRight", + "/actions/main": "Main Game Actions" + } + ] +} \ No newline at end of file diff --git a/Config/SteamVRBindings/vive.json b/Config/SteamVRBindings/vive.json new file mode 100644 index 0000000..2f8cb4e --- /dev/null +++ b/Config/SteamVRBindings/vive.json @@ -0,0 +1,13 @@ +{ + "name": "Default bindings for Vive Headset", + "controller_type": "vive", + "last_edited_by": "UnrealEngine", + "bindings": + { + "/actions/main": + { + "sources": [] + } + }, + "description": "Virtual Reality BP Game Template-11100242" +} \ No newline at end of file diff --git a/Config/SteamVRBindings/vive_controller.json b/Config/SteamVRBindings/vive_controller.json new file mode 100644 index 0000000..f87239d --- /dev/null +++ b/Config/SteamVRBindings/vive_controller.json @@ -0,0 +1,221 @@ +{ + "name": "Default bindings for Vive", + "controller_type": "vive_controller", + "last_edited_by": "UnrealEngine", + "bindings": + { + "/actions/main": + { + "sources": [ + { + "mode": "trackpad", + "path": "/user/hand/left/input/trackpad", + "inputs": + { + "touch": + { + "output": "/actions/main/in/TeleportLeft" + } + } + }, + { + "mode": "trackpad", + "path": "/user/hand/right/input/trackpad", + "inputs": + { + "touch": + { + "output": "/actions/main/in/TeleportRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/grip", + "inputs": + { + "click": + { + "output": "/actions/main/in/AlternateGripRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/grip", + "inputs": + { + "click": + { + "output": "/actions/main/in/AlternateGripLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/PrimaryGripLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/PrimaryGripRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/application_menu", + "inputs": + { + "click": + { + "output": "/actions/main/in/LaserBeamRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/application_menu", + "inputs": + { + "click": + { + "output": "/actions/main/in/LaserBeamLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/UseHeldObjectLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/UseHeldObjectRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/TriggerInteractionLEft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/TriggerInteractionRight" + } + } + }, + { + "mode": "trackpad", + "path": "/user/hand/left/input/trackpad", + "inputs": + { + "position": + { + "output": "/actions/main/in/MotionControllerThumbLeft_X,MotionControllerThumbLeft_Y X Y_axis2d" + } + } + }, + { + "mode": "trackpad", + "path": "/user/hand/right/input/trackpad", + "inputs": + { + "position": + { + "output": "/actions/main/in/MotionControllerThumbRight_X,MotionControllerThumbRight_Y X Y_axis2d" + } + } + }, + { + "mode": "scalar_constant", + "path": "/user/hand/left/input/trackpad", + "inputs": + { + "value": + { + "output": "/actions/main/in/ControllerMovementLeft axis" + } + } + }, + { + "mode": "scalar_constant", + "path": "/user/hand/right/input/trackpad", + "inputs": + { + "value": + { + "output": "/actions/main/in/ControllerMovementRight axis" + } + } + } + ], + "poses": [ + { + "output": "/actions/main/in/controllerleft", + "path": "/user/hand/left/pose/raw", + "requirement": "optional" + }, + { + "output": "/actions/main/in/controllerright", + "path": "/user/hand/right/pose/raw" + } + ], + "skeleton": [ + { + "output": "/actions/main/in/skeletonleft", + "path": "/user/hand/left/input/skeleton/left" + }, + { + "output": "/actions/main/in/skeletonright", + "path": "/user/hand/right/input/skeleton/right" + } + ], + "haptics": [ + { + "output": "/actions/main/out/vibrateleft", + "path": "/user/hand/left/output/haptic" + }, + { + "output": "/actions/main/out/vibrateright", + "path": "/user/hand/right/output/haptic" + } + ] + } + }, + "description": "Virtual Reality BP Game Template-11100242" +} \ No newline at end of file diff --git a/Config/SteamVRBindings/vive_cosmos_controller.json b/Config/SteamVRBindings/vive_cosmos_controller.json new file mode 100644 index 0000000..1b2ac33 --- /dev/null +++ b/Config/SteamVRBindings/vive_cosmos_controller.json @@ -0,0 +1,221 @@ +{ + "name": "Default bindings for Cosmos", + "controller_type": "vive_cosmos_controller", + "last_edited_by": "UnrealEngine", + "bindings": + { + "/actions/main": + { + "sources": [ + { + "mode": "joystick", + "path": "/user/hand/left/input/joystick", + "inputs": + { + "touch": + { + "output": "/actions/main/in/TeleportLeft" + } + } + }, + { + "mode": "joystick", + "path": "/user/hand/right/input/joystick", + "inputs": + { + "touch": + { + "output": "/actions/main/in/TeleportRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/grip", + "inputs": + { + "click": + { + "output": "/actions/main/in/AlternateGripRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/grip", + "inputs": + { + "click": + { + "output": "/actions/main/in/AlternateGripLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/PrimaryGripLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/PrimaryGripRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/b", + "inputs": + { + "click": + { + "output": "/actions/main/in/LaserBeamRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/y", + "inputs": + { + "click": + { + "output": "/actions/main/in/LaserBeamLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/UseHeldObjectLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/UseHeldObjectRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/TriggerInteractionLEft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/TriggerInteractionRight" + } + } + }, + { + "mode": "joystick", + "path": "/user/hand/left/input/joystick", + "inputs": + { + "position": + { + "output": "/actions/main/in/MotionControllerThumbLeft_X,MotionControllerThumbLeft_Y X Y_axis2d" + } + } + }, + { + "mode": "joystick", + "path": "/user/hand/right/input/joystick", + "inputs": + { + "position": + { + "output": "/actions/main/in/MotionControllerThumbRight_X,MotionControllerThumbRight_Y X Y_axis2d" + } + } + }, + { + "mode": "scalar_constant", + "path": "/user/hand/left/input/joystick", + "inputs": + { + "value": + { + "output": "/actions/main/in/ControllerMovementLeft axis" + } + } + }, + { + "mode": "scalar_constant", + "path": "/user/hand/right/input/joystick", + "inputs": + { + "value": + { + "output": "/actions/main/in/ControllerMovementRight axis" + } + } + } + ], + "poses": [ + { + "output": "/actions/main/in/controllerleft", + "path": "/user/hand/left/pose/raw", + "requirement": "optional" + }, + { + "output": "/actions/main/in/controllerright", + "path": "/user/hand/right/pose/raw" + } + ], + "skeleton": [ + { + "output": "/actions/main/in/skeletonleft", + "path": "/user/hand/left/input/skeleton/left" + }, + { + "output": "/actions/main/in/skeletonright", + "path": "/user/hand/right/input/skeleton/right" + } + ], + "haptics": [ + { + "output": "/actions/main/out/vibrateleft", + "path": "/user/hand/left/output/haptic" + }, + { + "output": "/actions/main/out/vibrateright", + "path": "/user/hand/right/output/haptic" + } + ] + } + }, + "description": "Virtual Reality BP Game Template-11100242" +} \ No newline at end of file diff --git a/Config/SteamVRBindings/vive_pro.json b/Config/SteamVRBindings/vive_pro.json new file mode 100644 index 0000000..5a7ce10 --- /dev/null +++ b/Config/SteamVRBindings/vive_pro.json @@ -0,0 +1,13 @@ +{ + "name": "Default bindings for Vive Pro Headset", + "controller_type": "vive_pro", + "last_edited_by": "UnrealEngine", + "bindings": + { + "/actions/main": + { + "sources": [] + } + }, + "description": "Virtual Reality BP Game Template-11100242" +} \ No newline at end of file diff --git a/Config/SteamVRBindings/vive_tracker_camera.json b/Config/SteamVRBindings/vive_tracker_camera.json new file mode 100644 index 0000000..d25fce8 --- /dev/null +++ b/Config/SteamVRBindings/vive_tracker_camera.json @@ -0,0 +1,232 @@ +{ + "name": "Default bindings for Vive Trackers", + "controller_type": "vive_tracker_camera", + "last_edited_by": "UnrealEngine", + "bindings": + { + "/actions/main": + { + "sources": [ + { + "mode": "trackpad", + "path": "/user/hand/left/input/trackpad", + "inputs": + { + "touch": + { + "output": "/actions/main/in/TeleportLeft" + } + } + }, + { + "mode": "trackpad", + "path": "/user/hand/right/input/trackpad", + "inputs": + { + "touch": + { + "output": "/actions/main/in/TeleportRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/grip", + "inputs": + { + "click": + { + "output": "/actions/main/in/AlternateGripRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/grip", + "inputs": + { + "click": + { + "output": "/actions/main/in/AlternateGripLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/PrimaryGripLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/PrimaryGripRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/application_menu", + "inputs": + { + "click": + { + "output": "/actions/main/in/LaserBeamRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/application_menu", + "inputs": + { + "click": + { + "output": "/actions/main/in/LaserBeamLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/UseHeldObjectLeft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/UseHeldObjectRight" + } + } + }, + { + "mode": "button", + "path": "/user/hand/left/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/TriggerInteractionLEft" + } + } + }, + { + "mode": "button", + "path": "/user/hand/right/input/trigger", + "inputs": + { + "click": + { + "output": "/actions/main/in/TriggerInteractionRight" + } + } + }, + { + "mode": "trackpad", + "path": "/user/hand/left/input/trackpad", + "inputs": + { + "position": + { + "output": "/actions/main/in/MotionControllerThumbLeft_X,MotionControllerThumbLeft_Y X Y_axis2d" + } + } + }, + { + "mode": "trackpad", + "path": "/user/hand/right/input/trackpad", + "inputs": + { + "position": + { + "output": "/actions/main/in/MotionControllerThumbRight_X,MotionControllerThumbRight_Y X Y_axis2d" + } + } + }, + { + "mode": "scalar_constant", + "path": "/user/hand/left/input/trackpad", + "inputs": + { + "value": + { + "output": "/actions/main/in/ControllerMovementLeft axis" + } + } + }, + { + "mode": "scalar_constant", + "path": "/user/hand/right/input/trackpad", + "inputs": + { + "value": + { + "output": "/actions/main/in/ControllerMovementRight axis" + } + } + } + ], + "poses": [ + { + "output": "/actions/main/in/special1", + "path": "/user/hand/left/pose/back", + "requirement": "optional" + }, + { + "output": "/actions/main/in/special2", + "path": "/user/hand/right/pose/back", + "requirement": "optional" + }, + { + "output": "/actions/main/in/special3", + "path": "/user/hand/left/pose/front", + "requirement": "optional" + }, + { + "output": "/actions/main/in/special4", + "path": "/user/hand/right/pose/front", + "requirement": "optional" + }, + { + "output": "/actions/main/in/special5", + "path": "/user/hand/left/pose/frontandrolled", + "requirement": "optional" + }, + { + "output": "/actions/main/in/special6", + "path": "/user/hand/right/pose/frontandrolled", + "requirement": "optional" + }, + { + "output": "/actions/main/in/special7", + "path": "/user/hand/left/pose/pistolgrip", + "requirement": "optional" + }, + { + "output": "/actions/main/in/special8", + "path": "/user/hand/right/pose/pistolgrip", + "requirement": "optional" + } + ] + } + }, + "description": "Virtual Reality BP Game Template-11100242" +} \ No newline at end of file diff --git a/Content/Senseglove/GripPoseData/CabinetPose.uasset b/Content/Senseglove/GripPoseData/CabinetPose.uasset new file mode 100644 index 0000000..6cced7b --- /dev/null +++ b/Content/Senseglove/GripPoseData/CabinetPose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07d084b3717a528d43f0454659af3327a9cba73307fc78790f7f3b9ae2363a43 +size 49768 diff --git a/Content/Senseglove/GripPoseData/DrawerGrip.uasset b/Content/Senseglove/GripPoseData/DrawerGrip.uasset new file mode 100644 index 0000000..b29e79a --- /dev/null +++ b/Content/Senseglove/GripPoseData/DrawerGrip.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d49e760e7bfc74dab0220ed703c7eee0784bbc5d25fb24524faf716fe098337 +size 49764 diff --git a/Content/Senseglove/GripPoseData/LeverGripPose.uasset b/Content/Senseglove/GripPoseData/LeverGripPose.uasset new file mode 100644 index 0000000..52617b8 --- /dev/null +++ b/Content/Senseglove/GripPoseData/LeverGripPose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3619bdcc71eed098c5a7f7697c466b6245f4d2f8b996c646f4986895c2708077 +size 49776 diff --git a/Content/Senseglove/Maps/SensegloveDemoMap.umap b/Content/Senseglove/Maps/SensegloveDemoMap.umap new file mode 100644 index 0000000..0629f88 --- /dev/null +++ b/Content/Senseglove/Maps/SensegloveDemoMap.umap @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8879dcbc88a76155ff18a8e7a3ecf826e73f38e8bea41db78df9c797f494150 +size 819118 diff --git a/Content/VRE/Core/Character/BP_Teleport_Controller.uasset b/Content/VRE/Core/Character/BP_Teleport_Controller.uasset new file mode 100644 index 0000000..fa4a502 --- /dev/null +++ b/Content/VRE/Core/Character/BP_Teleport_Controller.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:22f63ae6342445b59d87c687ffd17a735244624d51db8ea470fef5903d930731 +size 1297794 diff --git a/Content/VRE/Core/Character/BP_VRCharacter.uasset b/Content/VRE/Core/Character/BP_VRCharacter.uasset new file mode 100644 index 0000000..6b339e3 --- /dev/null +++ b/Content/VRE/Core/Character/BP_VRCharacter.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b8ada7ed99c9c5ddc4636df93e3d4edefa453b02ef5963c6d3d86a04fe37fd26 +size 5673820 diff --git a/Content/VRE/Core/Character/BasicShapeMaterialTrans.uasset b/Content/VRE/Core/Character/BasicShapeMaterialTrans.uasset new file mode 100644 index 0000000..3c801d6 --- /dev/null +++ b/Content/VRE/Core/Character/BasicShapeMaterialTrans.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58f1201bcbc50d575bdffa78d222f112da953bcfbc80856857a2f91165047a63 +size 31685 diff --git a/Content/VRE/Core/Character/DefaultTextMaterialOpaque2.uasset b/Content/VRE/Core/Character/DefaultTextMaterialOpaque2.uasset new file mode 100644 index 0000000..ba3b229 --- /dev/null +++ b/Content/VRE/Core/Character/DefaultTextMaterialOpaque2.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:635c9b00ebe64ad76ce2128397d65c75469984f909f1047a0f6571cbebcb61ed +size 53693 diff --git a/Content/VRE/Core/Character/FPS_VRCharacter.uasset b/Content/VRE/Core/Character/FPS_VRCharacter.uasset new file mode 100644 index 0000000..8b97d76 --- /dev/null +++ b/Content/VRE/Core/Character/FPS_VRCharacter.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df001bb7765c40bd975584ca8faa764e0c869a1301636dd239476ae9ff999119 +size 329013 diff --git a/Content/VRE/Core/Character/GripEnum.uasset b/Content/VRE/Core/Character/GripEnum.uasset new file mode 100644 index 0000000..d26bf51 --- /dev/null +++ b/Content/VRE/Core/Character/GripEnum.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:beff711e061a3bc2b8d308504cd1ccb6b9e44c702afdbfdbe18cc9297835a02c +size 2693 diff --git a/Content/VRE/Core/Character/LaserBeamSplineMat.uasset b/Content/VRE/Core/Character/LaserBeamSplineMat.uasset new file mode 100644 index 0000000..993462c --- /dev/null +++ b/Content/VRE/Core/Character/LaserBeamSplineMat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ce59b72a756fba9cacba821f446f5ad3776046c9c0875d06183811ce5a71c09 +size 21948 diff --git a/Content/VRE/Core/Character/Mannequin/Animations/MannequinHand_Right_CanGrab.uasset b/Content/VRE/Core/Character/Mannequin/Animations/MannequinHand_Right_CanGrab.uasset new file mode 100644 index 0000000..9b78d92 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Animations/MannequinHand_Right_CanGrab.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e2da68c5ea6e7a3ef662a7ac8c30c5d843549bd17e858c6a0fee4f7c6d38f04 +size 182385 diff --git a/Content/VRE/Core/Character/Mannequin/Animations/MannequinHand_Right_Grab.uasset b/Content/VRE/Core/Character/Mannequin/Animations/MannequinHand_Right_Grab.uasset new file mode 100644 index 0000000..d0350f3 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Animations/MannequinHand_Right_Grab.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e64c362bad08b3cf6807bdf7ddf3bd8d09fcdd6c8d5f4c677d08ed65d9b659cc +size 179613 diff --git a/Content/VRE/Core/Character/Mannequin/Animations/MannequinHand_Right_Open.uasset b/Content/VRE/Core/Character/Mannequin/Animations/MannequinHand_Right_Open.uasset new file mode 100644 index 0000000..52520d2 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Animations/MannequinHand_Right_Open.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df5662a655d4a1ed8c8b53eadc0efb7c10641d1addf84f9d18faa0ee71697de0 +size 181442 diff --git a/Content/VRE/Core/Character/Mannequin/Animations/RightGrip_BS.uasset b/Content/VRE/Core/Character/Mannequin/Animations/RightGrip_BS.uasset new file mode 100644 index 0000000..fe07cb3 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Animations/RightGrip_BS.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97afb117c4d48760302fe617cbb826dbf122c798235f2260e084c90b94104e4a +size 78621 diff --git a/Content/VRE/Core/Character/Mannequin/Animations/RightHand_AnimBP.uasset b/Content/VRE/Core/Character/Mannequin/Animations/RightHand_AnimBP.uasset new file mode 100644 index 0000000..7766563 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Animations/RightHand_AnimBP.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ace9b2a7b2461c05cf617151fe17d0e0c077772a18f2dc36c127373faa300d9 +size 89078 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Materials/M_HandMat.uasset b/Content/VRE/Core/Character/Mannequin/Character/Materials/M_HandMat.uasset new file mode 100644 index 0000000..2143b3c --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Materials/M_HandMat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5408d88d682b1d8ac4a19f308d8763b8b6831e082656a9610799d2f997c46b28 +size 126834 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Materials/M_UE4Man_Body.uasset b/Content/VRE/Core/Character/Mannequin/Character/Materials/M_UE4Man_Body.uasset new file mode 100644 index 0000000..dd0a558 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Materials/M_UE4Man_Body.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb1221b071760d9dcfba75f0571f49608c921310cfa2f488002a243198b8f1a5 +size 29782 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Materials/M_UE4Man_ChestLogo.uasset b/Content/VRE/Core/Character/Mannequin/Character/Materials/M_UE4Man_ChestLogo.uasset new file mode 100644 index 0000000..dc87ca7 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Materials/M_UE4Man_ChestLogo.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cfc7020cafbeee6767b0e78ed2d03cb0a5fa133357149120ed5c8bfe394e57df +size 9894 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/ML_GlossyBlack_Latex_UE4.uasset b/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/ML_GlossyBlack_Latex_UE4.uasset new file mode 100644 index 0000000..d10ffb4 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/ML_GlossyBlack_Latex_UE4.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ab6d666fd644894fa774fa9dda8eb352fd1bce6d6c31f7a30d1b117bb7aef33 +size 87003 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/ML_Plastic_Shiny_Beige.uasset b/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/ML_Plastic_Shiny_Beige.uasset new file mode 100644 index 0000000..464c92a --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/ML_Plastic_Shiny_Beige.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc6c2715548627e400f396bbb3b84ac8df814822e2f07a35cb1617e760d8dc76 +size 100213 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/ML_Plastic_Shiny_Beige_LOGO.uasset b/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/ML_Plastic_Shiny_Beige_LOGO.uasset new file mode 100644 index 0000000..8470a0a --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/ML_Plastic_Shiny_Beige_LOGO.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:290cf62fb29f6dfe8881596cf940b3ca128c45d56fe81707c08bb3c034ebd781 +size 11203 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/ML_SoftMetal_UE4.uasset b/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/ML_SoftMetal_UE4.uasset new file mode 100644 index 0000000..af20b4f --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/ML_SoftMetal_UE4.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd107a851b46f797ae0f07e68119092f47006e0a1b3a74fde58aac1baa45fc06 +size 87500 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/T_ML_Aluminum01.uasset b/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/T_ML_Aluminum01.uasset new file mode 100644 index 0000000..e7d7ef1 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/T_ML_Aluminum01.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb1c60928051c5bf2e48e56c6f6bf5d9664e1e0fa977d8968c946bfb8531ae5d +size 395367 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/T_ML_Aluminum01_N.uasset b/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/T_ML_Aluminum01_N.uasset new file mode 100644 index 0000000..a749813 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/T_ML_Aluminum01_N.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5d6d0c10c263d396cbe623561dd9f590378f4219f13256929aba78f2e7f9259 +size 404256 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/T_ML_Rubber_Blue_01_D.uasset b/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/T_ML_Rubber_Blue_01_D.uasset new file mode 100644 index 0000000..933e548 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/T_ML_Rubber_Blue_01_D.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6f7fa9ef137740de52f259ea1d53453e6d739a74e5cb77b6f110812d176e90a +size 428993 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/T_ML_Rubber_Blue_01_N.uasset b/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/T_ML_Rubber_Blue_01_N.uasset new file mode 100644 index 0000000..79c8dce --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Materials/MaterialLayers/T_ML_Rubber_Blue_01_N.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58ced35291d53058126de2e835460a0cde4993d2dd3cb364eeb026fb944cb1d9 +size 358491 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Mesh/MannequinHand_Right.uasset b/Content/VRE/Core/Character/Mannequin/Character/Mesh/MannequinHand_Right.uasset new file mode 100644 index 0000000..518d701 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Mesh/MannequinHand_Right.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:444309d9a0f79a3ecb48e66d13e9ab08d83daecd9d28a34fd92c34935cbff7f7 +size 555575 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Mesh/MannequinHand_Right_PhysicsAsset.uasset b/Content/VRE/Core/Character/Mannequin/Character/Mesh/MannequinHand_Right_PhysicsAsset.uasset new file mode 100644 index 0000000..8dae0fa --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Mesh/MannequinHand_Right_PhysicsAsset.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:384dbce181235b77e56d1915661c6a35002b1fa284c312708272c2270f0efda7 +size 8200 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Mesh/MannequinHand_Right_Skeleton.uasset b/Content/VRE/Core/Character/Mannequin/Character/Mesh/MannequinHand_Right_Skeleton.uasset new file mode 100644 index 0000000..f76f0fa --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Mesh/MannequinHand_Right_Skeleton.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e5e73f9c213323ace75dd9b87f27e79a7c739abb44d2885c0b4e916a25e9519 +size 10699 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Mesh/SK_Mannequin.uasset b/Content/VRE/Core/Character/Mannequin/Character/Mesh/SK_Mannequin.uasset new file mode 100644 index 0000000..ccf6e3a --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Mesh/SK_Mannequin.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7dc6c0ff7dbed333463595c609151c34154a746146649e69e943c8178f54b76d +size 5583019 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Mesh/SK_Mannequin_PhysicsAsset.uasset b/Content/VRE/Core/Character/Mannequin/Character/Mesh/SK_Mannequin_PhysicsAsset.uasset new file mode 100644 index 0000000..3eb1695 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Mesh/SK_Mannequin_PhysicsAsset.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ed75a8aaee902d169ddb980125d9dbeb929851ef33009693a136dc3928211e6 +size 46351 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Mesh/UE4_Mannequin_Skeleton.uasset b/Content/VRE/Core/Character/Mannequin/Character/Mesh/UE4_Mannequin_Skeleton.uasset new file mode 100644 index 0000000..c0b6225 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Mesh/UE4_Mannequin_Skeleton.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9012982f60619c314d67bd9477e6bc3c98d90b1864e5532ca7dd9f3147c8bf6b +size 21571 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Mesh/models_hands_vr_glove_vmat.uasset b/Content/VRE/Core/Character/Mannequin/Character/Mesh/models_hands_vr_glove_vmat.uasset new file mode 100644 index 0000000..19f514a --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Mesh/models_hands_vr_glove_vmat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a11e85324d5097e5a93563d4d706ec763ad4e6c8a9a0006be35776185476cf4f +size 122076 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_color.uasset b/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_color.uasset new file mode 100644 index 0000000..7930bf9 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_color.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f8c0dc8bc0cb9187b2af5b39ad5ffa58054e02d90954b15d7db5be165ce1a69 +size 1561204 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_color_red.uasset b/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_color_red.uasset new file mode 100644 index 0000000..834142c --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_color_red.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f6bc42a6e8c95b19afef0529046d803ad106cae5390790a0a0f2bd9f466b795 +size 1444461 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_left_model.uasset b/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_left_model.uasset new file mode 100644 index 0000000..4850151 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_left_model.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e4dad86a8d893b632636892641163cf90ffb6f39733269b15b28b2c4d1697c45 +size 599145 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_left_model_Skeleton.uasset b/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_left_model_Skeleton.uasset new file mode 100644 index 0000000..6e081c9 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_left_model_Skeleton.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ea51de7b170b0ef094cbfc17cbc576507fcce7697e8e16c8733ba856b68103a +size 10570 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_normal.uasset b/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_normal.uasset new file mode 100644 index 0000000..92f4fd6 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_normal.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:959ae0ad037205b36f8521a70359b45ae6ed51875cec9eb5f61036a5dbd0a754 +size 1825248 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_right_model.uasset b/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_right_model.uasset new file mode 100644 index 0000000..433a14c --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_right_model.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:add21dfee93998d0e96661bdd12ae44d51b042c54344348c96e524d9444b4da1 +size 598535 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_right_model_Skeleton.uasset b/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_right_model_Skeleton.uasset new file mode 100644 index 0000000..78be17e --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Mesh/vr_glove_right_model_Skeleton.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29f881745fdf7f236e29dcc7558ba940108c415a982e134a7f31f11df6b9b78a +size 10574 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4Man_Logo_N.uasset b/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4Man_Logo_N.uasset new file mode 100644 index 0000000..7a2a6dd --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4Man_Logo_N.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9492b25939ff1d478e15d1b7d0f1234ff4237a440705fd8b60288c0dd16f22e +size 137426 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4_LOGO_CARD.uasset b/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4_LOGO_CARD.uasset new file mode 100644 index 0000000..f783b6f --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4_LOGO_CARD.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c6badd78cd1054104de8a0acef1aec56fdefd0c57ca56f89802bf8f4581f33d9 +size 70878 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4_MAT_MASKA.uasset b/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4_MAT_MASKA.uasset new file mode 100644 index 0000000..0dd9b8d --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4_MAT_MASKA.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07842eb857d733ec1ba3ac29949afab7307f76f48051503a07d10e04219a1546 +size 211715 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4_Mannequin_MAT_MASKA.uasset b/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4_Mannequin_MAT_MASKA.uasset new file mode 100644 index 0000000..edd80a9 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4_Mannequin_MAT_MASKA.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:470dd9cda45e6e2c75a57a851a8748ac3be1e8e313460fc3cba1b49874a0f3f4 +size 211755 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4_Mannequin__norm.uasset b/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4_Mannequin__norm.uasset new file mode 100644 index 0000000..24eb036 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4_Mannequin__norm.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c2ed6047f58c4cd64dc8942ceeaab7d315fa94906148d5d6785b005b6b9f923a +size 5427379 diff --git a/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4_Mannequin__normals.uasset b/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4_Mannequin__normals.uasset new file mode 100644 index 0000000..5d5dff8 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequin/Character/Textures/UE4_Mannequin__normals.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d4707f8ef7073631612811dbd4a21beeadf7bb5c2a7809961d8dc3509de1dac0 +size 5427391 diff --git a/Content/VRE/Core/Character/Mannequins/Animations/ABP_Manny.uasset b/Content/VRE/Core/Character/Mannequins/Animations/ABP_Manny.uasset new file mode 100644 index 0000000..63d77ff --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Animations/ABP_Manny.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3ffd71bccec69abff163356446a7980111452b030a7a3dfee461424c2cde74d +size 370976 diff --git a/Content/VRE/Core/Character/Mannequins/Animations/ABP_Quinn.uasset b/Content/VRE/Core/Character/Mannequins/Animations/ABP_Quinn.uasset new file mode 100644 index 0000000..1639c5a --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Animations/ABP_Quinn.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:138a910497e5c70007ac3d8a0e4993c11398c7c6fd9d2544f4189f9f15f5cda2 +size 40139 diff --git a/Content/VRE/Core/Character/Mannequins/Animations/Manny/BS_MM_WalkRun.uasset b/Content/VRE/Core/Character/Mannequins/Animations/Manny/BS_MM_WalkRun.uasset new file mode 100644 index 0000000..4bc0329 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Animations/Manny/BS_MM_WalkRun.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8acae4dcedf36a5f5b136e061077a1c3ed992abbde86d358577dd4c3fca45dad +size 9153 diff --git a/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Fall_Loop.uasset b/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Fall_Loop.uasset new file mode 100644 index 0000000..3e40e51 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Fall_Loop.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d51e888c1eefd69b5232e4cc6334ed6686956de6ac17e69ae6e4d1f57b7e6350 +size 659645 diff --git a/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Idle.uasset b/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Idle.uasset new file mode 100644 index 0000000..5accf35 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Idle.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7aaf7ac0774daebe07de85da640c6507245067737734f2ba6bb12a62949789c +size 876005 diff --git a/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Jump.uasset b/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Jump.uasset new file mode 100644 index 0000000..f20cbf5 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Jump.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3540f4d3626cdc7e93dca2a3b867f395ceebb963f99d57b73dd7ae445e1c684 +size 252393 diff --git a/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Land.uasset b/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Land.uasset new file mode 100644 index 0000000..a22edbe --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Land.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7bb628219d7e653767b30cf86df62e227f1b8daf2dbfa6b852b8b905c87dab50 +size 261766 diff --git a/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Run_Fwd.uasset b/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Run_Fwd.uasset new file mode 100644 index 0000000..93f8183 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Run_Fwd.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c93ea1786347f2d3b52014f3e4d6f7a691726c333cc572721c740b91336380f +size 271611 diff --git a/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Walk_Fwd.uasset b/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Walk_Fwd.uasset new file mode 100644 index 0000000..3fd08d2 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Walk_Fwd.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:243e8534ffb8348f257e1e390b0acaffbced581987771c0564f01b5c4da241f5 +size 361158 diff --git a/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Walk_InPlace.uasset b/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Walk_InPlace.uasset new file mode 100644 index 0000000..6983ba1 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Animations/Manny/MM_Walk_InPlace.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c4f94a99357d4b8b8efb1ff23769a39932518b3a4e343db9222e9a29b63149a +size 570800 diff --git a/Content/VRE/Core/Character/Mannequins/Animations/Quinn/BS_MF_Unarmed_WalkRun.uasset b/Content/VRE/Core/Character/Mannequins/Animations/Quinn/BS_MF_Unarmed_WalkRun.uasset new file mode 100644 index 0000000..9352b9e --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Animations/Quinn/BS_MF_Unarmed_WalkRun.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28fef93862e8758129b5f7ee2997d2e71d27cf5cabace52eb5d6e228343b916f +size 9193 diff --git a/Content/VRE/Core/Character/Mannequins/Animations/Quinn/MF_Idle.uasset b/Content/VRE/Core/Character/Mannequins/Animations/Quinn/MF_Idle.uasset new file mode 100644 index 0000000..df3b1fe --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Animations/Quinn/MF_Idle.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:505d8e71cbe6761c0bb62af210ebf534ec253c8356d3984e23febf80329d2716 +size 880797 diff --git a/Content/VRE/Core/Character/Mannequins/Animations/Quinn/MF_Run_Fwd.uasset b/Content/VRE/Core/Character/Mannequins/Animations/Quinn/MF_Run_Fwd.uasset new file mode 100644 index 0000000..809e666 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Animations/Quinn/MF_Run_Fwd.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29b35e9ceeb7cca02d9f920db519472b758acccd78e6f2a846ebbbd1a3c0dcac +size 392562 diff --git a/Content/VRE/Core/Character/Mannequins/Animations/Quinn/MF_Walk_Fwd.uasset b/Content/VRE/Core/Character/Mannequins/Animations/Quinn/MF_Walk_Fwd.uasset new file mode 100644 index 0000000..29dbfce --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Animations/Quinn/MF_Walk_Fwd.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a52b767af2e9a9f8cee083466a068f7b29a4d30a0e7428b14b61dbd1d04263f5 +size 411429 diff --git a/Content/VRE/Core/Character/Mannequins/Materials/Functions/CA_Mannequin.uasset b/Content/VRE/Core/Character/Mannequins/Materials/Functions/CA_Mannequin.uasset new file mode 100644 index 0000000..c2cc1f0 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Materials/Functions/CA_Mannequin.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9f845106db23168ccf6f1638185bc7b5c1e458722cf1a757d14e550ca81f6f85 +size 4968 diff --git a/Content/VRE/Core/Character/Mannequins/Materials/Functions/ChromaticCurve.uasset b/Content/VRE/Core/Character/Mannequins/Materials/Functions/ChromaticCurve.uasset new file mode 100644 index 0000000..102734e --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Materials/Functions/ChromaticCurve.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e16b429037def385b9477be63f9c1dbe44eba465228660450b089bf8d60d259f +size 6435 diff --git a/Content/VRE/Core/Character/Mannequins/Materials/Functions/MF_Diffraction.uasset b/Content/VRE/Core/Character/Mannequins/Materials/Functions/MF_Diffraction.uasset new file mode 100644 index 0000000..4dc7f3b --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Materials/Functions/MF_Diffraction.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:23f1ece80ac62814a694cf50fd7854b8476cb6f2242cfc265012b1201d350c85 +size 32059 diff --git a/Content/VRE/Core/Character/Mannequins/Materials/Functions/MF_logo3layers.uasset b/Content/VRE/Core/Character/Mannequins/Materials/Functions/MF_logo3layers.uasset new file mode 100644 index 0000000..593cf82 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Materials/Functions/MF_logo3layers.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:913352fe76b0c0c44217ca76babf8ecae15e590e315470d98815a2e00f98173f +size 56015 diff --git a/Content/VRE/Core/Character/Mannequins/Materials/Functions/ML_BaseColorFallOff.uasset b/Content/VRE/Core/Character/Mannequins/Materials/Functions/ML_BaseColorFallOff.uasset new file mode 100644 index 0000000..01b6b66 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Materials/Functions/ML_BaseColorFallOff.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d54d6bc865c113b78654dc8497173ff83863fbd483f4cd91c1e933cdbf016e82 +size 13739 diff --git a/Content/VRE/Core/Character/Mannequins/Materials/Instances/Manny/MI_Manny_01.uasset b/Content/VRE/Core/Character/Mannequins/Materials/Instances/Manny/MI_Manny_01.uasset new file mode 100644 index 0000000..dc46ed4 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Materials/Instances/Manny/MI_Manny_01.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14719191a97abe54593ff2c8ac936121055d3fdd5f3c645e5b7100fbb0ab396c +size 21533 diff --git a/Content/VRE/Core/Character/Mannequins/Materials/Instances/Manny/MI_Manny_02.uasset b/Content/VRE/Core/Character/Mannequins/Materials/Instances/Manny/MI_Manny_02.uasset new file mode 100644 index 0000000..f29dbb0 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Materials/Instances/Manny/MI_Manny_02.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:71e67d413b3eecbadd402ce3f24759cbb1d08367194c7cf7a977764218a8690d +size 24564 diff --git a/Content/VRE/Core/Character/Mannequins/Materials/Instances/Quinn/MI_Quinn_01.uasset b/Content/VRE/Core/Character/Mannequins/Materials/Instances/Quinn/MI_Quinn_01.uasset new file mode 100644 index 0000000..486c014 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Materials/Instances/Quinn/MI_Quinn_01.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c66658b6032f46d60bb4271571b0954022a336a78c55cd02af4f7ebaeeae7fe3 +size 19578 diff --git a/Content/VRE/Core/Character/Mannequins/Materials/Instances/Quinn/MI_Quinn_02.uasset b/Content/VRE/Core/Character/Mannequins/Materials/Instances/Quinn/MI_Quinn_02.uasset new file mode 100644 index 0000000..7d2b736 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Materials/Instances/Quinn/MI_Quinn_02.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0aa8f6da31dd346b9e237f3221707d210a3a3df61b1e47b5a0f92b7844afa32d +size 24923 diff --git a/Content/VRE/Core/Character/Mannequins/Materials/M_Mannequin.uasset b/Content/VRE/Core/Character/Mannequins/Materials/M_Mannequin.uasset new file mode 100644 index 0000000..c02c488 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Materials/M_Mannequin.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:102c18dfb1698b567b0822a51c733ed6fd2c24b93bec07a6e9d9b940a5e38558 +size 83288 diff --git a/Content/VRE/Core/Character/Mannequins/Meshes/Mannequin_LODSettings.uasset b/Content/VRE/Core/Character/Mannequins/Meshes/Mannequin_LODSettings.uasset new file mode 100644 index 0000000..c1b9fac --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Meshes/Mannequin_LODSettings.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77d9c5e7fccd2887c53cdecf10234b85d2ba500e184b8c10774b4ade25edae3a +size 19131 diff --git a/Content/VRE/Core/Character/Mannequins/Meshes/SKM_Manny.uasset b/Content/VRE/Core/Character/Mannequins/Meshes/SKM_Manny.uasset new file mode 100644 index 0000000..183b2c3 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Meshes/SKM_Manny.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2872a0f2c074351aa06902e958a88acbbad3cb8bf392abb3c1e263ad0e746dd1 +size 34534742 diff --git a/Content/VRE/Core/Character/Mannequins/Meshes/SKM_Manny_Simple.uasset b/Content/VRE/Core/Character/Mannequins/Meshes/SKM_Manny_Simple.uasset new file mode 100644 index 0000000..af9abb0 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Meshes/SKM_Manny_Simple.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9fd6d74751113f7121ed50b0186e08eb173e2cb5d01b0f617d59cf67b00f6ef8 +size 18526982 diff --git a/Content/VRE/Core/Character/Mannequins/Meshes/SKM_Quinn.uasset b/Content/VRE/Core/Character/Mannequins/Meshes/SKM_Quinn.uasset new file mode 100644 index 0000000..2dfcd8a --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Meshes/SKM_Quinn.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc51eccd57660addda0e480d3db60e57e623e2e0cfb0af5e867a1d53b361b238 +size 36495758 diff --git a/Content/VRE/Core/Character/Mannequins/Meshes/SKM_Quinn_Simple.uasset b/Content/VRE/Core/Character/Mannequins/Meshes/SKM_Quinn_Simple.uasset new file mode 100644 index 0000000..91d07a3 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Meshes/SKM_Quinn_Simple.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2febd11df2ab7e875dbc44172e360e3779e84952954b5ff5a3a8d19bfd481d7b +size 19371456 diff --git a/Content/VRE/Core/Character/Mannequins/Meshes/SK_Mannequin.uasset b/Content/VRE/Core/Character/Mannequins/Meshes/SK_Mannequin.uasset new file mode 100644 index 0000000..2fb9db8 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Meshes/SK_Mannequin.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64245b653cdcbdf1c36f1f24bc2eea411505bf68f2ceb430a362bf4a9263630c +size 160772 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/ABP_Manny_PostProcess.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/ABP_Manny_PostProcess.uasset new file mode 100644 index 0000000..0003778 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/ABP_Manny_PostProcess.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76c17aacee9867a44c09c5ccbd7c7e618a7aac55152ceec8b9a2405e8925c565 +size 463186 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/ABP_Quinn_PostProcess.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/ABP_Quinn_PostProcess.uasset new file mode 100644 index 0000000..eb951eb --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/ABP_Quinn_PostProcess.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d805c548607edd93e1525f32f62be35fc0bc3b49288f0f28f75d475d733aa25 +size 462984 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/CR_Mannequin_BasicFootIK.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/CR_Mannequin_BasicFootIK.uasset new file mode 100644 index 0000000..4d3a1f4 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/CR_Mannequin_BasicFootIK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:63c0417f3b6045558911f27b41c79baa7338a2ee96d54bb67eee399ed8c89710 +size 590741 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/CR_Mannequin_Body.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/CR_Mannequin_Body.uasset new file mode 100644 index 0000000..b3fd00c --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/CR_Mannequin_Body.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5292dd182fba746bb222ee8ca0bad62684478259185ec288325309b28617b95d +size 12653677 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/CR_Mannequin_Procedural.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/CR_Mannequin_Procedural.uasset new file mode 100644 index 0000000..e12ec6d --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/CR_Mannequin_Procedural.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d85bba6546413f9e1b1cab62a290afcbd4e478c9e47ab02cd3e0578de1a8403 +size 2336132 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/IK_Mannequin.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/IK_Mannequin.uasset new file mode 100644 index 0000000..0411e13 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/IK_Mannequin.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66e8025f539146e688c3cb69af621514f295765cf4e0d30312ec8bcaf93274b1 +size 143511 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/PA_Mannequin.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/PA_Mannequin.uasset new file mode 100644 index 0000000..9e57443 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/PA_Mannequin.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32d8ce58623c077e25c0f260cc549377d4df1e81662e07bb96cc48113b78ae6d +size 289317 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_calf_l_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_calf_l_anim.uasset new file mode 100644 index 0000000..c59e631 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_calf_l_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ce02adaae5946a30bfc0f348815218640229bc92e34561509b14a84fbc38cb0 +size 105206 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_calf_l_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_calf_l_pose.uasset new file mode 100644 index 0000000..65ee716 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_calf_l_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:217815a8fbb02209d8ab7a27815067e8eec7c1c31544215cb9314863ee323166 +size 207531 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_calf_r_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_calf_r_anim.uasset new file mode 100644 index 0000000..4f45d23 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_calf_r_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c95783ce9cfb7ca8bfd429e2c9007bf01b266c2ffe6fbb23cdf8741b7dbe1c53 +size 105216 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_calf_r_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_calf_r_pose.uasset new file mode 100644 index 0000000..72fb9e6 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_calf_r_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a96b8c6935bf170cdef21b026148f07ecacfa3af22651f9b463fbdb8fc52e6df +size 207531 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_clavicle_l_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_clavicle_l_anim.uasset new file mode 100644 index 0000000..97f005f --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_clavicle_l_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a04dd3997ef95806234d2df5d287aa41f5715d1eae056de5a7e037e2f1aa803d +size 105242 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_clavicle_l_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_clavicle_l_pose.uasset new file mode 100644 index 0000000..05a78aa --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_clavicle_l_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb547ba1ee69dd4171187abb5dbc0f79d10844049ac78d881b6cb00aadd46cb2 +size 205837 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_clavicle_r_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_clavicle_r_anim.uasset new file mode 100644 index 0000000..e9853af --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_clavicle_r_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4707a92febba42851f293c526a373843fa181ab0d9071601c5e823e18b126952 +size 105244 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_clavicle_r_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_clavicle_r_pose.uasset new file mode 100644 index 0000000..bce7832 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_clavicle_r_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:efcbfde96d0c561d4f2737354d992561d6eed0855468dd77977275ccaeb22b59 +size 206439 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_foot_l_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_foot_l_anim.uasset new file mode 100644 index 0000000..a6f1e9d --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_foot_l_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21cafd1a5ee408867a834fa06245f6d074d98e180f78edd1b9affd69b407277f +size 93214 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_foot_l_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_foot_l_pose.uasset new file mode 100644 index 0000000..9581023 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_foot_l_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fcad5bad764e842adfc6088f1c054fd1db3eee86236ce421f345e2cda31b9210 +size 132277 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_foot_r_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_foot_r_anim.uasset new file mode 100644 index 0000000..489b0b4 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_foot_r_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34368aa5b3857b5d827d8b1706f4432e834823afa6159a0c4c4ec126dfa28d60 +size 93216 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_foot_r_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_foot_r_pose.uasset new file mode 100644 index 0000000..84dfebf --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_foot_r_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac5b5b1f6aa71eef22067ec547533c8d45de8d65f0808ecb59bddbc1cd92dc8a +size 132277 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_hand_l_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_hand_l_anim.uasset new file mode 100644 index 0000000..5a82929 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_hand_l_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ff41b8e57ca295e00365dc7a1c6ebc364f376d7cdde9ae0378badda8b30f3f1 +size 99214 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_hand_l_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_hand_l_pose.uasset new file mode 100644 index 0000000..8ca1d0a --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_hand_l_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c31dafc62605422678e3d2b2401ce8db9f41689d292184d96d5a164a492f8d16 +size 169307 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_hand_r_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_hand_r_anim.uasset new file mode 100644 index 0000000..7af6ceb --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_hand_r_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52c13d7f7a1b328aec3234a8ffa386b12c14069fe7217446c9c2080fb7c89b10 +size 99216 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_hand_r_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_hand_r_pose.uasset new file mode 100644 index 0000000..fee8a06 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_hand_r_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75052755245be0feb091c8834f6b611c75d6780cec4bb525c91d42e7be51b5a4 +size 169307 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_lowerarm_l_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_lowerarm_l_anim.uasset new file mode 100644 index 0000000..b7281fb --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_lowerarm_l_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3b23f1f90d33078cb5c0e1cb0b2f066491daa7a95cc4c19e0ba3e2e7b1ec6db6 +size 129596 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_lowerarm_l_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_lowerarm_l_pose.uasset new file mode 100644 index 0000000..1661689 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_lowerarm_l_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8af73466c4cfcf6fb805ac23e7e72b6b06297d592c4445a77ef72e8dbf057d02 +size 361749 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_lowerarm_r_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_lowerarm_r_anim.uasset new file mode 100644 index 0000000..dc5af61 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_lowerarm_r_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:84ac4e43287f2167d1d10a786eb3b09a7ae5178db58b370617e38fcfe384173d +size 129244 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_lowerarm_r_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_lowerarm_r_pose.uasset new file mode 100644 index 0000000..d2083f2 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_lowerarm_r_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c371e1e54db220b98992146383a757748eda80701ce9e743048a7209385666d +size 361749 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_thigh_l_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_thigh_l_anim.uasset new file mode 100644 index 0000000..c249f39 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_thigh_l_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:626f16b8aa0b278034ad93354f36f340c5eedb8dc0f9e1eb2d2ec6840e0ae1f0 +size 159223 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_thigh_l_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_thigh_l_pose.uasset new file mode 100644 index 0000000..e85bf2e --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_thigh_l_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a500c9e6709807db106a20a4ce9a1b6f3197c5ae5e493535f7424908f6368454 +size 558074 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_thigh_r_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_thigh_r_anim.uasset new file mode 100644 index 0000000..0f01e9e --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_thigh_r_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bbce93d680b6e54608205212e7cf59eccbe21f129ff8bbf5d6cfcbe56478b900 +size 159225 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_thigh_r_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_thigh_r_pose.uasset new file mode 100644 index 0000000..00e6374 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_thigh_r_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:102b63287bd6c6c8a6bda114c9cef7bed39086c34438a8fe84cbfc0270f6a5f0 +size 558074 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_upperarm_l_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_upperarm_l_anim.uasset new file mode 100644 index 0000000..efc5d1f --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_upperarm_l_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a54532246126cd1d7207cffc9f8ce45de791c7eba4aab45e7905dd526ac7717e +size 171244 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_upperarm_l_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_upperarm_l_pose.uasset new file mode 100644 index 0000000..4e66f77 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_upperarm_l_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34094764ce886228c6093d2f583f4fafa22aaa3b387c9b811d36da8602573460 +size 641738 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_upperarm_r_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_upperarm_r_anim.uasset new file mode 100644 index 0000000..dee9f14 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_upperarm_r_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90c6fcad7188756cdda1fe49a1ce75b698ecfef27c8b88f0d2ff3527adf0dcbc +size 171246 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_upperarm_r_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_upperarm_r_pose.uasset new file mode 100644 index 0000000..2ea225c --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Manny/Manny_upperarm_r_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc2fca5f70a43c8c98ac21acd711b2436de7d7e42cf321b30450a20686dcf020 +size 630300 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_calf_l_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_calf_l_anim.uasset new file mode 100644 index 0000000..0519f06 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_calf_l_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b540e31e20573fb60b5293bc5850e26d933f791c04695133ab4f902670725679 +size 153784 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_calf_l_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_calf_l_pose.uasset new file mode 100644 index 0000000..46bf9c5 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_calf_l_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a30d62bd32f58e232b30519721808fd49070f67e3ecbe101520661a6dde7e5e4 +size 245262 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_calf_r_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_calf_r_anim.uasset new file mode 100644 index 0000000..e394a3b --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_calf_r_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f91f63f68351873f8ef00dba1ef9aef6c334c90454da4460e9455332fb715389 +size 153775 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_calf_r_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_calf_r_pose.uasset new file mode 100644 index 0000000..32532f4 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_calf_r_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1aaa44d06f750c8ea5435bc42f2387ff650dd2453137f2fcdffe356228220611 +size 245343 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_clavicle_l_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_clavicle_l_anim.uasset new file mode 100644 index 0000000..83eaf73 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_clavicle_l_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd4c1f05ea456162e35c61d31b0c9c5034531c4940fa857d30f93889b18ab1d5 +size 147743 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_clavicle_l_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_clavicle_l_pose.uasset new file mode 100644 index 0000000..39c4e5b --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_clavicle_l_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76e3889df4ee68657936ddbb13d8db6de9f8b4818128d4882fb292f1a577566f +size 206014 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_clavicle_r_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_clavicle_r_anim.uasset new file mode 100644 index 0000000..710f59a --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_clavicle_r_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f79419b8a761026ffaae77fd07703404c92681fec9df9ec45819bcb9a9794f7b +size 147492 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_clavicle_r_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_clavicle_r_pose.uasset new file mode 100644 index 0000000..b05efff --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_clavicle_r_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:277f4410f9b80780972698064e0f4cf192b4375610506efa5d510ae0e8404f1a +size 206115 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_foot_l_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_foot_l_anim.uasset new file mode 100644 index 0000000..c2b2a80 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_foot_l_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8208edc319e609d4e6b1d326e62a877063d79cf503158a4bc1878fd02a93ed58 +size 135462 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_foot_l_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_foot_l_pose.uasset new file mode 100644 index 0000000..909c41a --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_foot_l_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6371fa829ebf962697f5be5b5650ceb195803537302f0ae3d1a0cd4111d74584 +size 132254 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_foot_r_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_foot_r_anim.uasset new file mode 100644 index 0000000..558cac0 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_foot_r_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3a6c53687aef19e408c06f41ee035835ca209af4ad8ff679152c47d0daf29600 +size 135464 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_foot_r_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_foot_r_pose.uasset new file mode 100644 index 0000000..d131e90 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_foot_r_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d83f07adb29976a36ddf99f245f24b5d3868ad3fdd5f0025acc9231346a014bc +size 132254 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_hand_l_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_hand_l_anim.uasset new file mode 100644 index 0000000..f4b66e0 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_hand_l_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed9e80e359140fb44037acbb066826198c27233bdd7c253cfb391ed6dc30d07b +size 141462 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_hand_l_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_hand_l_pose.uasset new file mode 100644 index 0000000..ace6e4b --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_hand_l_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b1aaee1c184ab23f77d462372726b9be294b25dc77eccb2f444e54ce72be812 +size 169284 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_hand_r_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_hand_r_anim.uasset new file mode 100644 index 0000000..a414ba1 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_hand_r_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83e66651a64a65e141384f67f3f036d82647c1c3024437b0b0ee0cc59533f6db +size 122362 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_hand_r_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_hand_r_pose.uasset new file mode 100644 index 0000000..dc73bac --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_hand_r_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac2d942e4fc64538231e1c921ec9d008a6d1bdecf76dc130bd372c687f781c08 +size 169284 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_lowerarm_l_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_lowerarm_l_anim.uasset new file mode 100644 index 0000000..1f49344 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_lowerarm_l_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9976a76b917eac5bdc0e4296a91d9816a198b8548d18594c3f623826726fe496 +size 158389 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_lowerarm_l_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_lowerarm_l_pose.uasset new file mode 100644 index 0000000..2c8178d --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_lowerarm_l_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba6822ed243f8452e0392cf4f198e636de9c868053e2261d63d8292ef96319c7 +size 399664 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_lowerarm_r_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_lowerarm_r_anim.uasset new file mode 100644 index 0000000..e2e3009 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_lowerarm_r_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:892f16dfdfa0d0d9957d427c7d620867adc3a33f3e7814fd92f91c7d696bf027 +size 158391 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_lowerarm_r_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_lowerarm_r_pose.uasset new file mode 100644 index 0000000..f933f99 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_lowerarm_r_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dee51a08a93109dec908d4cdffeba2be2ccc48d84cbed47048f99b12f43e7ddc +size 399664 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_thigh_l_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_thigh_l_anim.uasset new file mode 100644 index 0000000..5566b31 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_thigh_l_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:381b95e60bfc26a64d8595e047ea6a007e66adeeca20331d23127a82cdda783b +size 182369 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_thigh_l_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_thigh_l_pose.uasset new file mode 100644 index 0000000..90ff7c6 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_thigh_l_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbcbe04fcc189470ee8567f1e4363ebdd6b978cd018af41df6d6e849335dbaea +size 557750 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_thigh_r_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_thigh_r_anim.uasset new file mode 100644 index 0000000..5c41404 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_thigh_r_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b6c4a3386b121b0da667ca82a62986fb54575533bcaaf8797ee2ffb49e4b2629 +size 182371 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_thigh_r_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_thigh_r_pose.uasset new file mode 100644 index 0000000..c7cc3ae --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_thigh_r_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e4b3f86720ae78ec16ebcd7dcebef72bb89ad5216dc524cd193b6396faddf6a +size 557750 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_upperarm_l_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_upperarm_l_anim.uasset new file mode 100644 index 0000000..1e3518a --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_upperarm_l_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cedcccc8e20190a00ff514c5467ed6781748deb2178f856221f833b99c89f1ac +size 170390 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_upperarm_l_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_upperarm_l_pose.uasset new file mode 100644 index 0000000..15ec31f --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_upperarm_l_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:910546553703424dadce708ffb02ba320b60abff1b4bffa7ba637a1f76d8b5a3 +size 485575 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_upperarm_r_anim.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_upperarm_r_anim.uasset new file mode 100644 index 0000000..28b6e76 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_upperarm_r_anim.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02a0a2a388445683c68518c0062f7aff5baa45d8b490b8a0b7a0571a5977751a +size 170392 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_upperarm_r_pose.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_upperarm_r_pose.uasset new file mode 100644 index 0000000..886ec5e --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/Poses/Quinn/Quinn_upperarm_r_pose.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:167ccaa713eaa481437b4128bab282dd8e46a56c403d925f7a95ec8706289b70 +size 488585 diff --git a/Content/VRE/Core/Character/Mannequins/Rigs/RTG_Mannequin.uasset b/Content/VRE/Core/Character/Mannequins/Rigs/RTG_Mannequin.uasset new file mode 100644 index 0000000..0f1e5b1 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Rigs/RTG_Mannequin.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7f55f2e0aacf145904d8cbd2459af8739f043c928fbdc0b48bc8b92efda0fba +size 23761 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_ASAOPMASK_MSK.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_ASAOPMASK_MSK.uasset new file mode 100644 index 0000000..1b2b3ca --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_ASAOPMASK_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:adcfc2e6fb97e6625a6b358c6a2d4a96ac7f3cf7dea0551c486344291efa8295 +size 3612711 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_BN.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_BN.uasset new file mode 100644 index 0000000..2ee75cc --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_BN.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32a5d96fb2745b0d2c2a96aa6825a64ea177c9a1af64cbe7156a5a80852e60be +size 18514263 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_CCRCCPlastic_MSK.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_CCRCCPlastic_MSK.uasset new file mode 100644 index 0000000..daabd36 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_CCRCCPlastic_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6571dd4986df8ac46bbbba1f736ada982706ab0e5502a161142e368f4d7f52d +size 10272081 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_D.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_D.uasset new file mode 100644 index 0000000..8b78bd3 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_D.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1fbb07cb01e9eb29f8ceabbae27ede593bd4ede98957f492f197208e8db5dab2 +size 5740449 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_MSR_MSK.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_MSR_MSK.uasset new file mode 100644 index 0000000..88f75ce --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_MSR_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1751ca6b12e656c02c5e0fd50e1856d731c0304b81a6740a9847b2de30021547 +size 11038284 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_N.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_N.uasset new file mode 100644 index 0000000..9aeb54f --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_N.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a51fe0604dcb201b32ba900006f565b0330d826d3f6f891fb7e884c3cc7235c9 +size 7198345 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_Tan.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_Tan.uasset new file mode 100644 index 0000000..e016ef0 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_01_Tan.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bdc44109c7e4891fc8c8b15a98d06300f2c4e2b55f5513fb15a380de31a28d1 +size 1357866 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_ASAOPMASK_MSK.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_ASAOPMASK_MSK.uasset new file mode 100644 index 0000000..1824c76 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_ASAOPMASK_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb0e8f5e63df11c269dbffaf6a8a9c9ccf00261e985dfd6a42499ec78ce816e3 +size 8341487 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_BN.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_BN.uasset new file mode 100644 index 0000000..7573bb3 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_BN.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6cc567ea332550b67761d3c8afface743880d9ca2d7d701a328de16b4c9a0c1 +size 21139622 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_CCRCCPlastic_MSK.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_CCRCCPlastic_MSK.uasset new file mode 100644 index 0000000..e3a6b16 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_CCRCCPlastic_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acceca89b72d45be61b978671e8634e40b3439da0565565424bbb75bc491771a +size 13144152 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_D.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_D.uasset new file mode 100644 index 0000000..cb90248 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_D.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7f7e39f621fd09895097c8ef9be45b4c9114ff5434d41ff4875640377d90c048 +size 9033617 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_MSR_MSK.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_MSR_MSK.uasset new file mode 100644 index 0000000..a0cc5b4 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_MSR_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1cc57bbf89333f7053772d9d3ce220d5185af3b7b98e2b1be3710736ed81e385 +size 13677710 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_N.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_N.uasset new file mode 100644 index 0000000..02a6a68 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_N.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:774b5f12e83544218ad818e58a00e0651627e2a2139c6ae81740c32188b88790 +size 7269429 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_Tan.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_Tan.uasset new file mode 100644 index 0000000..1c513fc --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Manny/T_Manny_02_Tan.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb1d7c621fdcf8b600bcfb7ac7f10f5e1b1c9016a73997f4e024e94535a0e073 +size 2153886 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01ID_BN.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01ID_BN.uasset new file mode 100644 index 0000000..4fa1e57 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01ID_BN.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e399a20c77dcf93205859660f6fc938fa18c7eb0a7eef84fe11be57f44333f8f +size 16108696 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01ID_D.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01ID_D.uasset new file mode 100644 index 0000000..7e730a1 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01ID_D.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba3a9f3c53be7bcf473543fd7db586ddb25aeaa3654f2b334a42d97403e4cb4e +size 4711231 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01ID_MSR_MSK.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01ID_MSR_MSK.uasset new file mode 100644 index 0000000..bf17e43 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01ID_MSR_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2fe6e4d0e9dfe6b37fcfff10fd7828e57e303552d58d5097032c8d88e3f5ef01 +size 11656243 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01ID_N.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01ID_N.uasset new file mode 100644 index 0000000..dbe9183 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01ID_N.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:09b0a749d38658217ee32ff0d7cf875b8360eae15d10b2771a66edd8f49568dc +size 5217772 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01ID_Tan.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01ID_Tan.uasset new file mode 100644 index 0000000..abb1683 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01ID_Tan.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3a304782fd7992f18692fc5dc9b6fd121ec15d8e4088c09496cbfa73e5ebb466 +size 1104725 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01_ASAOMASK_MSK.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01_ASAOMASK_MSK.uasset new file mode 100644 index 0000000..a658a84 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01_ASAOMASK_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1d294824a3393a5b7abbef09dbbd08cea1eb248ca935b6727792a624d839f51 +size 5834939 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01_CCRCCPlastic_MSK.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01_CCRCCPlastic_MSK.uasset new file mode 100644 index 0000000..2ca4e1b --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_01_CCRCCPlastic_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7a0c808b5e0ea524c53e9be00e25bfa2bd2261b4f0ddfde14f3823e6c34f7ae +size 12400035 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02ID_BN.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02ID_BN.uasset new file mode 100644 index 0000000..5b55852 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02ID_BN.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae64881694d7d129425271e9749ae310de06e4f6b44b431048263a0bdd79269b +size 19706980 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02ID_D.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02ID_D.uasset new file mode 100644 index 0000000..9037825 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02ID_D.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff3848b1eba0eea285b8ed3f0bf32b3d06fcab26877eb30f56e55a1fbadf8f24 +size 6732599 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02ID_MSR_MSK.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02ID_MSR_MSK.uasset new file mode 100644 index 0000000..2ad72e2 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02ID_MSR_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f07854549aed14b0a08a810536fd3f92c7004f8cf325b6c229e199b77a70d210 +size 13169873 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02ID_N.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02ID_N.uasset new file mode 100644 index 0000000..610e4bd --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02ID_N.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:291193c31c0afedc313659a9712f91d771c5721af47dd1a074be93d6c97bf2a0 +size 5217772 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02ID_Tan.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02ID_Tan.uasset new file mode 100644 index 0000000..a82b78a --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02ID_Tan.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52e073a5286c21223e535aaa14196064e32da69a412bafaff889e45f1100f2cc +size 1758592 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02_ASAOMASK_MSK.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02_ASAOMASK_MSK.uasset new file mode 100644 index 0000000..45c6ee6 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02_ASAOMASK_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a8a3b6407fdeb750079ccfbd392598eb7ed13de5eebe3b3e02c4f1905021601 +size 6902078 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02_CCRCCPlastic_MSK.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02_CCRCCPlastic_MSK.uasset new file mode 100644 index 0000000..4fdb67a --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Quinn/T_Quinn_02_CCRCCPlastic_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6a1d60f0eabcd7d2655fb7619c7141f44ac7f2670f9f4113de67c5943c6c0db +size 13427967 diff --git a/Content/VRE/Core/Character/Mannequins/Textures/Shared/T_UE_Logo_M.uasset b/Content/VRE/Core/Character/Mannequins/Textures/Shared/T_UE_Logo_M.uasset new file mode 100644 index 0000000..4bc8f96 --- /dev/null +++ b/Content/VRE/Core/Character/Mannequins/Textures/Shared/T_UE_Logo_M.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47dae3eb7ff30f4c72bec58a775ee73523014520406e32c110a28f0ab1e092a2 +size 70054 diff --git a/Content/VRE/Core/Character/Materials/MF_OccludedPixels.uasset b/Content/VRE/Core/Character/Materials/MF_OccludedPixels.uasset new file mode 100644 index 0000000..6ab6003 --- /dev/null +++ b/Content/VRE/Core/Character/Materials/MF_OccludedPixels.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54a0408daab81a30343ab5a6eebbb7341858fd4327eea5a98bedd3703386fa26 +size 101110 diff --git a/Content/VRE/Core/Character/Materials/MI_ChaperoneOutline.uasset b/Content/VRE/Core/Character/Materials/MI_ChaperoneOutline.uasset new file mode 100644 index 0000000..442c544 --- /dev/null +++ b/Content/VRE/Core/Character/Materials/MI_ChaperoneOutline.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f16e14b4ebea466a0b9df780a72ba103a1c6673f7388c1dd2baa13dc18c70a47 +size 83176 diff --git a/Content/VRE/Core/Character/Materials/MI_SmallCubes.uasset b/Content/VRE/Core/Character/Materials/MI_SmallCubes.uasset new file mode 100644 index 0000000..3063540 --- /dev/null +++ b/Content/VRE/Core/Character/Materials/MI_SmallCubes.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62bcc58df01d0360bc1a9f0f15ca64e9c190b8bb68e1d577c4cf1e437ad8509a +size 93815 diff --git a/Content/VRE/Core/Character/Materials/MI_TeleportCylinderPreview.uasset b/Content/VRE/Core/Character/Materials/MI_TeleportCylinderPreview.uasset new file mode 100644 index 0000000..dc1b7b5 --- /dev/null +++ b/Content/VRE/Core/Character/Materials/MI_TeleportCylinderPreview.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9dc5a4c5036697c43ca19e908b333a5957af0f3fdcb519ab55afd01a51c97fe +size 86595 diff --git a/Content/VRE/Core/Character/Materials/M_ArcEndpoint.uasset b/Content/VRE/Core/Character/Materials/M_ArcEndpoint.uasset new file mode 100644 index 0000000..45bd2e7 --- /dev/null +++ b/Content/VRE/Core/Character/Materials/M_ArcEndpoint.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df74d0c1f039f45bf279012ec85336ff35ac6615c0b11b4fdebdcb8d675ab1b9 +size 39968 diff --git a/Content/VRE/Core/Character/Materials/M_BaseMaterial.uasset b/Content/VRE/Core/Character/Materials/M_BaseMaterial.uasset new file mode 100644 index 0000000..cf9c7bf --- /dev/null +++ b/Content/VRE/Core/Character/Materials/M_BaseMaterial.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4bba49da44c24411de48a207a27be18cd99c687e3c3bd5bf3a54ef2acdb6f74f +size 84767 diff --git a/Content/VRE/Core/Character/Materials/M_SplineArcMat.uasset b/Content/VRE/Core/Character/Materials/M_SplineArcMat.uasset new file mode 100644 index 0000000..6d84d80 --- /dev/null +++ b/Content/VRE/Core/Character/Materials/M_SplineArcMat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ed3c39989e69ab1d5b009cbbcdb162a079fed671c93dccd8e1576d8d96fbb7b +size 96939 diff --git a/Content/VRE/Core/Character/Materials/M_TeleportPreviews.uasset b/Content/VRE/Core/Character/Materials/M_TeleportPreviews.uasset new file mode 100644 index 0000000..644ddf6 --- /dev/null +++ b/Content/VRE/Core/Character/Materials/M_TeleportPreviews.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73a23e29e515999882607de2e1893ebd9049959d58e00b0b30f0fa3965383140 +size 98377 diff --git a/Content/VRE/Core/Character/Materials/TeleportMCP.uasset b/Content/VRE/Core/Character/Materials/TeleportMCP.uasset new file mode 100644 index 0000000..7bc999d --- /dev/null +++ b/Content/VRE/Core/Character/Materials/TeleportMCP.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e64974c83716a0270f5502fd90bd9a25a9228d9a8681f3fc94f0a8d8e929524 +size 1778 diff --git a/Content/VRE/Core/Character/Meshes/1x1_cube.uasset b/Content/VRE/Core/Character/Meshes/1x1_cube.uasset new file mode 100644 index 0000000..f7bb0c7 --- /dev/null +++ b/Content/VRE/Core/Character/Meshes/1x1_cube.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:93348fe619da2f377eb7a1f9abb2083c15a15004d032f433ad6b7d04fd4cbd58 +size 66048 diff --git a/Content/VRE/Core/Character/Meshes/BeaconDirection.uasset b/Content/VRE/Core/Character/Meshes/BeaconDirection.uasset new file mode 100644 index 0000000..2e61cec --- /dev/null +++ b/Content/VRE/Core/Character/Meshes/BeaconDirection.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e8320ab60f49afe35ae68ea9ec1c0f086751c9b1071360234d2d1c1e874b61f +size 23071 diff --git a/Content/VRE/Core/Character/Meshes/BeamMesh.uasset b/Content/VRE/Core/Character/Meshes/BeamMesh.uasset new file mode 100644 index 0000000..6a91c9f --- /dev/null +++ b/Content/VRE/Core/Character/Meshes/BeamMesh.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8fec217aa37eb7a505128347b5af8a3ccbf1c5337b18d0b10d2b45d89e15f443 +size 25004 diff --git a/Content/VRE/Core/Character/Meshes/SM_FatCylinder.uasset b/Content/VRE/Core/Character/Meshes/SM_FatCylinder.uasset new file mode 100644 index 0000000..e3a33aa --- /dev/null +++ b/Content/VRE/Core/Character/Meshes/SM_FatCylinder.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:856efe12362b5c9d2c2dc382bc1288200833381f07da2392409357d619d682c3 +size 23281 diff --git a/Content/VRE/Core/Character/MovementMode.uasset b/Content/VRE/Core/Character/MovementMode.uasset new file mode 100644 index 0000000..556cfec --- /dev/null +++ b/Content/VRE/Core/Character/MovementMode.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01c270fa3a06b43ac3906b8373466bbf5c0fcaa6a1efe1679afecbb55f79a804 +size 5307 diff --git a/Content/VRE/Core/Character/NewForceFeedbackEffect2.uasset b/Content/VRE/Core/Character/NewForceFeedbackEffect2.uasset new file mode 100644 index 0000000..656953c --- /dev/null +++ b/Content/VRE/Core/Character/NewForceFeedbackEffect2.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9e956a394bfe6a02e1101caee08e9f82779ef95bba5dd861e96a7b4f0c9bba0 +size 2482 diff --git a/Content/VRE/Core/Character/VOIPAtten.uasset b/Content/VRE/Core/Character/VOIPAtten.uasset new file mode 100644 index 0000000..ee5efbf --- /dev/null +++ b/Content/VRE/Core/Character/VOIPAtten.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30b8f0721f0f7186cf161fbebeb3f633f53b36cd80fa756b5fa902c838de2d94 +size 1368 diff --git a/Content/VRE/Core/Character/VR_MoverCharacter.uasset b/Content/VRE/Core/Character/VR_MoverCharacter.uasset new file mode 100644 index 0000000..f7af60e --- /dev/null +++ b/Content/VRE/Core/Character/VR_MoverCharacter.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56fbc7d94c3560ebef3c0344815f9f7d19dc16f01dca284b977e384ec260173b +size 66352 diff --git a/Content/VRE/Core/CustomLocalPlayer.uasset b/Content/VRE/Core/CustomLocalPlayer.uasset new file mode 100644 index 0000000..2ec26f4 --- /dev/null +++ b/Content/VRE/Core/CustomLocalPlayer.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d1dd04c7829b6a1f8c3495acb74dfd3f1ddb8a89c830f549c55e9bd58acd674 +size 6206 diff --git a/Content/VRE/Core/DefaultGameplayTags.uasset b/Content/VRE/Core/DefaultGameplayTags.uasset new file mode 100644 index 0000000..0895ccd --- /dev/null +++ b/Content/VRE/Core/DefaultGameplayTags.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ae95b01c3b9586c8865a8608f5a283501868837b6f2ed8b4449bf68a05c8355 +size 4870 diff --git a/Content/VRE/Core/GraspingHands/Gestures.uasset b/Content/VRE/Core/GraspingHands/Gestures.uasset new file mode 100644 index 0000000..f49c37f --- /dev/null +++ b/Content/VRE/Core/GraspingHands/Gestures.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa4cf0129b20a2d690c06d1ddeb3ac74e6608216d6625b69183f0520c72e9861 +size 6140 diff --git a/Content/VRE/Core/GraspingHands/GraspAnimBP.uasset b/Content/VRE/Core/GraspingHands/GraspAnimBP.uasset new file mode 100644 index 0000000..0ac6882 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/GraspAnimBP.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30f6cf32bcdb82d86b3a1c4279764c7010d29a1e0110a0a9cee61eed816489f5 +size 592475 diff --git a/Content/VRE/Core/GraspingHands/GraspAnimBPManny.uasset b/Content/VRE/Core/GraspingHands/GraspAnimBPManny.uasset new file mode 100644 index 0000000..b672e63 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/GraspAnimBPManny.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:113b070c95cabd0083641039ba8b9eea8513e343fc4243dd9f30ed12d14664e4 +size 604888 diff --git a/Content/VRE/Core/GraspingHands/GraspingBlend.uasset b/Content/VRE/Core/GraspingHands/GraspingBlend.uasset new file mode 100644 index 0000000..65ee1f5 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/GraspingBlend.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6a701a4008fcfde07775abfb54f0df35b4318316afd2f9eb8a2a6b6777d41af +size 7885 diff --git a/Content/VRE/Core/GraspingHands/GraspingBlendManny.uasset b/Content/VRE/Core/GraspingHands/GraspingBlendManny.uasset new file mode 100644 index 0000000..4792a35 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/GraspingBlendManny.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:888b3957bbb2c7423619b921b6de9c9b3f1ebed7eb9250967a16ac2179a5d70e +size 8868 diff --git a/Content/VRE/Core/GraspingHands/GraspingHand.uasset b/Content/VRE/Core/GraspingHands/GraspingHand.uasset new file mode 100644 index 0000000..e1467e2 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/GraspingHand.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5530a8573e12d46034bd24280c0abc6715ae2003f61c1b3d18a2ca389ca01906 +size 2446198 diff --git a/Content/VRE/Core/GraspingHands/GraspingHandManny.uasset b/Content/VRE/Core/GraspingHands/GraspingHandManny.uasset new file mode 100644 index 0000000..1be8650 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/GraspingHandManny.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e50ab842dad5857634ad9a9421668413c27bcf55830d88a97d85f274af707d98 +size 2554630 diff --git a/Content/VRE/Core/GraspingHands/GraspingPhysics.uasset b/Content/VRE/Core/GraspingHands/GraspingPhysics.uasset new file mode 100644 index 0000000..b030e54 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/GraspingPhysics.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c749c5c6ed2962234b07a3f5e01febce333d125eead42610649556c8a69692f8 +size 126272 diff --git a/Content/VRE/Core/GraspingHands/GraspingPhysicsManny.uasset b/Content/VRE/Core/GraspingHands/GraspingPhysicsManny.uasset new file mode 100644 index 0000000..3622fd8 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/GraspingPhysicsManny.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:058754dc3612df66d55038a7ff765967ce894f7b85f06376a20a6f20ce86ef4c +size 69933 diff --git a/Content/VRE/Core/GraspingHands/HandAnimState.uasset b/Content/VRE/Core/GraspingHands/HandAnimState.uasset new file mode 100644 index 0000000..c399504 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/HandAnimState.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b19e695b3faa89d8093b9b0b5eef960298d0b71d340459d5411e9ed0384b1d9f +size 3023 diff --git a/Content/VRE/Core/GraspingHands/PhysicsTossManager.uasset b/Content/VRE/Core/GraspingHands/PhysicsTossManager.uasset new file mode 100644 index 0000000..004c10c --- /dev/null +++ b/Content/VRE/Core/GraspingHands/PhysicsTossManager.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11d92c3fdb9ad0f88ccc631bcf239dff5a6341f79711b3eca311c6962c3e5292 +size 285951 diff --git a/Content/VRE/Core/GraspingHands/TriggerIndexs.uasset b/Content/VRE/Core/GraspingHands/TriggerIndexs.uasset new file mode 100644 index 0000000..4f65169 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/TriggerIndexs.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f230faef606a51133b4b90f52b6a3faeb10bea4e451bb5f15a27637d05880aea +size 5143 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/A_MannequinsXR_Grasp_Right.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/A_MannequinsXR_Grasp_Right.uasset new file mode 100644 index 0000000..470b2db --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/A_MannequinsXR_Grasp_Right.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c265c4a5179cbc49b00368235635ed1d8335dfca016bc78ff8e4948a095beb6 +size 29844 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/A_MannequinsXR_Idle_Right.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/A_MannequinsXR_Idle_Right.uasset new file mode 100644 index 0000000..8c0b03c --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/A_MannequinsXR_Idle_Right.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b8e07d4a99b3dc2ced7b8d4f05d986f6fdf2797eafcb50d525ae89c4935c9df +size 47127 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/A_MannequinsXR_IndexCurl_Right.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/A_MannequinsXR_IndexCurl_Right.uasset new file mode 100644 index 0000000..d4b7472 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/A_MannequinsXR_IndexCurl_Right.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04e0970c4cbc59c044ccf98219b746a974d8c71572d4ebcf35c894fd01d09264 +size 30163 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/A_MannequinsXR_Point_Right.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/A_MannequinsXR_Point_Right.uasset new file mode 100644 index 0000000..137e9ad --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/A_MannequinsXR_Point_Right.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:136de5f21df470e3322645d54b10ce70ddb1fbf24fe1758964caa61fb188223b +size 30075 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/A_MannequinsXR_ThumbUp_Right.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/A_MannequinsXR_ThumbUp_Right.uasset new file mode 100644 index 0000000..5ef3f67 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/A_MannequinsXR_ThumbUp_Right.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:170953d0519e3e7b9230a1e4347136fc1f102786f6cdeb6f73ca1b858f61ac8a +size 30136 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/GrabAnimation.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/GrabAnimation.uasset new file mode 100644 index 0000000..7b5b519 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/GrabAnimation.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29d60663acdcf836b1f18af8160e55605eed835f7860998f77bf8c5c64b935e7 +size 18098 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/MDT_MannequinsXR.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/MDT_MannequinsXR.uasset new file mode 100644 index 0000000..c1c81d8 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Animations/MDT_MannequinsXR.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:12e935fb2b9c993c1fea32f460877f99625f5ac9dc66e45713cafbf494c69c1c +size 12698 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/B_MannequinsXR.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/B_MannequinsXR.uasset new file mode 100644 index 0000000..a8aff4c --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/B_MannequinsXR.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c018cfaa312a441aeb0c3e3adfdce495c1da70d99effb180b75d8c6ab36b58cf +size 13722 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Functions/CA_Mannequin.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Functions/CA_Mannequin.uasset new file mode 100644 index 0000000..98e7dff --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Functions/CA_Mannequin.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b30315c5268c4c6f2bf734d3b92e2775cd157d159f4bbc5caf9caf8e6fa107d +size 4986 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Functions/ChromaticCurve.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Functions/ChromaticCurve.uasset new file mode 100644 index 0000000..7bd3825 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Functions/ChromaticCurve.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92f3173629d4560f25529f361141d58ac6fa21a8d6191c537f703b13ee929b73 +size 6447 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Functions/MF_Diffraction.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Functions/MF_Diffraction.uasset new file mode 100644 index 0000000..c815496 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Functions/MF_Diffraction.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0926a93a1f8fc963c4f1ea8a3938e268aac97d8637602351aa2a24214f76889 +size 32083 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Functions/MF_logo3layers.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Functions/MF_logo3layers.uasset new file mode 100644 index 0000000..ef5ad5d --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Functions/MF_logo3layers.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ec0f6fc2eedc7fccfcf37ea6ea4179896bc99cb556dcd05a1b467f1a0ed64e4f +size 54856 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Functions/ML_BaseColorFallOff.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Functions/ML_BaseColorFallOff.uasset new file mode 100644 index 0000000..e1f8e51 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Functions/ML_BaseColorFallOff.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd8135c90a2ee5475a026fda4d521aa5587c7cb37ecff60b5918ffbcbee74ad1 +size 13751 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Instances/Manny/MI_Manny_01.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Instances/Manny/MI_Manny_01.uasset new file mode 100644 index 0000000..8a6b70a --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Instances/Manny/MI_Manny_01.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5ababd4023308c31b036cbcb7807007169945e2be7811b495edc82405933917 +size 15549 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Instances/Manny/MI_Manny_02.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Instances/Manny/MI_Manny_02.uasset new file mode 100644 index 0000000..2dcd1f5 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/Instances/Manny/MI_Manny_02.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc3290f2fdab2392cdfe63ca1f39963eb6a3ab53e94c614b2b227cbebad8fd7b +size 20126 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/M_Mannequin.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/M_Mannequin.uasset new file mode 100644 index 0000000..4dbd090 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Materials/M_Mannequin.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d0de5cf3c470c1ea90877e3518ff9dc4b96545b56f0b0e8045519907c7bfeaa +size 79412 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Meshes/ABP_MannequinsXR.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Meshes/ABP_MannequinsXR.uasset new file mode 100644 index 0000000..20db8ae --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Meshes/ABP_MannequinsXR.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01de832d0c6c993b0f4a9d01605080af5cc8e11c625003c814e63a4e5955f999 +size 226849 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Meshes/SKM_MannyXR_left.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Meshes/SKM_MannyXR_left.uasset new file mode 100644 index 0000000..37ff094 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Meshes/SKM_MannyXR_left.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49761abd36fc336199f308b808a05edf93c531bc7e5de50e0a1a7277ebed5759 +size 2341113 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Meshes/SKM_MannyXR_right.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Meshes/SKM_MannyXR_right.uasset new file mode 100644 index 0000000..d2c4d9d --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Meshes/SKM_MannyXR_right.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a900ce60070e4f6a8286c3a25de9e2f55dc50863fbc89e95824c07d97f2a9973 +size 2340333 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Meshes/SK_MannequinsXR.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Meshes/SK_MannequinsXR.uasset new file mode 100644 index 0000000..778c06b --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Meshes/SK_MannequinsXR.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa6834d20b534c4919ed5d11564c65f3a8dc46462b12ec1e63ebdf019a46f7fc +size 53130 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_ASAOPMASK_MSK.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_ASAOPMASK_MSK.uasset new file mode 100644 index 0000000..89c075f --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_ASAOPMASK_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce32d32ba29bc7f506de3cecd6fca0f2f5890530ca3df2ad4028aacd5b3848ed +size 3612723 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_BN.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_BN.uasset new file mode 100644 index 0000000..23a94da --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_BN.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1cab472105172ff531e7d4b581d49a0b0267c3a01192a9b346d167227a01cafb +size 18514275 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_CCRCCPlastic_MSK.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_CCRCCPlastic_MSK.uasset new file mode 100644 index 0000000..f235d70 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_CCRCCPlastic_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:663d2b0ae07554ec74f1476f758828be6723bb4539974f02b9e06b445e25de82 +size 10272093 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_D.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_D.uasset new file mode 100644 index 0000000..1267d9e --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_D.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d3d691c0808c6378042935fd497fa6328fe6a0f65fc14ede6ef74bd897896fd +size 5740461 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_MSR_MSK.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_MSR_MSK.uasset new file mode 100644 index 0000000..6209c01 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_MSR_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:594997242a9e782913f417bf7b66bfdd4e973f61d37f19517946b00f8330fdcd +size 11038296 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_N.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_N.uasset new file mode 100644 index 0000000..da667a0 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_N.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6d855986290da65aeb62f194871eccb3345b756a16392b74f08e484de1187cb1 +size 7198357 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_Tan.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_Tan.uasset new file mode 100644 index 0000000..cc74e2e --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_01_Tan.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5198cf31123bfc90086843c08469c7446089a9c02e4730ac5a237770b4bcc38 +size 1357878 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_ASAOPMASK_MSK.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_ASAOPMASK_MSK.uasset new file mode 100644 index 0000000..815b6d6 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_ASAOPMASK_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:799d88e7e15925be4b7ebc9bd36a0e4a757cdf46e0cb2c7d3d09ebc9259c0f53 +size 8341499 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_BN.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_BN.uasset new file mode 100644 index 0000000..8bea4d6 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_BN.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ec720ed86dd6f43709a1da7edeb4a84adcefc17ee1417fbe58577ebf61adb580 +size 21139634 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_CCRCCPlastic_MSK.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_CCRCCPlastic_MSK.uasset new file mode 100644 index 0000000..6b381a5 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_CCRCCPlastic_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7cbed690c700c91f50e0869f80afc58d5cd23827937560acfc509840ea9567a4 +size 13144001 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_D.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_D.uasset new file mode 100644 index 0000000..752f2ce --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_D.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c352d07a48e228219b32dee09b7668594655cfca59d97b15dc8cb1a49e1eadd9 +size 9033629 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_MSR_MSK.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_MSR_MSK.uasset new file mode 100644 index 0000000..dfd2fda --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_MSR_MSK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ec66618f04ba83fca769b035feb5c006ff10a3e96e661484bb1dcd6b5d810dac +size 13677722 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_N.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_N.uasset new file mode 100644 index 0000000..c5c838b --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_N.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8966f6bab5c41e69e5145b4f17e95ab65fb31e917c74eef271051a566da80c7c +size 7269441 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_Tan.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_Tan.uasset new file mode 100644 index 0000000..558b417 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Manny/T_Manny_02_Tan.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:38467e22cf6c7828771d7f8184c9d6fed06b6711b35614f9760b64403e3c4945 +size 2153898 diff --git a/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Shared/T_UE_Logo_M.uasset b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Shared/T_UE_Logo_M.uasset new file mode 100644 index 0000000..906fae9 --- /dev/null +++ b/Content/VRE/Core/GraspingHands/VRHandMeshes/Textures/Shared/T_UE_Logo_M.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f07764fd1a0041865c1cf996725714a2ba3baf0df51a24e58f0adebdd99d5d8f +size 70066 diff --git a/Content/VRE/Core/HandSockets/HandSocketBase.uasset b/Content/VRE/Core/HandSockets/HandSocketBase.uasset new file mode 100644 index 0000000..3143dac --- /dev/null +++ b/Content/VRE/Core/HandSockets/HandSocketBase.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e9afbf8d9f9e4bbd7cb6db658f61a41bffe5c58c0cda80b9bf40bce72b13c216 +size 16993 diff --git a/Content/VRE/Core/HandSockets/HandSocketMat.uasset b/Content/VRE/Core/HandSockets/HandSocketMat.uasset new file mode 100644 index 0000000..6f7bc67 --- /dev/null +++ b/Content/VRE/Core/HandSockets/HandSocketMat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60d11e9fd42cd8cf37367a275aa7c98a8b428cc98942013db797bca364e2e287 +size 114250 diff --git a/Content/VRE/Core/OutlineFX/GRipHighLight.uasset b/Content/VRE/Core/OutlineFX/GRipHighLight.uasset new file mode 100644 index 0000000..0b60fc0 --- /dev/null +++ b/Content/VRE/Core/OutlineFX/GRipHighLight.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a2471b5e79cbc086f51b36886d4f0d4c18e8c13490f4d27b35d3c6b5c69a1ce +size 34061 diff --git a/Content/VRE/Core/OutlineFX/MT_I_OUTLINER.uasset b/Content/VRE/Core/OutlineFX/MT_I_OUTLINER.uasset new file mode 100644 index 0000000..4376c58 --- /dev/null +++ b/Content/VRE/Core/OutlineFX/MT_I_OUTLINER.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b25a83480cc6370e46dea0f658696f7e7a2fea6163d39c4ec2b5a0684acc3247 +size 14521 diff --git a/Content/VRE/Core/OutlineFX/M_LocalOutlines.uasset b/Content/VRE/Core/OutlineFX/M_LocalOutlines.uasset new file mode 100644 index 0000000..7bbe6e2 --- /dev/null +++ b/Content/VRE/Core/OutlineFX/M_LocalOutlines.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1db7104548222dd8257f7cc60517259424e70c3067cd610a041faa8acb7a8ca0 +size 110564 diff --git a/Content/VRE/Core/OutlineFX/OutLineOverlay.uasset b/Content/VRE/Core/OutlineFX/OutLineOverlay.uasset new file mode 100644 index 0000000..a4f5fb0 --- /dev/null +++ b/Content/VRE/Core/OutlineFX/OutLineOverlay.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f4e279329d584dc2cbcbadf57be9370e6fc367919bd795e3f5bbade7109a2f2 +size 19015 diff --git a/Content/VRE/Core/OutlineFX/OutlineOverlay_Inst.uasset b/Content/VRE/Core/OutlineFX/OutlineOverlay_Inst.uasset new file mode 100644 index 0000000..7e7289d --- /dev/null +++ b/Content/VRE/Core/OutlineFX/OutlineOverlay_Inst.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5895d7b2fd20fa5efb74f3ce7c7923ea513776ab6a82fdca9408b6b40edbd6d8 +size 9312 diff --git a/Content/VRE/Core/OutlineFX/VRStereoFixer.uasset b/Content/VRE/Core/OutlineFX/VRStereoFixer.uasset new file mode 100644 index 0000000..f528865 --- /dev/null +++ b/Content/VRE/Core/OutlineFX/VRStereoFixer.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d4356ad1143fae6b22f279cdf0897df9f9ededea214c7b6b24db2b17029e88f +size 26029 diff --git a/Content/VRE/Core/PendingPC.uasset b/Content/VRE/Core/PendingPC.uasset new file mode 100644 index 0000000..008bcb0 --- /dev/null +++ b/Content/VRE/Core/PendingPC.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b2167e82facf92adbeb93c08a63b213ea320776aa96d89e31d0bc35642710b2 +size 27086 diff --git a/Content/VRE/Core/PhysicalMats/PM_Alum.uasset b/Content/VRE/Core/PhysicalMats/PM_Alum.uasset new file mode 100644 index 0000000..99a6a72 --- /dev/null +++ b/Content/VRE/Core/PhysicalMats/PM_Alum.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a021ff228a4ae98acdcfcca3b75825059bd652798dc000eb5e76f5dc8f4e798a +size 1379 diff --git a/Content/VRE/Core/PhysicalMats/PM_Hardwood.uasset b/Content/VRE/Core/PhysicalMats/PM_Hardwood.uasset new file mode 100644 index 0000000..05822fc --- /dev/null +++ b/Content/VRE/Core/PhysicalMats/PM_Hardwood.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99d0b46af625ca3c6feba9a8fe1fcce90e7e3fd972c2389cb4b82deb4384ab88 +size 1477 diff --git a/Content/VRE/Core/PhysicalMats/PM_Steel.uasset b/Content/VRE/Core/PhysicalMats/PM_Steel.uasset new file mode 100644 index 0000000..9111aaa --- /dev/null +++ b/Content/VRE/Core/PhysicalMats/PM_Steel.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b359ecff9c2e3953ce83e8066ccf15a5ceb63f8ab5346bd15039eb6896b0b19b +size 1383 diff --git a/Content/VRE/Core/Template_VR_Player_Controller.uasset b/Content/VRE/Core/Template_VR_Player_Controller.uasset new file mode 100644 index 0000000..db7358e --- /dev/null +++ b/Content/VRE/Core/Template_VR_Player_Controller.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c8d0e7108076c15c4f87b88ea83abd84b50226f91a2c83c7007f867365aeec1 +size 238162 diff --git a/Content/VRE/Core/VRGameInstance.uasset b/Content/VRE/Core/VRGameInstance.uasset new file mode 100644 index 0000000..553aa52 --- /dev/null +++ b/Content/VRE/Core/VRGameInstance.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:71935ffebc175ba938413214c8fc35a1401603b164ee247025ecaf5dd9c44e4a +size 9094 diff --git a/Content/VRE/Core/VRGameMode.uasset b/Content/VRE/Core/VRGameMode.uasset new file mode 100644 index 0000000..ed10686 --- /dev/null +++ b/Content/VRE/Core/VRGameMode.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff2a09974e04b0cb5e29b828479eab8d9eeb50a464db264533519340783ebcf1 +size 26008 diff --git a/Content/VRE/Core/VRViewportClass.uasset b/Content/VRE/Core/VRViewportClass.uasset new file mode 100644 index 0000000..aa56d16 --- /dev/null +++ b/Content/VRE/Core/VRViewportClass.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dff16568830426dbf60838ea138a16bfe440db8055e1ed3f15943229c1816c07 +size 6006 diff --git a/Content/VRE/ExampleMap/LevelSMs/Box_Brush13_StaticMesh.uasset b/Content/VRE/ExampleMap/LevelSMs/Box_Brush13_StaticMesh.uasset new file mode 100644 index 0000000..5910f8c --- /dev/null +++ b/Content/VRE/ExampleMap/LevelSMs/Box_Brush13_StaticMesh.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10391fea96ab434d99d1d23737016a268a2c42440c7fad7d07f12c446d0f13a0 +size 18467 diff --git a/Content/VRE/ExampleMap/LevelSMs/Box_Brush14_StaticMesh.uasset b/Content/VRE/ExampleMap/LevelSMs/Box_Brush14_StaticMesh.uasset new file mode 100644 index 0000000..cbfebc2 --- /dev/null +++ b/Content/VRE/ExampleMap/LevelSMs/Box_Brush14_StaticMesh.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4e4a7867f411e848f08c9170a12920a9500666027432e8ef6c233a7dbf41c55 +size 24257 diff --git a/Content/VRE/ExampleMap/LevelSMs/Box_Brush22_StaticMesh.uasset b/Content/VRE/ExampleMap/LevelSMs/Box_Brush22_StaticMesh.uasset new file mode 100644 index 0000000..0896e49 --- /dev/null +++ b/Content/VRE/ExampleMap/LevelSMs/Box_Brush22_StaticMesh.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ebd328ddb48f91e11e4573b8357152ce511bdd249a2cdd8c629a770026651045 +size 17077 diff --git a/Content/VRE/ExampleMap/LevelSMs/Box_Brush2_StaticMesh.uasset b/Content/VRE/ExampleMap/LevelSMs/Box_Brush2_StaticMesh.uasset new file mode 100644 index 0000000..ce850f7 --- /dev/null +++ b/Content/VRE/ExampleMap/LevelSMs/Box_Brush2_StaticMesh.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e8250f324987ba218861508e39eec873fde808e69e570e10547bad10df042a0c +size 15733 diff --git a/Content/VRE/ExampleMap/LevelSMs/Box_Brush3_StaticMesh.uasset b/Content/VRE/ExampleMap/LevelSMs/Box_Brush3_StaticMesh.uasset new file mode 100644 index 0000000..6e3dd00 --- /dev/null +++ b/Content/VRE/ExampleMap/LevelSMs/Box_Brush3_StaticMesh.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e4653a80131ccccae3c410b5ac3c21b6e8575ef19b950e1fed0226a57aba5cd +size 15450 diff --git a/Content/VRE/ExampleMap/LevelSMs/Box_Brush4_StaticMesh.uasset b/Content/VRE/ExampleMap/LevelSMs/Box_Brush4_StaticMesh.uasset new file mode 100644 index 0000000..3f23cd5 --- /dev/null +++ b/Content/VRE/ExampleMap/LevelSMs/Box_Brush4_StaticMesh.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c2bc60803baf2e8b20485b5b0ec2facdc2384794f93c66754b2cabc5d64cfcf4 +size 15912 diff --git a/Content/VRE/ExampleMap/LevelSMs/Box_Brush6_StaticMesh.uasset b/Content/VRE/ExampleMap/LevelSMs/Box_Brush6_StaticMesh.uasset new file mode 100644 index 0000000..828d009 --- /dev/null +++ b/Content/VRE/ExampleMap/LevelSMs/Box_Brush6_StaticMesh.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e90fe931bea94598a40a5f072e81f0c40c05ae18375267915c5dffda2af0570 +size 16340 diff --git a/Content/VRE/ExampleMap/LevelSMs/Box_Brush7_StaticMesh.uasset b/Content/VRE/ExampleMap/LevelSMs/Box_Brush7_StaticMesh.uasset new file mode 100644 index 0000000..2747418 --- /dev/null +++ b/Content/VRE/ExampleMap/LevelSMs/Box_Brush7_StaticMesh.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91a7bde3205120e3ce15cea8b3ade316a2c3d6db86f7f3833fb7ba4834f15529 +size 15585 diff --git a/Content/VRE/ExampleMap/LevelSMs/Box_Brush8_StaticMesh.uasset b/Content/VRE/ExampleMap/LevelSMs/Box_Brush8_StaticMesh.uasset new file mode 100644 index 0000000..ca5f886 --- /dev/null +++ b/Content/VRE/ExampleMap/LevelSMs/Box_Brush8_StaticMesh.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6f64c3beeac932365b4a9e55db67408a28afd156c5a4a24ff107881c7304f4b +size 16785 diff --git a/Content/VRE/ExampleMap/LevelSMs/Box_Brush_StaticMesh.uasset b/Content/VRE/ExampleMap/LevelSMs/Box_Brush_StaticMesh.uasset new file mode 100644 index 0000000..6c62f89 --- /dev/null +++ b/Content/VRE/ExampleMap/LevelSMs/Box_Brush_StaticMesh.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7fc221df0d911f5870dd3b1c23d01399a86b89612b69be58ec3fc9f65220a19f +size 20563 diff --git a/Content/VRE/ExampleMap/LevelSMs/Curved_Stair_Brush_StaticMesh.uasset b/Content/VRE/ExampleMap/LevelSMs/Curved_Stair_Brush_StaticMesh.uasset new file mode 100644 index 0000000..7353f24 --- /dev/null +++ b/Content/VRE/ExampleMap/LevelSMs/Curved_Stair_Brush_StaticMesh.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66b277c3d6d61654ce7d50678eeb8eb3be4d3f7d70e88b141197024405606a7f +size 22965 diff --git a/Content/VRE/ExampleMap/MotionControllerMap.umap b/Content/VRE/ExampleMap/MotionControllerMap.umap new file mode 100644 index 0000000..2cc45e5 --- /dev/null +++ b/Content/VRE/ExampleMap/MotionControllerMap.umap @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fae8e1b6d856d4b0d04994683869e2d23d84e5a9e10f2722e3f9f8e3a8a1828a +size 817572 diff --git a/Content/VRE/Grippables/Misc/Examples/BP_PickupCube.uasset b/Content/VRE/Grippables/Misc/Examples/BP_PickupCube.uasset new file mode 100644 index 0000000..b6f7678 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/BP_PickupCube.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd1a07bf541a81e9cce6b581bf7cdadb1020431e5e3c32c8d456b15f392e8e92 +size 150174 diff --git a/Content/VRE/Grippables/Misc/Examples/Button/ButtonActor.uasset b/Content/VRE/Grippables/Misc/Examples/Button/ButtonActor.uasset new file mode 100644 index 0000000..f63846b --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Button/ButtonActor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1a8ea0819428917ed7950bfc6d46a01807df48a7351bf7cd5c9f94aeca5a2a9b +size 202238 diff --git a/Content/VRE/Grippables/Misc/Examples/Button/ButtonBase.uasset b/Content/VRE/Grippables/Misc/Examples/Button/ButtonBase.uasset new file mode 100644 index 0000000..526d831 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Button/ButtonBase.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64cc2164c96336613f8fe61a818946638eeb7b0bb21402e1fd63ed6fb61d1648 +size 35104 diff --git a/Content/VRE/Grippables/Misc/Examples/Button/ButtonComponent.uasset b/Content/VRE/Grippables/Misc/Examples/Button/ButtonComponent.uasset new file mode 100644 index 0000000..894caf2 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Button/ButtonComponent.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95bff05325a75be2a611e3470e106230ac6cb2bacc602f184ac6a88ea5e5b11b +size 379820 diff --git a/Content/VRE/Grippables/Misc/Examples/Button/ButtonTop.uasset b/Content/VRE/Grippables/Misc/Examples/Button/ButtonTop.uasset new file mode 100644 index 0000000..c1a6218 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Button/ButtonTop.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a81a6225e3093b7eb97a204fcdf6500ad2b9c2dea96dea3f55c576a8bc59986d +size 66155 diff --git a/Content/VRE/Grippables/Misc/Examples/Button/Button_Mat_Inst.uasset b/Content/VRE/Grippables/Misc/Examples/Button/Button_Mat_Inst.uasset new file mode 100644 index 0000000..e2ed19e --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Button/Button_Mat_Inst.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:80150b19456873f2b10d0e4b9b989640bc09f71baeead650a50f3beb306d875b +size 66333 diff --git a/Content/VRE/Grippables/Misc/Examples/Button/ColorChangingButtonComponent.uasset b/Content/VRE/Grippables/Misc/Examples/Button/ColorChangingButtonComponent.uasset new file mode 100644 index 0000000..ef0a800 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Button/ColorChangingButtonComponent.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:69830f818201f1723d8983d309044fd0f41227fc256509527e072f3747012e14 +size 62983 diff --git a/Content/VRE/Grippables/Misc/Examples/Button/EButtonType.uasset b/Content/VRE/Grippables/Misc/Examples/Button/EButtonType.uasset new file mode 100644 index 0000000..cdb8760 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Button/EButtonType.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5fb8ec1bd634dd924cf1c44fd8ee5e0aa39229e875137f63d6181938be77cef5 +size 2304 diff --git a/Content/VRE/Grippables/Misc/Examples/Button/ElectricalObject.uasset b/Content/VRE/Grippables/Misc/Examples/Button/ElectricalObject.uasset new file mode 100644 index 0000000..4159efb --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Button/ElectricalObject.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf4cc3e58aec9a98fa0bfe9f03ada09ce59d8d711734f053d9996c8b93bbd13d +size 12597 diff --git a/Content/VRE/Grippables/Misc/Examples/Button/Gray.uasset b/Content/VRE/Grippables/Misc/Examples/Button/Gray.uasset new file mode 100644 index 0000000..4967146 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Button/Gray.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a23deb87e91daf4031a23e2c72bc6c55c61dbf997b498c969f1b735d74dabea9 +size 6069 diff --git a/Content/VRE/Grippables/Misc/Examples/Button/Green.uasset b/Content/VRE/Grippables/Misc/Examples/Button/Green.uasset new file mode 100644 index 0000000..8a8d315 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Button/Green.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61cd829c1307abb54d7865e377f7ca8f11eb73496809713d1695055985d14a6b +size 17999 diff --git a/Content/VRE/Grippables/Misc/Examples/Cabinet/Cabinet.uasset b/Content/VRE/Grippables/Misc/Examples/Cabinet/Cabinet.uasset new file mode 100644 index 0000000..2b1cf7e --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Cabinet/Cabinet.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd4309da843eaa0c650dce6c4bb9dc91ec947494705222dacf8f29df64540990 +size 58168 diff --git a/Content/VRE/Grippables/Misc/Examples/Cabinet/CabinetBase.uasset b/Content/VRE/Grippables/Misc/Examples/Cabinet/CabinetBase.uasset new file mode 100644 index 0000000..18ae603 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Cabinet/CabinetBase.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90a1b2da8d54bd1cbec340ba64c6d9bf50118348e67a090ce036f35d8d96f1e6 +size 20834 diff --git a/Content/VRE/Grippables/Misc/Examples/Cabinet/CabinetDoor.uasset b/Content/VRE/Grippables/Misc/Examples/Cabinet/CabinetDoor.uasset new file mode 100644 index 0000000..ce7ccae --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Cabinet/CabinetDoor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a69477ea30c64b3a4c2427fa6f83c14135dd8db699a08024fa7f0edeb952ebdd +size 17717 diff --git a/Content/VRE/Grippables/Misc/Examples/Cabinet/Gray.uasset b/Content/VRE/Grippables/Misc/Examples/Cabinet/Gray.uasset new file mode 100644 index 0000000..4906592 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Cabinet/Gray.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5522aa366ce2d692e0012d2440f74795abe1ae374e7c38a87c805642c1ce71f9 +size 81208 diff --git a/Content/VRE/Grippables/Misc/Examples/Cabinet/Green.uasset b/Content/VRE/Grippables/Misc/Examples/Cabinet/Green.uasset new file mode 100644 index 0000000..de6b2c7 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Cabinet/Green.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a8838140790a8f0c9b45a47fe6b690c968fefa14881ca723ca28fe28cd383fa +size 94280 diff --git a/Content/VRE/Grippables/Misc/Examples/Cabinet/Lime.uasset b/Content/VRE/Grippables/Misc/Examples/Cabinet/Lime.uasset new file mode 100644 index 0000000..3e00508 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Cabinet/Lime.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:085d6332bf28450397ebbc9bd8fce6a136cec6db508843e0a3b436a10e087463 +size 94098 diff --git a/Content/VRE/Grippables/Misc/Examples/Camera/Black.uasset b/Content/VRE/Grippables/Misc/Examples/Camera/Black.uasset new file mode 100644 index 0000000..07912f0 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Camera/Black.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba8324a8a46e6155cb2a24ada3e678b52e17ec6d8066d0b98fe035815c37cc87 +size 25458 diff --git a/Content/VRE/Grippables/Misc/Examples/Camera/CameraRecorder.uasset b/Content/VRE/Grippables/Misc/Examples/Camera/CameraRecorder.uasset new file mode 100644 index 0000000..ced8b0a --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Camera/CameraRecorder.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79702223e28a0f8b0251e0bd4e4511483c0ecf9c1a6b5c1255ebb68ec3057284 +size 268529 diff --git a/Content/VRE/Grippables/Misc/Examples/Camera/CameraRenderTarget.uasset b/Content/VRE/Grippables/Misc/Examples/Camera/CameraRenderTarget.uasset new file mode 100644 index 0000000..e39807d --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Camera/CameraRenderTarget.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f32afb2d3f030b63aa27285f455371b0191343097d1d98f1a4abd79860fccfd +size 3641 diff --git a/Content/VRE/Grippables/Misc/Examples/Camera/CameraScreen.uasset b/Content/VRE/Grippables/Misc/Examples/Camera/CameraScreen.uasset new file mode 100644 index 0000000..f339cde --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Camera/CameraScreen.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e8a978d8e277ac685477e77140a5f6b05fb3bfcaeffbf32fb69e7299c1204d7c +size 41802 diff --git a/Content/VRE/Grippables/Misc/Examples/Camera/CameraScreenMat.uasset b/Content/VRE/Grippables/Misc/Examples/Camera/CameraScreenMat.uasset new file mode 100644 index 0000000..41d0331 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Camera/CameraScreenMat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:903272c3b4530e07619493df888b6f6e37b152ff9d8102fad6e3cecffd942677 +size 10873 diff --git a/Content/VRE/Grippables/Misc/Examples/Camera/Camerabody.uasset b/Content/VRE/Grippables/Misc/Examples/Camera/Camerabody.uasset new file mode 100644 index 0000000..8399df8 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Camera/Camerabody.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6426aa8965d838f8d7e3687ede63be7ba029c866339b43fa42cba0984a108767 +size 75902 diff --git a/Content/VRE/Grippables/Misc/Examples/Camera/ForeGroundRenderTarget.uasset b/Content/VRE/Grippables/Misc/Examples/Camera/ForeGroundRenderTarget.uasset new file mode 100644 index 0000000..b39d757 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Camera/ForeGroundRenderTarget.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f909b074d1c940bbdcb9c9802758d09d6041b228899315a89826249089675c88 +size 3492 diff --git a/Content/VRE/Grippables/Misc/Examples/Camera/GreenScreen_PP.uasset b/Content/VRE/Grippables/Misc/Examples/Camera/GreenScreen_PP.uasset new file mode 100644 index 0000000..f708984 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Camera/GreenScreen_PP.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:334a096855afefda3acaa1bcf70eb2bf7e820e81d8bfb4afc39f66d8b9bc576d +size 65017 diff --git a/Content/VRE/Grippables/Misc/Examples/Camera/MixedOutput.uasset b/Content/VRE/Grippables/Misc/Examples/Camera/MixedOutput.uasset new file mode 100644 index 0000000..5f0bd9d --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Camera/MixedOutput.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a988c604e1874c549b15b7c8453cb95c167cef32360216ddee3167d028176b9f +size 3377 diff --git a/Content/VRE/Grippables/Misc/Examples/Camera/MixedOutput_Mat.uasset b/Content/VRE/Grippables/Misc/Examples/Camera/MixedOutput_Mat.uasset new file mode 100644 index 0000000..8781aa0 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Camera/MixedOutput_Mat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:041a1ea331c26a214ac6732716105ff8dab91bdd795972b470299eca9225f493 +size 95569 diff --git a/Content/VRE/Grippables/Misc/Examples/Camera/MixedReality_MPC.uasset b/Content/VRE/Grippables/Misc/Examples/Camera/MixedReality_MPC.uasset new file mode 100644 index 0000000..004fee2 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Camera/MixedReality_MPC.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:559661367178dcdca61fb03f772e60fc6cb6018940c5c391335de3a1f9628b92 +size 2150 diff --git a/Content/VRE/Grippables/Misc/Examples/Camera/White.uasset b/Content/VRE/Grippables/Misc/Examples/Camera/White.uasset new file mode 100644 index 0000000..733fbfc --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Camera/White.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e575c89ace5e2d09c5bd99780b595cf63284e352497b74015a5fb4cbc03705f +size 74950 diff --git a/Content/VRE/Grippables/Misc/Examples/DialIndicator/DialComponent.uasset b/Content/VRE/Grippables/Misc/Examples/DialIndicator/DialComponent.uasset new file mode 100644 index 0000000..d4a89ed --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DialIndicator/DialComponent.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e1a99dd8b3ca2b77246336f1d27da028e603b27eac7f771784f68fe25e3afd2 +size 131681 diff --git a/Content/VRE/Grippables/Misc/Examples/DialIndicator/DialIndicator.uasset b/Content/VRE/Grippables/Misc/Examples/DialIndicator/DialIndicator.uasset new file mode 100644 index 0000000..5504cec --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DialIndicator/DialIndicator.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1af2ccaa51feb7292eab50373fd1c638172ef7bc2862fe88f0f5eb5f0013300d +size 196537 diff --git a/Content/VRE/Grippables/Misc/Examples/DialIndicator/DialIndicatorBase.uasset b/Content/VRE/Grippables/Misc/Examples/DialIndicator/DialIndicatorBase.uasset new file mode 100644 index 0000000..5e4d882 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DialIndicator/DialIndicatorBase.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:35474a9568c69f94180bcb1123c25a7e4aeda891aa15c7fa65c4b0172e8faea4 +size 16474 diff --git a/Content/VRE/Grippables/Misc/Examples/DialIndicator/DialIndicatorTop.uasset b/Content/VRE/Grippables/Misc/Examples/DialIndicator/DialIndicatorTop.uasset new file mode 100644 index 0000000..b46d0e3 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DialIndicator/DialIndicatorTop.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46741e029d1ec16ed7c83772456430b084feb98914228afb72a5a1918848b2de +size 119906 diff --git a/Content/VRE/Grippables/Misc/Examples/DialIndicator/Green.uasset b/Content/VRE/Grippables/Misc/Examples/DialIndicator/Green.uasset new file mode 100644 index 0000000..0ad2666 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DialIndicator/Green.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45dce261f7182c28d550ceb3a520de2d91c582c6972fff0c1d0be43302cfd43b +size 36251 diff --git a/Content/VRE/Grippables/Misc/Examples/DialIndicator/NativeDialIndicator.uasset b/Content/VRE/Grippables/Misc/Examples/DialIndicator/NativeDialIndicator.uasset new file mode 100644 index 0000000..681f4ba --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DialIndicator/NativeDialIndicator.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ad9cd7137188c080b26746c710459267b27aee900d509dc615f10a4b58061b6 +size 215281 diff --git a/Content/VRE/Grippables/Misc/Examples/DialIndicator/Turquoise.uasset b/Content/VRE/Grippables/Misc/Examples/DialIndicator/Turquoise.uasset new file mode 100644 index 0000000..f1a2768 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DialIndicator/Turquoise.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a6cd83380bf55b9abde582cd88ef63374cdcde8a2f936bc9d4fc04ca3a7d747 +size 39285 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/DeadBolt.uasset b/Content/VRE/Grippables/Misc/Examples/Door/DeadBolt.uasset new file mode 100644 index 0000000..f60b36a --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/DeadBolt.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6cf5a73b1099be46fc9a148dfb2763094df9f0b64763d56c0aee985ff0ae85b +size 30756 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/DeadboltKnob.uasset b/Content/VRE/Grippables/Misc/Examples/Door/DeadboltKnob.uasset new file mode 100644 index 0000000..a2087d5 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/DeadboltKnob.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b661932077b81f5914b0d14503944aee305c467ccbc59df2404b22fb4e57fef5 +size 20444 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/DeadboltKnobBase.uasset b/Content/VRE/Grippables/Misc/Examples/Door/DeadboltKnobBase.uasset new file mode 100644 index 0000000..484650b --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/DeadboltKnobBase.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5ed7dac671a4a05a230b858c5054c1941201a2d5192a8a888c5bda08192942e +size 37396 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/DoorActor.uasset b/Content/VRE/Grippables/Misc/Examples/Door/DoorActor.uasset new file mode 100644 index 0000000..5e16d72 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/DoorActor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce17327cd3d5f8a2a24afd737e596de392359fecc7e613930d57d293e3a8baa9 +size 482616 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/DoorHandle.uasset b/Content/VRE/Grippables/Misc/Examples/Door/DoorHandle.uasset new file mode 100644 index 0000000..d084f8a --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/DoorHandle.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef34824e65f8fcc98cbc0b8a38062f592e2601e52b4d3d004d14d4a5bc16de1b +size 27188 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/DoorHandleBase.uasset b/Content/VRE/Grippables/Misc/Examples/Door/DoorHandleBase.uasset new file mode 100644 index 0000000..05afe5a --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/DoorHandleBase.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:890004a21ec396b826fb1278c0666608f78736c089e47b7885af438d21e10932 +size 42483 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/DoorHandleLever.uasset b/Content/VRE/Grippables/Misc/Examples/Door/DoorHandleLever.uasset new file mode 100644 index 0000000..c23ef09 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/DoorHandleLever.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb8d56160493cd0a40c091068c5b492bfaed26c102e435449754cf7d95fa225e +size 65367 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/DoorKey.uasset b/Content/VRE/Grippables/Misc/Examples/Door/DoorKey.uasset new file mode 100644 index 0000000..696d794 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/DoorKey.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:00e2b7ebe5483e565299514705089198b9d04fd4a76bed5a9ede8792d62fb0e6 +size 408094 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/Key.uasset b/Content/VRE/Grippables/Misc/Examples/Door/Key.uasset new file mode 100644 index 0000000..11e5242 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/Key.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd857ca55f15461848584b49987fdfb1131681c62be2b5a3440b0fef2f466764 +size 43253 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/KeyBase.uasset b/Content/VRE/Grippables/Misc/Examples/Door/KeyBase.uasset new file mode 100644 index 0000000..201b05d --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/KeyBase.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a24c3814a4bb15da918c05eba3728a94898ba82527bb36dd1f2db583ab8dcbe +size 43831 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/Keycore.uasset b/Content/VRE/Grippables/Misc/Examples/Door/Keycore.uasset new file mode 100644 index 0000000..c7312f8 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/Keycore.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c14d750494e0099b614637dfecfe27116eea9e8e5cfe7ec7c95231d3964dbdc2 +size 23166 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/defaultMat.uasset b/Content/VRE/Grippables/Misc/Examples/Door/defaultMat.uasset new file mode 100644 index 0000000..d40dcb8 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/defaultMat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1aacfe5a0b4bc6f62d18c26e216bda6ee8e4c683256878385c7c2cfef7f9f7c5 +size 110540 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/door1_aldoor.uasset b/Content/VRE/Grippables/Misc/Examples/Door/door1_aldoor.uasset new file mode 100644 index 0000000..f6c8903 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/door1_aldoor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5260874df1dde108b2931d679350eb6e821cb645d7747649cb07c3d2ee77a3c +size 21908 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/door1_door.uasset b/Content/VRE/Grippables/Misc/Examples/Door/door1_door.uasset new file mode 100644 index 0000000..6d43d3d --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/door1_door.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4263e50843e1888f724b10d1f4420ee4dc3d1fb8b7ac94ef12b404250ec53c09 +size 24094 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/glas.uasset b/Content/VRE/Grippables/Misc/Examples/Door/glas.uasset new file mode 100644 index 0000000..8719abd --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/glas.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:194000a2f547acfa85ed79129f880db150a504b26246552e62f92a511e5056d6 +size 28970 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/wood.uasset b/Content/VRE/Grippables/Misc/Examples/Door/wood.uasset new file mode 100644 index 0000000..863d589 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/wood.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1e195f085561bbc017273590f789c4b5e9adca817f7836aba89152d2efc903c +size 31512 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/wood2.uasset b/Content/VRE/Grippables/Misc/Examples/Door/wood2.uasset new file mode 100644 index 0000000..9eab57d --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/wood2.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe79c61941651446755e024ce6a47ea35d3d0f58598a5e3f4e02c35f13035a76 +size 31516 diff --git a/Content/VRE/Grippables/Misc/Examples/Door/woodteak.uasset b/Content/VRE/Grippables/Misc/Examples/Door/woodteak.uasset new file mode 100644 index 0000000..7ee30cb --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Door/woodteak.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91b701891d8e479854277c3a4dbe0f4c521ba2df1dc32ad1a7bd01cbac1624ab +size 2433033 diff --git a/Content/VRE/Grippables/Misc/Examples/DrawerBase/DrawerBaseActor.uasset b/Content/VRE/Grippables/Misc/Examples/DrawerBase/DrawerBaseActor.uasset new file mode 100644 index 0000000..0222d18 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DrawerBase/DrawerBaseActor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f403550bb0a1097dde6a21a2f659d1c5f8d1c688c7fd261000bc0f5e731bb13 +size 86306 diff --git a/Content/VRE/Grippables/Misc/Examples/DrawerBase/temp_desk.uasset b/Content/VRE/Grippables/Misc/Examples/DrawerBase/temp_desk.uasset new file mode 100644 index 0000000..c7bf0cb --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DrawerBase/temp_desk.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87acc845c797c51c77d36f249df27f50ca137ca4e2fbdad94334292ea880fa55 +size 34344 diff --git a/Content/VRE/Grippables/Misc/Examples/DrawerBase/temp_desk_drawer1.uasset b/Content/VRE/Grippables/Misc/Examples/DrawerBase/temp_desk_drawer1.uasset new file mode 100644 index 0000000..14718e1 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DrawerBase/temp_desk_drawer1.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:052e9fa2d2d7844857b79951dfff6dc228fe2c96194c944939bf660772221d50 +size 22293 diff --git a/Content/VRE/Grippables/Misc/Examples/DrawerBase/temp_desk_drawer2.uasset b/Content/VRE/Grippables/Misc/Examples/DrawerBase/temp_desk_drawer2.uasset new file mode 100644 index 0000000..5e7ce1c --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DrawerBase/temp_desk_drawer2.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:346c24d947e981e760abe6c888a1ec69eec72382d862ea2ae698300c7a34f883 +size 22608 diff --git a/Content/VRE/Grippables/Misc/Examples/DrawingBoard/BaseWhiteBoardTool.uasset b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/BaseWhiteBoardTool.uasset new file mode 100644 index 0000000..b206c1e --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/BaseWhiteBoardTool.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e1b5385b120dae1c65a3b9b1260cd87fcd68d2e45949bb5b3648aa3e145ce611 +size 270932 diff --git a/Content/VRE/Grippables/Misc/Examples/DrawingBoard/DrawingBoard.uasset b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/DrawingBoard.uasset new file mode 100644 index 0000000..5e31cad --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/DrawingBoard.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e5f476146385a2fcb8a1ea30be8c211a18246a38bf3bb7bad7a6f35b7c082e7 +size 125384 diff --git a/Content/VRE/Grippables/Misc/Examples/DrawingBoard/Eraser.uasset b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/Eraser.uasset new file mode 100644 index 0000000..ee1d1c2 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/Eraser.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ebb1e920500f60c3603fc5c4ea4ee6b9bb8583471c3d5f3d2d71f4fdaaef147 +size 153827 diff --git a/Content/VRE/Grippables/Misc/Examples/DrawingBoard/MERGED_Eraser.uasset b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/MERGED_Eraser.uasset new file mode 100644 index 0000000..aac71cc --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/MERGED_Eraser.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97e35d483072b22159307911c038852fad0b03662f9692614157623bbc8a0f18 +size 15301 diff --git a/Content/VRE/Grippables/Misc/Examples/DrawingBoard/MERGED_Marker.uasset b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/MERGED_Marker.uasset new file mode 100644 index 0000000..ba476df --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/MERGED_Marker.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:088d9e4a46d0410b8ec1de2f0ec286a018f472537429ba39aa316698eef3f951 +size 31118 diff --git a/Content/VRE/Grippables/Misc/Examples/DrawingBoard/MERGED_SprayCan.uasset b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/MERGED_SprayCan.uasset new file mode 100644 index 0000000..8cee56d --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/MERGED_SprayCan.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c83a20b95e4f03a274b29badf291d9df18823fb9e23f69332654b10efc80ad2 +size 58204 diff --git a/Content/VRE/Grippables/Misc/Examples/DrawingBoard/Marker.uasset b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/Marker.uasset new file mode 100644 index 0000000..ea7d2cf --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/Marker.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e3a7dec1935eb88950bd50ce7893644aca8287f0d0db45dd28de4bf707d8ef0 +size 151638 diff --git a/Content/VRE/Grippables/Misc/Examples/DrawingBoard/MarkerBoardMat.uasset b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/MarkerBoardMat.uasset new file mode 100644 index 0000000..fee99be --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/MarkerBoardMat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a6d31a42a324dd4e72d005062383eb028b68aaacb27139df5a712d59a028139 +size 9469 diff --git a/Content/VRE/Grippables/Misc/Examples/DrawingBoard/MarkerMat.uasset b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/MarkerMat.uasset new file mode 100644 index 0000000..d63f422 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/MarkerMat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3c5a7a4236ea97fcc5be4c3c595dad5bfd2588857020a6bcbe830c3fbf3c215 +size 94918 diff --git a/Content/VRE/Grippables/Misc/Examples/DrawingBoard/Mat_Eraser.uasset b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/Mat_Eraser.uasset new file mode 100644 index 0000000..3ad5b0a --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/Mat_Eraser.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f380476ebb6ea8b12ea9b8d2b9cc4e696212e39107b2b74e7107714228c4116 +size 85981 diff --git a/Content/VRE/Grippables/Misc/Examples/DrawingBoard/SprayCan.uasset b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/SprayCan.uasset new file mode 100644 index 0000000..9ee4d52 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/DrawingBoard/SprayCan.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df42bf574eaa21c3b4788bb5453bf55b69c5fd7f7eba1a102aeeb5d5ef866efe +size 152211 diff --git a/Content/VRE/Grippables/Misc/Examples/Gestures/GestureViewer.uasset b/Content/VRE/Grippables/Misc/Examples/Gestures/GestureViewer.uasset new file mode 100644 index 0000000..32a6e37 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Gestures/GestureViewer.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:952c0bde0af4effcc991bbc910dae104918d5cabd1e2c82af091e871d2dec210 +size 171940 diff --git a/Content/VRE/Grippables/Misc/Examples/Gestures/GestureWand.uasset b/Content/VRE/Grippables/Misc/Examples/Gestures/GestureWand.uasset new file mode 100644 index 0000000..ab2bfab --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Gestures/GestureWand.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e0c4df3a7cd7ec384c243737025f7ba9b37088bc88f8b4a31c2b07b1d04ee84c +size 194664 diff --git a/Content/VRE/Grippables/Misc/Examples/Gestures/VRGestures.uasset b/Content/VRE/Grippables/Misc/Examples/Gestures/VRGestures.uasset new file mode 100644 index 0000000..ee529cc --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Gestures/VRGestures.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58529d9b47718196ede8460d3e80a9d319af36b502de104f0e970b52c6624c49 +size 10528 diff --git a/Content/VRE/Grippables/Misc/Examples/GrippableChar/GrippableChar.uasset b/Content/VRE/Grippables/Misc/Examples/GrippableChar/GrippableChar.uasset new file mode 100644 index 0000000..c7f5243 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/GrippableChar/GrippableChar.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6096c920fbcec3f2a7a87f0eb757f6db906eebe236a32b92b0a8c30be2407d0a +size 50949 diff --git a/Content/VRE/Grippables/Misc/Examples/GrippableChar/GrippableManniquin.uasset b/Content/VRE/Grippables/Misc/Examples/GrippableChar/GrippableManniquin.uasset new file mode 100644 index 0000000..fe5f4ba --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/GrippableChar/GrippableManniquin.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc29ab5ef52d0eb01c7863e443bc4c1ba5e1fee229f7031539219f4bfc5fa01d +size 94552 diff --git a/Content/VRE/Grippables/Misc/Examples/HandTruck/HandTruck.uasset b/Content/VRE/Grippables/Misc/Examples/HandTruck/HandTruck.uasset new file mode 100644 index 0000000..a87804c --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/HandTruck/HandTruck.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e50b5b22fb83eea948452c2e776b1e057316c067af2736da2ad18f9dde59caf +size 48570 diff --git a/Content/VRE/Grippables/Misc/Examples/HandTruck/MI_HandTruck.uasset b/Content/VRE/Grippables/Misc/Examples/HandTruck/MI_HandTruck.uasset new file mode 100644 index 0000000..9e9d95f --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/HandTruck/MI_HandTruck.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44a8465deb9a30bfe437f77414213a197080177c58e9a1801583c016c62cf4a7 +size 13945 diff --git a/Content/VRE/Grippables/Misc/Examples/HandTruck/SM_HandTruck_Body.uasset b/Content/VRE/Grippables/Misc/Examples/HandTruck/SM_HandTruck_Body.uasset new file mode 100644 index 0000000..7633858 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/HandTruck/SM_HandTruck_Body.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55dceb9c905187abbb630ae206ca2398fce1d154fe7f1047b2d88bbc4c67733a +size 131100 diff --git a/Content/VRE/Grippables/Misc/Examples/HandTruck/SM_HandTruck_Wheel.uasset b/Content/VRE/Grippables/Misc/Examples/HandTruck/SM_HandTruck_Wheel.uasset new file mode 100644 index 0000000..fafb830 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/HandTruck/SM_HandTruck_Wheel.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05b34d87202a0e97df3a1dd0998191d1612aa1d3e3e0058ed25b2787f578fbf4 +size 71160 diff --git a/Content/VRE/Grippables/Misc/Examples/HandTruck/T_HandTruck_AliOweidah_BaseColor.uasset b/Content/VRE/Grippables/Misc/Examples/HandTruck/T_HandTruck_AliOweidah_BaseColor.uasset new file mode 100644 index 0000000..93a4f0f --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/HandTruck/T_HandTruck_AliOweidah_BaseColor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e26c48e0e746ce733c7772a3101f1092cd18b26995cf6cd31f990d150c74e125 +size 4370558 diff --git a/Content/VRE/Grippables/Misc/Examples/HandTruck/T_HandTruck_AliOweidah_MetallicRoughnessAO.uasset b/Content/VRE/Grippables/Misc/Examples/HandTruck/T_HandTruck_AliOweidah_MetallicRoughnessAO.uasset new file mode 100644 index 0000000..90b5d28 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/HandTruck/T_HandTruck_AliOweidah_MetallicRoughnessAO.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83f7dacb84501221919aefa415fd647560835c33cbd7dd72bcf80d3380d2684c +size 4949633 diff --git a/Content/VRE/Grippables/Misc/Examples/HandTruck/T_HandTruck_AliOweidah_Normal.uasset b/Content/VRE/Grippables/Misc/Examples/HandTruck/T_HandTruck_AliOweidah_Normal.uasset new file mode 100644 index 0000000..760ce57 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/HandTruck/T_HandTruck_AliOweidah_Normal.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47b08848526ab3fff7b97dcdff9d64540f46de6f49b8ad3fb7764ffa80c2f507 +size 7035954 diff --git a/Content/VRE/Grippables/Misc/Examples/InteractibleTut/TutorialSlider.uasset b/Content/VRE/Grippables/Misc/Examples/InteractibleTut/TutorialSlider.uasset new file mode 100644 index 0000000..cc5be48 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/InteractibleTut/TutorialSlider.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ef355113eccb855e9ffac1cb2506f3b359caf156893d5bf2f8b535b0d62ce94 +size 252172 diff --git a/Content/VRE/Grippables/Misc/Examples/Lever/Gray.uasset b/Content/VRE/Grippables/Misc/Examples/Lever/Gray.uasset new file mode 100644 index 0000000..ce69622 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Lever/Gray.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f500399c20585f9041847650342b73a32df68dd9fc4eeea74aa6f80b768056d7 +size 32808 diff --git a/Content/VRE/Grippables/Misc/Examples/Lever/Green.uasset b/Content/VRE/Grippables/Misc/Examples/Lever/Green.uasset new file mode 100644 index 0000000..c825617 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Lever/Green.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:582c09c7a5b6b10b2db4d0ab62cf1a123eae396406cc68e79b26bc4843719511 +size 36243 diff --git a/Content/VRE/Grippables/Misc/Examples/Lever/LeverActor.uasset b/Content/VRE/Grippables/Misc/Examples/Lever/LeverActor.uasset new file mode 100644 index 0000000..9f6a7b4 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Lever/LeverActor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9dfa6ff0b0de5084fe99620f2fbf997891d914b5254b37b88be27a9eb30bb6b9 +size 222796 diff --git a/Content/VRE/Grippables/Misc/Examples/Lever/LeverBase.uasset b/Content/VRE/Grippables/Misc/Examples/Lever/LeverBase.uasset new file mode 100644 index 0000000..379e507 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Lever/LeverBase.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42a3bb07b48e9a7d3f936b7e686429341c96e06650c95c3b54d4aa1faa8bddac +size 17163 diff --git a/Content/VRE/Grippables/Misc/Examples/Lever/LeverComponent.uasset b/Content/VRE/Grippables/Misc/Examples/Lever/LeverComponent.uasset new file mode 100644 index 0000000..3a6209e --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Lever/LeverComponent.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:438604f263cfe5e15e41eeecb95dee988b09f1678eedbcb7144d9e6717e9e832 +size 245397 diff --git a/Content/VRE/Grippables/Misc/Examples/Lever/LeverTop.uasset b/Content/VRE/Grippables/Misc/Examples/Lever/LeverTop.uasset new file mode 100644 index 0000000..e05db9c --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Lever/LeverTop.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e8b02589009be42fac9ed88b160195d6dbbc22ad20b87d1d5bf55998c58a234 +size 77004 diff --git a/Content/VRE/Grippables/Misc/Examples/Lever/NativeLeverActor.uasset b/Content/VRE/Grippables/Misc/Examples/Lever/NativeLeverActor.uasset new file mode 100644 index 0000000..5399bf5 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Lever/NativeLeverActor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8cd4952a3bf075a62aab21dea62fcbf70619441e0de5109c74699014c350b4c +size 89640 diff --git a/Content/VRE/Grippables/Misc/Examples/Lever/NativeLeverActor_ThrowSwitch.uasset b/Content/VRE/Grippables/Misc/Examples/Lever/NativeLeverActor_ThrowSwitch.uasset new file mode 100644 index 0000000..f8174dd --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Lever/NativeLeverActor_ThrowSwitch.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c376e2d9aaceeeb89033c4b6587285f3a10aa3fee32dd7a9e691e550294bc800 +size 133801 diff --git a/Content/VRE/Grippables/Misc/Examples/Microphone/aluminium.uasset b/Content/VRE/Grippables/Misc/Examples/Microphone/aluminium.uasset new file mode 100644 index 0000000..e827cc3 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Microphone/aluminium.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e5f45a7f810a4a94b8455fe4652d245e31d71d30378ca4505877721d7d7ba3c +size 29654 diff --git a/Content/VRE/Grippables/Misc/Examples/Microphone/black_mate_plastic.uasset b/Content/VRE/Grippables/Misc/Examples/Microphone/black_mate_plastic.uasset new file mode 100644 index 0000000..4cbc444 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Microphone/black_mate_plastic.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54369a67837f6d040b25cfa951e999d05a17124736b65c2b6897653606230d4a +size 10786 diff --git a/Content/VRE/Grippables/Misc/Examples/Microphone/black_poli_plastic.uasset b/Content/VRE/Grippables/Misc/Examples/Microphone/black_poli_plastic.uasset new file mode 100644 index 0000000..49d9a73 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Microphone/black_poli_plastic.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:761abe2dd65aa06e948ce2a388d1914d5f1bdd096ed334ff28182e51eb697123 +size 10675 diff --git a/Content/VRE/Grippables/Misc/Examples/Microphone/fabric.uasset b/Content/VRE/Grippables/Misc/Examples/Microphone/fabric.uasset new file mode 100644 index 0000000..f675c5f --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Microphone/fabric.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:33c0118c19b766a04ce2221316160a1ad5b55dc993e125a084ee3a37cee77d0d +size 41501 diff --git a/Content/VRE/Grippables/Misc/Examples/Microphone/net.uasset b/Content/VRE/Grippables/Misc/Examples/Microphone/net.uasset new file mode 100644 index 0000000..9ba2a96 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Microphone/net.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7dc56ef826ad8f792fcf1a164dc40361aa5f8a1c1327f2cdab4e6e2aac91e1b1 +size 37417 diff --git a/Content/VRE/Grippables/Misc/Examples/Microphone/wireless_vocal_microphone.uasset b/Content/VRE/Grippables/Misc/Examples/Microphone/wireless_vocal_microphone.uasset new file mode 100644 index 0000000..f1bcd49 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Microphone/wireless_vocal_microphone.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa8c1bb3639baa0add6a8b0dc37002da24d8ed7e4503fb9be0c1a9358b07c225 +size 3734774 diff --git a/Content/VRE/Grippables/Misc/Examples/PPOutline/PP_OutlineCustomDepthOcclusion.uasset b/Content/VRE/Grippables/Misc/Examples/PPOutline/PP_OutlineCustomDepthOcclusion.uasset new file mode 100644 index 0000000..e497447 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/PPOutline/PP_OutlineCustomDepthOcclusion.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6f76aceabfbf35f0acd3c0d1c7193472fa8b75e3c9da7827d4ee4208ec6a3ca +size 70071 diff --git a/Content/VRE/Grippables/Misc/Examples/PPOutline/PP_OutlineCustomDepthOcclusion_Inst.uasset b/Content/VRE/Grippables/Misc/Examples/PPOutline/PP_OutlineCustomDepthOcclusion_Inst.uasset new file mode 100644 index 0000000..cbcd874 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/PPOutline/PP_OutlineCustomDepthOcclusion_Inst.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e6e1239e4c895b808e8dd2bb2be41d0814d82a3e5ad832e199e65b3fb865fe10 +size 24471 diff --git a/Content/VRE/Grippables/Misc/Examples/PickupCube.uasset b/Content/VRE/Grippables/Misc/Examples/PickupCube.uasset new file mode 100644 index 0000000..8a90b37 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/PickupCube.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c2def2681e56880ae4a57c5059c4dbe614d2ccd61f636567526124246bd090ea +size 31105 diff --git a/Content/VRE/Grippables/Misc/Examples/Potion/Potion.uasset b/Content/VRE/Grippables/Misc/Examples/Potion/Potion.uasset new file mode 100644 index 0000000..eb74bee --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Potion/Potion.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c83598eb5ca29960b40b59fb57e4ff9c5f93d3c375c6e81e2c5a6b839f30e1b +size 73721 diff --git a/Content/VRE/Grippables/Misc/Examples/Potion/PotionActor.uasset b/Content/VRE/Grippables/Misc/Examples/Potion/PotionActor.uasset new file mode 100644 index 0000000..348da12 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Potion/PotionActor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e8ea4d400a5353c6deaaef479e751bb8ad4637529c0d624334dae075082bb5ee +size 287635 diff --git a/Content/VRE/Grippables/Misc/Examples/Potion/PotionMat.uasset b/Content/VRE/Grippables/Misc/Examples/Potion/PotionMat.uasset new file mode 100644 index 0000000..9063951 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Potion/PotionMat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f152c24befbe476276a7ad62a7d0d36ca359e93337ad4212b6c816e8df53a801 +size 10279 diff --git a/Content/VRE/Grippables/Misc/Examples/Potion/Stopper.uasset b/Content/VRE/Grippables/Misc/Examples/Potion/Stopper.uasset new file mode 100644 index 0000000..a7d9849 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/Potion/Stopper.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0672aa3b1222e3cc5bfe2ccc381f2cfa5fc69c67caa6b789727ee8a9a6b9a40 +size 33960 diff --git a/Content/VRE/Grippables/Misc/Examples/SelfGraspActor/SelfGraspExample.uasset b/Content/VRE/Grippables/Misc/Examples/SelfGraspActor/SelfGraspExample.uasset new file mode 100644 index 0000000..ddb6a34 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/SelfGraspActor/SelfGraspExample.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73668b1ac902a37543284fa7b3cbf3adc2b0ad444eff101370a45867e6403d51 +size 138631 diff --git a/Content/VRE/Grippables/Misc/Examples/SnapPoint/SnapActor.uasset b/Content/VRE/Grippables/Misc/Examples/SnapPoint/SnapActor.uasset new file mode 100644 index 0000000..564dfe2 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/SnapPoint/SnapActor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7369ef195fb24315f8040a71d8183a122d7554ff4583f7a9641e35f76908d52e +size 174114 diff --git a/Content/VRE/Grippables/Misc/Examples/SnapPoint/SnapPointMat.uasset b/Content/VRE/Grippables/Misc/Examples/SnapPoint/SnapPointMat.uasset new file mode 100644 index 0000000..509c299 --- /dev/null +++ b/Content/VRE/Grippables/Misc/Examples/SnapPoint/SnapPointMat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb1df872f07f671841aa1679f62038b5c62a380627cd8818eb15edb552474ccd +size 74020 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Functions/MF_MicroDetail_01a.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Functions/MF_MicroDetail_01a.uasset new file mode 100644 index 0000000..3e3dfcd --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Functions/MF_MicroDetail_01a.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46de3f6d9eda13a259e2ce89e43509e9e2bbaa2e348b18351084caa581b9ae10 +size 130061 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Functions/MF_VertexBlend_01a.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Functions/MF_VertexBlend_01a.uasset new file mode 100644 index 0000000..56fd432 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Functions/MF_VertexBlend_01a.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2eb1a3a7be5ef4967b926fcd0438b067d007d36adca9c1bde966ca02832812e2 +size 53424 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Functions/MI_VertexBlend_02a.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Functions/MI_VertexBlend_02a.uasset new file mode 100644 index 0000000..865299b --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Functions/MI_VertexBlend_02a.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1dfa4ba4f6e7f4468bb26eb5bc081529e6901a923d55b5054736bc7bcec928b5 +size 101357 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Instances/MI_Cinderstack_01a.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Instances/MI_Cinderstack_01a.uasset new file mode 100644 index 0000000..60f79e0 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Instances/MI_Cinderstack_01a.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f2c6c9ce1f1e5201bd89b74ca29bc67d735902d6f33ed901af562b187ddb7a2 +size 130236 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Instances/MI_OilBarrel_01a.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Instances/MI_OilBarrel_01a.uasset new file mode 100644 index 0000000..fc56967 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Instances/MI_OilBarrel_01a.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:237757931ae10a9178c92453c455aad9a514beabb2a36c650e55bec6ad004123 +size 113923 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Instances/MI_WoodenPalette_01a.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Instances/MI_WoodenPalette_01a.uasset new file mode 100644 index 0000000..4149d6b --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Instances/MI_WoodenPalette_01a.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b18ff4d445db1dd7afe92ac44c4c9cb6054b4a99d37ca31803cbe6a1d6637ef +size 117766 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Masters/MM_Background_01a.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Masters/MM_Background_01a.uasset new file mode 100644 index 0000000..0e319ea --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Masters/MM_Background_01a.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aab16f3516b9f21762acd32f5b741a4332026fe5b19e0586202bce373c85f291 +size 160378 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Masters/MM_Decal_01.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Masters/MM_Decal_01.uasset new file mode 100644 index 0000000..9ca51b8 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Masters/MM_Decal_01.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56b5d41d00b73ca83606fc1a20821b572c464085807de61199ef537800e28ff3 +size 92078 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Masters/MM_MasterMaterial_01.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Masters/MM_MasterMaterial_01.uasset new file mode 100644 index 0000000..121d8bd --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Masters/MM_MasterMaterial_01.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a41595af710b517ff91f9fe236ab3ac6925b1016df38fa902a6d57944aa8d76f +size 152973 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Masters/MM_PP_Sharpen.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Masters/MM_PP_Sharpen.uasset new file mode 100644 index 0000000..81aa4bb --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Materials/Masters/MM_PP_Sharpen.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3bae9c42636782d7be44a833b5696bd0d1c09c47cf23bd89c536cdcc50d457c4 +size 97284 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Meshes/SM_Barrel_01.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Meshes/SM_Barrel_01.uasset new file mode 100644 index 0000000..8529cfc --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Meshes/SM_Barrel_01.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee089330d04e55771019df07689a86a66c1bc1fed294ce1480d1becd5037463f +size 53719 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Meshes/SM_CinderStack_Single_01a.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Meshes/SM_CinderStack_Single_01a.uasset new file mode 100644 index 0000000..18404af --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Meshes/SM_CinderStack_Single_01a.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7350a8a119cf53cf3de4e15b06bebfa8f6c93bdbb335949a4a10f891e4cf2c2c +size 22573 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Meshes/SM_woodenpalette_01.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Meshes/SM_woodenpalette_01.uasset new file mode 100644 index 0000000..32eaad9 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Meshes/SM_woodenpalette_01.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f87ea3210fe0d335d0d36f93b53b06d4398880aedd846e9db8817c54d29a1f1 +size 67207 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_DebrisTile_ALB.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_DebrisTile_ALB.uasset new file mode 100644 index 0000000..a9a9934 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_DebrisTile_ALB.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:168d5ef3074c9c661e459c699daddbd5c583fe93a0a62d27cd074da5ae312e80 +size 2543556 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_DebrisTile_NRM.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_DebrisTile_NRM.uasset new file mode 100644 index 0000000..29a77e5 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_DebrisTile_NRM.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c428772f2f3ca07677e5a50c64c2d3db5342d312b93135aa72d40dd3ac2f6e4a +size 3155023 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_DebrisTile_RMA.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_DebrisTile_RMA.uasset new file mode 100644 index 0000000..1d52381 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_DebrisTile_RMA.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:009179a5932b69793956fd253e44932b5b1b99821dce2a6fd3c4c74f42c2e2a2 +size 2240008 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_Dirt_01_ALB.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_Dirt_01_ALB.uasset new file mode 100644 index 0000000..c8b4b55 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_Dirt_01_ALB.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:357531740d3fdd72f7e6be6396b9ed30333a2a5198a4d7554bd8e6211b9696f7 +size 2866443 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_Micro_MASK.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_Micro_MASK.uasset new file mode 100644 index 0000000..e74e684 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_Micro_MASK.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2b02bd7ba793d75f52a6e05e13c3e0ff0f391b3cbc3be418c34d85cbb9116cf +size 564567 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_Noise_NRM.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_Noise_NRM.uasset new file mode 100644 index 0000000..83d1950 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_Noise_NRM.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:864e9a4b2fede4c864c1dbdfae0af968544381e52dcdc7fa083509288737ac27 +size 660264 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_01_ALB.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_01_ALB.uasset new file mode 100644 index 0000000..f345efa --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_01_ALB.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8714f0cbb121f613b39461bafb3d09d66307ba072e70f40aaef18f2510148e5 +size 8390576 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_01_NRM.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_01_NRM.uasset new file mode 100644 index 0000000..7e26d17 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_01_NRM.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47dbb52bd3eec831e7d501e841f908770964d44784756130aa817efa741c9aa1 +size 10932150 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_01_RHA.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_01_RHA.uasset new file mode 100644 index 0000000..7829a74 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_01_RHA.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dcfac76b178dc5355495ad83b1f19909174e1d869cd189eebf3aa19785232a4d +size 7534879 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_02_ALB.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_02_ALB.uasset new file mode 100644 index 0000000..d7573fd --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_02_ALB.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:816d326b9e476fdb06364a6d10243e9b2a2caa0560feb4e691c6e77faaa47b66 +size 7202171 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_02_NRM.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_02_NRM.uasset new file mode 100644 index 0000000..ef620d6 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_02_NRM.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1fa9075b4b85acec31277ac058b8503e453c862744d0033aba76a80832066dd +size 11008277 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_02_RHA.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_02_RHA.uasset new file mode 100644 index 0000000..b8a0d67 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Tileable/TX_RockyMud_02_RHA.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48e7a11f5e330dc29c7f1dbd9bc38678ca1da39d1a7dd64ba2c36242a91c540b +size 7413211 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_CinderStack_ALB.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_CinderStack_ALB.uasset new file mode 100644 index 0000000..5735871 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_CinderStack_ALB.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2cbb7c7de684ec63939ab6b94aaed76fc7b15dd66e37f4c65202f43928b594a +size 5091292 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_CinderStack_NRM.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_CinderStack_NRM.uasset new file mode 100644 index 0000000..a4c0bdf --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_CinderStack_NRM.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87e5010e03419020639deafb5370c430a545f36e76fcd6d50f1f3ecb6d06af22 +size 6858453 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_CinderStack_RMA.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_CinderStack_RMA.uasset new file mode 100644 index 0000000..b89fba7 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_CinderStack_RMA.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5dd9080c43668d00a4f4331dd2182ea677f081bd344618a02b24046fbec17dc5 +size 3624022 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_OilBarrel_01a_ALB.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_OilBarrel_01a_ALB.uasset new file mode 100644 index 0000000..fc98634 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_OilBarrel_01a_ALB.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13b4702228bd042b016f87904dcb6014a6c0c9dea23a2a4ad33b996c8ebca385 +size 3661816 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_OilBarrel_01a_NRM.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_OilBarrel_01a_NRM.uasset new file mode 100644 index 0000000..49b84ab --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_OilBarrel_01a_NRM.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a9a2ea530056a112fda331213d76faf4dbcc5dae2038164abd627b7200b164e7 +size 6255274 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_OilBarrel_01a_RMA.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_OilBarrel_01a_RMA.uasset new file mode 100644 index 0000000..7d8c000 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_OilBarrel_01a_RMA.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d61bd788260e36eb91619246519745837fe90bd3f501916d57b3a6a71cb87b8 +size 4853191 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_WoodenPalette_01_ALB.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_WoodenPalette_01_ALB.uasset new file mode 100644 index 0000000..31e27ae --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_WoodenPalette_01_ALB.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e8252f39e2986b4c9cd3cf9ef868867bfd192680799ea67fa40ffa0b116d4a21 +size 8132717 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_WoodenPalette_01_NRM.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_WoodenPalette_01_NRM.uasset new file mode 100644 index 0000000..461c99b --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_WoodenPalette_01_NRM.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01d00655b7100c23df0a97c9d225cda5362118d51b8feedba4a2fe60685e4f41 +size 7648965 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_WoodenPalette_01_RMA.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_WoodenPalette_01_RMA.uasset new file mode 100644 index 0000000..014c3fd --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Unique/TX_WoodenPalette_01_RMA.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd149ef586ec4d096fed5818ebcf22f573ab3da822555a4f1e708558b4d94fc2 +size 5332763 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Backdrop_01_ALB.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Backdrop_01_ALB.uasset new file mode 100644 index 0000000..d467fb5 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Backdrop_01_ALB.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e724c834c9f2bb6e66836eab618145664979312615acf36eab6c9ea1609c2b8 +size 5323994 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Backdrop_01_NRM.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Backdrop_01_NRM.uasset new file mode 100644 index 0000000..62e011a --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Backdrop_01_NRM.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ecfd969052860ea9ffd796813294496cbf5ae851d58a543797d8748a7f8ffbf0 +size 5096528 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Cubemap_Stairs.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Cubemap_Stairs.uasset new file mode 100644 index 0000000..9ddb474 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Cubemap_Stairs.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:306378ec3fa39fa39e98c4df608aa75b7e451b3bc461ebecfcb5f2051bb61a55 +size 1344026 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Fill_01_ALB.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Fill_01_ALB.uasset new file mode 100644 index 0000000..09509a1 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Fill_01_ALB.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a659af51fb2279a433998785e28c10f59def76b27e954fd40ca25d80dd43116c +size 4630 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Fill_01_NRM.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Fill_01_NRM.uasset new file mode 100644 index 0000000..2a45970 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Fill_01_NRM.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:24787f2f3893798b33f605d491ab1911c1d49629e47343def2a6091cee78450a +size 4971 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Fill_01_RMA.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Fill_01_RMA.uasset new file mode 100644 index 0000000..516056a --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_Fill_01_RMA.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78f0959e9ea208f1ed78d4b04f9ce8ce6485889c632ff53f606571a57ee9efcb +size 4791 diff --git a/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_LUT_01.uasset b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_LUT_01.uasset new file mode 100644 index 0000000..f34d476 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/Construction_VOL1/Textures/Utility/TX_LUT_01.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dac0ed2527081ae69997a0494d54893218beea1282af9b10319881781c364006 +size 9379 diff --git a/Content/VRE/Grippables/PhysicsProps/PhysicsProp.uasset b/Content/VRE/Grippables/PhysicsProps/PhysicsProp.uasset new file mode 100644 index 0000000..1bef523 --- /dev/null +++ b/Content/VRE/Grippables/PhysicsProps/PhysicsProp.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ffc9234413216c9cf322fca269e3d55d0ec2fe7807378b9a307673a5d6cec19 +size 28796 diff --git a/Content/VRE/Grippables/Weapons/Guns/BaseMaterial.uasset b/Content/VRE/Grippables/Weapons/Guns/BaseMaterial.uasset new file mode 100644 index 0000000..7944bb2 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/BaseMaterial.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79fa7371413bf0625027b539f441ce9d07dd32b70bd1dcf92c159e3ed558edac +size 37288 diff --git a/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/M_FPGun.uasset b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/M_FPGun.uasset new file mode 100644 index 0000000..69030a3 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/M_FPGun.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:88069a4e4ddaed5a467d821cae74ab0cf59eed443b75fb98172fcbe6cf9b3b32 +size 42891 diff --git a/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/ML_GlossyBlack_Latex_UE4.uasset b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/ML_GlossyBlack_Latex_UE4.uasset new file mode 100644 index 0000000..dd89f69 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/ML_GlossyBlack_Latex_UE4.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa1a7361d2e8419ce214d353423f6dc2f75b0a2fe94494454cf0f234be295b83 +size 11035 diff --git a/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/ML_Plastic_Shiny_Beige.uasset b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/ML_Plastic_Shiny_Beige.uasset new file mode 100644 index 0000000..55f57a2 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/ML_Plastic_Shiny_Beige.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ecca6588006834428240b3da4420d1d4bb38b065d50c4fa169a5cfb31de7dcbb +size 16411 diff --git a/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/ML_Plastic_Shiny_Beige_LOGO.uasset b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/ML_Plastic_Shiny_Beige_LOGO.uasset new file mode 100644 index 0000000..4ae8002 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/ML_Plastic_Shiny_Beige_LOGO.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02b4ba08e261bc3f8d711c1bb4f1d0581fc8714838500a19db047f9663f31918 +size 9346 diff --git a/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/ML_Screen.uasset b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/ML_Screen.uasset new file mode 100644 index 0000000..fac8e9e --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/ML_Screen.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1408f030db090d64b88848af82bdd4c7143933c643b1869b7c3aeb0474abe42e +size 5637 diff --git a/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/ML_SoftMetal_UE4.uasset b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/ML_SoftMetal_UE4.uasset new file mode 100644 index 0000000..001cc7f --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/ML_SoftMetal_UE4.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9cbacdbbfe28e1a92b5550db757a640f0ed8afa8a7d61b0e1b588ba12e2ae1d3 +size 20834 diff --git a/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/T_ML_Aluminum01.uasset b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/T_ML_Aluminum01.uasset new file mode 100644 index 0000000..2588b4e --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/T_ML_Aluminum01.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e74702634949dc793b5faf3362cc480ab86b35e4cd1933df639399110085bec9 +size 8630797 diff --git a/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/T_ML_Aluminum01_N.uasset b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/T_ML_Aluminum01_N.uasset new file mode 100644 index 0000000..a27a4f8 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/T_ML_Aluminum01_N.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c96051a4f0f700cf03578b2c132cfc01af83bb842e58937abef2ea8f9f5a742 +size 4395348 diff --git a/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/T_ML_FineRubber.uasset b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/T_ML_FineRubber.uasset new file mode 100644 index 0000000..bd184a7 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/T_ML_FineRubber.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0638dbd563e69ca689c8406ad9ef1ec699a511ddf6d160303f5135d4f5ffaf39 +size 6312755 diff --git a/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/T_ML_Rubber_Blue_01_D.uasset b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/T_ML_Rubber_Blue_01_D.uasset new file mode 100644 index 0000000..b0221a7 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/T_ML_Rubber_Blue_01_D.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41d350d266f5b5524e89f6442adb74532902201e8a78b43024bafa833f1a5e72 +size 5404974 diff --git a/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/T_ML_Rubber_Blue_01_N.uasset b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/T_ML_Rubber_Blue_01_N.uasset new file mode 100644 index 0000000..f655151 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Materials/MaterialLayers/T_ML_Rubber_Blue_01_N.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d9df78b7114730c1f6aeba1f3cf33f2cbf6c4af1ab932b8169d8cc6445fb1c4 +size 4850545 diff --git a/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Mesh/SK_FPGun.uasset b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Mesh/SK_FPGun.uasset new file mode 100644 index 0000000..9c7d0ee --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Mesh/SK_FPGun.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3e47ace89b14dfe90e808c925f5f226ddebbfd64fa4c3c83ea29a71c41d45e9 +size 1272029 diff --git a/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Mesh/SK_FPGun_PhysicsAsset.uasset b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Mesh/SK_FPGun_PhysicsAsset.uasset new file mode 100644 index 0000000..71dd339 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Mesh/SK_FPGun_PhysicsAsset.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:822e4aecb276c98ae7ff96a36762c6a48540f883a36ba5ed2364bce0d6d8bddc +size 7543 diff --git a/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Mesh/SK_FPGun_Skeleton.uasset b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Mesh/SK_FPGun_Skeleton.uasset new file mode 100644 index 0000000..e28638a --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Mesh/SK_FPGun_Skeleton.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3341d663057a271a84a00e1a28615d826c51e56f77587611ccd149e5fee1a73c +size 6626 diff --git a/Content/VRE/Grippables/Weapons/Guns/FPWeapon/SK_FPGun.uasset b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/SK_FPGun.uasset new file mode 100644 index 0000000..14f3daa --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/SK_FPGun.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5494698f9b66bb69ea99a4aaae9fa48de02a38606722b0976f5fc317f1197b8a +size 396510 diff --git a/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Textures/T_FPGun_M.uasset b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Textures/T_FPGun_M.uasset new file mode 100644 index 0000000..c6f904a --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Textures/T_FPGun_M.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:197e0dc9e1bb8a5fec6101157aae681370f2169f2f0344cdfe31568a02599581 +size 227728 diff --git a/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Textures/T_FPGun_N.uasset b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Textures/T_FPGun_N.uasset new file mode 100644 index 0000000..9ebb3f6 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FPWeapon/Textures/T_FPGun_N.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0b556925a72756d6bcb23f1e18bc141321515297ccbfd3ac33d6d4e59a55c19 +size 2044097 diff --git a/Content/VRE/Grippables/Weapons/Guns/FirstPersonProjectile.uasset b/Content/VRE/Grippables/Weapons/Guns/FirstPersonProjectile.uasset new file mode 100644 index 0000000..b3dc820 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FirstPersonProjectile.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:750523053f57c80de4ef91f018b8c64ac00a34763df68bcaaab8d88a152333f9 +size 54602 diff --git a/Content/VRE/Grippables/Weapons/Guns/FirstPersonProjectileMaterial.uasset b/Content/VRE/Grippables/Weapons/Guns/FirstPersonProjectileMaterial.uasset new file mode 100644 index 0000000..5e23e32 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FirstPersonProjectileMaterial.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:090191e27cddafbf08ad68b2c5c9490f93610e27901ec457ca7b29a7e80b219a +size 39588 diff --git a/Content/VRE/Grippables/Weapons/Guns/FirstPersonProjectileMesh.uasset b/Content/VRE/Grippables/Weapons/Guns/FirstPersonProjectileMesh.uasset new file mode 100644 index 0000000..e2241c1 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FirstPersonProjectileMesh.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:775f9c72d050928647dae6357e1e66b6bfe05614c070d3aff70a70863a7df31c +size 32065 diff --git a/Content/VRE/Grippables/Weapons/Guns/FirstPersonTemplateWeaponFire02.uasset b/Content/VRE/Grippables/Weapons/Guns/FirstPersonTemplateWeaponFire02.uasset new file mode 100644 index 0000000..bfa3993 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/FirstPersonTemplateWeaponFire02.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c08f6393f81a69f838aa1411fa245a9eb3ab8ee60951231772e9d67454e290d +size 306470 diff --git a/Content/VRE/Grippables/Weapons/Guns/GrappleGun.uasset b/Content/VRE/Grippables/Weapons/Guns/GrappleGun.uasset new file mode 100644 index 0000000..6a02069 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/GrappleGun.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:001e2ee5be3a783ad1c3798a034bcb9f25ce91be78edb5cfad15164ff7c92777 +size 540085 diff --git a/Content/VRE/Grippables/Weapons/Guns/GunBase.uasset b/Content/VRE/Grippables/Weapons/Guns/GunBase.uasset new file mode 100644 index 0000000..65890a5 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/GunBase.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:278f8570c03283b0fa592be406610c8dd2c63c41087dd24d7002f8a9f928e26f +size 898914 diff --git a/Content/VRE/Grippables/Weapons/Guns/M_FPGunGrapple.uasset b/Content/VRE/Grippables/Weapons/Guns/M_FPGunGrapple.uasset new file mode 100644 index 0000000..963e6c0 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Guns/M_FPGunGrapple.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2643ac81668975dc59ed047333ddb39d3be54898134c4e9fa297eabc83650d6b +size 25721 diff --git a/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/HeroSword.uasset b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/HeroSword.uasset new file mode 100644 index 0000000..3a862a3 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/HeroSword.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ffc54e3fbe51f9f0cd1552bc7d2de49005aa6f0d79bfb3a8523ad661222bce2a +size 298673 diff --git a/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/HeroSword_Phys.uasset b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/HeroSword_Phys.uasset new file mode 100644 index 0000000..fef389e --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/HeroSword_Phys.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e2e7dc0f58196b8fd57fa46f4b3737a537a3029c209e3d95c4009f74d230d94 +size 95578 diff --git a/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/M_Blade_HeroSword11.uasset b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/M_Blade_HeroSword11.uasset new file mode 100644 index 0000000..6d962d4 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/M_Blade_HeroSword11.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c91cc03d4a17c922e55388505f2abd289e45081e8d925357ee768877ed1249c8 +size 107825 diff --git a/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/PhysMat_MetalSmooth.uasset b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/PhysMat_MetalSmooth.uasset new file mode 100644 index 0000000..f251b74 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/PhysMat_MetalSmooth.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5219da2c8ab4269c5234d11e76e7b5d793c39ba8eb7da2c5dec12bd5b6ae2d19 +size 1522 diff --git a/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/SK_Blade_HeroSword11.uasset b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/SK_Blade_HeroSword11.uasset new file mode 100644 index 0000000..f590fdb --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/SK_Blade_HeroSword11.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a03c3f0e0f3de7d898c6ea025d720c7b904db99cb4fae52b867aebf973ba3b9c +size 196668 diff --git a/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/SK_Blade_HeroSword_01_Skeleton.uasset b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/SK_Blade_HeroSword_01_Skeleton.uasset new file mode 100644 index 0000000..d8ec25f --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/SK_Blade_HeroSword_01_Skeleton.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:815ea9b78e76cfb1b4348ae3a97cb7bf640c4fbd4e71d1e69bfb7e8369491c38 +size 5625 diff --git a/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/T_Blade_HeroSword_011_D.uasset b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/T_Blade_HeroSword_011_D.uasset new file mode 100644 index 0000000..8b4fffc --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/T_Blade_HeroSword_011_D.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f9d43f1ada74559bafe97e50bef7ea39b0215155a4d9a89621522bb499ca5ca6 +size 198578 diff --git a/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/T_Blade_HeroSword_011_N.uasset b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/T_Blade_HeroSword_011_N.uasset new file mode 100644 index 0000000..eb26f19 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/T_Blade_HeroSword_011_N.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0faac10cadc67807ce2653e847769c7675955566c5feb932195802d4c8e52693 +size 5443 diff --git a/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/T_Blade_HeroSword_012_D.uasset b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/T_Blade_HeroSword_012_D.uasset new file mode 100644 index 0000000..3913837 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Blade_HeroSword11/T_Blade_HeroSword_012_D.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86459d73ffac44b0dde0fcac8bac5cddc9280e3c3e700763e16277c39b4d61c2 +size 208578 diff --git a/Content/VRE/Grippables/Weapons/Melee/Dagger.uasset b/Content/VRE/Grippables/Weapons/Melee/Dagger.uasset new file mode 100644 index 0000000..c0089c3 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Dagger.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:840ca0e72c6aa513712ff9304b3c47ebe7aec55e7e09cb1f0abb44b098b527d2 +size 52177 diff --git a/Content/VRE/Grippables/Weapons/Melee/Mace.uasset b/Content/VRE/Grippables/Weapons/Melee/Mace.uasset new file mode 100644 index 0000000..027f171 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Mace.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30ee62fd73ce7d029101ff5ff3ffab54388311d85bf3e099243518f9e066346f +size 53504 diff --git a/Content/VRE/Grippables/Weapons/Melee/MeleeBase.uasset b/Content/VRE/Grippables/Weapons/Melee/MeleeBase.uasset new file mode 100644 index 0000000..aef5ed9 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/MeleeBase.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85a8f370b1c18dfaeb64365eea8477f366c29cf41229d96fa1414b7fe71171d3 +size 611254 diff --git a/Content/VRE/Grippables/Weapons/Melee/Shield.uasset b/Content/VRE/Grippables/Weapons/Melee/Shield.uasset new file mode 100644 index 0000000..2e844a3 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Shield.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:960db53865588c3a3896544a9c3a82286dbe7d15f8cca3ad2fd7f9656ab80fb5 +size 167573 diff --git a/Content/VRE/Grippables/Weapons/Melee/Sickle.uasset b/Content/VRE/Grippables/Weapons/Melee/Sickle.uasset new file mode 100644 index 0000000..281cf5d --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Sickle.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45a7328cc3ae60424a9c8c497b6d47e9366b7ed86ee6ea1763272c0d430dcf3b +size 64176 diff --git a/Content/VRE/Grippables/Weapons/Melee/Spear.uasset b/Content/VRE/Grippables/Weapons/Melee/Spear.uasset new file mode 100644 index 0000000..c3f40da --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Spear.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3a9d6a384458b315ef6826250a83a59cae9d730f45955215534dbaefe1454181 +size 56634 diff --git a/Content/VRE/Grippables/Weapons/Melee/Sword.uasset b/Content/VRE/Grippables/Weapons/Melee/Sword.uasset new file mode 100644 index 0000000..a3dec5f --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Sword.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a69b3ce430b15736f319d6606ddf2807aebd552922f7f7142143ef220a43318d +size 54395 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/BP_GodRay.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/BP_GodRay.uasset new file mode 100644 index 0000000..6e3d012 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/BP_GodRay.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2a46851c9932dd8d26ee0716b257d373c5172e1042279f1deccff8a2c9c1574 +size 183248 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/Lightshaft/M_GodRay.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/Lightshaft/M_GodRay.uasset new file mode 100644 index 0000000..f341bf0 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/Lightshaft/M_GodRay.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ee58fc59456ce4bb6e5fa0111232980474d4ffec3c0aa8571241f93f3f41849 +size 114319 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/Lightshaft/M_GodRay_Inst_Animated.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/Lightshaft/M_GodRay_Inst_Animated.uasset new file mode 100644 index 0000000..b2c102a --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/Lightshaft/M_GodRay_Inst_Animated.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:475e9d6c1c455ae69a9ee605fb75e4d5c33897142ae08f791c57ed17dbe15abd +size 87108 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/Lightshaft/SM_GodRay_Plane.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/Lightshaft/SM_GodRay_Plane.uasset new file mode 100644 index 0000000..9ac7995 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/Lightshaft/SM_GodRay_Plane.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d196272fdce50a2f28f8c84ab1783ff598acaa8f7055399d0024e16a520fce9 +size 13530 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/Lightshaft/T_GodRay_Mask01.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/Lightshaft/T_GodRay_Mask01.uasset new file mode 100644 index 0000000..4c2feae --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/Lightshaft/T_GodRay_Mask01.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7626534fadbc2771a3aa9b9d4e5053cc9ecc06a1756ffdf21b4a4704928c794 +size 300670 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/Lightshaft/T_GodRay_Mask02.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/Lightshaft/T_GodRay_Mask02.uasset new file mode 100644 index 0000000..401423a --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Blueprints/Lightshaft/Lightshaft/T_GodRay_Mask02.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:06b2668cde292942d34ad8ab348419b9b1467a55cd419a15ea384523177744a8 +size 92433 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Materials/Fire/M_Fire_SubUV_11X11_Noise.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Materials/Fire/M_Fire_SubUV_11X11_Noise.uasset new file mode 100644 index 0000000..78487ee --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Materials/Fire/M_Fire_SubUV_11X11_Noise.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5404e7a40c21f0941e2c0eec547e5b211e7afc7e8a0b5c0f79dc10f3644a7d7 +size 111655 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Materials/Fire/M_HeatDistort.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Materials/Fire/M_HeatDistort.uasset new file mode 100644 index 0000000..3b8f45f --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Materials/Fire/M_HeatDistort.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7fd51c9653bd123a8dd16b169497bfc8a4f9ee802f2919429ab7a687cd2ec214 +size 96107 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Materials/Flares/M_FlareRound.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Materials/Flares/M_FlareRound.uasset new file mode 100644 index 0000000..916197d --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Materials/Flares/M_FlareRound.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:766c8e34dbc04de89a7fdc9fcf6f7e5bf4cebc9b94e82ca1928574a8e28c2646 +size 98203 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Materials/Sparks/M_Spark_VelocityLerp.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Materials/Sparks/M_Spark_VelocityLerp.uasset new file mode 100644 index 0000000..5f67139 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Materials/Sparks/M_Spark_VelocityLerp.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0af6253a894c43bcc8bc87af60fc41cf6e6b8ac7dcbdee0bcc75e1219b3bae38 +size 117146 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Particles/Fire/P_TorchFire.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Particles/Fire/P_TorchFire.uasset new file mode 100644 index 0000000..9bdf9a4 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Particles/Fire/P_TorchFire.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:254759d62fe73fb2c58112f65980653bb8039d31ccdabe2764c124dfd806e407 +size 191472 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Fire/T_FireSubUV_11X11_32.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Fire/T_FireSubUV_11X11_32.uasset new file mode 100644 index 0000000..881845b --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Fire/T_FireSubUV_11X11_32.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:550111515d289af09c05a3415074c6a9c8199262f5a749698e78e5f7f87da302 +size 557282 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Flares/T_FlareRound_Noise.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Flares/T_FlareRound_Noise.uasset new file mode 100644 index 0000000..2a4261c --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Flares/T_FlareRound_Noise.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:989c52dec7176c3d608127b383fab088d65cb6343d225cd9129c40f343ddb654 +size 208151 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Noise/T_HeatTile3_N.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Noise/T_HeatTile3_N.uasset new file mode 100644 index 0000000..3d8f564 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Noise/T_HeatTile3_N.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11b0683b7f46609d570f48f7deaebb062261e0f51084f65b280e8e1af8c8f7c8 +size 856610 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Noise/T_TilingNoise03.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Noise/T_TilingNoise03.uasset new file mode 100644 index 0000000..9ccd9fb --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Noise/T_TilingNoise03.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d75511ea6c1cff25e9f5ace144dd4a5979700f54999053f0ee3bdb80b373cd1c +size 3405393 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Noise/T_TilingNoise12.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Noise/T_TilingNoise12.uasset new file mode 100644 index 0000000..2dacd6f --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Noise/T_TilingNoise12.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:378f11161767fa352819e7379e629444818d705455799b55f177ed082a392a03 +size 4373838 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Noise/T_TilingNoise16.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Noise/T_TilingNoise16.uasset new file mode 100644 index 0000000..225767d --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Noise/T_TilingNoise16.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d464fccf7965a757438468b30a0284ad304d3286482680d818f89a6680acd485 +size 406330 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Snow/T_Snow01_Packed.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Snow/T_Snow01_Packed.uasset new file mode 100644 index 0000000..80db722 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/Textures/Snow/T_Snow01_Packed.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6d9b5978040bf798bae763b407706b33d80799112cd0a289338cd214a4be071 +size 71605 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/VectorFields/VF_RandomNoise_01_90.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/VectorFields/VF_RandomNoise_01_90.uasset new file mode 100644 index 0000000..5caf55d --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Effects/VectorFields/VF_RandomNoise_01_90.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26f05d94150b20d5243039e8a131f8247b3815a90c0d3eb8f09810a836ff17d2 +size 2099406 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Materials/M_Stained_Glass.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Materials/M_Stained_Glass.uasset new file mode 100644 index 0000000..dceaf95 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Materials/M_Stained_Glass.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2fb023fe018378ff1a51b7e6e466f83d1fcc2a7d1af4223f16ab04bcf9091d66 +size 108387 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Materials/Weapons/M_WeaponSet_1.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Materials/Weapons/M_WeaponSet_1.uasset new file mode 100644 index 0000000..f7d8b24 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Materials/Weapons/M_WeaponSet_1.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59e46a0f80b43bb4a932358a636677c731f230d4b1e84c20d4c25823d7ccedce +size 153667 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Materials/Weapons/M_WeaponSet_1Dirty.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Materials/Weapons/M_WeaponSet_1Dirty.uasset new file mode 100644 index 0000000..76c494c --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Materials/Weapons/M_WeaponSet_1Dirty.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd36ff8ce6303a0f01569b0d85953a46005f369cb6cbefb7e5c0b1c06691bbca +size 167960 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Materials/Weapons/M_WeaponSet_2.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Materials/Weapons/M_WeaponSet_2.uasset new file mode 100644 index 0000000..d7b9048 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Materials/Weapons/M_WeaponSet_2.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:097117c1a29ff25bbcd612d34b4c5af58fd06b28da930763d6e6f27bb526557b +size 141726 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Materials/Weapons/M_WeaponSet_2Dirty.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Materials/Weapons/M_WeaponSet_2Dirty.uasset new file mode 100644 index 0000000..3cb63dc --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Materials/Weapons/M_WeaponSet_2Dirty.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc591651531e983b85ab41dfb80c4b2a14983226122b51b28ab0900e3778a75e +size 159444 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Axe.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Axe.uasset new file mode 100644 index 0000000..07bbfc3 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Axe.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:94187dc99d52e92126399a465c9eb439e6c4e878f2c1c124432e59dbaf71344f +size 128989 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Dagger_1.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Dagger_1.uasset new file mode 100644 index 0000000..e0ebc4c --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Dagger_1.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e3b6a414c337179dd48c59d919a707a9918eee407cd96c6ceea467f760481dc +size 124408 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Dagger_2.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Dagger_2.uasset new file mode 100644 index 0000000..3f937e5 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Dagger_2.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d56bc1f8bc9f88cf44dad20744972f6b7de11d6180240d1209bcb0a5d84d8ff +size 51054 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_GreatAxe.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_GreatAxe.uasset new file mode 100644 index 0000000..f14773f --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_GreatAxe.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7f89f5bb96bef13e5258c43d99834ad396bad2bf08cbd5913dff95bb67be2865 +size 143225 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_GreatHammer.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_GreatHammer.uasset new file mode 100644 index 0000000..aabb4e9 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_GreatHammer.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7481a49577f6e195a74ee5fc7bb51e4d72e422bbfc812f04ad18a648c7588ac1 +size 139673 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_H2H.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_H2H.uasset new file mode 100644 index 0000000..cf387dd --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_H2H.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e490bdae2c930f9b91f20f70c0b1a097dd1548c81e38f5afde78782d34357cb8 +size 125392 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Mace.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Mace.uasset new file mode 100644 index 0000000..19d2eb9 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Mace.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5a09b7b8f984e2a6417cf46c0dd13a9205b72bd7463710396fbca42f534f947 +size 44908 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Shield.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Shield.uasset new file mode 100644 index 0000000..a136b85 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Shield.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:860e01527b514d992288b9d246950454461a910e9c8a3110b2e5b8ea0faf8e1a +size 97265 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Sickle.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Sickle.uasset new file mode 100644 index 0000000..8f76040 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Sickle.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14b188a7e76b7070aaeb079d57cfdf8ca773c9b6be50d55602abd840b0d67942 +size 42760 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Spear.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Spear.uasset new file mode 100644 index 0000000..9c8a943 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Spear.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dff7bfe5730fba4cdac3157941d7e112e6d97911770b9e1cd06fb677569776a5 +size 32777 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Sword.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Sword.uasset new file mode 100644 index 0000000..378ed58 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Sword.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb798aaae1c576f72e26eb1da88d16d27cefe5cf956e6a5b6f1cd2bc941413b7 +size 45619 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Throwing.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Throwing.uasset new file mode 100644 index 0000000..e76eeb1 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Mesh/Weapons/Weapons_Kit/SM_Throwing.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ab8a56f350b2d6fca2ca70799fa8d7d221f50ec91886c343603488128ef33d4 +size 124904 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set1_BaseColor.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set1_BaseColor.uasset new file mode 100644 index 0000000..9812cf4 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set1_BaseColor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f27231b3a3f97e9e2b1c7a2527f963ece0d03a533e19e12a1148af4eca911b76 +size 22201596 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set1_Normal.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set1_Normal.uasset new file mode 100644 index 0000000..f0ead8b --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set1_Normal.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b315359708284f52047eb6e035476c8e8118dbb0fb87aab102195b5635a31091 +size 27731639 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set1_OcclusionRoughnessMetallic.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set1_OcclusionRoughnessMetallic.uasset new file mode 100644 index 0000000..ba2fea6 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set1_OcclusionRoughnessMetallic.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc57a2e130aa460d49e4f091be7186e7e94e09dc2a3d03c42f9ebc8ed8316e80 +size 21668041 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set2_BaseColor.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set2_BaseColor.uasset new file mode 100644 index 0000000..f19494e --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set2_BaseColor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6757304bf199367136e78bef88c47552e969c43618a6baedd3bac2ca548960b8 +size 19537489 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set2_Normal.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set2_Normal.uasset new file mode 100644 index 0000000..41f23c1 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set2_Normal.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eeb8f00cf65eb3a673d6d12fa86d16b778ef3696fde482e19f2c319d2870f5ce +size 28237997 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set2_OcclusionRoughnessMetallic.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set2_OcclusionRoughnessMetallic.uasset new file mode 100644 index 0000000..cd867e0 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Dirty_Weapon_Set2_OcclusionRoughnessMetallic.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6926ed6959a55f20091c3c7693705f73f17a431168fc697a35f08b93d00e453 +size 21919418 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set1_BaseColor.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set1_BaseColor.uasset new file mode 100644 index 0000000..e2646d2 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set1_BaseColor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e96bd7a5ffb230b013ce3a73491411323ddc32e99a5646b0fa177aa55f68eafa +size 16301026 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set1_Normal.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set1_Normal.uasset new file mode 100644 index 0000000..6931fca --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set1_Normal.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3820cbf36d6cef92cb5414d316bc6a90e2c01ee4b2d4b8adee885a2c9c118d35 +size 24691345 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set1_OcclusionRoughnessMetallic.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set1_OcclusionRoughnessMetallic.uasset new file mode 100644 index 0000000..4eceaec --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set1_OcclusionRoughnessMetallic.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3eaf8634a3d32fa06a9440dcd4dfaf13e2dac678d2dda181e94d4f1ba7edd83 +size 18813193 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set2_BaseColor.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set2_BaseColor.uasset new file mode 100644 index 0000000..0a0753e --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set2_BaseColor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:210eb6bd9c4f3120a7f97616b1033cdbbd6cea346739448b18997f9f2064f201 +size 16278172 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set2_Normal.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set2_Normal.uasset new file mode 100644 index 0000000..0488c33 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set2_Normal.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6887a707b1c9defcf84ed80247061f23a53d3931789cb1f36f1fed1397d4c8bd +size 22453854 diff --git a/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set2_OcclusionRoughnessMetallic.uasset b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set2_OcclusionRoughnessMetallic.uasset new file mode 100644 index 0000000..6dbdc00 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Melee/Weapon_Pack/Textures/Weapons/T_Weapon_Set2_OcclusionRoughnessMetallic.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:abd37e4193e561e39c3377ce3529db87a93b577bece881b952eef0704aa76bdc +size 22522560 diff --git a/Content/VRE/Grippables/Weapons/Misc/Cylinder1.uasset b/Content/VRE/Grippables/Weapons/Misc/Cylinder1.uasset new file mode 100644 index 0000000..c7c00b0 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Misc/Cylinder1.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:768fbb4f48589b55c7260e17e2c9403eda7b754b70894221f086d76df6e7e2bf +size 33387 diff --git a/Content/VRE/Grippables/Weapons/Misc/Dummy.uasset b/Content/VRE/Grippables/Weapons/Misc/Dummy.uasset new file mode 100644 index 0000000..6a0288f --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Misc/Dummy.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f46b9fa8ed6fc037539117502b6a6926f0a35ce2923bbc8572abfa618a8ce52 +size 42603 diff --git a/Content/VRE/Grippables/Weapons/Misc/Slicer/01_-_Default.uasset b/Content/VRE/Grippables/Weapons/Misc/Slicer/01_-_Default.uasset new file mode 100644 index 0000000..e401673 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Misc/Slicer/01_-_Default.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:932cdd3bb9fc0a6a2e2c7859bc24e10ac79943769e7585a42e3fa09892970f7b +size 101948 diff --git a/Content/VRE/Grippables/Weapons/Misc/Slicer/01_-_Defaultg.uasset b/Content/VRE/Grippables/Weapons/Misc/Slicer/01_-_Defaultg.uasset new file mode 100644 index 0000000..1c1f60f --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Misc/Slicer/01_-_Defaultg.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c2af53bc782c41a75638f767cc0e425e395f71221c8766e31395ae8c5bcfc5db +size 95583 diff --git a/Content/VRE/Grippables/Weapons/Misc/Slicer/01_-_Defaultgw.uasset b/Content/VRE/Grippables/Weapons/Misc/Slicer/01_-_Defaultgw.uasset new file mode 100644 index 0000000..5fb009b --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Misc/Slicer/01_-_Defaultgw.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f49205106745bca0b66a4fa65fc9dc896477ab180a014df7f7b423db84b34ea8 +size 51417 diff --git a/Content/VRE/Grippables/Weapons/Misc/Slicer/Sandra_s_Sword.uasset b/Content/VRE/Grippables/Weapons/Misc/Slicer/Sandra_s_Sword.uasset new file mode 100644 index 0000000..a18f9cf --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Misc/Slicer/Sandra_s_Sword.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e08448fd62c79e3e4f6ba35e0d0f06aa3ea00ba8a4a099132bc1ec12ef873b7f +size 251353 diff --git a/Content/VRE/Grippables/Weapons/Misc/Slicer/SliceDummy.uasset b/Content/VRE/Grippables/Weapons/Misc/Slicer/SliceDummy.uasset new file mode 100644 index 0000000..eacf3d6 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Misc/Slicer/SliceDummy.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:951117b745ace00e670c2a02075f91b1fd6d494563ccf9b3e8a35b86bc2c40a1 +size 26921 diff --git a/Content/VRE/Grippables/Weapons/Misc/Slicer/Slicer.uasset b/Content/VRE/Grippables/Weapons/Misc/Slicer/Slicer.uasset new file mode 100644 index 0000000..1a43812 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Misc/Slicer/Slicer.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b7b75445dd797b1c0a197c952063eb6055403ec66707f1a4d204764854cfeac +size 162371 diff --git a/Content/VRE/Grippables/Weapons/Misc/Slicer/SlicingDummy.uasset b/Content/VRE/Grippables/Weapons/Misc/Slicer/SlicingDummy.uasset new file mode 100644 index 0000000..82f2485 --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Misc/Slicer/SlicingDummy.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae36e55d206fb080cce3ba8d816e28d891ce507c8fc4b4ade937acfb2a1dacc4 +size 216357 diff --git a/Content/VRE/Grippables/Weapons/Misc/Slicer/defaultMat.uasset b/Content/VRE/Grippables/Weapons/Misc/Slicer/defaultMat.uasset new file mode 100644 index 0000000..e9382ba --- /dev/null +++ b/Content/VRE/Grippables/Weapons/Misc/Slicer/defaultMat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b61bb60f00f4342daeb6da43b2e73f8d0b3b25411d59638ccc419151fcc39ff4 +size 59089 diff --git a/Content/VRE/Input/Actions/AlternateGripLeft.uasset b/Content/VRE/Input/Actions/AlternateGripLeft.uasset new file mode 100644 index 0000000..a3ecb0f --- /dev/null +++ b/Content/VRE/Input/Actions/AlternateGripLeft.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e838ac7a16a9abfbff653a00a2b541db9d5039649b8962d867bd271f673354b +size 1733 diff --git a/Content/VRE/Input/Actions/AlternateGripRight.uasset b/Content/VRE/Input/Actions/AlternateGripRight.uasset new file mode 100644 index 0000000..4a50b4b --- /dev/null +++ b/Content/VRE/Input/Actions/AlternateGripRight.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b709af759ede67d0f1be1236ea9d32414abd47c8aecdf0af30d81518712544e5 +size 1742 diff --git a/Content/VRE/Input/Actions/ControllerMovementLeft.uasset b/Content/VRE/Input/Actions/ControllerMovementLeft.uasset new file mode 100644 index 0000000..7434073 --- /dev/null +++ b/Content/VRE/Input/Actions/ControllerMovementLeft.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:efb29e43077a95e58dc4701bac014adaeaa5a6aa59bbfbe67558023152a4b08a +size 1925 diff --git a/Content/VRE/Input/Actions/ControllerMovementRight.uasset b/Content/VRE/Input/Actions/ControllerMovementRight.uasset new file mode 100644 index 0000000..6cc857a --- /dev/null +++ b/Content/VRE/Input/Actions/ControllerMovementRight.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47cbe9c2325bfce551802aece2a33050ab71b31ad010a0a4c03fed01ebf4403e +size 1934 diff --git a/Content/VRE/Input/Actions/FPSActions/Jump.uasset b/Content/VRE/Input/Actions/FPSActions/Jump.uasset new file mode 100644 index 0000000..de27f0f --- /dev/null +++ b/Content/VRE/Input/Actions/FPSActions/Jump.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a1a5b728c4a1fb21be95307d7ce48439155eae8ff6b791f877d3309b8a62b29 +size 1645 diff --git a/Content/VRE/Input/Actions/FPSActions/LookUp.uasset b/Content/VRE/Input/Actions/FPSActions/LookUp.uasset new file mode 100644 index 0000000..dc3e867 --- /dev/null +++ b/Content/VRE/Input/Actions/FPSActions/LookUp.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3be15eb111e1907782872e423d45b0b6f441e710d0c144b4fdfbb0b380d1e8ec +size 1810 diff --git a/Content/VRE/Input/Actions/FPSActions/MoveForward.uasset b/Content/VRE/Input/Actions/FPSActions/MoveForward.uasset new file mode 100644 index 0000000..3e3270d --- /dev/null +++ b/Content/VRE/Input/Actions/FPSActions/MoveForward.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c52c5253dfbb4a1ff7ba50eb675b199b0999f5b704c34a6a4440114763e2426 +size 1857 diff --git a/Content/VRE/Input/Actions/FPSActions/MoveRight.uasset b/Content/VRE/Input/Actions/FPSActions/MoveRight.uasset new file mode 100644 index 0000000..d44788b --- /dev/null +++ b/Content/VRE/Input/Actions/FPSActions/MoveRight.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd6d29db7763b629a4e8588db43f677b0cae53855cee720530d918b0339556df +size 1837 diff --git a/Content/VRE/Input/Actions/FPSActions/Turn.uasset b/Content/VRE/Input/Actions/FPSActions/Turn.uasset new file mode 100644 index 0000000..0a7106f --- /dev/null +++ b/Content/VRE/Input/Actions/FPSActions/Turn.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2cef6554d211f2da6161b97663aeb2369c648f9ede8db34c919575257c025baf +size 1792 diff --git a/Content/VRE/Input/Actions/LaserBeamLeft.uasset b/Content/VRE/Input/Actions/LaserBeamLeft.uasset new file mode 100644 index 0000000..65cb30a --- /dev/null +++ b/Content/VRE/Input/Actions/LaserBeamLeft.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9197c15df99db7cf86c31af6b948278ddc6d228ed314aa15b97acb41d9009273 +size 1697 diff --git a/Content/VRE/Input/Actions/LaserBeamRight.uasset b/Content/VRE/Input/Actions/LaserBeamRight.uasset new file mode 100644 index 0000000..3435283 --- /dev/null +++ b/Content/VRE/Input/Actions/LaserBeamRight.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4eb9f86043920401304778a1247f7ccf600cfe2b62c8e78d4b5921d7575b5bf2 +size 1706 diff --git a/Content/VRE/Input/Actions/MotionControllerThumbLeft_X.uasset b/Content/VRE/Input/Actions/MotionControllerThumbLeft_X.uasset new file mode 100644 index 0000000..76bfaff --- /dev/null +++ b/Content/VRE/Input/Actions/MotionControllerThumbLeft_X.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f9514284ca54c4019335be42544a9c29de3e2ea179616f932b575a8ae927b0fd +size 1972 diff --git a/Content/VRE/Input/Actions/MotionControllerThumbLeft_Y.uasset b/Content/VRE/Input/Actions/MotionControllerThumbLeft_Y.uasset new file mode 100644 index 0000000..65f005c --- /dev/null +++ b/Content/VRE/Input/Actions/MotionControllerThumbLeft_Y.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4dc37821f7f0f5f745b527f6eb5ef09846a144a745ec9e970e4a54fe35a352c8 +size 1972 diff --git a/Content/VRE/Input/Actions/MotionControllerThumbRight_X.uasset b/Content/VRE/Input/Actions/MotionControllerThumbRight_X.uasset new file mode 100644 index 0000000..7eb201d --- /dev/null +++ b/Content/VRE/Input/Actions/MotionControllerThumbRight_X.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c809975f9f3d5b164dd94b1c5a13359035a3aa55a1201d28ef694eb8dcca694b +size 1981 diff --git a/Content/VRE/Input/Actions/MotionControllerThumbRight_Y.uasset b/Content/VRE/Input/Actions/MotionControllerThumbRight_Y.uasset new file mode 100644 index 0000000..4fb4d3f --- /dev/null +++ b/Content/VRE/Input/Actions/MotionControllerThumbRight_Y.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08334d0a62c0064bcbe385e62e42f18fd5394b8de87935dbf191c09b37d0703e +size 1981 diff --git a/Content/VRE/Input/Actions/PrimaryGripLeft.uasset b/Content/VRE/Input/Actions/PrimaryGripLeft.uasset new file mode 100644 index 0000000..0a2ad1a --- /dev/null +++ b/Content/VRE/Input/Actions/PrimaryGripLeft.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2118297fb54c03b90d3f600dc2359ae504078a606720a5b02a4504cff322153a +size 1725 diff --git a/Content/VRE/Input/Actions/PrimaryGripRight.uasset b/Content/VRE/Input/Actions/PrimaryGripRight.uasset new file mode 100644 index 0000000..f78e572 --- /dev/null +++ b/Content/VRE/Input/Actions/PrimaryGripRight.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45c451a28c509a1f29e80ee9d05df72e40267f376734866cd4c60f6a80ee0e8f +size 1734 diff --git a/Content/VRE/Input/Actions/TeleportLeft.uasset b/Content/VRE/Input/Actions/TeleportLeft.uasset new file mode 100644 index 0000000..9177e19 --- /dev/null +++ b/Content/VRE/Input/Actions/TeleportLeft.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a5639edfcc13491b91cc89d033361dbb8b92776c278a871d13ae51837ae9c82 +size 1686 diff --git a/Content/VRE/Input/Actions/TeleportRight.uasset b/Content/VRE/Input/Actions/TeleportRight.uasset new file mode 100644 index 0000000..054131e --- /dev/null +++ b/Content/VRE/Input/Actions/TeleportRight.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bca00b14c3c592ae8c8f97963794904c5718f02c62e59161e845b35305c62547 +size 1695 diff --git a/Content/VRE/Input/Actions/UseHeldObjectLeft.uasset b/Content/VRE/Input/Actions/UseHeldObjectLeft.uasset new file mode 100644 index 0000000..c55059d --- /dev/null +++ b/Content/VRE/Input/Actions/UseHeldObjectLeft.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de78a3a8cf9cb1ccd1f1a67814856637922e53c76dab8e5675f3f044d985d21d +size 1729 diff --git a/Content/VRE/Input/Actions/UseHeldObjectRight.uasset b/Content/VRE/Input/Actions/UseHeldObjectRight.uasset new file mode 100644 index 0000000..f93d245 --- /dev/null +++ b/Content/VRE/Input/Actions/UseHeldObjectRight.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8fb7e74eb8d0e577d5dd293a3e23bc7d850f43938a0f97ac16c8ba4cdd751863 +size 1738 diff --git a/Content/VRE/Input/FPSInputConfig.uasset b/Content/VRE/Input/FPSInputConfig.uasset new file mode 100644 index 0000000..7320fc5 --- /dev/null +++ b/Content/VRE/Input/FPSInputConfig.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a3dbd80f436cfb88b32ad754672a97aeb7831d9b27f0afd118dbb2e76a902f4 +size 2238 diff --git a/Content/VRE/Input/FPSInputContext.uasset b/Content/VRE/Input/FPSInputContext.uasset new file mode 100644 index 0000000..97f2e4a --- /dev/null +++ b/Content/VRE/Input/FPSInputContext.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d736f494febc8d56fbc8752af45f9f260547664bbe483db52c40e6960dc817b +size 11478 diff --git a/Content/VRE/Input/VREInputConfig.uasset b/Content/VRE/Input/VREInputConfig.uasset new file mode 100644 index 0000000..e57a916 --- /dev/null +++ b/Content/VRE/Input/VREInputConfig.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a93b6b73d5169be5db2c22c81bda929bb9a40900382197dac7f10f15ab59b694 +size 2252 diff --git a/Content/VRE/Input/VREInputMappingContext.uasset b/Content/VRE/Input/VREInputMappingContext.uasset new file mode 100644 index 0000000..b5a1533 --- /dev/null +++ b/Content/VRE/Input/VREInputMappingContext.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30f0005533acc9502120ee95719adb76b7b80478885cec3dcee2bf12ce51ffd9 +size 57589 diff --git a/Content/VRE/Level/Car/Vehicle/Sedan/FrontWheel.uasset b/Content/VRE/Level/Car/Vehicle/Sedan/FrontWheel.uasset new file mode 100644 index 0000000..2aaa864 --- /dev/null +++ b/Content/VRE/Level/Car/Vehicle/Sedan/FrontWheel.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ff5226c6d823f8dabf9a119e500c94c38f73e712ea4f7f7f6afca2ba07937cb +size 6125 diff --git a/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan.uasset b/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan.uasset new file mode 100644 index 0000000..eac566c --- /dev/null +++ b/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce2cd364db5148595af16df814568e853c4795cdb9a85c73ebf6dcc1d0324c2e +size 80345 diff --git a/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_Glass.uasset b/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_Glass.uasset new file mode 100644 index 0000000..516d9bc --- /dev/null +++ b/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_Glass.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f824bb413380bd1e4fdc134dd483fd4507bb1433e196affe9a8135f1ab42fd0c +size 9253 diff --git a/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_Headlights.uasset b/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_Headlights.uasset new file mode 100644 index 0000000..6812515 --- /dev/null +++ b/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_Headlights.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca34d3c81f602c0171bc6487ad2ee5d9d61e367d724d5901468a6ef6f68f6df9 +size 9320 diff --git a/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_Plastic.uasset b/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_Plastic.uasset new file mode 100644 index 0000000..7b2b6d4 --- /dev/null +++ b/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_Plastic.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:684a9e971512c9cfea6d34958b067e94882547e593da269f763f4af9fdedb8ec +size 7897 diff --git a/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_TailLights.uasset b/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_TailLights.uasset new file mode 100644 index 0000000..9d7e7a7 --- /dev/null +++ b/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_TailLights.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ce9249e77130d60f498e04affb1dc188fbd53d51fecc40a7bfc4b3b9c97e24b +size 9352 diff --git a/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_Tires.uasset b/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_Tires.uasset new file mode 100644 index 0000000..26ea8c8 --- /dev/null +++ b/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_Tires.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e457133da6737a691055d244332179173ea12542159c0205154e22471e0f4291 +size 7559 diff --git a/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_Wheels.uasset b/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_Wheels.uasset new file mode 100644 index 0000000..643dd84 --- /dev/null +++ b/Content/VRE/Level/Car/Vehicle/Sedan/Materials/M_Vehicle_Sedan_Inst_Wheels.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f3a4c897de984f16e4e94646a0d0934d5aff79fbc8edf106b1800797afb9043 +size 9385 diff --git a/Content/VRE/Level/Car/Vehicle/Sedan/RearWheel.uasset b/Content/VRE/Level/Car/Vehicle/Sedan/RearWheel.uasset new file mode 100644 index 0000000..7e0949a --- /dev/null +++ b/Content/VRE/Level/Car/Vehicle/Sedan/RearWheel.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb171705409ab03549023f637889281c864af540a4cd2cf9e2bee11e98466391 +size 6057 diff --git a/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_AnimBP.uasset b/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_AnimBP.uasset new file mode 100644 index 0000000..a77d01d --- /dev/null +++ b/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_AnimBP.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:69f58b972446fdac5fa06ba68227f995d22a1a4a6d4235fcfa63b6e7f8fbb868 +size 140414 diff --git a/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_PhysMat.uasset b/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_PhysMat.uasset new file mode 100644 index 0000000..5cf59a8 --- /dev/null +++ b/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_PhysMat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c3d7abb5517c9c5c43f78cc4c4a83762ca33852d92232b62125a8986c54e9bb +size 1310 diff --git a/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_PhysicsAsset.uasset b/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_PhysicsAsset.uasset new file mode 100644 index 0000000..f2dbc68 --- /dev/null +++ b/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_PhysicsAsset.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b6c1fd3bf8b4ff23436a824fd2340580e15017dc0c095f1f36907e77ae3b8514 +size 361660 diff --git a/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_SkelMesh.uasset b/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_SkelMesh.uasset new file mode 100644 index 0000000..3b2a848 --- /dev/null +++ b/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_SkelMesh.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc5f67c9ba2f5295d2018f68b5e5f047db15b0bb3924aa87448bfbbe6ca8067b +size 3665493 diff --git a/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_SkelMesh_Physics.uasset b/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_SkelMesh_Physics.uasset new file mode 100644 index 0000000..ce2991d --- /dev/null +++ b/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_SkelMesh_Physics.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0999149ddb59656da7236c8ef4fa0d81d3bce047e10574ecd71d752f5a46e07b +size 361365 diff --git a/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_Skeleton.uasset b/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_Skeleton.uasset new file mode 100644 index 0000000..ee232d9 --- /dev/null +++ b/Content/VRE/Level/Car/Vehicle/Sedan/Sedan_Skeleton.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a5fbcaa9e0b4dfb6f7d4095853718252887d767cdc00fe52b13621374049e70 +size 8338 diff --git a/Content/VRE/Level/Car/VehicleAdv/ArenaMesh/LoopBig.uasset b/Content/VRE/Level/Car/VehicleAdv/ArenaMesh/LoopBig.uasset new file mode 100644 index 0000000..190d20a --- /dev/null +++ b/Content/VRE/Level/Car/VehicleAdv/ArenaMesh/LoopBig.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dbce931b614a6e6ea567c99dfca6c9f8f4a943a35bf03556212baa77ebccab2a +size 45221 diff --git a/Content/VRE/Level/Car/VehicleAdv/Materials/MasterSolidColor.uasset b/Content/VRE/Level/Car/VehicleAdv/Materials/MasterSolidColor.uasset new file mode 100644 index 0000000..ad3870b --- /dev/null +++ b/Content/VRE/Level/Car/VehicleAdv/Materials/MasterSolidColor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d9afa56344449a31b7b84692c028610c0fd1ed112063fd6c99acd57fa9843b7 +size 112697 diff --git a/Content/VRE/Level/Car/VehicleAdv/Materials/MaterialInstances/SolidOrange.uasset b/Content/VRE/Level/Car/VehicleAdv/Materials/MaterialInstances/SolidOrange.uasset new file mode 100644 index 0000000..c6470f8 --- /dev/null +++ b/Content/VRE/Level/Car/VehicleAdv/Materials/MaterialInstances/SolidOrange.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb32a9e8a5294f86fea30d174b40f94f73354afe86918c1277f738d9d641306c +size 113444 diff --git a/Content/VRE/Level/Car/VehicleBP/Sedan/PassengerInfo.uasset b/Content/VRE/Level/Car/VehicleBP/Sedan/PassengerInfo.uasset new file mode 100644 index 0000000..6153d28 --- /dev/null +++ b/Content/VRE/Level/Car/VehicleBP/Sedan/PassengerInfo.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c363ef9c2d2737fae7f94fc100580601f146bb54e81e85f41aa048146609f3a +size 5053 diff --git a/Content/VRE/Level/Car/VehicleBP/Sedan/Sedan.uasset b/Content/VRE/Level/Car/VehicleBP/Sedan/Sedan.uasset new file mode 100644 index 0000000..a331a17 --- /dev/null +++ b/Content/VRE/Level/Car/VehicleBP/Sedan/Sedan.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87b7ffdec8a18a007d0b52c2254bce164c08e3745776727eaccbe3132f9b9d7e +size 872967 diff --git a/Content/VRE/Level/Car/VehicleBP/Sedan/SteeringWheel.uasset b/Content/VRE/Level/Car/VehicleBP/Sedan/SteeringWheel.uasset new file mode 100644 index 0000000..d98b232 --- /dev/null +++ b/Content/VRE/Level/Car/VehicleBP/Sedan/SteeringWheel.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:876735fa638611f892f65c692b440f7f73c39a17595a45370c6ebe4f317dc149 +size 30710 diff --git a/Content/VRE/Level/Car/VehicleBP/Sedan/ThrottleLever.uasset b/Content/VRE/Level/Car/VehicleBP/Sedan/ThrottleLever.uasset new file mode 100644 index 0000000..d563275 --- /dev/null +++ b/Content/VRE/Level/Car/VehicleBP/Sedan/ThrottleLever.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:635cb356d1c5527efce63067594d1b5d3ef86311ca935b3505104c33fe28ca5c +size 47382 diff --git a/Content/VRE/Level/Car/VehicleBP/Sedan/Turquoise.uasset b/Content/VRE/Level/Car/VehicleBP/Sedan/Turquoise.uasset new file mode 100644 index 0000000..cecc2af --- /dev/null +++ b/Content/VRE/Level/Car/VehicleBP/Sedan/Turquoise.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f958dc04dfec97c6c276e0758bf14efce612c5f7ea3efc9c86d95456248e2e1 +size 77363 diff --git a/Content/VRE/Level/Car/VehicleBP/Sedan/Yellow.uasset b/Content/VRE/Level/Car/VehicleBP/Sedan/Yellow.uasset new file mode 100644 index 0000000..698ea36 --- /dev/null +++ b/Content/VRE/Level/Car/VehicleBP/Sedan/Yellow.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56e63af559bfc33c426375085614864c582541a394c3594978fef13dd26cd1dc +size 75748 diff --git a/Content/VRE/Level/Console/ConsoleOutput.uasset b/Content/VRE/Level/Console/ConsoleOutput.uasset new file mode 100644 index 0000000..9cfcadd --- /dev/null +++ b/Content/VRE/Level/Console/ConsoleOutput.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8509d96aef98eee98867e8c1e46bf4436d2343600848756448166cc3f2ff8ea2 +size 789315 diff --git a/Content/VRE/Level/Console/VRConsoleMaterial.uasset b/Content/VRE/Level/Console/VRConsoleMaterial.uasset new file mode 100644 index 0000000..0ac27cf --- /dev/null +++ b/Content/VRE/Level/Console/VRConsoleMaterial.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0862ca33e347ace106d392902a6329c9c51b6e08176e0485417c7dc0301a6d0 +size 12326 diff --git a/Content/VRE/Level/Keyboard/2DKeyboard.uasset b/Content/VRE/Level/Keyboard/2DKeyboard.uasset new file mode 100644 index 0000000..9879206 --- /dev/null +++ b/Content/VRE/Level/Keyboard/2DKeyboard.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44661d761195da9d072b67bb113f1838cfd1d098cae2db645e4624ccd4afb4fe +size 321128 diff --git a/Content/VRE/Level/Keyboard/3DKeyboard.uasset b/Content/VRE/Level/Keyboard/3DKeyboard.uasset new file mode 100644 index 0000000..a9af119 --- /dev/null +++ b/Content/VRE/Level/Keyboard/3DKeyboard.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e22f99d5e56041b779772be7a63ba5dadd4dafd3d601b8769a01b38eadd2da57 +size 407554 diff --git a/Content/VRE/Level/Keyboard/3DKeyboardKey.uasset b/Content/VRE/Level/Keyboard/3DKeyboardKey.uasset new file mode 100644 index 0000000..e45f3e7 --- /dev/null +++ b/Content/VRE/Level/Keyboard/3DKeyboardKey.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e8c4f29f92e9a26ca55edd6cf2ae5137d0685eaa464b9e80dd4bb0fb8f3b1d8 +size 240589 diff --git a/Content/VRE/Level/Keyboard/BaseKeyboardKey.uasset b/Content/VRE/Level/Keyboard/BaseKeyboardKey.uasset new file mode 100644 index 0000000..6749129 --- /dev/null +++ b/Content/VRE/Level/Keyboard/BaseKeyboardKey.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ce1c750fc1377956a31649b38f8eb7f28f312e61dae4d70cc64e94c7403280b +size 86027 diff --git a/Content/VRE/Level/Keyboard/GreenFaceKeyboardKey.uasset b/Content/VRE/Level/Keyboard/GreenFaceKeyboardKey.uasset new file mode 100644 index 0000000..12d6c2d --- /dev/null +++ b/Content/VRE/Level/Keyboard/GreenFaceKeyboardKey.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:301c68d773c5dcfe727c53f17bb05e2e2c5023b0998487de2d1744add834ff4c +size 127284 diff --git a/Content/VRE/Level/Keyboard/KeyboardDataTable.uasset b/Content/VRE/Level/Keyboard/KeyboardDataTable.uasset new file mode 100644 index 0000000..c15b51b --- /dev/null +++ b/Content/VRE/Level/Keyboard/KeyboardDataTable.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5399edf9f2aeaa23649658320ff63462de49dc6c00a915725b136487fc6c7e9 +size 38731 diff --git a/Content/VRE/Level/Keyboard/KeyboardKeyTableRow.uasset b/Content/VRE/Level/Keyboard/KeyboardKeyTableRow.uasset new file mode 100644 index 0000000..3031dd7 --- /dev/null +++ b/Content/VRE/Level/Keyboard/KeyboardKeyTableRow.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e541ec061bc7cd0984ab9b194dab84d030f32f7b2d9e079462ebe9a7643893e +size 10438 diff --git a/Content/VRE/Level/Keyboard/KeyboardTestActor.uasset b/Content/VRE/Level/Keyboard/KeyboardTestActor.uasset new file mode 100644 index 0000000..f65b11c --- /dev/null +++ b/Content/VRE/Level/Keyboard/KeyboardTestActor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2b243e1cd3c289f7854c4cf467e2955c62caaa01d44881b61e58842417c4e77 +size 76187 diff --git a/Content/VRE/Level/Keyboard/KeypadDataTable.uasset b/Content/VRE/Level/Keyboard/KeypadDataTable.uasset new file mode 100644 index 0000000..9596ccb --- /dev/null +++ b/Content/VRE/Level/Keyboard/KeypadDataTable.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d1ef2e7d8fde8a332cec51c4632c939422f78a28fdf7f06b515279c1b978956 +size 12056 diff --git a/Content/VRE/Level/Keyboard/SpecialKeyType.uasset b/Content/VRE/Level/Keyboard/SpecialKeyType.uasset new file mode 100644 index 0000000..c481253 --- /dev/null +++ b/Content/VRE/Level/Keyboard/SpecialKeyType.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c07e1ed35deb9ac19ca322384ff3d5a3a4d9cc3432188ae22244584126e1b402 +size 8721 diff --git a/Content/VRE/Level/Keyboard/TextKeyboardKey.uasset b/Content/VRE/Level/Keyboard/TextKeyboardKey.uasset new file mode 100644 index 0000000..34eabb1 --- /dev/null +++ b/Content/VRE/Level/Keyboard/TextKeyboardKey.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26a31e4ac534a8aded5536364121a35b45c62ce2f298ae3dc5b25605f2c2b856 +size 85254 diff --git a/Content/VRE/Level/Mirror/MirrorActor.uasset b/Content/VRE/Level/Mirror/MirrorActor.uasset new file mode 100644 index 0000000..b0dadf0 --- /dev/null +++ b/Content/VRE/Level/Mirror/MirrorActor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30054a1224d11629877aec1b8a038bf079abfc84b9bb5230901e8d48b0f95c27 +size 51272 diff --git a/Content/VRE/Level/Mirror/MirrorFeed.uasset b/Content/VRE/Level/Mirror/MirrorFeed.uasset new file mode 100644 index 0000000..9019636 --- /dev/null +++ b/Content/VRE/Level/Mirror/MirrorFeed.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3702ec3cb3cbf0a574e3253078c333a04dfdde1609ba81ef9faf6b8f9ab65fff +size 38762 diff --git a/Content/VRE/Level/Mirror/MirrorMat.uasset b/Content/VRE/Level/Mirror/MirrorMat.uasset new file mode 100644 index 0000000..0393cc4 --- /dev/null +++ b/Content/VRE/Level/Mirror/MirrorMat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b21a4b79201347ca5135e003c04995f1d1704275ae5ab2f9cb0d0e28e437375 +size 28408 diff --git a/Content/VRE/Level/Misc/ClimbWallActor.uasset b/Content/VRE/Level/Misc/ClimbWallActor.uasset new file mode 100644 index 0000000..e9f878c --- /dev/null +++ b/Content/VRE/Level/Misc/ClimbWallActor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce2739b0b9d3d45b096bcd07e52493d9f704075337f94d033dd7a0a037193325 +size 41320 diff --git a/Content/VRE/Level/Misc/ConsoleCommandSliderActor.uasset b/Content/VRE/Level/Misc/ConsoleCommandSliderActor.uasset new file mode 100644 index 0000000..97fc719 --- /dev/null +++ b/Content/VRE/Level/Misc/ConsoleCommandSliderActor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4a9fe524691dd02d2d6baed4b0c7193cbf24d84812493ddff6621c2cafcd5e3 +size 218357 diff --git a/Content/VRE/Level/Misc/Floor_StaticMesh.uasset b/Content/VRE/Level/Misc/Floor_StaticMesh.uasset new file mode 100644 index 0000000..e1316a2 --- /dev/null +++ b/Content/VRE/Level/Misc/Floor_StaticMesh.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1221e832c3e593122a34f1a2af1323ead3dd2c1c531ea7e76c086f00cba42c4 +size 15023 diff --git a/Content/VRE/Level/Misc/Rotator.uasset b/Content/VRE/Level/Misc/Rotator.uasset new file mode 100644 index 0000000..8ef4d2a --- /dev/null +++ b/Content/VRE/Level/Misc/Rotator.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1a73a922a3e8c6651a9338c16fb071fab3620521ee934e0d2ee5117d403aa1a1 +size 50905 diff --git a/Content/VRE/Level/OptionsMenu/OptionsMenu.uasset b/Content/VRE/Level/OptionsMenu/OptionsMenu.uasset new file mode 100644 index 0000000..f4c1ec0 --- /dev/null +++ b/Content/VRE/Level/OptionsMenu/OptionsMenu.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:139496f4ef272cb1d13084015f9b96287296a91246acc5cfa3f7b57cc92d0c78 +size 161477 diff --git a/Content/VRE/Level/OptionsMenu/OptionsMenuActor.uasset b/Content/VRE/Level/OptionsMenu/OptionsMenuActor.uasset new file mode 100644 index 0000000..7f052b2 --- /dev/null +++ b/Content/VRE/Level/OptionsMenu/OptionsMenuActor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:748e0fcff1e1e348dd08bd825b04f97aab7f3bf7299e2b5a140b55ab4b1e6c51 +size 23156 diff --git a/Content/VRE/Level/ServerMenu/3DMenu.uasset b/Content/VRE/Level/ServerMenu/3DMenu.uasset new file mode 100644 index 0000000..7b7bd50 --- /dev/null +++ b/Content/VRE/Level/ServerMenu/3DMenu.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:71e8e33ea948f9b6ef3b99cef1e3e0ce2377d19bce9953abb1094adb51cc9327 +size 276488 diff --git a/Content/VRE/Level/ServerMenu/3DMenuActor.uasset b/Content/VRE/Level/ServerMenu/3DMenuActor.uasset new file mode 100644 index 0000000..590c8a3 --- /dev/null +++ b/Content/VRE/Level/ServerMenu/3DMenuActor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d48fd0a8a60b6dfa0aa072bc57d190f423ce1501139ab5d97e66f44372b96ea2 +size 23395 diff --git a/Content/VRE/Level/ServerMenu/ServerInfo.uasset b/Content/VRE/Level/ServerMenu/ServerInfo.uasset new file mode 100644 index 0000000..d37c5d7 --- /dev/null +++ b/Content/VRE/Level/ServerMenu/ServerInfo.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:142cb376e836f3b6ebd3da84ca963e2e2400beac1e1532e773b6e23eb5790879 +size 77987 diff --git a/Content/VRE/Level/WallWalking/WallWalkingMat.uasset b/Content/VRE/Level/WallWalking/WallWalkingMat.uasset new file mode 100644 index 0000000..b7ffd3f --- /dev/null +++ b/Content/VRE/Level/WallWalking/WallWalkingMat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b4d1001ff45b75964b0cbe3ae97e457a70e01aa5da965b0abbbe0d3358eb08d +size 8963 diff --git a/Content/VRE/Level/WallWalking/WallWalkingRamp.uasset b/Content/VRE/Level/WallWalking/WallWalkingRamp.uasset new file mode 100644 index 0000000..f3dddf0 --- /dev/null +++ b/Content/VRE/Level/WallWalking/WallWalkingRamp.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:607f2e7b5e5e574c7c9701289fd283466a381affa1bf40c2eea16ce6ff418cfb +size 22517 diff --git a/Content/VRE/Level/WallWalking/WallWalkingVolume.uasset b/Content/VRE/Level/WallWalking/WallWalkingVolume.uasset new file mode 100644 index 0000000..1be9b61 --- /dev/null +++ b/Content/VRE/Level/WallWalking/WallWalkingVolume.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60b46b6b8e21d6860ba5bedb096c1d2fc608d4529e4739cbba0fb0c4472bdd9a +size 62508 diff --git a/Content/VRE/Level/WallWalking/WallWalkingWall.uasset b/Content/VRE/Level/WallWalking/WallWalkingWall.uasset new file mode 100644 index 0000000..6f7f212 --- /dev/null +++ b/Content/VRE/Level/WallWalking/WallWalkingWall.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e1089fee314fe843d0c9edb06f4de9c886147412063dff81505580e012b3d5d8 +size 14964 diff --git a/Content/VRE/Misc/Meshes/1M_Cube.uasset b/Content/VRE/Misc/Meshes/1M_Cube.uasset new file mode 100644 index 0000000..2895a52 --- /dev/null +++ b/Content/VRE/Misc/Meshes/1M_Cube.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ec84195d01bfbac3fc8b0ab497c0c33fc6bae4254b91cec65d8a4e6e1904989 +size 15666 diff --git a/Content/VRE/Misc/Meshes/1M_Cube_Chamfer.uasset b/Content/VRE/Misc/Meshes/1M_Cube_Chamfer.uasset new file mode 100644 index 0000000..5ec7c86 --- /dev/null +++ b/Content/VRE/Misc/Meshes/1M_Cube_Chamfer.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1126f5d84f073db0a0b171757f6c82d6cc5535e48e762ba9f88328f73168a1bf +size 89045 diff --git a/Content/VRE/Misc/Meshes/CubeMaterial.uasset b/Content/VRE/Misc/Meshes/CubeMaterial.uasset new file mode 100644 index 0000000..67f9fa5 --- /dev/null +++ b/Content/VRE/Misc/Meshes/CubeMaterial.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afb6e4332e8e6adbc6371511f9e464e91c9b866368fcb07e076e510da8dd5465 +size 93059 diff --git a/Content/VRE/Misc/Meshes/TemplateFloor.uasset b/Content/VRE/Misc/Meshes/TemplateFloor.uasset new file mode 100644 index 0000000..21c8e48 --- /dev/null +++ b/Content/VRE/Misc/Meshes/TemplateFloor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:deffbbd85fa4b8b5744f2f4dc1db5921e1993716acfcc1c1f18ab37d8a5bb49a +size 95181 diff --git a/Content/VRE/Misc/PostProcess/PP_StereoTexture.uasset b/Content/VRE/Misc/PostProcess/PP_StereoTexture.uasset new file mode 100644 index 0000000..a297522 --- /dev/null +++ b/Content/VRE/Misc/PostProcess/PP_StereoTexture.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eafc13b2fd952c0ee10ea95a98a6e718d3ac9cb25992560a3395ee4f8c812191 +size 79674 diff --git a/Plugins/AdvancedSessions/AdvancedSessions.uplugin b/Plugins/AdvancedSessions/AdvancedSessions.uplugin new file mode 100644 index 0000000..7dc2e3a --- /dev/null +++ b/Plugins/AdvancedSessions/AdvancedSessions.uplugin @@ -0,0 +1,34 @@ +{ + "FileVersion": 3, + "FriendlyName": "Advanced Sessions", + "Version": 5.4, + "VersionName": "5.4", + "Description": "Adds new blueprint functions to handle more advanced session operations.", + "Category": "Advanced Sessions Plugin", + "CreatedBy": "Joshua Statzer", + "CreatedByURL": "N/A", + "Modules": [ + { + "Name": "AdvancedSessions", + "Type": "Runtime", + "LoadingPhase": "PreDefault" + } + ], + "Plugins": [ + { + "Name": "OnlineSubsystem", + "Enabled": true + }, + { + "Name": "OnlineSubsystemUtils", + "Enabled": true + } + ], + "DocsURL": "", + "MarketplaceURL": "", + "SupportURL": "", + "CanContainContent": false, + "IsBetaVersion": false, + "IsExperimentalVersion": false, + "Installed": false +} \ No newline at end of file diff --git a/Plugins/AdvancedSessions/Config/FilterPlugin.ini b/Plugins/AdvancedSessions/Config/FilterPlugin.ini new file mode 100644 index 0000000..ccebca2 --- /dev/null +++ b/Plugins/AdvancedSessions/Config/FilterPlugin.ini @@ -0,0 +1,8 @@ +[FilterPlugin] +; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and +; may include "...", "*", and "?" wildcards to match directories, files, and individual characters respectively. +; +; Examples: +; /README.txt +; /Extras/... +; /Binaries/ThirdParty/*.dll diff --git a/Plugins/AdvancedSessions/Resources/Icon128.png b/Plugins/AdvancedSessions/Resources/Icon128.png new file mode 100644 index 0000000..bc2b90d --- /dev/null +++ b/Plugins/AdvancedSessions/Resources/Icon128.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a4c9fd3d85a99b80d3008e8c9ede55943cc16b79a382a8200b3fa4883d5468b +size 3371 diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/AdvancedSessions.Build.cs b/Plugins/AdvancedSessions/Source/AdvancedSessions/AdvancedSessions.Build.cs new file mode 100644 index 0000000..a305151 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/AdvancedSessions.Build.cs @@ -0,0 +1,17 @@ +using UnrealBuildTool; +using System.IO; + +public class AdvancedSessions : ModuleRules +{ + public AdvancedSessions(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; + //bEnforceIWYU = true; + + PublicDefinitions.Add("WITH_ADVANCED_SESSIONS=1"); + + // PrivateIncludePaths.AddRange(new string[] { "AdvancedSessions/Private"/*, "OnlineSubsystemSteam/Private"*/ }); + // PublicIncludePaths.AddRange(new string[] { "AdvancedSessions/Public" }); + PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "OnlineSubsystem", "CoreUObject", "OnlineSubsystemUtils", "Networking", "Sockets"/*"Voice", "OnlineSubsystemSteam"*/ }); + } +} \ No newline at end of file diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedExternalUILibrary.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedExternalUILibrary.h new file mode 100644 index 0000000..6153ed3 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedExternalUILibrary.h @@ -0,0 +1,63 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "BlueprintDataDefinitions.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "Online.h" +#include "Engine/LocalPlayer.h" +#include "OnlineSubsystem.h" +#include "BlueprintDataDefinitions.h" +//#include "OnlineFriendsInterface.h" +//#include "OnlineUserInterface.h" +//#include "OnlineMessageInterface.h" +//#include "OnlinePresenceInterface.h" +//#include "Engine/GameInstance.h" +#include "Interfaces/OnlineSessionInterface.h" + +//#include "UObjectIterator.h" + +#include "AdvancedExternalUILibrary.generated.h" + + +//General Advanced Sessions Log +DECLARE_LOG_CATEGORY_EXTERN(AdvancedExternalUILog, Log, All); + +UCLASS() +class UAdvancedExternalUILibrary : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() +public: + + //********* External UI Functions *************// + + // Show the UI that handles the Friends list + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedExternalUI", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject")) + static void ShowFriendsUI(UObject* WorldContextObject, APlayerController *PlayerController, EBlueprintResultSwitch &Result); + + // Show the UI that handles inviting people to your game + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedExternalUI", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject")) + static void ShowInviteUI(UObject* WorldContextObject, APlayerController *PlayerController, EBlueprintResultSwitch &Result); + + // Show the UI that shows the leaderboard (doesn't work with steam) + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedExternalUI", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject")) + static void ShowLeaderBoardUI(UObject* WorldContextObject, FString LeaderboardName, EBlueprintResultSwitch &Result); + + // Show the UI that shows a web URL + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedExternalUI", meta = (ExpandEnumAsExecs = "Result", AutoCreateRefTerm = "AllowedDomains", WorldContext = "WorldContextObject")) + static void ShowWebURLUI(UObject* WorldContextObject, FString URLToShow, EBlueprintResultSwitch &Result, TArray& AllowedDomains, bool bEmbedded = false , bool bShowBackground = false, bool bShowCloseButton = false, int32 OffsetX = 0, int32 OffsetY = 0, int32 SizeX = 0, int32 SizeY = 0); + + // Show the UI that shows a web URL + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedExternalUI", meta = (WorldContext = "WorldContextObject")) + static void CloseWebURLUI(UObject* WorldContextObject); + + + // Show the UI that shows the profile of a uniquenetid + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedExternalUI", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject")) + static void ShowProfileUI(UObject* WorldContextObject, const FBPUniqueNetId PlayerViewingProfile, const FBPUniqueNetId PlayerToViewProfileOf, EBlueprintResultSwitch &Result); + + // Show the UI that shows the account upgrade UI (doesn't work with steam) + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedExternalUI", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject")) + static void ShowAccountUpgradeUI(UObject* WorldContextObject, const FBPUniqueNetId PlayerRequestingAccountUpgradeUI, EBlueprintResultSwitch &Result); + +}; diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedFriendsGameInstance.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedFriendsGameInstance.h new file mode 100644 index 0000000..29d5018 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedFriendsGameInstance.h @@ -0,0 +1,152 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "Engine/Engine.h" +#include "BlueprintDataDefinitions.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "Online.h" +#include "OnlineSubsystem.h" +#include "Interfaces/OnlineFriendsInterface.h" +#include "Interfaces/OnlineUserInterface.h" +#include "Interfaces/OnlineMessageInterface.h" +#include "Interfaces/OnlinePresenceInterface.h" +#include "Engine/GameInstance.h" +#include "Engine/LocalPlayer.h" +#include "Interfaces/OnlineSessionInterface.h" +#include "OnlineSessionSettings.h" +#include "UObject/UObjectIterator.h" +#include "AdvancedFriendsInterface.h" + +#include "AdvancedFriendsGameInstance.generated.h" + + +//General Advanced Sessions Log +DECLARE_LOG_CATEGORY_EXTERN(AdvancedFriendsInterfaceLog, Log, All); + +UCLASS() +class ADVANCEDSESSIONS_API UAdvancedFriendsGameInstance : public UGameInstance +{ + GENERATED_BODY() +public: + + UAdvancedFriendsGameInstance(const FObjectInitializer& ObjectInitializer); + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AdvancedFriendsInterface) + bool bCallFriendInterfaceEventsOnPlayerControllers; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AdvancedFriendsInterface) + bool bCallIdentityInterfaceEventsOnPlayerControllers; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AdvancedFriendsInterface) + bool bCallVoiceInterfaceEventsOnPlayerControllers; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AdvancedVoiceInterface) + bool bEnableTalkingStatusDelegate; + + //virtual void PostLoad() override; + virtual void Shutdown() override; + virtual void Init() override; + + //*** Session invite received by local ***// + FOnSessionInviteReceivedDelegate SessionInviteReceivedDelegate; + FDelegateHandle SessionInviteReceivedDelegateHandle; + + // custom handle to join directly from steam ui "Join Game" + FDelegateHandle OnJoinSessionCompleteDelegateHandle; + // custom Steam UI Join User function #Self invite# + void OnSessionUserInviteAccepted(const bool bWasSuccessful, const int32 ControllerId, FUniqueNetIdPtr UserId, const FOnlineSessionSearchResult& InviteResult); + // custom Steam UI function to client travel #Self invite# + void OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result); + + //const FUniqueNetId& /*UserId*/, const FUniqueNetId& /*FromId*/, const FString& /*AppId*/, const FOnlineSessionSearchResult& /*InviteResult*/ + void OnSessionInviteReceivedMaster(const FUniqueNetId & PersonInvited, const FUniqueNetId & PersonInviting, const FString & AppId, const FOnlineSessionSearchResult& SessionToJoin); + + // After a session invite has been accepted by the local player this event is triggered, call JoinSession on the session result to join it + UFUNCTION(BlueprintImplementableEvent, Category = "AdvancedFriends") + void OnSessionInviteReceived(int32 LocalPlayerNum, FBPUniqueNetId PersonInviting, const FString& AppId, const FBlueprintSessionResult& SessionToJoin); + + //*** Session invite accepted by local ***// + FOnSessionUserInviteAcceptedDelegate SessionInviteAcceptedDelegate; + FDelegateHandle SessionInviteAcceptedDelegateHandle; + + void OnSessionInviteAcceptedMaster(const bool bWasSuccessful, int32 LocalPlayer, TSharedPtr PersonInviting, const FOnlineSessionSearchResult& SessionToJoin); + + // After a session invite has been accepted by the local player this event is triggered, call JoinSession on the session result to join it + // This function is currently not hooked up in any of Epics default subsystems, it is here for custom subsystems + UFUNCTION(BlueprintImplementableEvent, Category = "AdvancedFriends") + void OnSessionInviteAccepted(int32 LocalPlayerNum, FBPUniqueNetId PersonInvited, const FBlueprintSessionResult& SessionToJoin); + + + // After a voice status has changed this event is triggered if the bEnableTalkingStatusDelegate property is true + UFUNCTION(BlueprintImplementableEvent, Category = "AdvancedVoice") + void OnPlayerTalkingStateChanged(FBPUniqueNetId PlayerId, bool bIsTalking); + + void OnPlayerTalkingStateChangedMaster(TSharedRef PlayerId, bool bIsTalking); + + FOnPlayerTalkingStateChangedDelegate PlayerTalkingStateChangedDelegate; + FDelegateHandle PlayerTalkingStateChangedDelegateHandle; + + + // Called when the designated LocalUser has changed login state + UFUNCTION(BlueprintImplementableEvent , Category = "AdvancedIdentity", meta = (DisplayName = "OnPlayerLoginChanged")) + void OnPlayerLoginChanged(int32 PlayerNum); + + void OnPlayerLoginChangedMaster(int32 PlayerNum); + FOnLoginChangedDelegate PlayerLoginChangedDelegate; + FDelegateHandle PlayerLoginChangedDelegateHandle; + + // Called when the designated LocalUser has changed login status + UFUNCTION(BlueprintImplementableEvent, Category = "AdvancedIdentity", meta = (DisplayName = "OnPlayerLoginStatusChanged")) + void OnPlayerLoginStatusChanged(int32 PlayerNum, EBPLoginStatus PreviousStatus, EBPLoginStatus NewStatus, FBPUniqueNetId NewPlayerUniqueNetID); + + void OnPlayerLoginStatusChangedMaster(int32 PlayerNum, ELoginStatus::Type PreviousStatus, ELoginStatus::Type NewStatus, const FUniqueNetId & NewPlayerUniqueNetID); + FOnLoginStatusChangedDelegate PlayerLoginStatusChangedDelegate; + FDelegateHandle PlayerLoginStatusChangedDelegateHandle; + + + //*** Session Invite Received From Friend ***// + // REMOVED BECAUSE IT NEVER GETS CALLED + /*FOnSessionInviteReceivedDelegate SessionInviteReceivedDelegate; + FDelegateHandle SessionInviteReceivedDelegateHandle; + + void OnSessionInviteReceivedMaster(const FUniqueNetId &InvitedPlayer, const FUniqueNetId &FriendInviting, const FOnlineSessionSearchResult& Session); + + // After a session invite has been sent from a friend this event is triggered, call JoinSession on the session result to join it + UFUNCTION(BlueprintImplementableEvent, Category = "AdvancedFriends") + void OnSessionInviteReceived(const FBPUniqueNetId &InvitedPlayer, const FBPUniqueNetId &FriendInviting, const FBlueprintSessionResult &Session); + */ + + //*** Friend Invite Accepted ***// + /*FOnInviteAcceptedDelegate FriendInviteAcceptedDelegate; + FDelegateHandle FriendInviteAcceptedDelegateHandle; + + void OnFriendInviteAcceptedDelegateMaster(const FUniqueNetId& LocalPlayer, const FUniqueNetId &PlayerInvited); + + // After a session invite has been accepted by a friend this event is triggered + UFUNCTION(BlueprintImplementableEvent, Category = "AdvancedFriends") + void OnFriendInviteAccepted(const FBPUniqueNetId &InvitedPlayer, const FBPUniqueNetId &PlayerInvited); + */ + + //*** Friend Invite Rejected ***// + /*FOnInviteRejectedDelegate SessionInviteRejectedByFriendDelegate; + FDelegateHandle InviteRejectedByFriendDelegateHandle; + + void OnFriendInviteRejectedDelegateMaster(const FUniqueNetId& LocalPlayer, const FUniqueNetId &PlayerDeclined); + + // After a friend invite has been rejected this event is triggered + UFUNCTION(BlueprintImplementableEvent, Category = "AdvancedFriends") + void OnFriendInviteRejected(const FBPUniqueNetId &InvitedPlayer, const FBPUniqueNetId &PlayerDeclined); + */ + + //*** Removed By Friend ***// + /*FOnFriendRemovedDelegate RemovedByFriendDelegate; + FDelegateHandle RemovedByFriendDelegateHandle; + + void OnRemovedByFriendDelegateMaster(const FUniqueNetId& LocalPlayer, const FUniqueNetId &FriendRemoved); + + // After a friend removed the player this event is triggered + UFUNCTION(BlueprintImplementableEvent, Category = "AdvancedFriends") + void OnRemovedByFriend(const FBPUniqueNetId &InvitedPlayer, const FBPUniqueNetId &FriendRemoved);*/ +}; + diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedFriendsInterface.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedFriendsInterface.h new file mode 100644 index 0000000..44cfc0b --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedFriendsInterface.h @@ -0,0 +1,56 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "Online.h" +#include "OnlineSubsystem.h" +#include "Interfaces/OnlineFriendsInterface.h" +#include "Interfaces/OnlineUserInterface.h" +#include "Interfaces/OnlineMessageInterface.h" +#include "Interfaces/OnlinePresenceInterface.h" +#include "Engine/GameInstance.h" +#include "Interfaces/OnlineSessionInterface.h" +#include "OnlineSessionSettings.h" +#include "UObject/UObjectIterator.h" +#include "BlueprintDataDefinitions.h" +#include "AdvancedFriendsInterface.generated.h" + + +UINTERFACE(MinimalAPI) +class UAdvancedFriendsInterface : public UInterface +{ + GENERATED_UINTERFACE_BODY() +}; + +class IAdvancedFriendsInterface +{ + GENERATED_IINTERFACE_BODY() +public: + + // Called when the designated LocalUser has accepted a session invite, use JoinSession on result to connect + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "OnSessionInviteReceived")) + void OnSessionInviteReceived(FBPUniqueNetId PersonInviting, const FBlueprintSessionResult& SearchResult); + + // Called when the designated LocalUser has accepted a session invite, use JoinSession on result to connect + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "OnSessionInviteAccepted")) + void OnSessionInviteAccepted(FBPUniqueNetId PersonInvited, const FBlueprintSessionResult& SearchResult); + + // Called when the designated LocalUser has accepted a session invite, use JoinSession on result to connect + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "OnPlayerVoiceStateChanged")) + void OnPlayerVoiceStateChanged(FBPUniqueNetId PlayerId, bool bIsTalking); + + // Called when the designated LocalUser has changed login state + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "OnPlayerLoginChanged")) + void OnPlayerLoginChanged(int32 PlayerNum); + + // Called when the designated LocalUser has changed login state + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "OnPlayerLoginStatusChanged")) + void OnPlayerLoginStatusChanged(EBPLoginStatus PreviousStatus, EBPLoginStatus NewStatus, FBPUniqueNetId PlayerUniqueNetID); + + // REMOVED BECAUSE IT WAS NEVER BEING CALLED + // Called when the designated LocalUser has received a session invite, use JoinSession on result to connect + //UFUNCTION(BlueprintImplementableEvent, meta = (FriendlyName = "OnSessionInviteReceived")) + //void OnSessionInviteReceived(const FBPUniqueNetId &FriendInviting, const FBlueprintSessionResult &Session); + +}; diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedFriendsLibrary.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedFriendsLibrary.h new file mode 100644 index 0000000..fedf2c1 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedFriendsLibrary.h @@ -0,0 +1,56 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "BlueprintDataDefinitions.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "Online.h" +#include "Engine/LocalPlayer.h" +#include "OnlineSubsystem.h" +#include "Interfaces/OnlineFriendsInterface.h" +#include "Interfaces/OnlineUserInterface.h" +#include "Interfaces/OnlineMessageInterface.h" +#include "Interfaces/OnlinePresenceInterface.h" +#include "Engine/GameInstance.h" +#include "Interfaces/OnlineSessionInterface.h" + +#include "UObject/UObjectIterator.h" + +#include "AdvancedFriendsLibrary.generated.h" + + +//General Advanced Sessions Log +DECLARE_LOG_CATEGORY_EXTERN(AdvancedFriendsLog, Log, All); + +UCLASS() +class UAdvancedFriendsLibrary : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() +public: + + //********* Friend List Functions *************// + + // Sends an Invite to the current online session to a list of friends + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|FriendsList", meta = (ExpandEnumAsExecs = "Result")) + static void SendSessionInviteToFriends(APlayerController *PlayerController, const TArray &Friends, EBlueprintResultSwitch &Result); + + // Sends an Invite to the current online session to a friend + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|FriendsList", meta = (ExpandEnumAsExecs = "Result")) + static void SendSessionInviteToFriend(APlayerController *PlayerController, const FBPUniqueNetId &FriendUniqueNetId, EBlueprintResultSwitch &Result); + + // Get a friend from the previously read/saved friends list (Must Call GetFriends first for this to return anything) + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|FriendsList") + static void GetFriend(APlayerController *PlayerController, const FBPUniqueNetId FriendUniqueNetId, FBPFriendInfo &Friend); + + // Get the previously read/saved friends list (Must Call GetFriends first for this to return anything) + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|FriendsList") + static void GetStoredFriendsList(APlayerController *PlayerController, TArray &FriendsList); + + // Get the previously read/saved recent players list (Must Call GetRecentPlayers first for this to return anything) + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|RecentPlayersList") + static void GetStoredRecentPlayersList(FBPUniqueNetId UniqueNetId, TArray &PlayersList); + + // Check if a UniqueNetId is a friend + UFUNCTION(BlueprintPure, Category = "Online|AdvancedFriends|FriendsList") + static void IsAFriend(APlayerController *PlayerController, const FBPUniqueNetId UniqueNetId, bool &IsFriend); +}; diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedGameSession.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedGameSession.h new file mode 100644 index 0000000..179d857 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedGameSession.h @@ -0,0 +1,71 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "Engine/Engine.h" +#include "Online.h" +#include "OnlineSubsystem.h" +#include "Engine/GameInstance.h" +#include "GameFramework/GameModeBase.h" +#include "GameFramework/GameSession.h" +#include "GameFramework/PlayerState.h" + +//#include "UObjectIterator.h" + +#include "AdvancedGameSession.generated.h" + + + + +/** + A quick wrapper around the game session to add a partial ban implementation. Just bans for the duration of the current session +*/ +UCLASS(config = Game, notplaceable) +class AAdvancedGameSession : public AGameSession +{ + GENERATED_UCLASS_BODY() + +public: + + UPROPERTY(Transient) + TMap BanList; + + virtual bool BanPlayer(class APlayerController* BannedPlayer, const FText& BanReason) + { + + if (APlayerState* PlayerState = (BannedPlayer != NULL) ? BannedPlayer->PlayerState : NULL) + { + FUniqueNetIdRepl UniqueNetID = PlayerState->GetUniqueId(); + bool bWasKicked = KickPlayer(BannedPlayer, BanReason); + + if (bWasKicked) + { + BanList.Add(UniqueNetID, BanReason); + } + + return bWasKicked; + } + + return false; + } + + // This should really be handled in the game mode asking game session, but I didn't want to force a custom game session AND game mode + // If done in the game mode, we could check prior to actually spooling up any player information in ApproveLogin + virtual void PostLogin(APlayerController* NewPlayer) override + { + if (APlayerState* PlayerState = (NewPlayer != NULL) ? NewPlayer->PlayerState : NULL) + { + FUniqueNetIdRepl UniqueNetID = PlayerState->GetUniqueId(); + + if (BanList.Contains(UniqueNetID)) + { + KickPlayer(NewPlayer, BanList[UniqueNetID]); + } + } + } +}; + +AAdvancedGameSession::AAdvancedGameSession(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ +} \ No newline at end of file diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedIdentityLibrary.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedIdentityLibrary.h new file mode 100644 index 0000000..5f0dc15 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedIdentityLibrary.h @@ -0,0 +1,81 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "BlueprintDataDefinitions.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "Online.h" +#include "OnlineSubsystem.h" +#include "Interfaces/OnlineIdentityInterface.h" +#include "Interfaces/OnlineUserInterface.h" +#include "Interfaces/OnlinePresenceInterface.h" +#include "Engine/GameInstance.h" +#include "Engine/LocalPlayer.h" + +#include "UObject/UObjectIterator.h" + +#include "AdvancedIdentityLibrary.generated.h" + + +//General Advanced Sessions Log +DECLARE_LOG_CATEGORY_EXTERN(AdvancedIdentityLog, Log, All); + +UCLASS() +class UAdvancedIdentityLibrary : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() +public: + //********* Identity Functions *************// + + // Get the login status of a local player + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedIdentity", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject")) + static void GetLoginStatus(UObject* WorldContextObject, const FBPUniqueNetId & UniqueNetID, EBPLoginStatus & LoginStatus, EBlueprintResultSwitch &Result); + + // Get the auth token for a local player + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedIdentity", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject")) + static void GetPlayerAuthToken(UObject* WorldContextObject, APlayerController * PlayerController, FString & AuthToken, EBlueprintResultSwitch &Result); + + // Get a players nickname + UFUNCTION(BlueprintPure, Category = "Online|AdvancedIdentity", meta = (WorldContext = "WorldContextObject")) + static void GetPlayerNickname(UObject* WorldContextObject, const FBPUniqueNetId & UniqueNetID, FString & PlayerNickname); + + //********* User Account Functions *************// + + // Get a users account + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedIdentity|UserAccount", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject")) + static void GetUserAccount(UObject* WorldContextObject, const FBPUniqueNetId & UniqueNetId, FBPUserOnlineAccount & AccountInfo, EBlueprintResultSwitch &Result); + + // Get all known users accounts + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedIdentity|UserAccount", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject")) + static void GetAllUserAccounts(UObject* WorldContextObject, TArray & AccountInfos, EBlueprintResultSwitch &Result); + + // Get a user account access token + UFUNCTION(BlueprintPure, Category = "Online|AdvancedIdentity|UserAccount") + static void GetUserAccountAccessToken(const FBPUserOnlineAccount & AccountInfo, FString & AccessToken); + + // Get a user account Auth attribute (depends on subsystem) + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedIdentity|UserAccount", meta = (ExpandEnumAsExecs = "Result")) + static void GetUserAccountAuthAttribute(const FBPUserOnlineAccount & AccountInfo, const FString & AttributeName, FString & AuthAttribute, EBlueprintResultSwitch &Result); + + // Set a user account attribute (depends on subsystem) + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedIdentity|UserAccount", meta = (ExpandEnumAsExecs = "Result")) + static void SetUserAccountAttribute(const FBPUserOnlineAccount & AccountInfo, const FString & AttributeName, const FString & NewAttributeValue, EBlueprintResultSwitch &Result); + + // Get user ID + UFUNCTION(BlueprintPure, Category = "Online|AdvancedIdentity|UserAccount") + static void GetUserID(const FBPUserOnlineAccount & AccountInfo, FBPUniqueNetId & UniqueNetID); + + // Get user accounts real name if possible + UFUNCTION(BlueprintPure, Category = "Online|AdvancedIdentity|UserAccount") + static void GetUserAccountRealName(const FBPUserOnlineAccount & AccountInfo, FString & UserName); + + // Get user account display name if possible + UFUNCTION(BlueprintPure, Category = "Online|AdvancedIdentity|UserAccount") + static void GetUserAccountDisplayName(const FBPUserOnlineAccount & AccountInfo, FString & DisplayName); + + // Get user account attribute (depends on subsystem) + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedIdentity|UserAccount", meta = (ExpandEnumAsExecs = "Result")) + static void GetUserAccountAttribute(const FBPUserOnlineAccount & AccountInfo, const FString & AttributeName, FString & AttributeValue, EBlueprintResultSwitch &Result); + + +}; diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedSessions.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedSessions.h new file mode 100644 index 0000000..6218cd0 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedSessions.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Modules/ModuleManager.h" + +class AdvancedSessions : public IModuleInterface +{ +public: + /** IModuleInterface implementation */ + void StartupModule(); + void ShutdownModule(); +}; \ No newline at end of file diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedSessionsLibrary.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedSessionsLibrary.h new file mode 100644 index 0000000..457bcdd --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedSessionsLibrary.h @@ -0,0 +1,213 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "Engine/Engine.h" +#include "BlueprintDataDefinitions.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "Online.h" +#include "OnlineSubsystem.h" +#include "Interfaces/OnlineFriendsInterface.h" +#include "Interfaces/OnlineUserInterface.h" +#include "Interfaces/OnlineMessageInterface.h" +#include "Interfaces/OnlinePresenceInterface.h" +#include "Engine/GameInstance.h" +#include "Interfaces/OnlineSessionInterface.h" + +#include "GameFramework/GameModeBase.h" +#include "GameFramework/GameSession.h" + +//#include "UObjectIterator.h" + +#include "AdvancedSessionsLibrary.generated.h" + + +//General Advanced Sessions Log +DECLARE_LOG_CATEGORY_EXTERN(AdvancedSessionsLog, Log, All); + + +UCLASS() +class UAdvancedSessionsLibrary : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() +public: + //********* Session Admin Functions *************// + + // Kick a player from the currently active game session, only available on the server + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions", meta = (WorldContext = "WorldContextObject")) + static bool KickPlayer(UObject* WorldContextObject, APlayerController* PlayerToKick, FText KickReason); + + // Ban a player from the currently active game session, only available on the server + // Note that the default gamesession class does not implement an actual ban list and just kicks when this is called + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions", meta = (WorldContext = "WorldContextObject")) + static bool BanPlayer(UObject* WorldContextObject, APlayerController* PlayerToBan, FText BanReason); + + //********* Session Search Functions *************// + + // Adds or modifies session settings in an existing array depending on if they exist already or not + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo") + static void AddOrModifyExtraSettings(UPARAM(ref) TArray & SettingsArray, UPARAM(ref) TArray & NewOrChangedSettings, TArray & ModifiedSettingsArray); + + // Get an array of the session settings from a session search result + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo") + static void GetExtraSettings(FBlueprintSessionResult SessionResult, TArray & ExtraSettings); + + // Get the current session state + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (WorldContext = "WorldContextObject")) + static void GetSessionState(UObject* WorldContextObject, EBPOnlineSessionState &SessionState); + + // Get the current session settings + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject")) + static void GetSessionSettings(UObject* WorldContextObject, int32 &NumConnections, int32 &NumPrivateConnections, bool &bIsLAN, bool &bIsDedicated, bool &bAllowInvites, bool &bAllowJoinInProgress, bool &bIsAnticheatEnabled, int32 &BuildUniqueID, TArray &ExtraSettings, EBlueprintResultSwitch &Result); + + // Check if someone is in the current session + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (WorldContext = "WorldContextObject")) + static void IsPlayerInSession(UObject* WorldContextObject, const FBPUniqueNetId &PlayerToCheck, bool &bIsInSession); + + // Make a literal session search parameter + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo|Literals") + static FSessionsSearchSetting MakeLiteralSessionSearchProperty(FSessionPropertyKeyPair SessionSearchProperty, EOnlineComparisonOpRedux ComparisonOp); + + + //********* Session Information Functions ***********// + + // Check if a session result is valid or not + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo") + static bool IsValidSession(const FBlueprintSessionResult & SessionResult); + + // Get a string copy of a session ID + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo") + static void GetSessionID_AsString(const FBlueprintSessionResult & SessionResult, FString& SessionID); + + // Get a string copy of the current session ID + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo", meta = (WorldContext = "WorldContextObject")) + static void GetCurrentSessionID_AsString(UObject* WorldContextObject, FString& SessionID); + + // Get the Unique Current Build ID + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo") + static void GetCurrentUniqueBuildID(int32 &UniqueBuildId); + + // Get the Unique Build ID from a session search result + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo") + static void GetUniqueBuildID(FBlueprintSessionResult SessionResult, int32 &UniqueBuildId); + + + // Thanks CriErr for submission + + + // Get session property Key Name value + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo") + static FName GetSessionPropertyKey(const FSessionPropertyKeyPair& SessionProperty); + + // Find session property by Name + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "Result")) + static void FindSessionPropertyByName(const TArray& ExtraSettings, FName SettingsName, EBlueprintResultSwitch &Result, FSessionPropertyKeyPair& OutProperty); + + // Find session property index by Name + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "Result")) + static void FindSessionPropertyIndexByName(const TArray& ExtraSettings, FName SettingName, EBlueprintResultSwitch &Result, int32& OutIndex); + + /// Removed the Index_None part of the last function, that isn't accessible in blueprint, better to return success/failure + // End Thanks CriErr :p + + // Get session custom information key/value as Byte (For Enums) + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "SearchResult")) + static void GetSessionPropertyByte(const TArray & ExtraSettings, FName SettingName, ESessionSettingSearchResult &SearchResult, uint8 &SettingValue); + + // Get session custom information key/value as Bool + // Steam only currently supports Int,Float,String,BYTE values for search filtering!!! + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "SearchResult")) + static void GetSessionPropertyBool(const TArray & ExtraSettings, FName SettingName, ESessionSettingSearchResult &SearchResult, bool &SettingValue); + + // Get session custom information key/value as String + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "SearchResult")) + static void GetSessionPropertyString(const TArray & ExtraSettings, FName SettingName, ESessionSettingSearchResult &SearchResult, FString &SettingValue); + + // Get session custom information key/value as Int + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "SearchResult")) + static void GetSessionPropertyInt(const TArray & ExtraSettings, FName SettingName, ESessionSettingSearchResult &SearchResult, int32 &SettingValue); + + // Get session custom information key/value as Float + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "SearchResult")) + static void GetSessionPropertyFloat(const TArray & ExtraSettings, FName SettingName, ESessionSettingSearchResult &SearchResult, float &SettingValue); + + + // Make a literal session custom information key/value pair from Byte (For Enums) + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo|Literals") + static FSessionPropertyKeyPair MakeLiteralSessionPropertyByte(FName Key, uint8 Value); + + // Make a literal session custom information key/value pair from Bool + // Steam only currently supports Int,Float,String,BYTE values for search filtering! + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo|Literals") + static FSessionPropertyKeyPair MakeLiteralSessionPropertyBool(FName Key, bool Value); + + // Make a literal session custom information key/value pair from String + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo|Literals") + static FSessionPropertyKeyPair MakeLiteralSessionPropertyString(FName Key, FString Value); + + // Make a literal session custom information key/value pair from Int + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo|Literals") + static FSessionPropertyKeyPair MakeLiteralSessionPropertyInt(FName Key, int32 Value); + + // Make a literal session custom information key/value pair from Float + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo|Literals") + static FSessionPropertyKeyPair MakeLiteralSessionPropertyFloat(FName Key, float Value); + + + //******* Player ID functions *********// + + // Get the unique net id of a network player attached to the given controller + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|PlayerInfo|PlayerID") + static void GetUniqueNetID(APlayerController *PlayerController, FBPUniqueNetId &UniqueNetId); + + // Get the unique net id of a network player who is assigned the the given player state + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|PlayerInfo|PlayerID") + static void GetUniqueNetIDFromPlayerState(APlayerState *PlayerState, FBPUniqueNetId &UniqueNetId); + + // Return True if Unique Net ID is valid + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|PlayerInfo|PlayerID") + static bool IsValidUniqueNetID(const FBPUniqueNetId &UniqueNetId); + + /* Returns true if the values are equal (A == B) */ + UFUNCTION(BlueprintPure, meta = (DisplayName = "Equal Unique Net ID", CompactNodeTitle = "==", Keywords = "== equal"), Category = "Online|AdvancedSessions|PlayerInfo|PlayerID") + static bool EqualEqual_UNetIDUnetID(const FBPUniqueNetId &A, const FBPUniqueNetId &B); + + /** Converts a FBPUniqueNetID into a FUniqueNetID_Repl */ + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToUniqueNetIDRepl (Unique Net ID)", CompactNodeTitle = "->", BlueprintAutocast), Category = "Online|AdvancedSessions|PlayerInfo|PlayerID") + static FUniqueNetIdRepl Conv_BPUniqueIDToUniqueNetIDRepl(const FBPUniqueNetId& InUniqueID); + + // Check if a UniqueNetId is a friend + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|UniqueNetId") + static void UniqueNetIdToString(const FBPUniqueNetId &UniqueNetId, FString &String); + + //******** Player Name Functions **********// + + // Get the player name of a network player attached to the given controller + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|PlayerInfo|PlayerName") + static void GetPlayerName(APlayerController *PlayerController, FString &PlayerName); + + // Set the player name of a network player attached to the given controller + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|PlayerInfo|PlayerName") + static void SetPlayerName(APlayerController *PlayerController, FString PlayerName); + + //********** Misc Player Info Functions *********// + + // Get the number of network players + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|PlayerInfo|Misc", meta = (bIgnoreSelf = "true", WorldContext = "WorldContextObject", DisplayName = "GetNumNetworkPlayers")) + static void GetNumberOfNetworkPlayers(UObject* WorldContextObject, int32 &NumNetPlayers); + + // Get the network player index of the given controller + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|PlayerInfo|Misc") + static void GetNetPlayerIndex(APlayerController *PlayerController, int32 &NetPlayerIndex); + + // Checks if the stated session subsystem is active + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|Misc") + static bool HasOnlineSubsystem(FName SubSystemName); + + //**** Seamless travel Functions ****// + + //Exposes Server travel to blueprint + UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "Online|AdvancedSessions|Seamless", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject")) + static bool ServerTravel(UObject* WorldContextObject, const FString& InURL, bool bAbsolute, bool bShouldSkipGameNotify); + +}; diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedVoiceLibrary.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedVoiceLibrary.h new file mode 100644 index 0000000..da1128d --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedVoiceLibrary.h @@ -0,0 +1,99 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "BlueprintDataDefinitions.h" +#include "Online.h" +#include "OnlineSubsystem.h" +#include "Interfaces/VoiceInterface.h" +//#include "OnlineFriendsInterface.h" +//#include "OnlineUserInterface.h" +//#include "OnlineMessageInterface.h" +//#include "OnlinePresenceInterface.h" +#include "Engine/GameInstance.h" +//#include "OnlineSessionInterface.h" + +#include "UObject/UObjectIterator.h" + +#include "AdvancedVoiceLibrary.generated.h" + + +//General Advanced Sessions Log +DECLARE_LOG_CATEGORY_EXTERN(AdvancedVoiceLog, Log, All); + + +UCLASS() +class UAdvancedVoiceLibrary : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() +public: + + //********* Voice Library Functions *************// + + // Get if a headset is present for the specified local user + UFUNCTION(BlueprintPure, Category = "Online|AdvancedVoice|VoiceInfo", meta = (WorldContext = "WorldContextObject")) + static void IsHeadsetPresent(UObject* WorldContextObject, bool & bHasHeadset, uint8 LocalPlayerNum = 0); + + // Starts networked voice, allows push to talk in coordination with StopNetworkedVoice + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject")) + static void StartNetworkedVoice(UObject* WorldContextObject, uint8 LocalPlayerNum = 0); + + // Stops networked voice, allows push to talk in coordination with StartNetworkedVoice + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject")) + static void StopNetworkedVoice(UObject* WorldContextObject, uint8 LocalPlayerNum = 0); + + // Registers a local player as someone interested in voice data + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject")) + static bool RegisterLocalTalker(UObject* WorldContextObject, uint8 LocalPlayerNum = 0); + + // Registers all signed in players as local talkers + // This is already done automatically, only do it manually if you unregistered someone + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject")) + static void RegisterAllLocalTalkers(UObject* WorldContextObject); + + // UnRegisters local player as a local talker + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject")) + static void UnRegisterLocalTalker(UObject* WorldContextObject, uint8 LocalPlayerNum = 0); + + // UnRegisters all signed in players as local talkers + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject")) + static void UnRegisterAllLocalTalkers(UObject* WorldContextObject); + + // Registers a remote player as a talker + // This is already done automatically, only do it manually if you unregistered someone + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject")) + static bool RegisterRemoteTalker(UObject* WorldContextObject, const FBPUniqueNetId& UniqueNetId); + + // UnRegisters a remote player as a talker + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject")) + static bool UnRegisterRemoteTalker(UObject* WorldContextObject, const FBPUniqueNetId& UniqueNetId); + + // UnRegisters all remote players as talkers + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject")) + static void RemoveAllRemoteTalkers(UObject* WorldContextObject); + + // Returns whether a local player is currently talking + UFUNCTION(BlueprintPure, Category = "Online|AdvancedVoice|VoiceInfo", meta = (WorldContext = "WorldContextObject")) + static bool IsLocalPlayerTalking(UObject* WorldContextObject, uint8 LocalPlayerNum); + + // Returns whether a remote player is currently talking + UFUNCTION(BlueprintPure, Category = "Online|AdvancedVoice|VoiceInfo", meta = (WorldContext = "WorldContextObject")) + static bool IsRemotePlayerTalking(UObject* WorldContextObject, const FBPUniqueNetId& UniqueNetId); + + // Returns whether a player is muted for the specified local player + UFUNCTION(BlueprintPure, Category = "Online|AdvancedVoice|VoiceInfo", meta = (WorldContext = "WorldContextObject")) + static bool IsPlayerMuted(UObject* WorldContextObject, uint8 LocalUserNumChecking, const FBPUniqueNetId& UniqueNetId); + + // Mutes the player associated with the uniquenetid for the specified local player, if IsSystemWide is true then it will attempt to mute globally for the player + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject")) + static bool MuteRemoteTalker(UObject* WorldContextObject, uint8 LocalUserNum, const FBPUniqueNetId& UniqueNetId, bool bIsSystemWide = false); + + // UnMutes the player associated with the uniquenetid for the specified local player, if IsSystemWide is true then it will attempt to unmute globally for the player + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject")) + static bool UnMuteRemoteTalker(UObject* WorldContextObject, uint8 LocalUserNum, const FBPUniqueNetId& UniqueNetId, bool bIsSystemWide = false); + + // Gets the number of local talkers for this system + UFUNCTION(BlueprintPure, Category = "Online|AdvancedVoice|VoiceInfo", meta = (WorldContext = "WorldContextObject")) + static void GetNumLocalTalkers(UObject* WorldContextObject, int32 & NumLocalTalkers); +}; diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AutoLoginUserCallbackProxy.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AutoLoginUserCallbackProxy.h new file mode 100644 index 0000000..d07a666 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/AutoLoginUserCallbackProxy.h @@ -0,0 +1,55 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "CoreMinimal.h" +#include "BlueprintDataDefinitions.h" +#include "Interfaces/OnlineIdentityInterface.h" +#include "Engine/LocalPlayer.h" +#include "AutoLoginUserCallbackProxy.generated.h" + +UCLASS(MinimalAPI) +class UAutoLoginUserCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when there is a successful destroy + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnSuccess; + + // Called when there is an unsuccessful destroy + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnFailure; + + /** + * Logs the player into the online service using parameters passed on the + * command line. Expects -AUTH_LOGIN= -AUTH_PASSWORD=. If either + * are missing, the function returns false and doesn't start the login + * process + * + * @param LocalUserNum the controller number of the associated user + * + */ + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedIdentity") + static UAutoLoginUserCallbackProxy* AutoLoginUser(UObject* WorldContextObject, int32 LocalUserNum); + + // UOnlineBlueprintCallProxyBase interface + virtual void Activate() override; + // End of UOnlineBlueprintCallProxyBase interface + +private: + // Internal callback when the operation completes, calls out to the public success/failure callbacks + void OnCompleted(int32 LocalUserNum, bool bWasSuccessful, const FUniqueNetId& UserId, const FString& ErrorVal); + +private: + // The controller number of the associated user + int32 LocalUserNumber; + + // The delegate executed by the online subsystem + FOnLoginCompleteDelegate Delegate; + + // Handle to the registered OnDestroySessionComplete delegate + FDelegateHandle DelegateHandle; + + // The world context object in which this call is taking place + TWeakObjectPtr WorldContextObject; +}; diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/BlueprintDataDefinitions.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/BlueprintDataDefinitions.h new file mode 100644 index 0000000..b5dc438 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/BlueprintDataDefinitions.h @@ -0,0 +1,435 @@ +#pragma once +#include "CoreMinimal.h" +//#include "EngineMinimal.h" +#include "Engine/Engine.h" +#include "GameFramework/PlayerState.h" +//#include "Core.h" +#include "Interfaces/OnlineSessionInterface.h" +#include "OnlineSessionSettings.h" +#include "OnlineDelegateMacros.h" +#include "OnlineSubsystem.h" +#include "OnlineSubsystemImpl.h" +#include "OnlineSubsystemUtils.h" +#include "OnlineSubsystemUtilsModule.h" +#include "GameFramework/PlayerController.h" +#include "Modules/ModuleManager.h" +#include "OnlineSubsystemUtilsClasses.h" +#include "BlueprintDataDefinitions.generated.h" + +UENUM(BlueprintType) +enum class EBPUserPrivileges : uint8 +{ + /** Whether the user can play at all, online or offline - may be age restricted */ + CanPlay, + /** Whether the user can play in online modes */ + CanPlayOnline, + /** Whether the user can use voice and text chat */ + CanCommunicateOnline, + /** Whether the user can use content generated by other users */ + CanUseUserGeneratedContent +}; + + +UENUM(BlueprintType) +enum class EBPLoginStatus : uint8 +{ + /** Player has not logged in or chosen a local profile */ + NotLoggedIn, + /** Player is using a local profile but is not logged in */ + UsingLocalProfile, + /** Player has been validated by the platform specific authentication service */ + LoggedIn +}; + + +USTRUCT(BlueprintType) +struct FBPUserOnlineAccount +{ + GENERATED_USTRUCT_BODY() + +public: + TSharedPtr UserAccountInfo; + + FBPUserOnlineAccount() + { + + } + + FBPUserOnlineAccount(TSharedPtr UserAccount) + { + UserAccountInfo = UserAccount; + } +}; + +UENUM() +enum class ESessionSettingSearchResult : uint8 +{ + // Found the setting + Found, + + // Did not find the setting + NotFound, + + // Was not the correct type + WrongType +}; + +// This makes a lot of the blueprint functions cleaner +UENUM() +enum class EBlueprintResultSwitch : uint8 +{ + // On Success + OnSuccess, + + // On Failure + OnFailure +}; + +// This makes a lot of the blueprint functions cleaner +UENUM() +enum class EBlueprintAsyncResultSwitch : uint8 +{ + // On Success + OnSuccess, + + // Still loading + AsyncLoading, + // On Failure + OnFailure +}; + +// This is to define server type searches +UENUM(BlueprintType) +enum class EBPServerPresenceSearchType : uint8 +{ + AllServers, + ClientServersOnly, + DedicatedServersOnly +}; + +// Wanted this to be switchable in the editor +UENUM(BlueprintType) +enum class EBPOnlinePresenceState : uint8 +{ + Online, + Offline, + Away, + ExtendedAway, + DoNotDisturb, + Chat +}; + +UENUM(BlueprintType) +enum class EBPOnlineSessionState : uint8 +{ + /** An online session has not been created yet */ + NoSession, + /** An online session is in the process of being created */ + Creating, + /** Session has been created but the session hasn't started (pre match lobby) */ + Pending, + /** Session has been asked to start (may take time due to communication with backend) */ + Starting, + /** The current session has started. Sessions with join in progress disabled are no longer joinable */ + InProgress, + /** The session is still valid, but the session is no longer being played (post match lobby) */ + Ending, + /** The session is closed and any stats committed */ + Ended, + /** The session is being destroyed */ + Destroying +}; + +// Boy oh boy is this a dirty hack, but I can't figure out a good way to do it otherwise at the moment +// The UniqueNetId is an abstract class so I can't exactly re-initialize it to make a shared pointer on some functions +// So I made the blueprintable UniqueNetID into a dual variable struct with access functions and I am converting the const var for the pointer +// I really need to re-think this later +USTRUCT(BlueprintType) +struct FBPUniqueNetId +{ + GENERATED_USTRUCT_BODY() + +private: + bool bUseDirectPointer; + + +public: + TSharedPtr UniqueNetId; + const FUniqueNetId * UniqueNetIdPtr; + + void SetUniqueNetId(const TSharedPtr &ID) + { + bUseDirectPointer = false; + UniqueNetIdPtr = nullptr; + UniqueNetId = ID; + } + + void SetUniqueNetId(const FUniqueNetId *ID) + { + bUseDirectPointer = true; + UniqueNetIdPtr = ID; + } + + bool IsValid() const + { + if (bUseDirectPointer && UniqueNetIdPtr != nullptr && UniqueNetIdPtr->IsValid()) + { + return true; + } + else if (UniqueNetId.IsValid()) + { + return true; + } + else + return false; + + } + + const FUniqueNetId* GetUniqueNetId() const + { + if (bUseDirectPointer && UniqueNetIdPtr != nullptr) + { + // No longer converting to non const as all functions now pass const UniqueNetIds + return /*const_cast*/(UniqueNetIdPtr); + } + else if (UniqueNetId.IsValid()) + { + return UniqueNetId.Get(); + } + else + return nullptr; + } + + // Adding in a compare operator so that std functions will work with this struct + FORCEINLINE bool operator==(const FBPUniqueNetId& Other) const + { + return (IsValid() && Other.IsValid() && (*GetUniqueNetId() == *Other.GetUniqueNetId())); + } + + FORCEINLINE bool operator!=(const FBPUniqueNetId& Other) const + { + return !(IsValid() && Other.IsValid() && (*GetUniqueNetId() == *Other.GetUniqueNetId())); + } + + FBPUniqueNetId() + { + bUseDirectPointer = false; + UniqueNetIdPtr = nullptr; + } +}; + +USTRUCT(BluePrintType) +struct FBPOnlineUser +{ + GENERATED_USTRUCT_BODY() + +public: + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + FBPUniqueNetId UniqueNetId; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + FString DisplayName; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + FString RealName; +}; + +USTRUCT(BluePrintType) +struct FBPOnlineRecentPlayer : public FBPOnlineUser +{ + GENERATED_USTRUCT_BODY() + +public: + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + FString LastSeen; +}; + + +USTRUCT(BlueprintType) +struct FBPFriendPresenceInfo +{ + GENERATED_USTRUCT_BODY() + +public: + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + bool bIsOnline = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + bool bIsPlaying = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + bool bIsPlayingThisGame = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + bool bIsJoinable = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + bool bHasVoiceSupport = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + EBPOnlinePresenceState PresenceState = EBPOnlinePresenceState::Offline; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + FString StatusString; + + FBPFriendPresenceInfo() + { + bIsOnline = false; + bIsPlaying = false; + bIsPlayingThisGame = false; + bIsJoinable = false; + bHasVoiceSupport = false; + PresenceState = EBPOnlinePresenceState::Offline; + } +}; + +USTRUCT(BlueprintType) +struct FBPFriendInfo +{ + GENERATED_USTRUCT_BODY() + +public: + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + FString DisplayName; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + FString RealName; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + EBPOnlinePresenceState OnlineState = EBPOnlinePresenceState::Offline; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + FBPUniqueNetId UniqueNetId; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + bool bIsPlayingSameGame = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + FBPFriendPresenceInfo PresenceInfo; + + FBPFriendInfo() + { + OnlineState = EBPOnlinePresenceState::Offline; + bIsPlayingSameGame = false; + } +}; + + +/** The types of comparison operations for a given search query */ +// Used to compare session properties +UENUM(BlueprintType) +enum class EOnlineComparisonOpRedux : uint8 +{ + Equals, + NotEquals, + GreaterThan, + GreaterThanEquals, + LessThan, + LessThanEquals, +}; + + +// Used to store session properties before converting to FVariantData +USTRUCT(BlueprintType) +struct FSessionPropertyKeyPair +{ + GENERATED_USTRUCT_BODY() + + FName Key; + FVariantData Data; +}; + + +// Sent to the FindSessionsAdvanced to filter the end results +USTRUCT(BlueprintType) +struct FSessionsSearchSetting +{ + GENERATED_USTRUCT_BODY() + //UPROPERTY() + + + // Had to make a copy of this to account for the original not being exposed to blueprints + /** How is this session setting compared on the backend searches */ + EOnlineComparisonOpRedux ComparisonOp; + + // The key pair to search for + FSessionPropertyKeyPair PropertyKeyPair; +}; + +// Couldn't use the default one as it is not exposed to other modules, had to re-create it here +// Helper class for various methods to reduce the call hierarchy +struct FOnlineSubsystemBPCallHelperAdvanced +{ +public: + FOnlineSubsystemBPCallHelperAdvanced(const TCHAR* CallFunctionContext, UWorld* World, FName SystemName = NAME_None) + : OnlineSub(Online::GetSubsystem(World, SystemName)) + , FunctionContext(CallFunctionContext) + { + if (OnlineSub == nullptr) + { + FFrame::KismetExecutionMessage(*FString::Printf(TEXT("%s - Invalid or uninitialized OnlineSubsystem"), FunctionContext), ELogVerbosity::Warning); + } + } + + void QueryIDFromPlayerController(APlayerController* PlayerController) + { + UserID.Reset(); + //return const_cast(UniqueNetIdPtr); + if (APlayerState* PlayerState = (PlayerController != NULL) ? PlayerController->PlayerState : NULL) + { + UserID = PlayerState->GetUniqueId().GetUniqueNetId(); + if (!UserID.IsValid()) + { + FFrame::KismetExecutionMessage(*FString::Printf(TEXT("%s - Cannot map local player to unique net ID"), FunctionContext), ELogVerbosity::Warning); + } + } + else + { + FFrame::KismetExecutionMessage(*FString::Printf(TEXT("%s - Invalid player state"), FunctionContext), ELogVerbosity::Warning); + } + } + + + bool IsValid() const + { + return UserID.IsValid() && (OnlineSub != nullptr); + } + +public: + //TSharedPtr& GetUniqueNetId() + TSharedPtr UserID; + IOnlineSubsystem* const OnlineSub; + const TCHAR* FunctionContext; +}; +class FOnlineSearchSettingsEx : public FOnlineSearchSettings +{ + /** + * Sets a key value pair combination that defines a search parameter + * + * @param Key key for the setting + * @param Value value of the setting + * @param InType type of comparison + */ +public: + + void HardSet(FName Key, const FVariantData& Value, EOnlineComparisonOpRedux CompOp) + { + FOnlineSessionSearchParam* SearchParam = SearchParams.Find(Key); + + TEnumAsByte op; + + switch (CompOp) + { + case EOnlineComparisonOpRedux::Equals: op = EOnlineComparisonOp::Equals; break; + case EOnlineComparisonOpRedux::GreaterThan: op = EOnlineComparisonOp::GreaterThan; break; + case EOnlineComparisonOpRedux::GreaterThanEquals: op = EOnlineComparisonOp::GreaterThanEquals; break; + case EOnlineComparisonOpRedux::LessThan: op = EOnlineComparisonOp::LessThan; break; + case EOnlineComparisonOpRedux::LessThanEquals: op = EOnlineComparisonOp::LessThanEquals; break; + case EOnlineComparisonOpRedux::NotEquals: op = EOnlineComparisonOp::NotEquals; break; + default: op = EOnlineComparisonOp::Equals; break; + } + + if (SearchParam) + { + SearchParam->Data = Value; + SearchParam->ComparisonOp = op; + } + else + { + FOnlineSessionSearchParam searchSetting((int)0, op); + searchSetting.Data = Value; + SearchParams.Add(Key, searchSetting); + } + } +}; + +#define INVALID_INDEX -1 \ No newline at end of file diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/CancelFindSessionsCallbackProxy.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/CancelFindSessionsCallbackProxy.h new file mode 100644 index 0000000..58d2ea0 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/CancelFindSessionsCallbackProxy.h @@ -0,0 +1,46 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once +#include "CoreMinimal.h" +#include "Engine/Engine.h" +#include "Interfaces/OnlineSessionInterface.h" +#include "BlueprintDataDefinitions.h" +#include "CancelFindSessionsCallbackProxy.generated.h" + +UCLASS(MinimalAPI) +class UCancelFindSessionsCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when there is a successful destroy + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnSuccess; + + // Called when there is an unsuccessful destroy + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnFailure; + + // Cancels finding sessions + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedSessions") + static UCancelFindSessionsCallbackProxy* CancelFindSessions(UObject* WorldContextObject, class APlayerController* PlayerController); + + // UOnlineBlueprintCallProxyBase interface + virtual void Activate() override; + // End of UOnlineBlueprintCallProxyBase interface + +private: + // Internal callback when the operation completes, calls out to the public success/failure callbacks + void OnCompleted(bool bWasSuccessful); + +private: + // The player controller triggering things + TWeakObjectPtr PlayerControllerWeakPtr; + + // The delegate executed by the online subsystem + FOnCancelFindSessionsCompleteDelegate Delegate; + + // Handle to the registered OnDestroySessionComplete delegate + FDelegateHandle DelegateHandle; + + // The world context object in which this call is taking place + TWeakObjectPtr WorldContextObject; +}; diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/CreateSessionCallbackProxyAdvanced.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/CreateSessionCallbackProxyAdvanced.h new file mode 100644 index 0000000..04ae6d1 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/CreateSessionCallbackProxyAdvanced.h @@ -0,0 +1,107 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "CoreMinimal.h" +#include "Engine/Engine.h" +#include "BlueprintDataDefinitions.h" +#include "CreateSessionCallbackProxyAdvanced.generated.h" + +UCLASS(MinimalAPI) +class UCreateSessionCallbackProxyAdvanced : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when the session was created successfully + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnSuccess; + + // Called when there was an error creating the session + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnFailure; + + /** + * Creates a session with the default online subsystem with advanced optional inputs, for dedicated servers leave UsePresence as false and set IsDedicatedServer to true. Dedicated servers don't use presence. + * @param PublicConnections When doing a 'listen' server, this must be >=2 (ListenServer itself counts as a connection) + * @param bUseLAN When you want to play LAN, the level to play on must be loaded with option 'bIsLanMatch' + * @param bUsePresence Must be true for a 'listen' server (Map must be loaded with option 'listen'), false for a 'dedicated' server. + * @param bUseLobbiesIfAvailable Used to flag the subsystem to use a lobby api instead of general hosting if the API supports it, generally true on steam for listen servers and false for dedicated + * @param bShouldAdvertise Set to true when the OnlineSubsystem should list your server when someone is searching for servers. Otherwise the server is hidden and only join via invite is possible. + * @param bUseLobbiesVoiceChatIfAvailable Set to true to setup voice chat lobbies if the API supports it + * @param bStartAfterCreate Set to true to start the session after it's created. If false you need to manually call StartSession when ready. + */ + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject",AutoCreateRefTerm="ExtraSettings"), Category = "Online|AdvancedSessions") + static UCreateSessionCallbackProxyAdvanced* CreateAdvancedSession(UObject* WorldContextObject, const TArray& ExtraSettings, class APlayerController* PlayerController = NULL, int32 PublicConnections = 100, int32 PrivateConnections = 0, bool bUseLAN = false, bool bAllowInvites = true, bool bIsDedicatedServer = false, bool bUsePresence = true, bool bUseLobbiesIfAvailable = true, bool bAllowJoinViaPresence = true, bool bAllowJoinViaPresenceFriendsOnly = false, bool bAntiCheatProtected = false, bool bUsesStats = false, bool bShouldAdvertise = true, bool bUseLobbiesVoiceChatIfAvailable = false, bool bStartAfterCreate = true); + + // UOnlineBlueprintCallProxyBase interface + virtual void Activate() override; + // End of UOnlineBlueprintCallProxyBase interface + +private: + // Internal callback when session creation completes, optionally calls StartSession + void OnCreateCompleted(FName SessionName, bool bWasSuccessful); + + // Internal callback when session start completes + void OnStartCompleted(FName SessionName, bool bWasSuccessful); + + // The player controller triggering things + TWeakObjectPtr PlayerControllerWeakPtr; + + // The delegate executed by the online subsystem + FOnCreateSessionCompleteDelegate CreateCompleteDelegate; + + // The delegate executed by the online subsystem + FOnStartSessionCompleteDelegate StartCompleteDelegate; + + // Handles to the registered delegates above + FDelegateHandle CreateCompleteDelegateHandle; + FDelegateHandle StartCompleteDelegateHandle; + + // Number of public connections + int NumPublicConnections; + + // Number of private connections + int NumPrivateConnections; + + // Whether or not to search LAN + bool bUseLAN; + + // Whether or not to allow invites + bool bAllowInvites; + + // Whether this is a dedicated server or not + bool bDedicatedServer; + + // Whether to use the presence option + bool bUsePresence; + + // Whether to prefer the use of lobbies for hosting if the api supports them + bool bUseLobbiesIfAvailable; + + // Whether to allow joining via presence + bool bAllowJoinViaPresence; + + // Allow joining via presence for friends only + bool bAllowJoinViaPresenceFriendsOnly; + + // Delcare the server to be anti cheat protected + bool bAntiCheatProtected; + + // Record Stats + bool bUsesStats; + + // Should advertise server? + bool bShouldAdvertise; + + // Whether to prefer the use of voice chat lobbies if the api supports them + bool bUseLobbiesVoiceChatIfAvailable; + + // Whether to start the session automatically after it is created + bool bStartAfterCreate; + + // Store extra settings + TArray ExtraSettings; + + // The world context object in which this call is taking place + TWeakObjectPtr WorldContextObject; +}; + diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/EndSessionCallbackProxy.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/EndSessionCallbackProxy.h new file mode 100644 index 0000000..e527c58 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/EndSessionCallbackProxy.h @@ -0,0 +1,49 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once +#include "CoreMinimal.h" +#include "Engine/Engine.h" +#include "Interfaces/OnlineSessionInterface.h" +#include "BlueprintDataDefinitions.h" +#include "EndSessionCallbackProxy.generated.h" + +UCLASS(MinimalAPI) +class UEndSessionCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when there is a successful destroy + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnSuccess; + + // Called when there is an unsuccessful destroy + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnFailure; + + /** + * Ends the current sessions, Generally for almost all uses you should be using the engines native Destroy Session node instead. + * This exists for people using StartSession and optionally hand managing the session state. + */ + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedSessions") + static UEndSessionCallbackProxy* EndSession(UObject* WorldContextObject, class APlayerController* PlayerController); + + // UOnlineBlueprintCallProxyBase interface + virtual void Activate() override; + // End of UOnlineBlueprintCallProxyBase interface + +private: + // Internal callback when the operation completes, calls out to the public success/failure callbacks + void OnCompleted(FName SessionName, bool bWasSuccessful); + +private: + // The player controller triggering things + TWeakObjectPtr PlayerControllerWeakPtr; + + // The delegate executed by the online subsystem + FOnEndSessionCompleteDelegate Delegate; + + // Handle to the registered OnDestroySessionComplete delegate + FDelegateHandle DelegateHandle; + + // The world context object in which this call is taking place + TWeakObjectPtr WorldContextObject; +}; diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/FindFriendSessionCallbackProxy.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/FindFriendSessionCallbackProxy.h new file mode 100644 index 0000000..58ef8f5 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/FindFriendSessionCallbackProxy.h @@ -0,0 +1,51 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "CoreMinimal.h" +#include "BlueprintDataDefinitions.h" +#include "Engine/LocalPlayer.h" +#include "FindFriendSessionCallbackProxy.generated.h" + +DECLARE_LOG_CATEGORY_EXTERN(AdvancedFindFriendSessionLog, Log, All); + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBlueprintFindFriendSessionDelegate, const TArray &, SessionInfo); + +UCLASS(MinimalAPI) +class UFindFriendSessionCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when the friends list successfully was retrieved + UPROPERTY(BlueprintAssignable) + FBlueprintFindFriendSessionDelegate OnSuccess; + + // Called when there was an error retrieving the friends list + UPROPERTY(BlueprintAssignable) + FBlueprintFindFriendSessionDelegate OnFailure; + + // Attempts to get the current session that a friend is in + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedFriends") + static UFindFriendSessionCallbackProxy* FindFriendSession(UObject* WorldContextObject, APlayerController *PlayerController, const FBPUniqueNetId &FriendUniqueNetId); + + virtual void Activate() override; + +private: + // Internal callback when the friends list is retrieved + void OnFindFriendSessionCompleted(int32 LocalPlayer, bool bWasSuccessful, const TArray& SessionInfo); + + // The player controller triggering things + TWeakObjectPtr PlayerControllerWeakPtr; + + // The UniqueNetID of the person to invite + FBPUniqueNetId cUniqueNetId; + + // The delegate to call on completion + FOnFindFriendSessionCompleteDelegate OnFindFriendSessionCompleteDelegate; + + // Handles to the registered delegates above + FDelegateHandle FindFriendSessionCompleteDelegateHandle; + + // The world context object in which this call is taking place + TWeakObjectPtr WorldContextObject; +}; + diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/FindSessionsCallbackProxyAdvanced.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/FindSessionsCallbackProxyAdvanced.h new file mode 100644 index 0000000..e610277 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/FindSessionsCallbackProxyAdvanced.h @@ -0,0 +1,109 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once +#include "CoreMinimal.h" +#include "Engine/Engine.h" +#include "Interfaces/OnlineSessionInterface.h" +#include "FindSessionsCallbackProxy.h" +#include "BlueprintDataDefinitions.h" +#include "FindSessionsCallbackProxyAdvanced.generated.h" + + +FORCEINLINE bool operator==(const FBlueprintSessionResult& A, const FBlueprintSessionResult& B) +{ + return (A.OnlineResult.IsValid() == B.OnlineResult.IsValid() && (A.OnlineResult.GetSessionIdStr() == B.OnlineResult.GetSessionIdStr())); +} + +UCLASS(MinimalAPI) +class UFindSessionsCallbackProxyAdvanced : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when there is a successful query + UPROPERTY(BlueprintAssignable) + FBlueprintFindSessionsResultDelegate OnSuccess; + + // Called when there is an unsuccessful query + UPROPERTY(BlueprintAssignable) + FBlueprintFindSessionsResultDelegate OnFailure; + + // Searches for advertised sessions with the default online subsystem and includes an array of filters + UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true", WorldContext = "WorldContextObject", AutoCreateRefTerm="Filters"), Category = "Online|AdvancedSessions") + static UFindSessionsCallbackProxyAdvanced* FindSessionsAdvanced(UObject* WorldContextObject, class APlayerController* PlayerController, int32 MaxResults, bool bUseLAN, EBPServerPresenceSearchType ServerTypeToSearch, const TArray &Filters, bool bEmptyServersOnly = false, bool bNonEmptyServersOnly = false, bool bSecureServersOnly = false, bool bSearchLobbies = true, int MinSlotsAvailable = 0); + + static bool CompareVariants(const FVariantData &A, const FVariantData &B, EOnlineComparisonOpRedux Comparator); + + // Filters an array of session results by the given search parameters, returns a new array with the filtered results + UFUNCTION(BluePrintCallable, meta = (Category = "Online|AdvancedSessions")) + static void FilterSessionResults(const TArray &SessionResults, const TArray &Filters, TArray &FilteredResults); + + // Removed, the default built in versions work fine in the normal FindSessionsCallbackProxy + /*UFUNCTION(BlueprintPure, Category = "Online|Session") + static int32 GetPingInMs(const FBlueprintSessionResult& Result); + + UFUNCTION(BlueprintPure, Category = "Online|Session") + static FString GetServerName(const FBlueprintSessionResult& Result); + + UFUNCTION(BlueprintPure, Category = "Online|Session") + static int32 GetCurrentPlayers(const FBlueprintSessionResult& Result); + + UFUNCTION(BlueprintPure, Category = "Online|Session") + static int32 GetMaxPlayers(const FBlueprintSessionResult& Result);*/ + + + // UOnlineBlueprintCallProxyBase interface + virtual void Activate() override; + // End of UOnlineBlueprintCallProxyBase interface + +private: + // Internal callback when the session search completes, calls out to the public success/failure callbacks + void OnCompleted(bool bSuccess); + + bool bRunSecondSearch; + bool bIsOnSecondSearch; + + TArray SessionSearchResults; + +private: + // The player controller triggering things + TWeakObjectPtr PlayerControllerWeakPtr; + + // The delegate executed by the online subsystem + FOnFindSessionsCompleteDelegate Delegate; + + // Handle to the registered OnFindSessionsComplete delegate + FDelegateHandle DelegateHandle; + + // Object to track search results + TSharedPtr SearchObject; + TSharedPtr SearchObjectDedicated; + + // Whether or not to search LAN + bool bUseLAN; + + // Whether or not to search for dedicated servers + EBPServerPresenceSearchType ServerSearchType; + + // Maximum number of results to return + int MaxResults; + + // Store extra settings + TArray SearchSettings; + + // Search for empty servers only + bool bEmptyServersOnly; + + // Search for non empty servers only + bool bNonEmptyServersOnly; + + // Search for secure servers only + bool bSecureServersOnly; + + // Search through lobbies + bool bSearchLobbies; + + // Min slots requires to search + int MinSlotsAvailable; + + // The world context object in which this call is taking place + TWeakObjectPtr WorldContextObject; +}; diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/GetFriendsCallbackProxy.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/GetFriendsCallbackProxy.h new file mode 100644 index 0000000..844bef6 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/GetFriendsCallbackProxy.h @@ -0,0 +1,49 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "CoreMinimal.h" +#include "BlueprintDataDefinitions.h" +#include "Engine/LocalPlayer.h" +#include "GetFriendsCallbackProxy.generated.h" + +DECLARE_LOG_CATEGORY_EXTERN(AdvancedGetFriendsLog, Log, All); + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBlueprintGetFriendsListDelegate, const TArray&, Results); + +UCLASS(MinimalAPI) +class UGetFriendsCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when the friends list successfully was retrieved + UPROPERTY(BlueprintAssignable) + FBlueprintGetFriendsListDelegate OnSuccess; + + // Called when there was an error retrieving the friends list + UPROPERTY(BlueprintAssignable) + FBlueprintGetFriendsListDelegate OnFailure; + + // Gets the players list of friends from the OnlineSubsystem and returns it, can be retrieved later with GetStoredFriendsList + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedFriends") + static UGetFriendsCallbackProxy* GetAndStoreFriendsList(UObject* WorldContextObject, class APlayerController* PlayerController); + + virtual void Activate() override; + +private: + // Internal callback when the friends list is retrieved + void OnReadFriendsListCompleted(int32 LocalUserNum, bool bWasSuccessful, const FString& ListName, const FString& ErrorString); + + // The player controller triggering things + TWeakObjectPtr PlayerControllerWeakPtr; + + // The delegate executed + FOnReadFriendsListComplete FriendListReadCompleteDelegate; + + // The Type of friends list to get + // Removed because all but the facebook interfaces don't even currently support anything but the default friends list. + //EBPFriendsLists FriendListToGet; + + // The world context object in which this call is taking place + TWeakObjectPtr WorldContextObject; +}; + diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/GetRecentPlayersCallbackProxy.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/GetRecentPlayersCallbackProxy.h new file mode 100644 index 0000000..2b12c9f --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/GetRecentPlayersCallbackProxy.h @@ -0,0 +1,49 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "CoreMinimal.h" +#include "BlueprintDataDefinitions.h" +#include "GetRecentPlayersCallbackProxy.generated.h" + +DECLARE_LOG_CATEGORY_EXTERN(AdvancedGetRecentPlayersLog, Log, All); + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBlueprintGetRecentPlayersDelegate, const TArray&, Results); + +UCLASS(MinimalAPI) +class UGetRecentPlayersCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when the friends list successfully was retrieved + UPROPERTY(BlueprintAssignable) + FBlueprintGetRecentPlayersDelegate OnSuccess; + + // Called when there was an error retrieving the friends list + UPROPERTY(BlueprintAssignable) + FBlueprintGetRecentPlayersDelegate OnFailure; + + // Gets the list of recent players from the OnlineSubsystem and returns it, can be retrieved later with GetStoredRecentPlayersList, can fail if no recent players are found + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedFriends") + static UGetRecentPlayersCallbackProxy* GetAndStoreRecentPlayersList(UObject* WorldContextObject, const FBPUniqueNetId &UniqueNetId); + + virtual void Activate() override; + +private: + // Internal callback when the friends list is retrieved + void OnQueryRecentPlayersCompleted(const FUniqueNetId &UserID, const FString &Namespace, bool bWasSuccessful, const FString& ErrorString); + // Handle to the registered OnFindSessionsComplete delegate + FDelegateHandle DelegateHandle; + + // The player controller triggering things + //TWeakObjectPtr PlayerControllerWeakPtr; + + // The UniqueNetID of the person to get recent players for + FBPUniqueNetId cUniqueNetId; + + // The delegate executed + FOnQueryRecentPlayersCompleteDelegate QueryRecentPlayersCompleteDelegate; + + // The world context object in which this call is taking place + TWeakObjectPtr WorldContextObject; +}; + diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/GetUserPrivilegeCallbackProxy.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/GetUserPrivilegeCallbackProxy.h new file mode 100644 index 0000000..f47d2a5 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/GetUserPrivilegeCallbackProxy.h @@ -0,0 +1,45 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "CoreMinimal.h" +#include "BlueprintDataDefinitions.h" +#include "Interfaces/OnlineIdentityInterface.h" +#include "GetUserPrivilegeCallbackProxy.generated.h" + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FBlueprintGetUserPrivilegeDelegate,/* const &FBPUniqueNetId, PlayerID,*/ EBPUserPrivileges, QueriedPrivilege, bool, HadPrivilege); + +UCLASS(MinimalAPI) +class UGetUserPrivilegeCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when there is a successful destroy + UPROPERTY(BlueprintAssignable) + FBlueprintGetUserPrivilegeDelegate OnSuccess; + + // Called when there is an unsuccessful destroy + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnFailure; + + // Gets the privilage of the user + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedIdentity") + static UGetUserPrivilegeCallbackProxy* GetUserPrivilege(UObject* WorldContextObject, const EBPUserPrivileges & PrivilegeToCheck, const FBPUniqueNetId & PlayerUniqueNetID); + + // UOnlineBlueprintCallProxyBase interface + virtual void Activate() override; + // End of UOnlineBlueprintCallProxyBase interface + +private: + // Internal callback when the operation completes, calls out to the public success/failure callbacks + void OnCompleted(const FUniqueNetId& PlayerID, EUserPrivileges::Type Privilege, uint32 Result); + +private: + // The player controller triggering things + FBPUniqueNetId PlayerUniqueNetID; + + // Privilege to check + EBPUserPrivileges UserPrivilege; + + // The world context object in which this call is taking place + TWeakObjectPtr WorldContextObject; +}; diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/LoginUserCallbackProxy.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/LoginUserCallbackProxy.h new file mode 100644 index 0000000..ba65b68 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/LoginUserCallbackProxy.h @@ -0,0 +1,55 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "CoreMinimal.h" +#include "BlueprintDataDefinitions.h" +#include "Interfaces/OnlineIdentityInterface.h" +#include "Engine/LocalPlayer.h" +#include "LoginUserCallbackProxy.generated.h" + +UCLASS(MinimalAPI) +class ULoginUserCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when there is a successful destroy + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnSuccess; + + // Called when there is an unsuccessful destroy + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnFailure; + + // Logs into the identity interface + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject", AdvancedDisplay = "AuthType"), Category = "Online|AdvancedIdentity") + static ULoginUserCallbackProxy* LoginUser(UObject* WorldContextObject, class APlayerController* PlayerController, FString UserID, FString UserToken, FString AuthType); + + // UOnlineBlueprintCallProxyBase interface + virtual void Activate() override; + // End of UOnlineBlueprintCallProxyBase interface + +private: + // Internal callback when the operation completes, calls out to the public success/failure callbacks + void OnCompleted(int32 LocalUserNum, bool bWasSuccessful, const FUniqueNetId& UserId, const FString& ErrorVal); + +private: + // The player controller triggering things + TWeakObjectPtr PlayerControllerWeakPtr; + + // The user ID + FString UserID; + + // The user pass / token + FString UserToken; + + FString AuthType; + + // The delegate executed by the online subsystem + FOnLoginCompleteDelegate Delegate; + + // Handle to the registered OnDestroySessionComplete delegate + FDelegateHandle DelegateHandle; + + // The world context object in which this call is taking place + TWeakObjectPtr WorldContextObject; +}; diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/LogoutUserCallbackProxy.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/LogoutUserCallbackProxy.h new file mode 100644 index 0000000..5f85b0a --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/LogoutUserCallbackProxy.h @@ -0,0 +1,47 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "CoreMinimal.h" +#include "BlueprintDataDefinitions.h" +#include "Interfaces/OnlineIdentityInterface.h" +#include "Engine/LocalPlayer.h" +#include "LogoutUserCallbackProxy.generated.h" + +UCLASS(MinimalAPI) +class ULogoutUserCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when there is a successful destroy + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnSuccess; + + // Called when there is an unsuccessful destroy + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnFailure; + + // Logs out of the identity interface + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedIdentity") + static ULogoutUserCallbackProxy* LogoutUser(UObject* WorldContextObject, class APlayerController* PlayerController); + + // UOnlineBlueprintCallProxyBase interface + virtual void Activate() override; + // End of UOnlineBlueprintCallProxyBase interface + +private: + // Internal callback when the operation completes, calls out to the public success/failure callbacks + void OnCompleted(int LocalUserNum, bool bWasSuccessful); + +private: + // The player controller triggering things + TWeakObjectPtr PlayerControllerWeakPtr; + + // The delegate executed by the online subsystem + FOnLogoutCompleteDelegate Delegate; + + // Handle to the registered OnDestroySessionComplete delegate + FDelegateHandle DelegateHandle; + + // The world context object in which this call is taking place + TWeakObjectPtr WorldContextObject; +}; diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/OnlineSubSystemHeader.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/OnlineSubSystemHeader.h new file mode 100644 index 0000000..ad4b18f --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/OnlineSubSystemHeader.h @@ -0,0 +1,27 @@ +#pragma once + +//#include "EngineMinimal.h" +//#include "Core.h" +//#include "OnlineSessionInterface.h" +//#include "OnlineSessionSettings.h" +//#include "OnlineDelegateMacros.h" +//#include "OnlineSubsystem.h" +//#include "OnlineSubsystemImpl.h" +//#include "OnlineSubsystemUtils.h" +//#include "OnlineSubsystemUtilsModule.h" +//#include "ModuleManager.h" +//#include "OnlineSubsystemUtilsClasses.h" +//#include "BlueprintDataDefinitions.h" + + +/*#include "VoiceEngineImpl.h" +#include "VoiceInterfaceImpl.h" +#include "Voice.h"" +*/ + +// Found this in the steam controller, seems like a nice thought since steam is throwing errors +// Disable crazy warnings that claim that standard C library is "deprecated". +//#ifdef _MSC_VER +//#pragma warning(push) +//#pragma warning(disable:4996) +//#endif diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/SendFriendInviteCallbackProxy.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/SendFriendInviteCallbackProxy.h new file mode 100644 index 0000000..e878f51 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/SendFriendInviteCallbackProxy.h @@ -0,0 +1,49 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "CoreMinimal.h" +#include "BlueprintDataDefinitions.h" +#include "Engine/LocalPlayer.h" +#include "SendFriendInviteCallbackProxy.generated.h" + +DECLARE_LOG_CATEGORY_EXTERN(AdvancedSendFriendInviteLog, Log, All); + +DECLARE_DYNAMIC_MULTICAST_DELEGATE(FBlueprintSendFriendInviteDelegate); + +UCLASS(MinimalAPI) +class USendFriendInviteCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when the friends list successfully was retrieved + UPROPERTY(BlueprintAssignable) + FBlueprintSendFriendInviteDelegate OnSuccess; + + // Called when there was an error retrieving the friends list + UPROPERTY(BlueprintAssignable) + FBlueprintSendFriendInviteDelegate OnFailure; + + // Adds a friend who is using the defined UniqueNetId, some interfaces do now allow this function to be called (INCLUDING STEAM) + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedFriends") + static USendFriendInviteCallbackProxy* SendFriendInvite(UObject* WorldContextObject, APlayerController *PlayerController, const FBPUniqueNetId &UniqueNetIDInvited); + + virtual void Activate() override; + +private: + // Internal callback when the friends list is retrieved + void OnSendInviteComplete(int32 LocalPlayerNum, bool bWasSuccessful, const FUniqueNetId &InvitedPlayer, const FString &ListName, const FString &ErrorString); + + + // The player controller triggering things + TWeakObjectPtr PlayerControllerWeakPtr; + + // The UniqueNetID of the person to invite + FBPUniqueNetId cUniqueNetId; + + // The delegate to call on completion + FOnSendInviteComplete OnSendInviteCompleteDelegate; + + // The world context object in which this call is taking place + TWeakObjectPtr WorldContextObject; +}; + diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/StartSessionCallbackProxyAdvanced.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/StartSessionCallbackProxyAdvanced.h new file mode 100644 index 0000000..e82cce8 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/StartSessionCallbackProxyAdvanced.h @@ -0,0 +1,46 @@ +#pragma once + +#include "CoreMinimal.h" +#include "BlueprintDataDefinitions.h" +#include "StartSessionCallbackProxyAdvanced.generated.h" + +UCLASS(MinimalAPI) +class UStartSessionCallbackProxyAdvanced : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + // Called when the session starts successfully + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnSuccess; + + // Called when there is an error starting the session + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnFailure; + + /** + * Starts a session with the default online subsystem. The session needs to be previously created by calling the "CreateAdvancedSession" node. + * @param WorldContextObject + */ + UFUNCTION( + BlueprintCallable + , meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject") + , Category = "Online|AdvancedSessions" + ) + static UStartSessionCallbackProxyAdvanced* StartAdvancedSession(UObject* WorldContextObject); + + // UOnlineBlueprintCallProxyBase interface + virtual void Activate() override; + // End of UOnlineBlueprintCallProxyBase interface + +private: + // Internal callback when session start completes + void OnStartCompleted(FName SessionName, bool bWasSuccessful); + + // The delegate executed by the online subsystem + FOnStartSessionCompleteDelegate StartCompleteDelegate; + + // Handles to the registered delegates above + FDelegateHandle StartCompleteDelegateHandle; + + // The world context object in which this call is taking place + TWeakObjectPtr WorldContextObject; +}; \ No newline at end of file diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/UpdateSessionCallbackProxyAdvanced.h b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/UpdateSessionCallbackProxyAdvanced.h new file mode 100644 index 0000000..afdc181 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Classes/UpdateSessionCallbackProxyAdvanced.h @@ -0,0 +1,69 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "CoreMinimal.h" +#include "Engine/Engine.h" +#include "BlueprintDataDefinitions.h" +#include "UpdateSessionCallbackProxyAdvanced.generated.h" + +UCLASS(MinimalAPI) +class UUpdateSessionCallbackProxyAdvanced : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when the session was updated successfully + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnSuccess; + + // Called when there was an error updating the session + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnFailure; + + // Creates a session with the default online subsystem with advanced optional inputs, you MUST fill in all categories or it will pass in values that you didn't want as default values + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject",AutoCreateRefTerm="ExtraSettings"), Category = "Online|AdvancedSessions") + static UUpdateSessionCallbackProxyAdvanced* UpdateSession(UObject* WorldContextObject, const TArray &ExtraSettings, int32 PublicConnections = 100, int32 PrivateConnections = 0, bool bUseLAN = false, bool bAllowInvites = false, bool bAllowJoinInProgress = false, bool bRefreshOnlineData = true, bool bIsDedicatedServer = false, bool bShouldAdvertise = true); + + // UOnlineBlueprintCallProxyBase interface + virtual void Activate() override; + // End of UOnlineBlueprintCallProxyBase interface + +private: + // Internal callback when session creation completes, calls StartSession + void OnUpdateCompleted(FName SessionName, bool bWasSuccessful); + + // The delegate executed by the online subsystem + FOnUpdateSessionCompleteDelegate OnUpdateSessionCompleteDelegate; + + // Handles to the registered delegates above + FDelegateHandle OnUpdateSessionCompleteDelegateHandle; + + // Number of public connections + int NumPublicConnections = 100; + + // Number of private connections + int NumPrivateConnections = 0; + + // Whether or not to search LAN + bool bUseLAN = false; + + // Whether or not to allow invites + bool bAllowInvites = true; + + // Store extra settings + TArray ExtraSettings; + + // Whether to update the online data + bool bRefreshOnlineData = true; + + // Allow joining in progress + bool bAllowJoinInProgress = true; + + // Update whether this is a dedicated server or not + bool bDedicatedServer = false; + + bool bShouldAdvertise = true; + + // The world context object in which this call is taking place + TWeakObjectPtr WorldContextObject; +}; + diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedExternalUILibrary.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedExternalUILibrary.cpp new file mode 100644 index 0000000..a1792a1 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedExternalUILibrary.cpp @@ -0,0 +1,209 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "AdvancedExternalUILibrary.h" +#include "Engine/LocalPlayer.h" + + +//General Log +DEFINE_LOG_CATEGORY(AdvancedExternalUILog); + +void UAdvancedExternalUILibrary::ShowAccountUpgradeUI(UObject* WorldContextObject, const FBPUniqueNetId PlayerRequestingAccountUpgradeUI, EBlueprintResultSwitch &Result) +{ + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + IOnlineExternalUIPtr ExternalUIInterface = Online::GetExternalUIInterface(World); + + if (!ExternalUIInterface.IsValid()) + { + UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowAccountUpgradeUI Failed to get External UI interface!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + ExternalUIInterface->ShowAccountUpgradeUI(*PlayerRequestingAccountUpgradeUI.GetUniqueNetId()); + Result = EBlueprintResultSwitch::OnSuccess; +} + +void UAdvancedExternalUILibrary::ShowProfileUI(UObject* WorldContextObject, const FBPUniqueNetId PlayerViewingProfile, const FBPUniqueNetId PlayerToViewProfileOf, EBlueprintResultSwitch &Result) +{ + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + IOnlineExternalUIPtr ExternalUIInterface = Online::GetExternalUIInterface(World); + + if (!ExternalUIInterface.IsValid()) + { + UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowProfileUI Failed to get External UI interface!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + ExternalUIInterface->ShowProfileUI(*PlayerViewingProfile.GetUniqueNetId(), *PlayerToViewProfileOf.GetUniqueNetId(), NULL); + Result = EBlueprintResultSwitch::OnSuccess; +} + + + +void UAdvancedExternalUILibrary::ShowWebURLUI(UObject* WorldContextObject, FString URLToShow, EBlueprintResultSwitch &Result, TArray& AllowedDomains, bool bEmbedded, bool bShowBackground, bool bShowCloseButton, int32 OffsetX, int32 OffsetY, int32 SizeX, int32 SizeY) +{ + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + IOnlineExternalUIPtr ExternalUIInterface = Online::GetExternalUIInterface(World); + + if (!ExternalUIInterface.IsValid()) + { + UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowWebURLUI Failed to get External UI interface!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + URLToShow = URLToShow.Replace(TEXT("http://"), TEXT("")); + URLToShow = URLToShow.Replace(TEXT("https://"), TEXT("")); + + FShowWebUrlParams Params; + Params.AllowedDomains = AllowedDomains; + Params.bEmbedded = bEmbedded; + Params.bShowBackground = bShowBackground; + Params.bShowCloseButton = bShowCloseButton; + Params.OffsetX = OffsetX; + Params.OffsetY = OffsetY; + Params.SizeX = SizeX; + Params.SizeY = SizeY; + + ExternalUIInterface->ShowWebURL(URLToShow, Params); + Result = EBlueprintResultSwitch::OnSuccess; +} + +void UAdvancedExternalUILibrary::CloseWebURLUI(UObject* WorldContextObject) +{ + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return; + } + + IOnlineExternalUIPtr ExternalUIInterface = Online::GetExternalUIInterface(World); + + if (!ExternalUIInterface.IsValid()) + { + UE_LOG(AdvancedExternalUILog, Warning, TEXT("CloseWebURLUI Failed to get External UI interface!")); + return; + } + + ExternalUIInterface->CloseWebURL(); +} + +void UAdvancedExternalUILibrary::ShowLeaderBoardUI(UObject* WorldContextObject, FString LeaderboardName, EBlueprintResultSwitch &Result) +{ + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + IOnlineExternalUIPtr ExternalUIInterface = Online::GetExternalUIInterface(World); + + if (!ExternalUIInterface.IsValid()) + { + UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowLeaderboardsUI Failed to get External UI interface!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + ExternalUIInterface->ShowLeaderboardUI(LeaderboardName); + Result = EBlueprintResultSwitch::OnSuccess; + +} + + +void UAdvancedExternalUILibrary::ShowInviteUI(UObject* WorldContextObject, APlayerController *PlayerController, EBlueprintResultSwitch &Result) +{ + if (!PlayerController) + { + UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowInviteUI Had a bad Player Controller!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + IOnlineExternalUIPtr ExternalUIInterface = Online::GetExternalUIInterface(World); + + if (!ExternalUIInterface.IsValid()) + { + UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowInviteUI Failed to get External UI interface!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + ULocalPlayer* Player = Cast(PlayerController->Player); + + if (!Player) + { + UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowInviteUI Failed to get ULocalPlayer for the given PlayerController!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + ExternalUIInterface->ShowInviteUI(Player->GetControllerId(), NAME_GameSession); + Result = EBlueprintResultSwitch::OnSuccess; +} + +void UAdvancedExternalUILibrary::ShowFriendsUI(UObject* WorldContextObject, APlayerController *PlayerController, EBlueprintResultSwitch &Result) +{ + if (!PlayerController) + { + UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowFriendsUI Had a bad Player Controller!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + IOnlineExternalUIPtr ExternalUIInterface = Online::GetExternalUIInterface(World); + + if (!ExternalUIInterface.IsValid()) + { + UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowFriendsUI Failed to get External UI interface!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + ULocalPlayer* Player = Cast(PlayerController->Player); + + if (!Player) + { + UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowFriendsUI Failed to get ULocalPlayer for the given PlayerController!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + ExternalUIInterface->ShowFriendsUI(Player->GetControllerId()); + Result = EBlueprintResultSwitch::OnSuccess; +} \ No newline at end of file diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedFriendsGameInstance.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedFriendsGameInstance.cpp new file mode 100644 index 0000000..706bae5 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedFriendsGameInstance.cpp @@ -0,0 +1,369 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "AdvancedFriendsGameInstance.h" +#include "Kismet/GameplayStatics.h" +#include "GameFramework/PlayerController.h" + +//General Log +DEFINE_LOG_CATEGORY(AdvancedFriendsInterfaceLog); + +UAdvancedFriendsGameInstance::UAdvancedFriendsGameInstance(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , bCallFriendInterfaceEventsOnPlayerControllers(true) + , bCallIdentityInterfaceEventsOnPlayerControllers(true) + , bCallVoiceInterfaceEventsOnPlayerControllers(true) + , bEnableTalkingStatusDelegate(true) + , SessionInviteReceivedDelegate(FOnSessionInviteReceivedDelegate::CreateUObject(this, &ThisClass::OnSessionInviteReceivedMaster)) + , SessionInviteAcceptedDelegate(FOnSessionUserInviteAcceptedDelegate::CreateUObject(this, &ThisClass::OnSessionInviteAcceptedMaster)) + , PlayerTalkingStateChangedDelegate(FOnPlayerTalkingStateChangedDelegate::CreateUObject(this, &ThisClass::OnPlayerTalkingStateChangedMaster)) + , PlayerLoginChangedDelegate(FOnLoginChangedDelegate::CreateUObject(this, &ThisClass::OnPlayerLoginChangedMaster)) + , PlayerLoginStatusChangedDelegate(FOnLoginStatusChangedDelegate::CreateUObject(this, &ThisClass::OnPlayerLoginStatusChangedMaster)) +{ +} + +void UAdvancedFriendsGameInstance::OnSessionUserInviteAccepted(const bool bWasSuccessful, const int32 ControllerId, FUniqueNetIdPtr UserId, const FOnlineSessionSearchResult& InviteResult) +{ + IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); + if (SessionInterface.IsValid()) + { + SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(OnJoinSessionCompleteDelegateHandle); + OnJoinSessionCompleteDelegateHandle = SessionInterface->AddOnJoinSessionCompleteDelegate_Handle( + FOnJoinSessionCompleteDelegate::CreateUObject(this, &UAdvancedFriendsGameInstance::OnJoinSessionComplete)); + + SessionInterface->JoinSession(0, NAME_GameSession, InviteResult); + } + UE_LOG(AdvancedFriendsInterfaceLog, Log, TEXT("Called Join Session for Steam Friends List UI InviteResults: %s, UserId: %s"), *InviteResult.GetSessionIdStr(), *UserId->ToString()); +} + +void UAdvancedFriendsGameInstance::OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result) +{ + IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); + if (SessionInterface.IsValid()) + { + FString ConnectInfo; + if (SessionInterface->GetResolvedConnectString(NAME_GameSession, ConnectInfo)) + { + APlayerController* PlayerController = GetFirstLocalPlayerController(); + if (PlayerController) + { + PlayerController->ClientTravel(ConnectInfo, ETravelType::TRAVEL_Absolute); + } + } + } +} + +void UAdvancedFriendsGameInstance::Shutdown() +{ + IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); + + if (!SessionInterface.IsValid()) + { + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsGameInstance Failed to get session system!")); + //return; + } + else + { + // Clear all of the delegate handles here + SessionInterface->ClearOnSessionUserInviteAcceptedDelegate_Handle(SessionInviteAcceptedDelegateHandle); + SessionInterface->ClearOnSessionInviteReceivedDelegate_Handle(SessionInviteReceivedDelegateHandle); + SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(OnJoinSessionCompleteDelegateHandle); + } + + + if (bEnableTalkingStatusDelegate) + { + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(GetWorld()); + + if (VoiceInterface.IsValid()) + { + VoiceInterface->ClearOnPlayerTalkingStateChangedDelegate_Handle(PlayerTalkingStateChangedDelegateHandle); + } + else + { + + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get voice interface!")); + } + } + + IOnlineIdentityPtr IdentityInterface = Online::GetIdentityInterface(GetWorld()); + + if (IdentityInterface.IsValid()) + { + IdentityInterface->ClearOnLoginChangedDelegate_Handle(PlayerLoginChangedDelegateHandle); + + + // I am just defaulting to player 1 + IdentityInterface->ClearOnLoginStatusChangedDelegate_Handle(0, PlayerLoginStatusChangedDelegateHandle); + } + + + Super::Shutdown(); +} + +void UAdvancedFriendsGameInstance::Init() +{ + IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());//OnlineSub->GetSessionInterface(); + + if (SessionInterface.IsValid()) + { + // Currently doesn't store a handle or assign a delegate to any local player beyond the first.....should handle? + // Thought about directly handling it but friends for multiple players probably isn't required + // Iterating through the local player TArray only works if it has had players assigned to it, most of the online interfaces don't support + // Multiple logins either (IE: Steam) + SessionInviteAcceptedDelegateHandle = SessionInterface->AddOnSessionUserInviteAcceptedDelegate_Handle(SessionInviteAcceptedDelegate); + + SessionInviteReceivedDelegateHandle = SessionInterface->AddOnSessionInviteReceivedDelegate_Handle(SessionInviteReceivedDelegate); + + // Custom steam join game delegate + SessionInterface->OnSessionUserInviteAcceptedDelegates.AddUObject(this, &UAdvancedFriendsGameInstance::OnSessionUserInviteAccepted); + } + else + { + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get session interface!")); + //return; + } + + // Beginning work on the voice interface + if (bEnableTalkingStatusDelegate) + { + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(GetWorld()); + + if (VoiceInterface.IsValid()) + { + PlayerTalkingStateChangedDelegateHandle = VoiceInterface->AddOnPlayerTalkingStateChangedDelegate_Handle(PlayerTalkingStateChangedDelegate); + } + else + { + + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get voice interface!")); + } + } + + IOnlineIdentityPtr IdentityInterface = Online::GetIdentityInterface(GetWorld()); + + if (IdentityInterface.IsValid()) + { + PlayerLoginChangedDelegateHandle = IdentityInterface->AddOnLoginChangedDelegate_Handle(PlayerLoginChangedDelegate); + + // Just defaulting to player 1 + PlayerLoginStatusChangedDelegateHandle = IdentityInterface->AddOnLoginStatusChangedDelegate_Handle(0, PlayerLoginStatusChangedDelegate); + } + else + { + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get identity interface!")); + } + + + Super::Init(); +} + +/*void UAdvancedFriendsGameInstance::PostLoad() +{ + Super::PostLoad(); +}*/ + + +// Removed because it never gets called by the online subsystems +/*void UAdvancedFriendsGameInstance::OnSessionInviteReceivedMaster(const FUniqueNetId &InvitedPlayer, const FUniqueNetId &FriendInviting, const FOnlineSessionSearchResult& Session) +{ + // Just call the blueprint event to let the user handle this + + FBPUniqueNetId IP, FI; + + IP.SetUniqueNetId(&InvitedPlayer); + + FI.SetUniqueNetId(&FriendInviting); + + FBlueprintSessionResult BPS; + BPS.OnlineResult = Session; + OnSessionInviteReceived(IP,FI,BPS); + + TArray& PlayerArray = GetWorld()->GetGameState()->PlayerArray; + const TArray&ControllerArray = this->GetLocalPlayers(); + + for (int i = 0; i < ControllerArray.Num(); i++) + { + if (*PlayerArray[ControllerArray[i]->PlayerController->NetPlayerIndex]->UniqueId.GetUniqueNetId().Get() == InvitedPlayer) + { + //Run the Event specific to the actor, if the actor has the interface, otherwise ignore + if (ControllerArray[i]->PlayerController->GetClass()->ImplementsInterface(UAdvancedFriendsInterface::StaticClass())) + { + IAdvancedFriendsInterface::Execute_OnSessionInviteReceived(ControllerArray[i]->PlayerController, FI, BPS); + } + break; + } + } +}*/ + +void UAdvancedFriendsGameInstance::OnPlayerLoginStatusChangedMaster(int32 PlayerNum, ELoginStatus::Type PreviousStatus, ELoginStatus::Type NewStatus, const FUniqueNetId & NewPlayerUniqueNetID) +{ + EBPLoginStatus OrigStatus = (EBPLoginStatus)PreviousStatus; + EBPLoginStatus CurrentStatus = (EBPLoginStatus)NewStatus; + FBPUniqueNetId PlayerID; + PlayerID.SetUniqueNetId(&NewPlayerUniqueNetID); + + OnPlayerLoginStatusChanged(PlayerNum, OrigStatus,CurrentStatus,PlayerID); + + + if (bCallIdentityInterfaceEventsOnPlayerControllers) + { + APlayerController* Player = UGameplayStatics::GetPlayerController(GetWorld(), PlayerNum); + + if (Player != NULL) + { + //Run the Event specific to the actor, if the actor has the interface, otherwise ignore + if (Player->GetClass()->ImplementsInterface(UAdvancedFriendsInterface::StaticClass())) + { + IAdvancedFriendsInterface::Execute_OnPlayerLoginStatusChanged(Player, OrigStatus, CurrentStatus, PlayerID); + } + } + else + { + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get a controller with the specified index in OnPlayerLoginStatusChangedMaster!")); + } + } +} + +void UAdvancedFriendsGameInstance::OnPlayerLoginChangedMaster(int32 PlayerNum) +{ + OnPlayerLoginChanged(PlayerNum); + + if (bCallIdentityInterfaceEventsOnPlayerControllers) + { + APlayerController* Player = UGameplayStatics::GetPlayerController(GetWorld(), PlayerNum); + + if (Player != NULL) + { + //Run the Event specific to the actor, if the actor has the interface, otherwise ignore + if (Player->GetClass()->ImplementsInterface(UAdvancedFriendsInterface::StaticClass())) + { + IAdvancedFriendsInterface::Execute_OnPlayerLoginChanged(Player, PlayerNum); + } + } + else + { + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get a controller with the specified index in OnPlayerLoginChanged!")); + } + } +} + +void UAdvancedFriendsGameInstance::OnPlayerTalkingStateChangedMaster(TSharedRef PlayerId, bool bIsTalking) +{ + FBPUniqueNetId PlayerTalking; + PlayerTalking.SetUniqueNetId(PlayerId); + OnPlayerTalkingStateChanged(PlayerTalking, bIsTalking); + + if (bCallVoiceInterfaceEventsOnPlayerControllers) + { + APlayerController* Player = NULL; + + for (const ULocalPlayer* LPlayer : LocalPlayers) + { + Player = UGameplayStatics::GetPlayerController(GetWorld(), LPlayer->GetControllerId()); + + if (Player != NULL) + { + //Run the Event specific to the actor, if the actor has the interface, otherwise ignore + if (Player->GetClass()->ImplementsInterface(UAdvancedFriendsInterface::StaticClass())) + { + IAdvancedFriendsInterface::Execute_OnPlayerVoiceStateChanged(Player, PlayerTalking, bIsTalking); + } + } + else + { + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get a controller with the specified index in OnVoiceStateChanged!")); + } + } + } +} + +void UAdvancedFriendsGameInstance::OnSessionInviteReceivedMaster(const FUniqueNetId & PersonInvited, const FUniqueNetId & PersonInviting, const FString& AppId, const FOnlineSessionSearchResult& SessionToJoin) +{ + if (SessionToJoin.IsValid()) + { + FBlueprintSessionResult BluePrintResult; + BluePrintResult.OnlineResult = SessionToJoin; + + FBPUniqueNetId PInvited; + PInvited.SetUniqueNetId(&PersonInvited); + + FBPUniqueNetId PInviting; + PInviting.SetUniqueNetId(&PersonInviting); + + + TArray PlayerList; + GEngine->GetAllLocalPlayerControllers(PlayerList); + + APlayerController* Player = NULL; + + int32 LocalPlayer = 0; + for (int i = 0; i < PlayerList.Num(); i++) + { + if (*PlayerList[i]->PlayerState->GetUniqueId().GetUniqueNetId() == PersonInvited) + { + LocalPlayer = i; + Player = PlayerList[i]; + break; + } + } + + OnSessionInviteReceived(LocalPlayer, PInviting, AppId, BluePrintResult); + + //IAdvancedFriendsInterface* TheInterface = NULL; + + if (Player != NULL) + { + //Run the Event specific to the actor, if the actor has the interface, otherwise ignore + if (Player->GetClass()->ImplementsInterface(UAdvancedFriendsInterface::StaticClass())) + { + IAdvancedFriendsInterface::Execute_OnSessionInviteReceived(Player, PInviting, BluePrintResult); + } + } + else + { + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get a controller with the specified index in OnSessionInviteReceived!")); + } + } + else + { + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Return a bad search result in OnSessionInviteReceived!")); + } +} + +void UAdvancedFriendsGameInstance::OnSessionInviteAcceptedMaster(const bool bWasSuccessful, int32 LocalPlayer, TSharedPtr PersonInvited, const FOnlineSessionSearchResult& SessionToJoin) +{ + if (bWasSuccessful) + { + if (SessionToJoin.IsValid()) + { + + FBlueprintSessionResult BluePrintResult; + BluePrintResult.OnlineResult = SessionToJoin; + + FBPUniqueNetId PInvited; + PInvited.SetUniqueNetId(PersonInvited); + + OnSessionInviteAccepted(LocalPlayer,PInvited, BluePrintResult); + + APlayerController* Player = UGameplayStatics::GetPlayerController(GetWorld(), LocalPlayer); + + //IAdvancedFriendsInterface* TheInterface = NULL; + + if (Player != NULL) + { + //Run the Event specific to the actor, if the actor has the interface, otherwise ignore + if (Player->GetClass()->ImplementsInterface(UAdvancedFriendsInterface::StaticClass())) + { + IAdvancedFriendsInterface::Execute_OnSessionInviteAccepted(Player,PInvited, BluePrintResult); + } + } + else + { + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get a controller with the specified index in OnSessionInviteAccepted!")); + } + } + else + { + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Return a bad search result in OnSessionInviteAccepted!")); + } + } +} \ No newline at end of file diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedFriendsInterface.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedFriendsInterface.cpp new file mode 100644 index 0000000..92e5138 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedFriendsInterface.cpp @@ -0,0 +1,9 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "AdvancedFriendsInterface.h" + + + +UAdvancedFriendsInterface::UAdvancedFriendsInterface(const class FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ +} diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedFriendsLibrary.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedFriendsLibrary.cpp new file mode 100644 index 0000000..5df1a94 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedFriendsLibrary.cpp @@ -0,0 +1,281 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "AdvancedFriendsLibrary.h" + + + +// This is taken directly from UE4 - OnlineSubsystemSteamPrivatePCH.h as a fix for the array_count macro + +//General Log +DEFINE_LOG_CATEGORY(AdvancedFriendsLog); + +void UAdvancedFriendsLibrary::SendSessionInviteToFriends(APlayerController *PlayerController, const TArray &Friends, EBlueprintResultSwitch &Result) +{ + if (!PlayerController) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Had a bad Player Controller!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + if (Friends.Num() < 1) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Had no friends in invitation array!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(); + + if (!SessionInterface.IsValid()) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Failed to get session interface!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + ULocalPlayer* Player = Cast(PlayerController->Player); + + if (!Player) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend failed to get LocalPlayer!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + TArray> List; + for (int i = 0; i < Friends.Num(); i++) + { + TSharedRef val(Friends[i].UniqueNetId.ToSharedRef()); + //TSharedRef val(Friends[i].GetUniqueNetId()); + List.Add(val); + } + + if (SessionInterface->SendSessionInviteToFriends(Player->GetControllerId(), NAME_GameSession, List)) + { + Result = EBlueprintResultSwitch::OnSuccess; + return; + } + + Result = EBlueprintResultSwitch::OnFailure; + return; +} + +void UAdvancedFriendsLibrary::SendSessionInviteToFriend(APlayerController *PlayerController, const FBPUniqueNetId &FriendUniqueNetId, EBlueprintResultSwitch &Result) +{ + if (!PlayerController) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Had a bad Player Controller!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + if (!FriendUniqueNetId.IsValid()) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Had a bad UniqueNetId!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(); + + if (!SessionInterface.IsValid()) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Failed to get session interface!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + ULocalPlayer* Player = Cast(PlayerController->Player); + + if (!Player) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend failed to get LocalPlayer!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + if (SessionInterface->SendSessionInviteToFriend(Player->GetControllerId(), NAME_GameSession, *FriendUniqueNetId.GetUniqueNetId())) + { + Result = EBlueprintResultSwitch::OnSuccess; + return; + } + + Result = EBlueprintResultSwitch::OnFailure; + return; +} + +void UAdvancedFriendsLibrary::GetFriend(APlayerController *PlayerController, const FBPUniqueNetId FriendUniqueNetId, FBPFriendInfo &Friend) +{ + + if (!PlayerController) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriend Had a bad Player Controller!")); + return; + } + + if (!FriendUniqueNetId.IsValid()) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriend Had a bad UniqueNetId!")); + return; + } + + IOnlineFriendsPtr FriendsInterface = Online::GetFriendsInterface(); + + if (!FriendsInterface.IsValid()) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriend Failed to get friends interface!")); + return; + } + + ULocalPlayer* Player = Cast(PlayerController->Player); + + if (!Player) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriend failed to get LocalPlayer!")); + return; + } + + TSharedPtr fr = FriendsInterface->GetFriend(Player->GetControllerId(), *FriendUniqueNetId.GetUniqueNetId(), EFriendsLists::ToString(EFriendsLists::Default)); + if (fr.IsValid()) + { + const FOnlineUserPresence& pres = fr->GetPresence(); + Friend.DisplayName = fr->GetDisplayName(); + Friend.OnlineState = ((EBPOnlinePresenceState)((int32)pres.Status.State)); + Friend.RealName = fr->GetRealName(); + Friend.UniqueNetId.SetUniqueNetId(fr->GetUserId()); + Friend.bIsPlayingSameGame = pres.bIsPlayingThisGame; + + Friend.PresenceInfo.bHasVoiceSupport = pres.bHasVoiceSupport; + Friend.PresenceInfo.bIsJoinable = pres.bIsJoinable; + Friend.PresenceInfo.bIsOnline = pres.bIsOnline; + Friend.PresenceInfo.bIsPlaying = pres.bIsPlaying; + Friend.PresenceInfo.bIsPlayingThisGame = pres.bIsPlayingThisGame; + Friend.PresenceInfo.PresenceState = ((EBPOnlinePresenceState)((int32)pres.Status.State)); + // #TODO: Check back in on this in shipping, epic is missing the UTF8_TO_TCHAR call on converting this and its making an invalid string + //Friend.PresenceInfo.StatusString = pres.Status.StatusStr; + } +} + +void UAdvancedFriendsLibrary::IsAFriend(APlayerController *PlayerController, const FBPUniqueNetId UniqueNetId, bool &IsFriend) +{ + if (!PlayerController) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("IsAFriend Had a bad Player Controller!")); + return; + } + + if (!UniqueNetId.IsValid()) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("IsAFriend Had a bad UniqueNetId!")); + return; + } + + IOnlineFriendsPtr FriendsInterface = Online::GetFriendsInterface(); + + if (!FriendsInterface.IsValid()) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("IsAFriend Failed to get friends interface!")); + return; + } + + ULocalPlayer* Player = Cast(PlayerController->Player); + + if (!Player) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("IsAFriend Failed to get LocalPlayer!")); + return; + } + + IsFriend = FriendsInterface->IsFriend(Player->GetControllerId(), *UniqueNetId.GetUniqueNetId(), EFriendsLists::ToString(EFriendsLists::Default)); +} + +void UAdvancedFriendsLibrary::GetStoredRecentPlayersList(FBPUniqueNetId UniqueNetId, TArray &PlayersList) +{ + IOnlineFriendsPtr FriendsInterface = Online::GetFriendsInterface(); + + if (!FriendsInterface.IsValid()) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetRecentPlayersList Failed to get friends interface!")); + return; + } + + if (!UniqueNetId.IsValid()) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetRecentPlayersList Failed was given an invalid UniqueNetId!")); + return; + } + + TArray< TSharedRef > PlayerList; + + // For now getting all namespaces + FriendsInterface->GetRecentPlayers(*(UniqueNetId.GetUniqueNetId()),"", PlayerList); + + for (int32 i = 0; i < PlayerList.Num(); i++) + { + TSharedRef Player = PlayerList[i]; + FBPOnlineRecentPlayer BPF; + BPF.DisplayName = Player->GetDisplayName(); + BPF.RealName = Player->GetRealName(); + BPF.UniqueNetId.SetUniqueNetId(Player->GetUserId()); + PlayersList.Add(BPF); + } +} + +void UAdvancedFriendsLibrary::GetStoredFriendsList(APlayerController *PlayerController, TArray &FriendsList) +{ + + if (!PlayerController) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriendsList Had a bad Player Controller!")); + return; + } + + IOnlineFriendsPtr FriendsInterface = Online::GetFriendsInterface(); + + if (!FriendsInterface.IsValid()) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriendsList Failed to get friends interface!")); + return; + } + + ULocalPlayer* Player = Cast(PlayerController->Player); + + if (!Player) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriendsList Failed to get LocalPlayer!")); + return; + } + + + TArray< TSharedRef > FriendList; + if (FriendsInterface->GetFriendsList(Player->GetControllerId(), EFriendsLists::ToString((EFriendsLists::Default)), FriendList)) + { + for (int32 i = 0; i < FriendList.Num(); i++) + { + FBPFriendInfo BPF; + const FOnlineUserPresence& pres = FriendList[i]->GetPresence(); + + BPF.OnlineState = ((EBPOnlinePresenceState)((int32)pres.Status.State)); + BPF.DisplayName = FriendList[i]->GetDisplayName(); + BPF.RealName = FriendList[i]->GetRealName(); + BPF.UniqueNetId.SetUniqueNetId(FriendList[i]->GetUserId()); + BPF.bIsPlayingSameGame = pres.bIsPlayingThisGame; + + BPF.PresenceInfo.bIsOnline = pres.bIsOnline; + BPF.PresenceInfo.bHasVoiceSupport = pres.bHasVoiceSupport; + BPF.PresenceInfo.bIsPlaying = pres.bIsPlaying; + BPF.PresenceInfo.PresenceState = ((EBPOnlinePresenceState)((int32)pres.Status.State)); + // #TODO: Check back in on this in shipping, epic is missing the UTF8_TO_TCHAR call on converting this and its making an invalid string + //BPF.PresenceInfo.StatusString = pres.Status.StatusStr; + BPF.PresenceInfo.bIsJoinable = pres.bIsJoinable; + BPF.PresenceInfo.bIsPlayingThisGame = pres.bIsPlayingThisGame; + + FriendsList.Add(BPF); + } + + return; + } + + UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriendsList Failed to get any friends!")); + return; +} \ No newline at end of file diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedIdentityLibrary.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedIdentityLibrary.cpp new file mode 100644 index 0000000..47a554b --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedIdentityLibrary.cpp @@ -0,0 +1,271 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "AdvancedIdentityLibrary.h" + +//General Log +DEFINE_LOG_CATEGORY(AdvancedIdentityLog); + + +void UAdvancedIdentityLibrary::GetPlayerAuthToken(UObject* WorldContextObject, APlayerController * PlayerController, FString & AuthToken, EBlueprintResultSwitch &Result) +{ + if (!PlayerController) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetPlayerAuthToken was passed a bad player controller!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + ULocalPlayer* Player = Cast(PlayerController->Player); + + if (!Player) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetPlayerAuthToken failed to get LocalPlayer!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + IOnlineIdentityPtr IdentityInterface = Online::GetIdentityInterface(World); + + if (!IdentityInterface.IsValid()) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetPlayerAuthToken Failed to get identity interface!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + AuthToken = IdentityInterface->GetAuthToken(Player->GetControllerId()); + Result = EBlueprintResultSwitch::OnSuccess; +} + +void UAdvancedIdentityLibrary::GetPlayerNickname(UObject* WorldContextObject, const FBPUniqueNetId & UniqueNetID, FString & PlayerNickname) +{ + if (!UniqueNetID.IsValid()) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetPlayerNickname was passed a bad player uniquenetid!")); + return; + } + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return; + } + + IOnlineIdentityPtr IdentityInterface = Online::GetIdentityInterface(World); + + if (!IdentityInterface.IsValid()) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetPlayerNickname Failed to get identity interface!")); + return; + } + PlayerNickname = IdentityInterface->GetPlayerNickname(*UniqueNetID.GetUniqueNetId()); +} + + +void UAdvancedIdentityLibrary::GetLoginStatus(UObject* WorldContextObject, const FBPUniqueNetId & UniqueNetID, EBPLoginStatus & LoginStatus, EBlueprintResultSwitch &Result) +{ + if (!UniqueNetID.IsValid()) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetLoginStatus was passed a bad player uniquenetid!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + IOnlineIdentityPtr IdentityInterface = Online::GetIdentityInterface(World); + + if (!IdentityInterface.IsValid()) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetLoginStatus Failed to get identity interface!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + LoginStatus = (EBPLoginStatus)IdentityInterface->GetLoginStatus(*UniqueNetID.GetUniqueNetId()); + Result = EBlueprintResultSwitch::OnSuccess; +} + + +void UAdvancedIdentityLibrary::GetAllUserAccounts(UObject* WorldContextObject, TArray & AccountInfos, EBlueprintResultSwitch &Result) +{ + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + IOnlineIdentityPtr IdentityInterface = Online::GetIdentityInterface(World); + + if (!IdentityInterface.IsValid()) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetAllUserAccounts Failed to get identity interface!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + TArray> accountInfos = IdentityInterface->GetAllUserAccounts(); + + for (int i = 0; i < accountInfos.Num(); ++i) + { + AccountInfos.Add(FBPUserOnlineAccount(accountInfos[i])); + } + + Result = EBlueprintResultSwitch::OnSuccess; +} + +void UAdvancedIdentityLibrary::GetUserAccount(UObject* WorldContextObject, const FBPUniqueNetId & UniqueNetId, FBPUserOnlineAccount & AccountInfo, EBlueprintResultSwitch &Result) +{ + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + IOnlineIdentityPtr IdentityInterface = Online::GetIdentityInterface(World); + + if(!UniqueNetId.IsValid()) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccount was passed a bad unique net id!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + if (!IdentityInterface.IsValid()) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccount Failed to get identity interface!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + TSharedPtr accountInfo = IdentityInterface->GetUserAccount(*UniqueNetId.GetUniqueNetId()); + + if (!accountInfo.IsValid()) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccount Failed to get the account!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + AccountInfo.UserAccountInfo = accountInfo; + Result = EBlueprintResultSwitch::OnSuccess; +} + +void UAdvancedIdentityLibrary::GetUserAccountAccessToken(const FBPUserOnlineAccount & AccountInfo, FString & AccessToken) +{ + if (!AccountInfo.UserAccountInfo.IsValid()) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccountAccessToken was passed an invalid account!")); + return; + } + + AccessToken = AccountInfo.UserAccountInfo->GetAccessToken(); +} + +void UAdvancedIdentityLibrary::GetUserAccountAuthAttribute(const FBPUserOnlineAccount & AccountInfo, const FString & AttributeName, FString & AuthAttribute, EBlueprintResultSwitch &Result) +{ + if (!AccountInfo.UserAccountInfo.IsValid()) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccountAuthAttribute was passed an invalid account!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + if (!AccountInfo.UserAccountInfo->GetAuthAttribute(AttributeName, AuthAttribute)) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccountAuthAttribute couldn't find the attribute!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + Result = EBlueprintResultSwitch::OnSuccess; +} + +void UAdvancedIdentityLibrary::SetUserAccountAttribute(const FBPUserOnlineAccount & AccountInfo, const FString & AttributeName, const FString & NewAttributeValue, EBlueprintResultSwitch &Result) +{ + if (!AccountInfo.UserAccountInfo.IsValid()) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("SetUserAccountAuthAttribute was passed an invalid account!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + if (!AccountInfo.UserAccountInfo->SetUserAttribute(AttributeName, NewAttributeValue)) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("SetUserAccountAuthAttribute was unable to set the attribute!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + Result = EBlueprintResultSwitch::OnSuccess; +} + +void UAdvancedIdentityLibrary::GetUserID(const FBPUserOnlineAccount & AccountInfo, FBPUniqueNetId & UniqueNetID) +{ + if (!AccountInfo.UserAccountInfo.IsValid()) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserID was passed an invalid account!")); + return; + } + + + UniqueNetID.SetUniqueNetId(AccountInfo.UserAccountInfo->GetUserId()); +} + +void UAdvancedIdentityLibrary::GetUserAccountRealName(const FBPUserOnlineAccount & AccountInfo, FString & UserName) +{ + if (!AccountInfo.UserAccountInfo.IsValid()) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccountRealName was passed an invalid account!")); + return; + } + + + UserName = AccountInfo.UserAccountInfo->GetRealName(); +} + +void UAdvancedIdentityLibrary::GetUserAccountDisplayName(const FBPUserOnlineAccount & AccountInfo, FString & DisplayName) +{ + if (!AccountInfo.UserAccountInfo.IsValid()) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccountDisplayName was passed an invalid account!")); + return; + } + + + DisplayName = AccountInfo.UserAccountInfo->GetDisplayName(); +} + +void UAdvancedIdentityLibrary::GetUserAccountAttribute(const FBPUserOnlineAccount & AccountInfo, const FString & AttributeName, FString & AttributeValue, EBlueprintResultSwitch &Result) +{ + if (!AccountInfo.UserAccountInfo.IsValid()) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccountAttribute was passed an invalid account!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + if (!AccountInfo.UserAccountInfo->GetUserAttribute(AttributeName, AttributeValue)) + { + UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccountAttribute failed to get user attribute!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + Result = EBlueprintResultSwitch::OnSuccess; +} \ No newline at end of file diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedSessions.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedSessions.cpp new file mode 100644 index 0000000..8a12271 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedSessions.cpp @@ -0,0 +1,12 @@ +//#include "StandAlonePrivatePCH.h" +#include "AdvancedSessions.h" + +void AdvancedSessions::StartupModule() +{ +} + +void AdvancedSessions::ShutdownModule() +{ +} + +IMPLEMENT_MODULE(AdvancedSessions, AdvancedSessions) \ No newline at end of file diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedSessionsLibrary.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedSessionsLibrary.cpp new file mode 100644 index 0000000..a5453d1 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedSessionsLibrary.cpp @@ -0,0 +1,552 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "AdvancedSessionsLibrary.h" +#include "GameFramework/PlayerState.h" +#include "GameFramework/GameStateBase.h" + +//General Log +DEFINE_LOG_CATEGORY(AdvancedSessionsLog); + + +bool UAdvancedSessionsLibrary::KickPlayer(UObject* WorldContextObject, APlayerController* PlayerToKick, FText KickReason) +{ + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + + if (World) + { + if (AGameModeBase* GameMode = World->GetAuthGameMode()) + { + if (GameMode->GameSession) + { + return GameMode->GameSession->KickPlayer(PlayerToKick, KickReason); + } + } + } + + return false; +} + +bool UAdvancedSessionsLibrary::BanPlayer(UObject* WorldContextObject, APlayerController* PlayerToBan, FText BanReason) +{ + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + + if (World) + { + if (AGameModeBase* GameMode = World->GetAuthGameMode()) + { + if (GameMode->GameSession) + { + return GameMode->GameSession->BanPlayer(PlayerToBan, BanReason); + } + } + } + + return false; +} + +bool UAdvancedSessionsLibrary::IsValidSession(const FBlueprintSessionResult & SessionResult) +{ + return SessionResult.OnlineResult.IsValid(); +} + +void UAdvancedSessionsLibrary::GetSessionID_AsString(const FBlueprintSessionResult & SessionResult, FString& SessionID) +{ + const TSharedPtr SessionInfo = SessionResult.OnlineResult.Session.SessionInfo; + if (SessionInfo.IsValid() && SessionInfo->IsValid() && SessionInfo->GetSessionId().IsValid()) + { + SessionID = SessionInfo->GetSessionId().ToString(); + return; + } + + // Zero the string out if we didn't have a valid one, in case this is called in c++ + SessionID.Empty(); +} + +void UAdvancedSessionsLibrary::GetCurrentSessionID_AsString(UObject* WorldContextObject, FString& SessionID) +{ + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(World); + + if (!SessionInterface.IsValid()) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetCurrentSessionID_AsString couldn't get the session interface!")); + SessionID.Empty(); + return; + } + + const FNamedOnlineSession* Session = SessionInterface->GetNamedSession(NAME_GameSession); + if (Session != nullptr) + { + const TSharedPtr SessionInfo = Session->SessionInfo; + if (SessionInfo.IsValid() && SessionInfo->IsValid() && SessionInfo->GetSessionId().IsValid()) + { + SessionID = SessionInfo->GetSessionId().ToString(); + return; + } + } + + // Zero the string out if we didn't have a valid one, in case this is called in c++ + SessionID.Empty(); +} + +void UAdvancedSessionsLibrary::GetCurrentUniqueBuildID(int32 &UniqueBuildId) +{ + UniqueBuildId = GetBuildUniqueId(); +} + +void UAdvancedSessionsLibrary::GetUniqueBuildID(FBlueprintSessionResult SessionResult, int32 &UniqueBuildId) +{ + UniqueBuildId = SessionResult.OnlineResult.Session.SessionSettings.BuildUniqueId; +} + +FName UAdvancedSessionsLibrary::GetSessionPropertyKey(const FSessionPropertyKeyPair& SessionProperty) +{ + return SessionProperty.Key; +} + +void UAdvancedSessionsLibrary::FindSessionPropertyByName(const TArray& ExtraSettings, FName SettingName, EBlueprintResultSwitch &Result, FSessionPropertyKeyPair& OutProperty) +{ + const FSessionPropertyKeyPair* prop = ExtraSettings.FindByPredicate([&](const FSessionPropertyKeyPair& it) {return it.Key == SettingName; }); + if (prop) + { + Result = EBlueprintResultSwitch::OnSuccess; + OutProperty = *prop; + return; + } + + Result = EBlueprintResultSwitch::OnFailure; +} + +void UAdvancedSessionsLibrary::FindSessionPropertyIndexByName(const TArray& ExtraSettings, FName SettingName, EBlueprintResultSwitch &Result, int32& OutIndex) +{ + OutIndex = ExtraSettings.IndexOfByPredicate([&](const FSessionPropertyKeyPair& it) {return it.Key == SettingName; }); + + Result = OutIndex != INDEX_NONE ? EBlueprintResultSwitch::OnSuccess : EBlueprintResultSwitch::OnFailure; +} + +void UAdvancedSessionsLibrary::AddOrModifyExtraSettings(UPARAM(ref) TArray & SettingsArray, UPARAM(ref) TArray & NewOrChangedSettings, TArray & ModifiedSettingsArray) +{ + ModifiedSettingsArray = SettingsArray; + + bool bFoundSetting = false; + // For each new setting + for (const FSessionPropertyKeyPair& Setting : NewOrChangedSettings) + { + bFoundSetting = false; + + for (FSessionPropertyKeyPair & itr : ModifiedSettingsArray) + { + // Manually comparing the keys + if (itr.Key == Setting.Key) + { + bFoundSetting = true; + itr.Data = Setting.Data; + } + } + + // If it was not found, add to the array instead + if (!bFoundSetting) + { + ModifiedSettingsArray.Add(Setting); + } + } + +} + +void UAdvancedSessionsLibrary::GetExtraSettings(FBlueprintSessionResult SessionResult, TArray & ExtraSettings) +{ + FSessionPropertyKeyPair NewSetting; + for (auto& Elem : SessionResult.OnlineResult.Session.SessionSettings.Settings) + { + NewSetting.Key = Elem.Key; + NewSetting.Data = Elem.Value.Data; + ExtraSettings.Add(NewSetting); + } +} + +void UAdvancedSessionsLibrary::GetSessionState(UObject* WorldContextObject, EBPOnlineSessionState &SessionState) +{ + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(World); + + if (!SessionInterface.IsValid()) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetSessionState couldn't get the session interface!")); + return; + } + + SessionState = ((EBPOnlineSessionState)SessionInterface->GetSessionState(NAME_GameSession)); +} + +void UAdvancedSessionsLibrary::GetSessionSettings(UObject* WorldContextObject, int32 &NumConnections, int32 &NumPrivateConnections, bool &bIsLAN, bool &bIsDedicated, bool &bAllowInvites, bool &bAllowJoinInProgress, bool &bIsAnticheatEnabled, int32 &BuildUniqueID, TArray &ExtraSettings, EBlueprintResultSwitch &Result) +{ + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(World); + + if (!SessionInterface.IsValid()) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetSessionSettings couldn't get the session interface!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + FOnlineSessionSettings* settings = SessionInterface->GetSessionSettings(NAME_GameSession); + if (!settings) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetSessionSettings couldn't get the session settings!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + BuildUniqueID = settings->BuildUniqueId; + NumConnections = settings->NumPublicConnections; + NumPrivateConnections = settings->NumPrivateConnections; + bIsLAN = settings->bIsLANMatch; + bIsDedicated = settings->bIsDedicated; + bIsAnticheatEnabled = settings->bAntiCheatProtected; + bAllowInvites = settings->bAllowInvites; + bAllowJoinInProgress = settings->bAllowJoinInProgress; + + FSessionPropertyKeyPair NewSetting; + + for (auto& Elem : settings->Settings) + { + NewSetting.Key = Elem.Key; + NewSetting.Data = Elem.Value.Data; + ExtraSettings.Add(NewSetting); + } + + Result = EBlueprintResultSwitch::OnSuccess; +} + +void UAdvancedSessionsLibrary::IsPlayerInSession(UObject* WorldContextObject, const FBPUniqueNetId &PlayerToCheck, bool &bIsInSession) +{ + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(World); + + if (!SessionInterface.IsValid()) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("IsPlayerInSession couldn't get the session interface!")); + bIsInSession = false; + return; + } + + bIsInSession = SessionInterface->IsPlayerInSession(NAME_GameSession, *PlayerToCheck.GetUniqueNetId()); +} + +FSessionsSearchSetting UAdvancedSessionsLibrary::MakeLiteralSessionSearchProperty(FSessionPropertyKeyPair SessionSearchProperty, EOnlineComparisonOpRedux ComparisonOp) +{ + FSessionsSearchSetting setting; + setting.PropertyKeyPair = SessionSearchProperty; + setting.ComparisonOp = ComparisonOp; + + return setting; +} + +FSessionPropertyKeyPair UAdvancedSessionsLibrary::MakeLiteralSessionPropertyByte(FName Key, uint8 Value) +{ + FSessionPropertyKeyPair Prop; + Prop.Key = Key; + Prop.Data.SetValue((int32)Value); + return Prop; +} + +FSessionPropertyKeyPair UAdvancedSessionsLibrary::MakeLiteralSessionPropertyBool(FName Key, bool Value) +{ + FSessionPropertyKeyPair Prop; + Prop.Key = Key; + Prop.Data.SetValue(Value); + return Prop; +} + +FSessionPropertyKeyPair UAdvancedSessionsLibrary::MakeLiteralSessionPropertyString(FName Key, FString Value) +{ + FSessionPropertyKeyPair Prop; + Prop.Key = Key; + Prop.Data.SetValue(Value); + return Prop; +} + +FSessionPropertyKeyPair UAdvancedSessionsLibrary::MakeLiteralSessionPropertyInt(FName Key, int32 Value) +{ + FSessionPropertyKeyPair Prop; + Prop.Key = Key; + Prop.Data.SetValue(Value); + return Prop; +} + +FSessionPropertyKeyPair UAdvancedSessionsLibrary::MakeLiteralSessionPropertyFloat(FName Key, float Value) +{ + FSessionPropertyKeyPair Prop; + Prop.Key = Key; + Prop.Data.SetValue(Value); + return Prop; +} + +void UAdvancedSessionsLibrary::GetSessionPropertyByte(const TArray & ExtraSettings, FName SettingName, ESessionSettingSearchResult &SearchResult, uint8 &SettingValue) +{ + for (FSessionPropertyKeyPair itr : ExtraSettings) + { + if (itr.Key == SettingName) + { + if (itr.Data.GetType() == EOnlineKeyValuePairDataType::Int32) + { + int32 Val; + itr.Data.GetValue(Val); + SettingValue = (uint8)(Val); + SearchResult = ESessionSettingSearchResult::Found; + } + else + { + SearchResult = ESessionSettingSearchResult::WrongType; + } + return; + } + } + + SearchResult = ESessionSettingSearchResult::NotFound; + return; +} + +void UAdvancedSessionsLibrary::GetSessionPropertyBool(const TArray & ExtraSettings, FName SettingName, ESessionSettingSearchResult &SearchResult, bool &SettingValue) +{ + for (FSessionPropertyKeyPair itr : ExtraSettings) + { + if (itr.Key == SettingName) + { + if (itr.Data.GetType() == EOnlineKeyValuePairDataType::Bool) + { + itr.Data.GetValue(SettingValue); + SearchResult = ESessionSettingSearchResult::Found; + } + else + { + SearchResult = ESessionSettingSearchResult::WrongType; + } + return; + } + } + + SearchResult = ESessionSettingSearchResult::NotFound; + return; +} + +void UAdvancedSessionsLibrary::GetSessionPropertyString(const TArray & ExtraSettings, FName SettingName, ESessionSettingSearchResult &SearchResult, FString &SettingValue) +{ + for (FSessionPropertyKeyPair itr : ExtraSettings) + { + if (itr.Key == SettingName) + { + if (itr.Data.GetType() == EOnlineKeyValuePairDataType::String) + { + itr.Data.GetValue(SettingValue); + SearchResult = ESessionSettingSearchResult::Found; + } + else + { + SearchResult = ESessionSettingSearchResult::WrongType; + } + return; + } + } + + SearchResult = ESessionSettingSearchResult::NotFound; + return; +} + +void UAdvancedSessionsLibrary::GetSessionPropertyInt(const TArray & ExtraSettings, FName SettingName, ESessionSettingSearchResult &SearchResult, int32 &SettingValue) +{ + for (FSessionPropertyKeyPair itr : ExtraSettings) + { + if (itr.Key == SettingName) + { + if (itr.Data.GetType() == EOnlineKeyValuePairDataType::Int32) + { + itr.Data.GetValue(SettingValue); + SearchResult = ESessionSettingSearchResult::Found; + } + else + { + SearchResult = ESessionSettingSearchResult::WrongType; + } + return; + } + } + + SearchResult = ESessionSettingSearchResult::NotFound; + return; +} + +void UAdvancedSessionsLibrary::GetSessionPropertyFloat(const TArray & ExtraSettings, FName SettingName, ESessionSettingSearchResult &SearchResult, float &SettingValue) +{ + for (FSessionPropertyKeyPair itr : ExtraSettings) + { + if (itr.Key == SettingName) + { + if (itr.Data.GetType() == EOnlineKeyValuePairDataType::Float) + { + itr.Data.GetValue(SettingValue); + SearchResult = ESessionSettingSearchResult::Found; + } + else + { + SearchResult = ESessionSettingSearchResult::WrongType; + } + return; + } + } + + SearchResult = ESessionSettingSearchResult::NotFound; + return; +} + + +bool UAdvancedSessionsLibrary::HasOnlineSubsystem(FName SubSystemName) +{ + return IOnlineSubsystem::DoesInstanceExist(SubSystemName); +} + +void UAdvancedSessionsLibrary::GetNetPlayerIndex(APlayerController *PlayerController, int32 &NetPlayerIndex) +{ + if (!PlayerController) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetNetPlayerIndex received a bad PlayerController!")); + NetPlayerIndex = 0; + return; + } + + NetPlayerIndex = PlayerController->NetPlayerIndex; + return; +} + +void UAdvancedSessionsLibrary::UniqueNetIdToString(const FBPUniqueNetId& UniqueNetId, FString &String) +{ + const FUniqueNetId * ID = UniqueNetId.GetUniqueNetId(); + + if ( !ID ) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("UniqueNetIdToString received a bad UniqueNetId!")); + String = "ERROR, BAD UNIQUE NET ID"; + } + else + String = ID->ToString(); +} + + +void UAdvancedSessionsLibrary::GetUniqueNetID(APlayerController *PlayerController, FBPUniqueNetId &UniqueNetId) +{ + if (!PlayerController) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetUniqueNetIdFromController received a bad PlayerController!")); + return; + } + + if (APlayerState* PlayerState = (PlayerController != NULL) ? PlayerController->PlayerState : NULL) + { + UniqueNetId.SetUniqueNetId(PlayerState->GetUniqueId().GetUniqueNetId()); + if (!UniqueNetId.IsValid()) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetUniqueNetIdFromController couldn't get the player uniquenetid!")); + } + return; + } +} + +void UAdvancedSessionsLibrary::GetUniqueNetIDFromPlayerState(APlayerState *PlayerState, FBPUniqueNetId &UniqueNetId) +{ + if (!PlayerState) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetUniqueNetIdFromPlayerState received a bad PlayerState!")); + return; + } + + UniqueNetId.SetUniqueNetId(PlayerState->GetUniqueId().GetUniqueNetId()); + if (!UniqueNetId.IsValid()) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetUniqueNetIdFromPlayerState couldn't get the player uniquenetid!")); + } + return; +} + +bool UAdvancedSessionsLibrary::IsValidUniqueNetID(const FBPUniqueNetId &UniqueNetId) +{ + return UniqueNetId.IsValid(); +} + +bool UAdvancedSessionsLibrary::EqualEqual_UNetIDUnetID(const FBPUniqueNetId &A, const FBPUniqueNetId &B) +{ + return ((A.IsValid() && B.IsValid()) && (*A.GetUniqueNetId() == *B.GetUniqueNetId())); +} + +FUniqueNetIdRepl UAdvancedSessionsLibrary::Conv_BPUniqueIDToUniqueNetIDRepl(const FBPUniqueNetId& InUniqueID) +{ + return FUniqueNetIdRepl(InUniqueID.GetUniqueNetId()->AsShared()); +} + +void UAdvancedSessionsLibrary::SetPlayerName(APlayerController *PlayerController, FString PlayerName) +{ + if (!PlayerController) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("SetLocalPlayerNameFromController Bad Player Controller!")); + return; + } + + if (APlayerState* PlayerState = (PlayerController != NULL) ? PlayerController->PlayerState : NULL) + { + PlayerState->SetPlayerName(PlayerName); + return; + } + else + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("SetLocalPlayerNameFromController had a bad player state!")); + } +} + +void UAdvancedSessionsLibrary::GetPlayerName(APlayerController *PlayerController, FString &PlayerName) +{ + if (!PlayerController) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetLocalPlayerNameFromController Bad Player Controller!")); + return; + } + + if (APlayerState* PlayerState = (PlayerController != NULL) ? PlayerController->PlayerState : NULL) + { + PlayerName = PlayerState->GetPlayerName(); + return; + } + else + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetLocalPlayerNameFromController had a bad player state!")); + } +} + +void UAdvancedSessionsLibrary::GetNumberOfNetworkPlayers(UObject* WorldContextObject, int32 &NumNetPlayers) +{ + //Get World + UWorld* TheWorld = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + + if (!TheWorld) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetNumberOfNetworkPlayers Failed to get World()!")); + return; + } + + NumNetPlayers = TheWorld->GetGameState()->PlayerArray.Num(); +} + +bool UAdvancedSessionsLibrary::ServerTravel(UObject* WorldContextObject, const FString& FURL, bool bAbsolute, bool bShouldSkipGameNotify) +{ + if (!WorldContextObject) + { + return false; + } + + //using a context object to get the world + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); + if (World) + { + return World->ServerTravel(FURL, bAbsolute, bShouldSkipGameNotify); + } + + return false; +} \ No newline at end of file diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedVoiceLibrary.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedVoiceLibrary.cpp new file mode 100644 index 0000000..f6321c1 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedVoiceLibrary.cpp @@ -0,0 +1,359 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "AdvancedVoiceLibrary.h" + + +//General Log +DEFINE_LOG_CATEGORY(AdvancedVoiceLog); + +void UAdvancedVoiceLibrary::IsHeadsetPresent(UObject* WorldContextObject, bool & bHasHeadset, uint8 LocalPlayerNum) +{ + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return; + } + + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World); + + if (!VoiceInterface.IsValid()) + { + bHasHeadset = false; + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Check For Headset couldn't get the voice interface!")); + return; + } + + bHasHeadset = VoiceInterface->IsHeadsetPresent(LocalPlayerNum); +} + +void UAdvancedVoiceLibrary::StartNetworkedVoice(UObject* WorldContextObject, uint8 LocalPlayerNum) +{ + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return; + } + + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Start Networked Voice couldn't get the voice interface!")); + return; + } + + VoiceInterface->StartNetworkedVoice(LocalPlayerNum); +} + +void UAdvancedVoiceLibrary::StopNetworkedVoice(UObject* WorldContextObject, uint8 LocalPlayerNum) +{ + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return; + } + + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Start Networked Voice couldn't get the voice interface!")); + return; + } + + VoiceInterface->StopNetworkedVoice(LocalPlayerNum); +} + +bool UAdvancedVoiceLibrary::RegisterLocalTalker(UObject* WorldContextObject, uint8 LocalPlayerNum) +{ + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return false; + } + + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Register Local Talker couldn't get the voice interface!")); + return false; + } + + return VoiceInterface->RegisterLocalTalker(LocalPlayerNum); +} + +void UAdvancedVoiceLibrary::RegisterAllLocalTalkers(UObject* WorldContextObject) +{ + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return; + } + + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Register Local Talkers couldn't get the voice interface!")); + return; + } + + VoiceInterface->RegisterLocalTalkers(); +} + + +void UAdvancedVoiceLibrary::UnRegisterLocalTalker(UObject* WorldContextObject, uint8 LocalPlayerNum) +{ + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return; + } + + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Unregister Local Talker couldn't get the voice interface!")); + return; + } + + VoiceInterface->UnregisterLocalTalker(LocalPlayerNum); +} + +void UAdvancedVoiceLibrary::UnRegisterAllLocalTalkers(UObject* WorldContextObject) +{ + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return; + } + + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("UnRegister All Local Talkers couldn't get the voice interface!")); + return; + } + + VoiceInterface->UnregisterLocalTalkers(); +} + +bool UAdvancedVoiceLibrary::RegisterRemoteTalker(UObject* WorldContextObject, const FBPUniqueNetId& UniqueNetId) +{ + if (!UniqueNetId.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Register Remote Talker was passed an invalid unique net id!")); + return false; + } + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return false; + } + + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Register Remote Talker couldn't get the voice interface!")); + return false; + } + + return VoiceInterface->RegisterRemoteTalker(*UniqueNetId.GetUniqueNetId()); +} + +bool UAdvancedVoiceLibrary::UnRegisterRemoteTalker(UObject* WorldContextObject, const FBPUniqueNetId& UniqueNetId) +{ + if (!UniqueNetId.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("UnRegister Remote Talker was passed an invalid unique net id!")); + return false; + } + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return false; + } + + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("UnRegister Remote Talker couldn't get the voice interface!")); + return false; + } + + return VoiceInterface->UnregisterRemoteTalker(*UniqueNetId.GetUniqueNetId()); +} + +void UAdvancedVoiceLibrary::RemoveAllRemoteTalkers(UObject* WorldContextObject) +{ + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return; + } + + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Remove All Remote Talkers couldn't get the voice interface!")); + return; + } + + VoiceInterface->RemoveAllRemoteTalkers(); +} + +bool UAdvancedVoiceLibrary::IsLocalPlayerTalking(UObject* WorldContextObject, uint8 LocalPlayerNum) +{ + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return false; + } + + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Is Local Player Talking couldn't get the voice interface!")); + return false; + } + + return VoiceInterface->IsLocalPlayerTalking(LocalPlayerNum); +} + +bool UAdvancedVoiceLibrary::IsRemotePlayerTalking(UObject* WorldContextObject, const FBPUniqueNetId& UniqueNetId) +{ + if (!UniqueNetId.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Is Remote Player Talking was passed an invalid unique net id!")); + return false; + } + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return false; + } + + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Is Remote Player Talking couldn't get the voice interface!")); + return false; + } + + return VoiceInterface->IsRemotePlayerTalking(*UniqueNetId.GetUniqueNetId()); +} + +bool UAdvancedVoiceLibrary::IsPlayerMuted(UObject* WorldContextObject, uint8 LocalUserNumChecking, const FBPUniqueNetId& UniqueNetId) +{ + if (!UniqueNetId.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Is Player Muted was passed an invalid unique net id!")); + return false; + } + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return false; + } + + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Is Player Muted couldn't get the voice interface!")); + return false; + } + + return VoiceInterface->IsMuted(LocalUserNumChecking, *UniqueNetId.GetUniqueNetId()); +} + +bool UAdvancedVoiceLibrary::MuteRemoteTalker(UObject* WorldContextObject, uint8 LocalUserNum, const FBPUniqueNetId& UniqueNetId, bool bIsSystemWide) +{ + if (!UniqueNetId.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Mute Remote Talker was passed an invalid unique net id!")); + return false; + } + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return false; + } + + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Mute Remote Talker couldn't get the voice interface!")); + return false; + } + + return VoiceInterface->MuteRemoteTalker(LocalUserNum, *UniqueNetId.GetUniqueNetId(), bIsSystemWide); +} + +bool UAdvancedVoiceLibrary::UnMuteRemoteTalker(UObject* WorldContextObject, uint8 LocalUserNum, const FBPUniqueNetId& UniqueNetId, bool bIsSystemWide) +{ + if (!UniqueNetId.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Unmute Remote Talker was passed an invalid unique net id!")); + return false; + } + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return false; + } + + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Unmute Remote Talker couldn't get the voice interface!")); + return false; + } + + return VoiceInterface->UnmuteRemoteTalker(LocalUserNum, *UniqueNetId.GetUniqueNetId(), bIsSystemWide); +} + + +void UAdvancedVoiceLibrary::GetNumLocalTalkers(UObject* WorldContextObject, int32 & NumLocalTalkers) +{ + + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + if (!IsValid(World)) + { + return; + } + + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World); + + if (!VoiceInterface.IsValid()) + { + NumLocalTalkers = 0; + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Unmute Remote Talker couldn't get the voice interface!")); + return; + } + + NumLocalTalkers = VoiceInterface->GetNumLocalTalkers(); +} \ No newline at end of file diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AutoLoginUserCallbackProxy.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AutoLoginUserCallbackProxy.cpp new file mode 100644 index 0000000..9046773 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/AutoLoginUserCallbackProxy.cpp @@ -0,0 +1,89 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. + +#include "AutoLoginUserCallbackProxy.h" +#include "Kismet/GameplayStatics.h" + +#include "Online.h" + +////////////////////////////////////////////////////////////////////////// +// ULoginUserCallbackProxy + +UAutoLoginUserCallbackProxy::UAutoLoginUserCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , Delegate(FOnLoginCompleteDelegate::CreateUObject(this, &ThisClass::OnCompleted)) +{ +} + +UAutoLoginUserCallbackProxy* UAutoLoginUserCallbackProxy::AutoLoginUser(UObject* WorldContextObject, int32 LocalUserNum) +{ + UAutoLoginUserCallbackProxy* Proxy = NewObject(); + Proxy->LocalUserNumber = LocalUserNum; + Proxy->WorldContextObject = WorldContextObject; + return Proxy; +} + +void UAutoLoginUserCallbackProxy::Activate() +{ + + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("AutoLoginUser"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + + if (Helper.OnlineSub != nullptr) + { + auto Identity = Helper.OnlineSub->GetIdentityInterface(); + + if (Identity.IsValid()) + { + DelegateHandle = Identity->AddOnLoginCompleteDelegate_Handle(LocalUserNumber, Delegate); + Identity->AutoLogin(LocalUserNumber); + return; + } + } + + // Fail immediately + OnFailure.Broadcast(); +} + +void UAutoLoginUserCallbackProxy::OnCompleted(int32 LocalUserNum, bool bWasSuccessful, const FUniqueNetId& UserId, const FString& ErrorVal) +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("AutoLoginUser"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + + if (Helper.OnlineSub != nullptr) + { + auto Identity = Helper.OnlineSub->GetIdentityInterface(); + + if (Identity.IsValid()) + { + Identity->ClearOnLoginCompleteDelegate_Handle(LocalUserNum, DelegateHandle); + } + + if (APlayerController* PController = UGameplayStatics::GetPlayerController(WorldContextObject->GetWorld(), LocalUserNum)) + { + ULocalPlayer* Player = Cast(PController->Player); + + FUniqueNetIdRepl uniqueId(UserId.AsShared()); + + if (Player) + { + Player->SetCachedUniqueNetId(uniqueId); + } + + if (APlayerState* State = PController->PlayerState) + { + // Update UniqueId. See also ShowLoginUICallbackProxy.cpp + State->SetUniqueId(uniqueId); + } + } + + + if (bWasSuccessful) + { + OnSuccess.Broadcast(); + } + else + { + OnFailure.Broadcast(); + } + } + + OnFailure.Broadcast(); +} diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/CancelFindSessionsCallbackProxy.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/CancelFindSessionsCallbackProxy.cpp new file mode 100644 index 0000000..600187e --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/CancelFindSessionsCallbackProxy.cpp @@ -0,0 +1,70 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#include "CancelFindSessionsCallbackProxy.h" + + +////////////////////////////////////////////////////////////////////////// +// UCancelFindSessionsCallbackProxy + +UCancelFindSessionsCallbackProxy::UCancelFindSessionsCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , Delegate(FOnCancelFindSessionsCompleteDelegate::CreateUObject(this, &ThisClass::OnCompleted)) +{ +} + +UCancelFindSessionsCallbackProxy* UCancelFindSessionsCallbackProxy::CancelFindSessions(UObject* WorldContextObject, class APlayerController* PlayerController) +{ + UCancelFindSessionsCallbackProxy* Proxy = NewObject(); + Proxy->PlayerControllerWeakPtr = PlayerController; + Proxy->WorldContextObject = WorldContextObject; + return Proxy; +} + +void UCancelFindSessionsCallbackProxy::Activate() +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("CancelFindSessions"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.IsValid()) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + DelegateHandle = Sessions->AddOnCancelFindSessionsCompleteDelegate_Handle(Delegate); + Sessions->CancelFindSessions(); + + // OnCompleted will get called, nothing more to do now + return; + } + else + { + FFrame::KismetExecutionMessage(TEXT("Sessions not supported by Online Subsystem"), ELogVerbosity::Warning); + } + } + + // Fail immediately + OnFailure.Broadcast(); +} + +void UCancelFindSessionsCallbackProxy::OnCompleted(bool bWasSuccessful) +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("CancelFindSessionsCallback"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.IsValid()) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + Sessions->ClearOnCancelFindSessionsCompleteDelegate_Handle(DelegateHandle); + } + } + + if (bWasSuccessful) + { + OnSuccess.Broadcast(); + } + else + { + OnFailure.Broadcast(); + } +} diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/CreateSessionCallbackProxyAdvanced.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/CreateSessionCallbackProxyAdvanced.cpp new file mode 100644 index 0000000..1ff10c1 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/CreateSessionCallbackProxyAdvanced.cpp @@ -0,0 +1,182 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#include "CreateSessionCallbackProxyAdvanced.h" + + +////////////////////////////////////////////////////////////////////////// +// UCreateSessionCallbackProxyAdvanced + +UCreateSessionCallbackProxyAdvanced::UCreateSessionCallbackProxyAdvanced(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , CreateCompleteDelegate(FOnCreateSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnCreateCompleted)) + , StartCompleteDelegate(FOnStartSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnStartCompleted)) + , NumPublicConnections(1) +{ +} + +UCreateSessionCallbackProxyAdvanced* UCreateSessionCallbackProxyAdvanced::CreateAdvancedSession(UObject* WorldContextObject, const TArray& ExtraSettings, class APlayerController* PlayerController, int32 PublicConnections, int32 PrivateConnections, bool bUseLAN, bool bAllowInvites, bool bIsDedicatedServer, bool bUsePresence, bool bUseLobbiesIfAvailable, bool bAllowJoinViaPresence, bool bAllowJoinViaPresenceFriendsOnly, bool bAntiCheatProtected, bool bUsesStats, bool bShouldAdvertise, bool bUseLobbiesVoiceChatIfAvailable, bool bStartAfterCreate) +{ + UCreateSessionCallbackProxyAdvanced* Proxy = NewObject(); + Proxy->PlayerControllerWeakPtr = PlayerController; + Proxy->NumPublicConnections = PublicConnections; + Proxy->NumPrivateConnections = PrivateConnections; + Proxy->bUseLAN = bUseLAN; + Proxy->WorldContextObject = WorldContextObject; + Proxy->bAllowInvites = bAllowInvites; + Proxy->ExtraSettings = ExtraSettings; + Proxy->bDedicatedServer = bIsDedicatedServer; + Proxy->bUsePresence = bUsePresence; + Proxy->bUseLobbiesIfAvailable = bUseLobbiesIfAvailable; + Proxy->bAllowJoinViaPresence = bAllowJoinViaPresence; + Proxy->bAllowJoinViaPresenceFriendsOnly = bAllowJoinViaPresenceFriendsOnly; + Proxy->bAntiCheatProtected = bAntiCheatProtected; + Proxy->bUsesStats = bUsesStats; + Proxy->bShouldAdvertise = bShouldAdvertise; + Proxy->bUseLobbiesVoiceChatIfAvailable = bUseLobbiesVoiceChatIfAvailable; + Proxy->bStartAfterCreate = bStartAfterCreate; + return Proxy; +} + +void UCreateSessionCallbackProxyAdvanced::Activate() +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("CreateSession"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + + if (PlayerControllerWeakPtr.IsValid() ) + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.OnlineSub != nullptr) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + CreateCompleteDelegateHandle = Sessions->AddOnCreateSessionCompleteDelegate_Handle(CreateCompleteDelegate); + + FOnlineSessionSettings Settings; + Settings.NumPublicConnections = NumPublicConnections; + Settings.NumPrivateConnections = NumPrivateConnections; + Settings.bShouldAdvertise = bShouldAdvertise; + Settings.bAllowJoinInProgress = true; + Settings.bIsLANMatch = bUseLAN; + Settings.bAllowJoinViaPresence = bAllowJoinViaPresence; + Settings.bIsDedicated = bDedicatedServer; + + if (bDedicatedServer) + { + Settings.bUsesPresence = false; + Settings.bUseLobbiesIfAvailable = false; + } + else + { + Settings.bUsesPresence = bUsePresence; + Settings.bUseLobbiesIfAvailable = bUseLobbiesIfAvailable; + } + + Settings.bUseLobbiesVoiceChatIfAvailable = bUseLobbiesIfAvailable ? bUseLobbiesVoiceChatIfAvailable : false; + Settings.bAllowJoinViaPresenceFriendsOnly = bAllowJoinViaPresenceFriendsOnly; + Settings.bAntiCheatProtected = bAntiCheatProtected; + Settings.bUsesStats = bUsesStats; + + // These are about the only changes over the standard Create Sessions Node + Settings.bAllowInvites = bAllowInvites; + + FOnlineSessionSetting ExtraSetting; + for (int i = 0; i < ExtraSettings.Num(); i++) + { + ExtraSetting.Data = ExtraSettings[i].Data; + // ViaOnlineServiceAndPing + ExtraSetting.AdvertisementType = EOnlineDataAdvertisementType::ViaOnlineService; + Settings.Settings.Add(ExtraSettings[i].Key, ExtraSetting); + } + + + if (!bDedicatedServer ) + { + if (PlayerControllerWeakPtr.IsValid() && Helper.UserID.IsValid()) + { + Sessions->CreateSession(*Helper.UserID, NAME_GameSession, Settings); + } + else + { + FFrame::KismetExecutionMessage(TEXT("Invalid Player controller when attempting to start a session"), ELogVerbosity::Warning); + Sessions->ClearOnCreateSessionCompleteDelegate_Handle(CreateCompleteDelegateHandle); + + // Fail immediately + OnFailure.Broadcast(); + } + } + else + Sessions->CreateSession(0, NAME_GameSession, Settings); + + // OnCreateCompleted will get called, nothing more to do now + return; + } + else + { + FFrame::KismetExecutionMessage(TEXT("Sessions not supported by Online Subsystem"), ELogVerbosity::Warning); + } + } + + // Fail immediately + OnFailure.Broadcast(); +} + +void UCreateSessionCallbackProxyAdvanced::OnCreateCompleted(FName SessionName, bool bWasSuccessful) +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("CreateSessionCallback"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + //Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.OnlineSub != nullptr) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + Sessions->ClearOnCreateSessionCompleteDelegate_Handle(CreateCompleteDelegateHandle); + + if (bWasSuccessful) + { + if (this->bStartAfterCreate) + { + UE_LOG_ONLINE_SESSION(Display, TEXT("Session creation completed. Automatic start is turned on, starting session now.")); + StartCompleteDelegateHandle = Sessions->AddOnStartSessionCompleteDelegate_Handle(StartCompleteDelegate); + Sessions->StartSession(NAME_GameSession); // We'll call `OnSuccess.Broadcast()` when start succeeds. + } + else + { + UE_LOG_ONLINE_SESSION(Display, TEXT("Session creation completed. Automatic start is turned off, to start the session call 'StartSession'.")); + OnSuccess.Broadcast(); + } + + // OnStartCompleted will get called, nothing more to do now + return; + } + } + } + + if (!bWasSuccessful) + { + OnFailure.Broadcast(); + } +} + +void UCreateSessionCallbackProxyAdvanced::OnStartCompleted(FName SessionName, bool bWasSuccessful) +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("StartSessionCallback"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + //Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.OnlineSub != nullptr) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + Sessions->ClearOnStartSessionCompleteDelegate_Handle(StartCompleteDelegateHandle); + } + } + + if (bWasSuccessful) + { + OnSuccess.Broadcast(); + } + else + { + OnFailure.Broadcast(); + } +} diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/EndSessionCallbackProxy.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/EndSessionCallbackProxy.cpp new file mode 100644 index 0000000..ddb248c --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/EndSessionCallbackProxy.cpp @@ -0,0 +1,78 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#include "EndSessionCallbackProxy.h" + + +////////////////////////////////////////////////////////////////////////// +// UEndSessionCallbackProxy + +UEndSessionCallbackProxy::UEndSessionCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , Delegate(FOnEndSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnCompleted)) +{ +} + +UEndSessionCallbackProxy* UEndSessionCallbackProxy::EndSession(UObject* WorldContextObject, class APlayerController* PlayerController) +{ + UEndSessionCallbackProxy* Proxy = NewObject(); + Proxy->PlayerControllerWeakPtr = PlayerController; + Proxy->WorldContextObject = WorldContextObject; + return Proxy; +} + +void UEndSessionCallbackProxy::Activate() +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("EndSession"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.IsValid()) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + FNamedOnlineSession* Session = Sessions->GetNamedSession(NAME_GameSession); + if (Session && + Session->SessionState == EOnlineSessionState::InProgress) + { + DelegateHandle = Sessions->AddOnEndSessionCompleteDelegate_Handle(Delegate); + Sessions->EndSession(NAME_GameSession); + } + else + { + OnSuccess.Broadcast(); + } + // OnCompleted will get called, nothing more to do now + return; + } + else + { + FFrame::KismetExecutionMessage(TEXT("Sessions not supported by Online Subsystem"), ELogVerbosity::Warning); + } + } + + // Fail immediately + OnFailure.Broadcast(); +} + +void UEndSessionCallbackProxy::OnCompleted(FName SessionName, bool bWasSuccessful) +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("EndSessionCallback"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.IsValid()) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + Sessions->ClearOnEndSessionCompleteDelegate_Handle(DelegateHandle); + } + } + + if (bWasSuccessful) + { + OnSuccess.Broadcast(); + } + else + { + OnFailure.Broadcast(); + } +} diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/FindFriendSessionCallbackProxy.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/FindFriendSessionCallbackProxy.cpp new file mode 100644 index 0000000..019255c --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/FindFriendSessionCallbackProxy.cpp @@ -0,0 +1,130 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#include "FindFriendSessionCallbackProxy.h" + + +////////////////////////////////////////////////////////////////////////// +// UGetRecentPlayersCallbackProxy +DEFINE_LOG_CATEGORY(AdvancedFindFriendSessionLog); + +UFindFriendSessionCallbackProxy::UFindFriendSessionCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , OnFindFriendSessionCompleteDelegate(FOnFindFriendSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnFindFriendSessionCompleted)) +{ +} + +UFindFriendSessionCallbackProxy* UFindFriendSessionCallbackProxy::FindFriendSession(UObject* WorldContextObject, APlayerController *PlayerController, const FBPUniqueNetId &FriendUniqueNetId) +{ + UFindFriendSessionCallbackProxy* Proxy = NewObject(); + Proxy->PlayerControllerWeakPtr = PlayerController; + Proxy->cUniqueNetId = FriendUniqueNetId; + Proxy->WorldContextObject = WorldContextObject; + return Proxy; +} + +void UFindFriendSessionCallbackProxy::Activate() +{ + if (!cUniqueNetId.IsValid()) + { + // Fail immediately + UE_LOG(AdvancedFindFriendSessionLog, Warning, TEXT("FindFriendSession Failed received a bad UniqueNetId!")); + TArray EmptyResult; + OnFailure.Broadcast(EmptyResult); + return; + } + + if (!PlayerControllerWeakPtr.IsValid()) + { + // Fail immediately + UE_LOG(AdvancedFindFriendSessionLog, Warning, TEXT("FindFriendSession Failed received a bad playercontroller!")); + TArray EmptyResult; + OnFailure.Broadcast(EmptyResult); + return; + } + + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("EndSessionCallback"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (!Helper.IsValid()) + { + // Fail immediately + TArray EmptyResult; + OnFailure.Broadcast(EmptyResult); + return; + } + + IOnlineSessionPtr Sessions = Helper.OnlineSub->GetSessionInterface(); + + if (Sessions.IsValid()) + { + ULocalPlayer* Player = Cast(PlayerControllerWeakPtr->Player); + + if (!Player) + { + // Fail immediately + UE_LOG(AdvancedFindFriendSessionLog, Warning, TEXT("FindFriendSession Failed couldn't cast to ULocalPlayer!")); + TArray EmptyResult; + OnFailure.Broadcast(EmptyResult); + return; + } + + FindFriendSessionCompleteDelegateHandle = Sessions->AddOnFindFriendSessionCompleteDelegate_Handle(Player->GetControllerId(), OnFindFriendSessionCompleteDelegate); + + Sessions->FindFriendSession(Player->GetControllerId(), *cUniqueNetId.GetUniqueNetId()); + + return; + } + + // Fail immediately + TArray EmptyResult; + OnFailure.Broadcast(EmptyResult); +} + + +void UFindFriendSessionCallbackProxy::OnFindFriendSessionCompleted(int32 LocalPlayer, bool bWasSuccessful, const TArray& SessionInfo) +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("EndSessionCallback"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.IsValid()) + { + IOnlineSessionPtr Sessions = Helper.OnlineSub->GetSessionInterface(); + + if (Sessions.IsValid()) + Sessions->ClearOnFindFriendSessionCompleteDelegate_Handle(LocalPlayer, FindFriendSessionCompleteDelegateHandle); + + if (bWasSuccessful) + { + TArray Result; + + for (auto& Sesh : SessionInfo) + { + if (Sesh.IsValid()) + { + FBlueprintSessionResult BSesh; + BSesh.OnlineResult = Sesh; + Result.Add(BSesh); + } + } + + if (Result.Num() > 0) + OnSuccess.Broadcast(Result); + else + { + UE_LOG(AdvancedFindFriendSessionLog, Warning, TEXT("FindFriendSession Failed, returned an invalid session.")); + OnFailure.Broadcast(Result); + } + } + else + { + UE_LOG(AdvancedFindFriendSessionLog, Warning, TEXT("FindFriendSession Failed")); + TArray EmptyResult; + OnFailure.Broadcast(EmptyResult); + } + } + else + { + UE_LOG(AdvancedFindFriendSessionLog, Warning, TEXT("FindFriendSession Failed")); + TArray EmptyResult; + OnFailure.Broadcast(EmptyResult); + } +} diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/FindSessionsCallbackProxyAdvanced.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/FindSessionsCallbackProxyAdvanced.cpp new file mode 100644 index 0000000..dc0dc4b --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/FindSessionsCallbackProxyAdvanced.cpp @@ -0,0 +1,444 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#include "FindSessionsCallbackProxyAdvanced.h" + +#include "Online/OnlineSessionNames.h" + +////////////////////////////////////////////////////////////////////////// +// UFindSessionsCallbackProxyAdvanced + + +UFindSessionsCallbackProxyAdvanced::UFindSessionsCallbackProxyAdvanced(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , Delegate(FOnFindSessionsCompleteDelegate::CreateUObject(this, &ThisClass::OnCompleted)) + , bUseLAN(false) +{ + bRunSecondSearch = false; + bIsOnSecondSearch = false; +} + +UFindSessionsCallbackProxyAdvanced* UFindSessionsCallbackProxyAdvanced::FindSessionsAdvanced(UObject* WorldContextObject, class APlayerController* PlayerController, int MaxResults, bool bUseLAN, EBPServerPresenceSearchType ServerTypeToSearch, const TArray &Filters, bool bEmptyServersOnly, bool bNonEmptyServersOnly, bool bSecureServersOnly, bool bSearchLobbies, int MinSlotsAvailable) +{ + UFindSessionsCallbackProxyAdvanced* Proxy = NewObject(); + Proxy->PlayerControllerWeakPtr = PlayerController; + Proxy->bUseLAN = bUseLAN; + Proxy->MaxResults = MaxResults; + Proxy->WorldContextObject = WorldContextObject; + Proxy->SearchSettings = Filters; + Proxy->ServerSearchType = ServerTypeToSearch; + Proxy->bEmptyServersOnly = bEmptyServersOnly, + Proxy->bNonEmptyServersOnly = bNonEmptyServersOnly; + Proxy->bSecureServersOnly = bSecureServersOnly; + Proxy->bSearchLobbies = bSearchLobbies; + Proxy->MinSlotsAvailable = MinSlotsAvailable; + return Proxy; +} + +void UFindSessionsCallbackProxyAdvanced::Activate() +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("FindSessions"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.IsValid()) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + // Re-initialize here, otherwise I think there might be issues with people re-calling search for some reason before it is destroyed + bRunSecondSearch = false; + bIsOnSecondSearch = false; + + DelegateHandle = Sessions->AddOnFindSessionsCompleteDelegate_Handle(Delegate); + + SearchObject = MakeShareable(new FOnlineSessionSearch); + SearchObject->MaxSearchResults = MaxResults; + SearchObject->bIsLanQuery = bUseLAN; + //SearchObject->QuerySettings.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals); + + // Create temp filter variable, because I had to re-define a blueprint version of this, it is required. + FOnlineSearchSettingsEx tem; + + /* // Search only for dedicated servers (value is true/false) + #define SEARCH_DEDICATED_ONLY FName(TEXT("DEDICATEDONLY")) + // Search for empty servers only (value is true/false) + #define SEARCH_EMPTY_SERVERS_ONLY FName(TEXT("EMPTYONLY")) + // Search for non empty servers only (value is true/false) + #define SEARCH_NONEMPTY_SERVERS_ONLY FName(TEXT("NONEMPTYONLY")) + // Search for secure servers only (value is true/false) + #define SEARCH_SECURE_SERVERS_ONLY FName(TEXT("SECUREONLY")) + // Search for presence sessions only (value is true/false) + #define SEARCH_PRESENCE FName(TEXT("PRESENCESEARCH")) + // Search for a match with min player availability (value is int) + #define SEARCH_MINSLOTSAVAILABLE FName(TEXT("MINSLOTSAVAILABLE")) + // Exclude all matches where any unique ids in a given array are present (value is string of the form "uniqueid1;uniqueid2;uniqueid3") + #define SEARCH_EXCLUDE_UNIQUEIDS FName(TEXT("EXCLUDEUNIQUEIDS")) + // User ID to search for session of + #define SEARCH_USER FName(TEXT("SEARCHUSER")) + // Keywords to match in session search + #define SEARCH_KEYWORDS FName(TEXT("SEARCHKEYWORDS"))*/ + /** Keywords to match in session search */ + /** The matchmaking queue name to matchmake in, e.g. "TeamDeathmatch" (value is string) */ + /** #define SEARCH_MATCHMAKING_QUEUE FName(TEXT("MATCHMAKINGQUEUE"))*/ + /** If set, use the named Xbox Live hopper to find a session via matchmaking (value is a string) */ + /** #define SEARCH_XBOX_LIVE_HOPPER_NAME FName(TEXT("LIVEHOPPERNAME"))*/ + /** Which session template from the service configuration to use */ + /** #define SEARCH_XBOX_LIVE_SESSION_TEMPLATE_NAME FName(TEXT("LIVESESSIONTEMPLATE"))*/ + /** Selection method used to determine which match to join when multiple are returned (valid only on Switch) */ + /** #define SEARCH_SWITCH_SELECTION_METHOD FName(TEXT("SWITCHSELECTIONMETHOD"))*/ + /** Whether to use lobbies vs sessions */ + /** #define SEARCH_LOBBIES FName(TEXT("LOBBYSEARCH"))*/ + + if (bEmptyServersOnly) + tem.Set(SEARCH_EMPTY_SERVERS_ONLY, true, EOnlineComparisonOp::Equals); + + if (bNonEmptyServersOnly) + tem.Set(SEARCH_NONEMPTY_SERVERS_ONLY, true, EOnlineComparisonOp::Equals); + + if (bSecureServersOnly) + tem.Set(SEARCH_SECURE_SERVERS_ONLY, true, EOnlineComparisonOp::Equals); + + if (MinSlotsAvailable != 0) + tem.Set(SEARCH_MINSLOTSAVAILABLE, MinSlotsAvailable, EOnlineComparisonOp::GreaterThanEquals); + + // Filter results + if (SearchSettings.Num() > 0) + { + for (int i = 0; i < SearchSettings.Num(); i++) + { + // Function that was added to make directly adding a FVariant possible + tem.HardSet(SearchSettings[i].PropertyKeyPair.Key, SearchSettings[i].PropertyKeyPair.Data, SearchSettings[i].ComparisonOp); + } + } + + switch (ServerSearchType) + { + + case EBPServerPresenceSearchType::ClientServersOnly: + { + tem.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals); + + if (bSearchLobbies && !IOnlineSubsystem::DoesInstanceExist("STEAM")) + tem.Set(SEARCH_LOBBIES, true, EOnlineComparisonOp::Equals); + } + break; + + case EBPServerPresenceSearchType::DedicatedServersOnly: + { + //tem.Set(SEARCH_DEDICATED_ONLY, true, EOnlineComparisonOp::Equals); + } + break; + + case EBPServerPresenceSearchType::AllServers: + default: + { + //if (IOnlineSubsystem::DoesInstanceExist("STEAM")) + //{ + bRunSecondSearch = true; + + SearchObjectDedicated = MakeShareable(new FOnlineSessionSearch); + SearchObjectDedicated->MaxSearchResults = MaxResults; + SearchObjectDedicated->bIsLanQuery = bUseLAN; + + FOnlineSearchSettingsEx DedicatedOnly = tem; + + tem.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals); + + if (bSearchLobbies && !IOnlineSubsystem::DoesInstanceExist("STEAM")) + tem.Set(SEARCH_LOBBIES, true, EOnlineComparisonOp::Equals); + + //DedicatedOnly.Set(SEARCH_DEDICATED_ONLY, true, EOnlineComparisonOp::Equals); + SearchObjectDedicated->QuerySettings = DedicatedOnly; + //} + } + break; + } + + // Copy the derived temp variable over to it's base class + SearchObject->QuerySettings = tem; + + Sessions->FindSessions(*Helper.UserID, SearchObject.ToSharedRef()); + + // OnQueryCompleted will get called, nothing more to do now + return; + } + else + { + FFrame::KismetExecutionMessage(TEXT("Sessions not supported by Online Subsystem"), ELogVerbosity::Warning); + } + } + + // Fail immediately + OnFailure.Broadcast(SessionSearchResults); +} + +void UFindSessionsCallbackProxyAdvanced::OnCompleted(bool bSuccess) +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("FindSessionsCallback"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (!Helper.IsValid()) + { + // Fail immediately + OnFailure.Broadcast(SessionSearchResults); + return; + } + + if (!bRunSecondSearch && Helper.IsValid()) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + Sessions->ClearOnFindSessionsCompleteDelegate_Handle(DelegateHandle); + } + } + + if (bSuccess) + { + if (bIsOnSecondSearch) + { + if (SearchObjectDedicated.IsValid()) + { + // Just log the results for now, will need to add a blueprint-compatible search result struct + for (auto& Result : SearchObjectDedicated->SearchResults) + { + FString ResultText = FString::Printf(TEXT("Found a session. Ping is %d"), Result.PingInMs); + + FFrame::KismetExecutionMessage(*ResultText, ELogVerbosity::Log); + + FBlueprintSessionResult BPResult; + BPResult.OnlineResult = Result; + SessionSearchResults.AddUnique(BPResult); + } + OnSuccess.Broadcast(SessionSearchResults); + return; + } + } + else + { + if (SearchObject.IsValid()) + { + // Just log the results for now, will need to add a blueprint-compatible search result struct + for (auto& Result : SearchObject->SearchResults) + { + FString ResultText = FString::Printf(TEXT("Found a session. Ping is %d"), Result.PingInMs); + + FFrame::KismetExecutionMessage(*ResultText, ELogVerbosity::Log); + + FBlueprintSessionResult BPResult; + BPResult.OnlineResult = Result; + SessionSearchResults.AddUnique(BPResult); + } + if (!bRunSecondSearch) + { + OnSuccess.Broadcast(SessionSearchResults); + return; + } + } + } + } + else + { + if (!bRunSecondSearch) + { + // Need to account for only one of the searches failing + if (SessionSearchResults.Num() > 0) + OnSuccess.Broadcast(SessionSearchResults); + else + OnFailure.Broadcast(SessionSearchResults); + return; + } + } + + if (Helper.IsValid() && bRunSecondSearch && ServerSearchType == EBPServerPresenceSearchType::AllServers) + { + bRunSecondSearch = false; + bIsOnSecondSearch = true; + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + Sessions->FindSessions(*Helper.UserID, SearchObjectDedicated.ToSharedRef()); + } + else // We lost our player controller + { + if (bSuccess && SessionSearchResults.Num() > 0) + OnSuccess.Broadcast(SessionSearchResults); + else + OnFailure.Broadcast(SessionSearchResults); + } +} + + +void UFindSessionsCallbackProxyAdvanced::FilterSessionResults(const TArray &SessionResults, const TArray &Filters, TArray &FilteredResults) +{ + for (int j = 0; j < SessionResults.Num(); j++) + { + bool bAddResult = true; + + // Filter results + if (Filters.Num() > 0) + { + const FOnlineSessionSetting * setting; + for (int i = 0; i < Filters.Num(); i++) + { + setting = SessionResults[j].OnlineResult.Session.SessionSettings.Settings.Find(Filters[i].PropertyKeyPair.Key); + + // Couldn't find this key + if (!setting) + continue; + + if (!CompareVariants(setting->Data, Filters[i].PropertyKeyPair.Data, Filters[i].ComparisonOp)) + { + bAddResult = false; + break; + } + } + } + + if (bAddResult) + FilteredResults.Add(SessionResults[j]); + } + + return; +} + + +bool UFindSessionsCallbackProxyAdvanced::CompareVariants(const FVariantData &A, const FVariantData &B, EOnlineComparisonOpRedux Comparator) +{ + if (A.GetType() != B.GetType()) + return false; + + switch (A.GetType()) + { + case EOnlineKeyValuePairDataType::Bool: + { + bool bA, bB; + A.GetValue(bA); + B.GetValue(bB); + switch (Comparator) + { + case EOnlineComparisonOpRedux::Equals: + return bA == bB; break; + case EOnlineComparisonOpRedux::NotEquals: + return bA != bB; break; + default: + return false;break; + } + } + case EOnlineKeyValuePairDataType::Double: + { + double bA, bB; + A.GetValue(bA); + B.GetValue(bB); + switch (Comparator) + { + case EOnlineComparisonOpRedux::Equals: + return bA == bB; break; + case EOnlineComparisonOpRedux::NotEquals: + return bA != bB; break; + case EOnlineComparisonOpRedux::GreaterThanEquals: + return (bA == bB || bA > bB); break; + case EOnlineComparisonOpRedux::LessThanEquals: + return (bA == bB || bA < bB); break; + case EOnlineComparisonOpRedux::GreaterThan: + return bA > bB; break; + case EOnlineComparisonOpRedux::LessThan: + return bA < bB; break; + default: + return false; break; + } + } + case EOnlineKeyValuePairDataType::Float: + { + float tbA, tbB; + double bA, bB; + A.GetValue(tbA); + B.GetValue(tbB); + bA = (double)tbA; + bB = (double)tbB; + switch (Comparator) + { + case EOnlineComparisonOpRedux::Equals: + return bA == bB; break; + case EOnlineComparisonOpRedux::NotEquals: + return bA != bB; break; + case EOnlineComparisonOpRedux::GreaterThanEquals: + return (bA == bB || bA > bB); break; + case EOnlineComparisonOpRedux::LessThanEquals: + return (bA == bB || bA < bB); break; + case EOnlineComparisonOpRedux::GreaterThan: + return bA > bB; break; + case EOnlineComparisonOpRedux::LessThan: + return bA < bB; break; + default: + return false; break; + } + } + case EOnlineKeyValuePairDataType::Int32: + { + int32 bA, bB; + A.GetValue(bA); + B.GetValue(bB); + switch (Comparator) + { + case EOnlineComparisonOpRedux::Equals: + return bA == bB; break; + case EOnlineComparisonOpRedux::NotEquals: + return bA != bB; break; + case EOnlineComparisonOpRedux::GreaterThanEquals: + return (bA == bB || bA > bB); break; + case EOnlineComparisonOpRedux::LessThanEquals: + return (bA == bB || bA < bB); break; + case EOnlineComparisonOpRedux::GreaterThan: + return bA > bB; break; + case EOnlineComparisonOpRedux::LessThan: + return bA < bB; break; + default: + return false; break; + } + } + case EOnlineKeyValuePairDataType::Int64: + { + uint64 bA, bB; + A.GetValue(bA); + B.GetValue(bB); + switch (Comparator) + { + case EOnlineComparisonOpRedux::Equals: + return bA == bB; break; + case EOnlineComparisonOpRedux::NotEquals: + return bA != bB; break; + case EOnlineComparisonOpRedux::GreaterThanEquals: + return (bA == bB || bA > bB); break; + case EOnlineComparisonOpRedux::LessThanEquals: + return (bA == bB || bA < bB); break; + case EOnlineComparisonOpRedux::GreaterThan: + return bA > bB; break; + case EOnlineComparisonOpRedux::LessThan: + return bA < bB; break; + default: + return false; break; + } + } + + case EOnlineKeyValuePairDataType::String: + { + FString bA, bB; + A.GetValue(bA); + B.GetValue(bB); + switch (Comparator) + { + case EOnlineComparisonOpRedux::Equals: + return bA == bB; break; + case EOnlineComparisonOpRedux::NotEquals: + return bA != bB; break; + default: + return false; break; + } + } + + case EOnlineKeyValuePairDataType::Empty: + case EOnlineKeyValuePairDataType::Blob: + default: + return false; break; + } + + + +} \ No newline at end of file diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/GetFriendsCallbackProxy.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/GetFriendsCallbackProxy.cpp new file mode 100644 index 0000000..2d1d738 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/GetFriendsCallbackProxy.cpp @@ -0,0 +1,114 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#include "GetFriendsCallbackProxy.h" + +#include "Online.h" +#include "Interfaces/OnlineFriendsInterface.h" +#include "Interfaces/OnlinePresenceInterface.h" + +////////////////////////////////////////////////////////////////////////// +// UGetFriendsCallbackProxy +DEFINE_LOG_CATEGORY(AdvancedGetFriendsLog); + +UGetFriendsCallbackProxy::UGetFriendsCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , FriendListReadCompleteDelegate(FOnReadFriendsListComplete::CreateUObject(this, &ThisClass::OnReadFriendsListCompleted)) +{ +} + +UGetFriendsCallbackProxy* UGetFriendsCallbackProxy::GetAndStoreFriendsList(UObject* WorldContextObject, class APlayerController* PlayerController) +{ + UGetFriendsCallbackProxy* Proxy = NewObject(); + Proxy->PlayerControllerWeakPtr = PlayerController; + Proxy->WorldContextObject = WorldContextObject; + return Proxy; +} + +void UGetFriendsCallbackProxy::Activate() +{ + if (!PlayerControllerWeakPtr.IsValid()) + { + // Fail immediately + UE_LOG(AdvancedGetFriendsLog, Warning, TEXT("GetFriends Failed received a bad player controller!")); + TArray EmptyArray; + OnFailure.Broadcast(EmptyArray); + return; + } + + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("GetFriends"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.IsValid()) + { + IOnlineFriendsPtr Friends = Helper.OnlineSub->GetFriendsInterface(); + if (Friends.IsValid()) + { + ULocalPlayer* Player = Cast(PlayerControllerWeakPtr->Player); + + Friends->ReadFriendsList(Player->GetControllerId(), EFriendsLists::ToString((EFriendsLists::Default)), FriendListReadCompleteDelegate); + return; + } + } + + // Fail immediately + TArray EmptyArray; + OnFailure.Broadcast(EmptyArray); +} + +void UGetFriendsCallbackProxy::OnReadFriendsListCompleted(int32 LocalUserNum, bool bWasSuccessful, const FString& ListName, const FString& ErrorString) +{ + if (bWasSuccessful) + { + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("GetFriends"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (!Helper.IsValid()) + { + TArray EmptyArray; + OnFailure.Broadcast(EmptyArray); + return; + } + + auto Friends = Helper.OnlineSub->GetFriendsInterface(); + if (Friends.IsValid()) + { + // Not actually needed anymore, plus was not being validated and causing a crash + //ULocalPlayer* Player = Cast(PlayerControllerWeakPtr->Player); + + TArray FriendsListOut; + TArray< TSharedRef > FriendList; + if (Friends->GetFriendsList(LocalUserNum, ListName, FriendList)) + { + for (int32 i = 0; i < FriendList.Num(); i++) + { + FBPFriendInfo BPF; + const FOnlineUserPresence& pres = FriendList[i]->GetPresence(); + BPF.OnlineState = ((EBPOnlinePresenceState)((int32)pres.Status.State)); + BPF.DisplayName = FriendList[i]->GetDisplayName(); + BPF.RealName = FriendList[i]->GetRealName(); + BPF.UniqueNetId.SetUniqueNetId(FriendList[i]->GetUserId()); + BPF.bIsPlayingSameGame = pres.bIsPlayingThisGame; + + BPF.PresenceInfo.bIsOnline = pres.bIsOnline; + BPF.PresenceInfo.bHasVoiceSupport = pres.bHasVoiceSupport; + BPF.PresenceInfo.bIsPlaying = pres.bIsPlaying; + BPF.PresenceInfo.PresenceState = ((EBPOnlinePresenceState)((int32)pres.Status.State)); + + // #TODO: Check back in on this in shipping, epic is missing the UTF8_TO_TCHAR call on converting this and its making an invalid string + //BPF.PresenceInfo.StatusString = pres.Status.StatusStr; + BPF.PresenceInfo.bIsJoinable = pres.bIsJoinable; + BPF.PresenceInfo.bIsPlayingThisGame = pres.bIsPlayingThisGame; + + + FriendsListOut.Add(BPF); + } + } + + OnSuccess.Broadcast(FriendsListOut); + } + } + else + { + TArray EmptyArray; + OnFailure.Broadcast(EmptyArray); + } +} diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/GetRecentPlayersCallbackProxy.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/GetRecentPlayersCallbackProxy.cpp new file mode 100644 index 0000000..84bdcec --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/GetRecentPlayersCallbackProxy.cpp @@ -0,0 +1,104 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#include "GetRecentPlayersCallbackProxy.h" + +#include "Online.h" + +////////////////////////////////////////////////////////////////////////// +// UGetRecentPlayersCallbackProxy +DEFINE_LOG_CATEGORY(AdvancedGetRecentPlayersLog); + +UGetRecentPlayersCallbackProxy::UGetRecentPlayersCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , QueryRecentPlayersCompleteDelegate(FOnQueryRecentPlayersCompleteDelegate::CreateUObject(this, &ThisClass::OnQueryRecentPlayersCompleted)) +{ +} + +UGetRecentPlayersCallbackProxy* UGetRecentPlayersCallbackProxy::GetAndStoreRecentPlayersList(UObject* WorldContextObject, const FBPUniqueNetId& UniqueNetId) +{ + UGetRecentPlayersCallbackProxy* Proxy = NewObject(); + Proxy->cUniqueNetId = UniqueNetId; + Proxy->WorldContextObject = WorldContextObject; + return Proxy; +} + +void UGetRecentPlayersCallbackProxy::Activate() +{ + if (!cUniqueNetId.IsValid()) + { + // Fail immediately + UE_LOG(AdvancedGetRecentPlayersLog, Warning, TEXT("GetRecentPlayers Failed received a bad UniqueNetId!")); + TArray EmptyArray; + OnFailure.Broadcast(EmptyArray); + return; + } + + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("GetRecentPlayers"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + + if (!Helper.OnlineSub) + { + TArray EmptyArray; + OnFailure.Broadcast(EmptyArray); + return; + } + + IOnlineFriendsPtr Friends = Helper.OnlineSub->GetFriendsInterface(); + if (Friends.IsValid()) + { + DelegateHandle = Friends->AddOnQueryRecentPlayersCompleteDelegate_Handle(QueryRecentPlayersCompleteDelegate); + + // Testing with null namespace + Friends->QueryRecentPlayers(*(cUniqueNetId.GetUniqueNetId()), ""); + return; + } + // Fail immediately + TArray EmptyArray; + OnFailure.Broadcast(EmptyArray); +} + +void UGetRecentPlayersCallbackProxy::OnQueryRecentPlayersCompleted(const FUniqueNetId &UserID, const FString &Namespace, bool bWasSuccessful, const FString& ErrorString) +{ + + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("GetRecentPlayers"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + + if (!Helper.OnlineSub) + { + TArray EmptyArray; + OnFailure.Broadcast(EmptyArray); + return; + } + + IOnlineFriendsPtr Friends = Helper.OnlineSub->GetFriendsInterface(); + if (Friends.IsValid()) + Friends->ClearOnQueryRecentPlayersCompleteDelegate_Handle(DelegateHandle); + + + if (bWasSuccessful) + { + // WHOOPS + //IOnlineFriendsPtr Friends = Online::GetFriendsInterface(); + if (Friends.IsValid()) + { + TArray PlayersListOut; + TArray< TSharedRef > PlayerList; + + Friends->GetRecentPlayers(*(cUniqueNetId.GetUniqueNetId()), "", PlayerList); + + for (int32 i = 0; i < PlayerList.Num(); i++) + { + TSharedRef Player = PlayerList[i]; + FBPOnlineRecentPlayer BPF; + BPF.DisplayName = Player->GetDisplayName(); + BPF.RealName = Player->GetRealName(); + BPF.UniqueNetId.SetUniqueNetId(Player->GetUserId()); + PlayersListOut.Add(BPF); + } + + OnSuccess.Broadcast(PlayersListOut); + } + } + else + { + TArray EmptyArray; + OnFailure.Broadcast(EmptyArray); + } +} diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/GetUserPrivilegeCallbackProxy.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/GetUserPrivilegeCallbackProxy.cpp new file mode 100644 index 0000000..7b1ef39 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/GetUserPrivilegeCallbackProxy.cpp @@ -0,0 +1,48 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. + +#include "GetUserPrivilegeCallbackProxy.h" + +#include "Online.h" + +////////////////////////////////////////////////////////////////////////// +// UGetUserPrivilegeCallbackProxy + +UGetUserPrivilegeCallbackProxy::UGetUserPrivilegeCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ +} + +UGetUserPrivilegeCallbackProxy* UGetUserPrivilegeCallbackProxy::GetUserPrivilege(UObject* WorldContextObject, const EBPUserPrivileges & PrivilegeToCheck, const FBPUniqueNetId & PlayerUniqueNetID) +{ + UGetUserPrivilegeCallbackProxy* Proxy = NewObject(); + Proxy->PlayerUniqueNetID.SetUniqueNetId(PlayerUniqueNetID.GetUniqueNetId()); + Proxy->UserPrivilege = PrivilegeToCheck; + Proxy->WorldContextObject = WorldContextObject; + return Proxy; +} + +void UGetUserPrivilegeCallbackProxy::Activate() +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("GetUserPrivilege"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + + if (!Helper.OnlineSub) + { + OnFailure.Broadcast(); + return; + } + auto Identity = Helper.OnlineSub->GetIdentityInterface(); + + if (Identity.IsValid()) + { + Identity->GetUserPrivilege(*PlayerUniqueNetID.GetUniqueNetId(), (EUserPrivileges::Type)UserPrivilege, IOnlineIdentity::FOnGetUserPrivilegeCompleteDelegate::CreateUObject(this, &ThisClass::OnCompleted)); + return; + } + + // Fail immediately + OnFailure.Broadcast(); +} + +void UGetUserPrivilegeCallbackProxy::OnCompleted(const FUniqueNetId& PlayerID, EUserPrivileges::Type Privilege, uint32 PrivilegeResult) +{ + OnSuccess.Broadcast(/*PlayerID,*/ (EBPUserPrivileges)Privilege, PrivilegeResult == 0); +} diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/LoginUserCallbackProxy.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/LoginUserCallbackProxy.cpp new file mode 100644 index 0000000..584edc5 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/LoginUserCallbackProxy.cpp @@ -0,0 +1,111 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. + +#include "LoginUserCallbackProxy.h" + +#include "Online.h" + +////////////////////////////////////////////////////////////////////////// +// ULoginUserCallbackProxy + +ULoginUserCallbackProxy::ULoginUserCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , Delegate(FOnLoginCompleteDelegate::CreateUObject(this, &ThisClass::OnCompleted)) +{ +} + +ULoginUserCallbackProxy* ULoginUserCallbackProxy::LoginUser(UObject* WorldContextObject, class APlayerController* PlayerController, FString UserID, FString UserToken, FString AuthType) +{ + ULoginUserCallbackProxy* Proxy = NewObject(); + Proxy->PlayerControllerWeakPtr = PlayerController; + Proxy->UserID = UserID; + Proxy->UserToken = UserToken; + Proxy->AuthType = AuthType; + Proxy->WorldContextObject = WorldContextObject; + return Proxy; +} + +void ULoginUserCallbackProxy::Activate() +{ + + if (!PlayerControllerWeakPtr.IsValid()) + { + OnFailure.Broadcast(); + return; + } + + ULocalPlayer* Player = Cast(PlayerControllerWeakPtr->Player); + + if (!Player) + { + OnFailure.Broadcast(); + return; + } + + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("LoginUser"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + + if (!Helper.OnlineSub) + { + OnFailure.Broadcast(); + return; + } + + auto Identity = Helper.OnlineSub->GetIdentityInterface(); + if (Identity.IsValid()) + { + // Fallback to default AuthType if nothing is specified + if (AuthType.IsEmpty()) + { + AuthType = Identity->GetAuthType(); + } + DelegateHandle = Identity->AddOnLoginCompleteDelegate_Handle(Player->GetControllerId(), Delegate); + FOnlineAccountCredentials AccountCreds(AuthType, UserID, UserToken); + Identity->Login(Player->GetControllerId(), AccountCreds); + return; + } + + // Fail immediately + OnFailure.Broadcast(); +} + +void ULoginUserCallbackProxy::OnCompleted(int32 LocalUserNum, bool bWasSuccessful, const FUniqueNetId& UserId, const FString& ErrorVal) +{ + if (PlayerControllerWeakPtr.IsValid()) + { + ULocalPlayer* Player = Cast(PlayerControllerWeakPtr->Player); + + FUniqueNetIdRepl UniqueID(UserId.AsShared()); + + if (Player) + { + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("GetUserPrivilege"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + + if (!Helper.OnlineSub) + { + OnFailure.Broadcast(); + return; + } + + auto Identity = Helper.OnlineSub->GetIdentityInterface(); + if (Identity.IsValid()) + { + Identity->ClearOnLoginCompleteDelegate_Handle(Player->GetControllerId(), DelegateHandle); + } + Player->SetCachedUniqueNetId(UniqueID); + } + + if (APlayerState* State = PlayerControllerWeakPtr->PlayerState) + { + // Update UniqueId. See also ShowLoginUICallbackProxy.cpp + State->SetUniqueId(UniqueID); + } + } + + if (bWasSuccessful) + { + OnSuccess.Broadcast(); + } + else + { + OnFailure.Broadcast(); + } +} diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/LogoutUserCallbackProxy.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/LogoutUserCallbackProxy.cpp new file mode 100644 index 0000000..07bc666 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/LogoutUserCallbackProxy.cpp @@ -0,0 +1,94 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. + +#include "LogoutUserCallbackProxy.h" + +#include "Online.h" + +////////////////////////////////////////////////////////////////////////// +// ULogoutUserCallbackProxy + +ULogoutUserCallbackProxy::ULogoutUserCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , Delegate(FOnLogoutCompleteDelegate::CreateUObject(this, &ThisClass::OnCompleted)) +{ +} + +ULogoutUserCallbackProxy* ULogoutUserCallbackProxy::LogoutUser(UObject* WorldContextObject, class APlayerController* PlayerController) +{ + ULogoutUserCallbackProxy* Proxy = NewObject(); + Proxy->PlayerControllerWeakPtr = PlayerController; + Proxy->WorldContextObject = WorldContextObject; + return Proxy; +} + +void ULogoutUserCallbackProxy::Activate() +{ + + if (!PlayerControllerWeakPtr.IsValid()) + { + OnFailure.Broadcast(); + return; + } + + ULocalPlayer* Player = Cast(PlayerControllerWeakPtr->Player); + + if (!Player) + { + OnFailure.Broadcast(); + return; + } + + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("LogoutUser"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + + if (!Helper.OnlineSub) + { + OnFailure.Broadcast(); + return; + } + auto Identity = Helper.OnlineSub->GetIdentityInterface(); + + if (Identity.IsValid()) + { + DelegateHandle = Identity->AddOnLogoutCompleteDelegate_Handle(Player->GetControllerId(), Delegate); + Identity->Logout(Player->GetControllerId()); + return; + } + + // Fail immediately + OnFailure.Broadcast(); +} + +void ULogoutUserCallbackProxy::OnCompleted(int LocalUserNum, bool bWasSuccessful) +{ + + if (PlayerControllerWeakPtr.IsValid()) + { + ULocalPlayer* Player = Cast(PlayerControllerWeakPtr->Player); + + if (Player) + { + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("LogoutUser"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + + if (!Helper.OnlineSub) + { + OnFailure.Broadcast(); + return; + } + auto Identity = Helper.OnlineSub->GetIdentityInterface(); + + if (Identity.IsValid()) + { + Identity->ClearOnLogoutCompleteDelegate_Handle(Player->GetControllerId(), DelegateHandle); + } + } + } + + if (bWasSuccessful) + { + OnSuccess.Broadcast(); + } + else + { + OnFailure.Broadcast(); + } +} diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/SendFriendInviteCallbackProxy.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/SendFriendInviteCallbackProxy.cpp new file mode 100644 index 0000000..7c407c4 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/SendFriendInviteCallbackProxy.cpp @@ -0,0 +1,82 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#include "SendFriendInviteCallbackProxy.h" + +#include "Online.h" + +////////////////////////////////////////////////////////////////////////// +// UGetRecentPlayersCallbackProxy +DEFINE_LOG_CATEGORY(AdvancedSendFriendInviteLog); + +USendFriendInviteCallbackProxy::USendFriendInviteCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , OnSendInviteCompleteDelegate(FOnSendInviteComplete::CreateUObject(this, &ThisClass::OnSendInviteComplete)) +{ +} + +USendFriendInviteCallbackProxy* USendFriendInviteCallbackProxy::SendFriendInvite(UObject* WorldContextObject, APlayerController *PlayerController, const FBPUniqueNetId &UniqueNetIDInvited) +{ + USendFriendInviteCallbackProxy* Proxy = NewObject(); + Proxy->PlayerControllerWeakPtr = PlayerController; + Proxy->cUniqueNetId = UniqueNetIDInvited; + Proxy->WorldContextObject = WorldContextObject; + return Proxy; +} + +void USendFriendInviteCallbackProxy::Activate() +{ + if (!cUniqueNetId.IsValid()) + { + // Fail immediately + UE_LOG(AdvancedSendFriendInviteLog, Warning, TEXT("SendFriendInvite Failed received a bad UniqueNetId!")); + OnFailure.Broadcast(); + return; + } + + if (!PlayerControllerWeakPtr.IsValid()) + { + // Fail immediately + UE_LOG(AdvancedSendFriendInviteLog, Warning, TEXT("SendFriendInvite Failed received a bad playercontroller!")); + OnFailure.Broadcast(); + return; + } + + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("SendFriendInvite"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + + if (!Helper.OnlineSub) + { + OnFailure.Broadcast(); + return; + } + + auto Friends = Helper.OnlineSub->GetFriendsInterface(); + if (Friends.IsValid()) + { + ULocalPlayer* Player = Cast(PlayerControllerWeakPtr->Player); + + if (!Player) + { + // Fail immediately + UE_LOG(AdvancedSendFriendInviteLog, Warning, TEXT("SendFriendInvite Failed couldn't cast to ULocalPlayer!")); + OnFailure.Broadcast(); + return; + } + + Friends->SendInvite(Player->GetControllerId(), *cUniqueNetId.GetUniqueNetId(), EFriendsLists::ToString((EFriendsLists::Default)), OnSendInviteCompleteDelegate); + return; + } + // Fail immediately + OnFailure.Broadcast(); +} + +void USendFriendInviteCallbackProxy::OnSendInviteComplete(int32 LocalPlayerNum, bool bWasSuccessful, const FUniqueNetId &InvitedPlayer, const FString &ListName, const FString &ErrorString) +{ + if ( bWasSuccessful ) + { + OnSuccess.Broadcast(); + } + else + { + UE_LOG(AdvancedSendFriendInviteLog, Warning, TEXT("SendFriendInvite Failed with error: %s"), *ErrorString); + OnFailure.Broadcast(); + } +} diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/StartSessionCallbackProxyAdvanced.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/StartSessionCallbackProxyAdvanced.cpp new file mode 100644 index 0000000..d41e428 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/StartSessionCallbackProxyAdvanced.cpp @@ -0,0 +1,58 @@ +#include "StartSessionCallbackProxyAdvanced.h" + +UStartSessionCallbackProxyAdvanced::UStartSessionCallbackProxyAdvanced(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , StartCompleteDelegate(FOnStartSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnStartCompleted)) +{ +} + +UStartSessionCallbackProxyAdvanced* UStartSessionCallbackProxyAdvanced::StartAdvancedSession( + UObject* WorldContextObject) +{ + UStartSessionCallbackProxyAdvanced* Proxy = NewObject(); + Proxy->WorldContextObject = WorldContextObject; + return Proxy; +} + +void UStartSessionCallbackProxyAdvanced::Activate() +{ + const FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("StartSession"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + + if (Helper.OnlineSub != nullptr) + { + const auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + StartCompleteDelegateHandle = Sessions->AddOnStartSessionCompleteDelegate_Handle(StartCompleteDelegate); + Sessions->StartSession(NAME_GameSession); + return; + } + FFrame::KismetExecutionMessage(TEXT("Sessions not supported by Online Subsystem"), ELogVerbosity::Warning); + } + + // Fail immediately + OnFailure.Broadcast(); +} + +void UStartSessionCallbackProxyAdvanced::OnStartCompleted(FName SessionName, bool bWasSuccessful) +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("StartSessionCallback"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + + if (Helper.OnlineSub != nullptr) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + Sessions->ClearOnStartSessionCompleteDelegate_Handle(StartCompleteDelegateHandle); + } + } + + if (bWasSuccessful) + { + OnSuccess.Broadcast(); + } + else + { + OnFailure.Broadcast(); + } +} \ No newline at end of file diff --git a/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/UpdateSessionCallbackProxyAdvanced.cpp b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/UpdateSessionCallbackProxyAdvanced.cpp new file mode 100644 index 0000000..31aa9d9 --- /dev/null +++ b/Plugins/AdvancedSessions/Source/AdvancedSessions/Private/UpdateSessionCallbackProxyAdvanced.cpp @@ -0,0 +1,130 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#include "UpdateSessionCallbackProxyAdvanced.h" + + +////////////////////////////////////////////////////////////////////////// +// UUpdateSessionCallbackProxyAdvanced + +UUpdateSessionCallbackProxyAdvanced::UUpdateSessionCallbackProxyAdvanced(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , OnUpdateSessionCompleteDelegate(FOnUpdateSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnUpdateCompleted)) + , NumPublicConnections(1) +{ +} + +UUpdateSessionCallbackProxyAdvanced* UUpdateSessionCallbackProxyAdvanced::UpdateSession(UObject* WorldContextObject, const TArray &ExtraSettings, int32 PublicConnections, int32 PrivateConnections, bool bUseLAN, bool bAllowInvites, bool bAllowJoinInProgress, bool bRefreshOnlineData, bool bIsDedicatedServer, bool bShouldAdvertise) +{ + UUpdateSessionCallbackProxyAdvanced* Proxy = NewObject(); + Proxy->NumPublicConnections = PublicConnections; + Proxy->NumPrivateConnections = PrivateConnections; + Proxy->bUseLAN = bUseLAN; + Proxy->WorldContextObject = WorldContextObject; + Proxy->bAllowInvites = bAllowInvites; + Proxy->ExtraSettings = ExtraSettings; + Proxy->bRefreshOnlineData = bRefreshOnlineData; + Proxy->bAllowJoinInProgress = bAllowJoinInProgress; + Proxy->bDedicatedServer = bIsDedicatedServer; + Proxy->bShouldAdvertise = bShouldAdvertise; + return Proxy; +} + +void UUpdateSessionCallbackProxyAdvanced::Activate() +{ + const FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("UpdateSession"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + + if (Helper.OnlineSub != nullptr) + { + const auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + if (Sessions->GetNumSessions() < 1) + { + OnFailure.Broadcast(); + GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("NO REGISTERED SESSIONS!")); + return; + } + + // This gets the actual session itself + //FNamedOnlineSession * curSession = Sessions->GetNamedSession(NAME_GameSession); + FOnlineSessionSettings* Settings = Sessions->GetSessionSettings(NAME_GameSession); + + if (!Settings) + { + // Fail immediately + OnFailure.Broadcast(); + return; + } + + OnUpdateSessionCompleteDelegateHandle = Sessions->AddOnUpdateSessionCompleteDelegate_Handle(OnUpdateSessionCompleteDelegate); + + // FOnlineSessionSettings Settings; + //Settings->BuildUniqueId = GetBuildUniqueId(); + Settings->NumPublicConnections = NumPublicConnections; + Settings->NumPrivateConnections = NumPrivateConnections; + Settings->bShouldAdvertise = bShouldAdvertise; + Settings->bAllowJoinInProgress = bAllowJoinInProgress; + Settings->bIsLANMatch = bUseLAN; + //Settings->bUsesPresence = true; + //Settings->bAllowJoinViaPresence = true; + Settings->bAllowInvites = bAllowInvites; + Settings->bAllowJoinInProgress = bAllowJoinInProgress; + Settings->bIsDedicated = bDedicatedServer; + + FOnlineSessionSetting * fSetting = NULL; + FOnlineSessionSetting ExtraSetting; + for (int i = 0; i < ExtraSettings.Num(); i++) + { + fSetting = Settings->Settings.Find(ExtraSettings[i].Key); + + if (fSetting) + { + fSetting->Data = ExtraSettings[i].Data; + } + else + { + ExtraSetting.Data = ExtraSettings[i].Data; + ExtraSetting.AdvertisementType = EOnlineDataAdvertisementType::ViaOnlineService; + Settings->Settings.Add(ExtraSettings[i].Key, ExtraSetting); + } + } + + Sessions->UpdateSession(NAME_GameSession, *Settings, bRefreshOnlineData); + + // OnUpdateCompleted will get called, nothing more to do now + return; + } + else + { + FFrame::KismetExecutionMessage(TEXT("Sessions not supported by Online Subsystem"), ELogVerbosity::Warning); + } + } + // Fail immediately + OnFailure.Broadcast(); + GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Sessions not supported")); +} + +void UUpdateSessionCallbackProxyAdvanced::OnUpdateCompleted(FName SessionName, bool bWasSuccessful) +{ + const FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("UpdateSessionCallback"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull)); + + if (Helper.OnlineSub != nullptr) + { + const auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + Sessions->ClearOnUpdateSessionCompleteDelegate_Handle(OnUpdateSessionCompleteDelegateHandle); + + if (bWasSuccessful) + { + OnSuccess.Broadcast(); + return; + } + } + } + + if (!bWasSuccessful) + { + OnFailure.Broadcast(); + GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("WAS NOT SUCCESSFUL")); + } +} \ No newline at end of file diff --git a/Plugins/AdvancedSteamSessions/AdvancedSteamSessions.uplugin b/Plugins/AdvancedSteamSessions/AdvancedSteamSessions.uplugin new file mode 100644 index 0000000..307c51e --- /dev/null +++ b/Plugins/AdvancedSteamSessions/AdvancedSteamSessions.uplugin @@ -0,0 +1,42 @@ +{ + "FileVersion" : 3, + + "FriendlyName" : "Advanced Steam Sessions", + "Version" : 5.4, + "VersionName": "5.4", + "Description" : "Adds new blueprint functions to handle more advanced session operations in Steam. REQUIRES ADVANCED SESSIONS", + "Category" : "Advanced Sessions Plugin", + "CreatedBy" : "Joshua Statzer", + "CreatedByURL" : "N/A", + + "Modules" : + [ + { + "Name": "AdvancedSteamSessions", + "Type": "RunTime", + "LoadingPhase": "Default" + } + ], + "Plugins": [ + { + "Name": "AdvancedSessions", + "Enabled": true + }, + { + "Name": "OnlineSubsystem", + "Enabled": true + }, + { + "Name": "OnlineSubsystemSteam", + "Enabled": true + }, + { + "Name": "OnlineSubsystemUtils", + "Enabled": true + }, + { + "Name": "SteamShared", + "Enabled": true + } + ] +} \ No newline at end of file diff --git a/Plugins/AdvancedSteamSessions/Config/FilterPlugin.ini b/Plugins/AdvancedSteamSessions/Config/FilterPlugin.ini new file mode 100644 index 0000000..ccebca2 --- /dev/null +++ b/Plugins/AdvancedSteamSessions/Config/FilterPlugin.ini @@ -0,0 +1,8 @@ +[FilterPlugin] +; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and +; may include "...", "*", and "?" wildcards to match directories, files, and individual characters respectively. +; +; Examples: +; /README.txt +; /Extras/... +; /Binaries/ThirdParty/*.dll diff --git a/Plugins/AdvancedSteamSessions/Resources/Icon128.png b/Plugins/AdvancedSteamSessions/Resources/Icon128.png new file mode 100644 index 0000000..fee08fc --- /dev/null +++ b/Plugins/AdvancedSteamSessions/Resources/Icon128.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eac09a19149b472680abd8bcb38513edbe29083a34edb4bbdbfbebec68540029 +size 5879 diff --git a/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/AdvancedSteamSessions.Build.cs b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/AdvancedSteamSessions.Build.cs new file mode 100644 index 0000000..6a4c768 --- /dev/null +++ b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/AdvancedSteamSessions.Build.cs @@ -0,0 +1,22 @@ +using UnrealBuildTool; +using System.IO; + +public class AdvancedSteamSessions : ModuleRules +{ + public AdvancedSteamSessions(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; + //bEnforceIWYU = true; + + PublicDefinitions.Add("WITH_ADVANCED_STEAM_SESSIONS=1"); + + PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "OnlineSubsystem", "CoreUObject", "OnlineSubsystemUtils", "Networking", "Sockets", "AdvancedSessions"/*"Voice", "OnlineSubsystemSteam"*/ }); + PrivateDependencyModuleNames.AddRange(new string[] { "OnlineSubsystem", "Sockets", "Networking", "OnlineSubsystemUtils" /*"Voice", "Steamworks","OnlineSubsystemSteam"*/}); + + if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Linux) || (Target.Platform == UnrealTargetPlatform.Mac)) + { + PublicDependencyModuleNames.AddRange(new string[] { "SteamShared", "Steamworks", "OnlineSubsystemSteam" }); + //PublicIncludePaths.AddRange(new string[] { "../Plugins/Online/OnlineSubsystemSteam/Source/Private" });// This is dumb but it isn't very open + } + } +} \ No newline at end of file diff --git a/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/AdvancedSteamFriendsLibrary.h b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/AdvancedSteamFriendsLibrary.h new file mode 100644 index 0000000..83de461 --- /dev/null +++ b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/AdvancedSteamFriendsLibrary.h @@ -0,0 +1,389 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "BlueprintDataDefinitions.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "Online.h" +#include "OnlineSubsystem.h" +#include "Interfaces/OnlineFriendsInterface.h" +#include "Interfaces/OnlineUserInterface.h" +#include "Interfaces/OnlineMessageInterface.h" +#include "Interfaces/OnlinePresenceInterface.h" +#include "Engine/GameInstance.h" +#include "Interfaces/OnlineSessionInterface.h" +#include "BlueprintDataDefinitions.h" +#include "UObject/UObjectIterator.h" + +// This is taken directly from UE4 - OnlineSubsystemSteamPrivatePCH.h as a fix for the array_count macro +// @todo Steam: Steam headers trigger secure-C-runtime warnings in Visual C++. Rather than mess with _CRT_SECURE_NO_WARNINGS, we'll just +// disable the warnings locally. Remove when this is fixed in the SDK +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4996) +// #TODO check back on this at some point +#pragma warning(disable:4265) // SteamAPI CCallback< specifically, this warning is off by default but 4.17 turned it on.... +#endif + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + +#pragma push_macro("ARRAY_COUNT") +#undef ARRAY_COUNT + +#if USING_CODE_ANALYSIS +MSVC_PRAGMA(warning(push)) +MSVC_PRAGMA(warning(disable : ALL_CODE_ANALYSIS_WARNINGS)) +#endif // USING_CODE_ANALYSIS + +#include + +#if USING_CODE_ANALYSIS +MSVC_PRAGMA(warning(pop)) +#endif // USING_CODE_ANALYSIS + +#include +#include +//#include +#pragma pop_macro("ARRAY_COUNT") + +// @todo Steam: See above +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +// Making a copy of this here since the original is still in a private folder and is screwing with things +/** +* Steam specific implementation of the unique net id +*/ +class FUniqueNetIdSteam2 : + public FUniqueNetId +{ +PACKAGE_SCOPE: + /** Holds the net id for a player */ + uint64 UniqueNetId; + + /** Hidden on purpose */ + FUniqueNetIdSteam2() : + UniqueNetId(0) + { + } + + /** + * Copy Constructor + * + * @param Src the id to copy + */ + explicit FUniqueNetIdSteam2(const FUniqueNetIdSteam2& Src) : + UniqueNetId(Src.UniqueNetId) + { + } + +public: + /** + * Constructs this object with the specified net id + * + * @param InUniqueNetId the id to set ours to + */ + explicit FUniqueNetIdSteam2(uint64 InUniqueNetId) : + UniqueNetId(InUniqueNetId) + { + } + + /** + * Constructs this object with the steam id + * + * @param InUniqueNetId the id to set ours to + */ + explicit FUniqueNetIdSteam2(CSteamID InSteamId) : + UniqueNetId(InSteamId.ConvertToUint64()) + { + } + + /** + * Constructs this object with the specified net id + * + * @param String textual representation of an id + */ + explicit FUniqueNetIdSteam2(const FString& Str) : + UniqueNetId(FCString::Atoi64(*Str)) + { + } + + + /** + * Constructs this object with the specified net id + * + * @param InUniqueNetId the id to set ours to (assumed to be FUniqueNetIdSteam in fact) + */ + explicit FUniqueNetIdSteam2(const FUniqueNetId& InUniqueNetId) : + UniqueNetId(*(uint64*)InUniqueNetId.GetBytes()) + { + } + + virtual FName GetType() const override + { + return STEAM_SUBSYSTEM; + } + + /** + * Get the raw byte representation of this net id + * This data is platform dependent and shouldn't be manipulated directly + * + * @return byte array of size GetSize() + */ + virtual const uint8* GetBytes() const override + { + return (uint8*)&UniqueNetId; + } + + /** + * Get the size of the id + * + * @return size in bytes of the id representation + */ + virtual int32 GetSize() const override + { + return sizeof(uint64); + } + + /** + * Check the validity of the id + * + * @return true if this is a well formed ID, false otherwise + */ + virtual bool IsValid() const override + { + return UniqueNetId != 0 && CSteamID(UniqueNetId).IsValid(); + } + + /** + * Platform specific conversion to string representation of data + * + * @return data in string form + */ + virtual FString ToString() const override + { + return FString::Printf(TEXT("%llu"), UniqueNetId); + } + + /** + * Get a human readable representation of the net id + * Shouldn't be used for anything other than logging/debugging + * + * @return id in string form + */ + virtual FString ToDebugString() const override + { + CSteamID SteamID(UniqueNetId); + if (SteamID.IsLobby()) + { + return FString::Printf(TEXT("Lobby [0x%llX]"), UniqueNetId); + } + else if (SteamID.BAnonGameServerAccount()) + { + return FString::Printf(TEXT("Server [0x%llX]"), UniqueNetId); + } + else if (SteamID.IsValid()) + { + const FString NickName(SteamFriends() ? UTF8_TO_TCHAR(SteamFriends()->GetFriendPersonaName(UniqueNetId)) : TEXT("UNKNOWN")); + return FString::Printf(TEXT("%s [0x%llX]"), *NickName, UniqueNetId); + } + else + { + return FString::Printf(TEXT("INVALID [0x%llX]"), UniqueNetId); + } + } + + + virtual uint32 GetTypeHash() const override + { + return ::GetTypeHash(UniqueNetId); + } + + /** Convenience cast to CSteamID */ + operator CSteamID() + { + return UniqueNetId; + } + + /** Convenience cast to CSteamID */ + operator const CSteamID() const + { + return UniqueNetId; + } + + /** Convenience cast to CSteamID pointer */ + operator CSteamID*() + { + return (CSteamID*)&UniqueNetId; + } + + /** Convenience cast to CSteamID pointer */ + operator const CSteamID*() const + { + return (const CSteamID*)&UniqueNetId; + } + + friend FArchive& operator<<(FArchive& Ar, FUniqueNetIdSteam2& UserId) + { + return Ar << UserId.UniqueNetId; + } +}; + +#endif + +#include "AdvancedSteamFriendsLibrary.generated.h" + + +//General Advanced Sessions Log +DECLARE_LOG_CATEGORY_EXTERN(AdvancedSteamFriendsLog, Log, All); + +UENUM(Blueprintable) +enum class SteamAvatarSize : uint8 +{ + SteamAvatar_INVALID = 0, + SteamAvatar_Small = 1, + SteamAvatar_Medium = 2, + SteamAvatar_Large = 3 +}; + +UENUM(Blueprintable) +enum class ESteamUserOverlayType : uint8 +{ + /*Opens the overlay web browser to the specified user or groups profile.*/ + steamid, + /*Opens a chat window to the specified user, or joins the group chat.*/ + chat, + /*Opens a window to a Steam Trading session that was started with the ISteamEconomy / StartTrade Web API.*/ + jointrade, + /*Opens the overlay web browser to the specified user's stats.*/ + stats, + /*Opens the overlay web browser to the specified user's achievements.*/ + achievements, + /*Opens the overlay in minimal mode prompting the user to add the target user as a friend.*/ + friendadd, + /*Opens the overlay in minimal mode prompting the user to remove the target friend.*/ + friendremove, + /*Opens the overlay in minimal mode prompting the user to accept an incoming friend invite.*/ + friendrequestaccept, + /*Opens the overlay in minimal mode prompting the user to ignore an incoming friend invite.*/ + friendrequestignore, + /*Opens the invite overlay, invitations sent from this dialog will be for the provided lobby*/ + invitetolobby +}; + +static FString EnumToString(const FString& enumName, uint8 value) +{ + + const UEnum* EnumPtr = FindFirstObject(*enumName, EFindFirstObjectOptions::None, ELogVerbosity::Warning, TEXT("EumtoString")); + + if (!EnumPtr) + return FString(); + + FString EnumName = EnumPtr->GetNameStringByIndex(value); + return EnumName; +} + + +USTRUCT(BlueprintType, Category = "Online|SteamAPI|SteamGroups") +struct FBPSteamGroupInfo +{ + GENERATED_USTRUCT_BODY() + +public: + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|SteamAPI|SteamGroups") + FBPUniqueNetId GroupID; // Uint64 representation + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|SteamAPI|SteamGroups") + FString GroupName; + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|SteamAPI|SteamGroups") + FString GroupTag; + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|SteamAPI|SteamGroups") + int32 numOnline = 0; + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|SteamAPI|SteamGroups") + int32 numInGame = 0; + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|SteamAPI|SteamGroups") + int32 numChatting = 0; + +}; + +UENUM(Blueprintable) +enum class EBPTextFilteringContext : uint8 +{ + /*Unknown context.*/ + FContext_Unknown = 0, + /*Game content, only legally required filtering is performed.*/ + FContext_GameContent = 1, + /*Char from another player.*/ + FContext_Chat = 2, + /*Character or item name.*/ + FContext_Name = 3 +}; + +UCLASS() +class UAdvancedSteamFriendsLibrary : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() +public: + + //********* Friend List Functions *************// + + // Get a texture of a valid friends avatar, STEAM ONLY, Returns invalid texture if the subsystem hasn't loaded that size of avatar yet + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|SteamAPI", meta = (ExpandEnumAsExecs = "Result")) + static UTexture2D * GetSteamFriendAvatar(const FBPUniqueNetId UniqueNetId, EBlueprintAsyncResultSwitch &Result, SteamAvatarSize AvatarSize = SteamAvatarSize::SteamAvatar_Medium); + + // Preloads the avatar and name of a steam friend, return whether it is already available or not, STEAM ONLY, Takes time to actually load everything after this is called. + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|SteamAPI") + static bool RequestSteamFriendInfo(const FBPUniqueNetId UniqueNetId, bool bRequireNameOnly = false); + + // Opens the steam overlay to go to the specified user dialog + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|SteamAPI") + static bool OpenSteamUserOverlay(const FBPUniqueNetId UniqueNetId, ESteamUserOverlayType DialogType); + + // Returns if the steam overlay is currently active (this can return false during initial overlay hooking) + UFUNCTION(BlueprintPure, Category = "Online|AdvancedFriends|SteamAPI") + static bool IsOverlayEnabled(); + + // Gets the level of a friends steam account, STEAM ONLY, Returns -1 if the steam level is not known, might need RequestSteamFriendInfo called first. + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|SteamAPI") + static int32 GetFriendSteamLevel(const FBPUniqueNetId UniqueNetId); + + // Gets the persona name of a steam ID, STEAM ONLY, Returns empty if no result, might need RequestSteamFriendInfo called first. + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|SteamAPI") + static FString GetSteamPersonaName(const FBPUniqueNetId UniqueNetId); + + // Creates a unique steam id directly from a string holding a uint64 value, useful for testing + UFUNCTION(BlueprintPure, Category = "Online|AdvancedFriends|SteamAPI") + static FBPUniqueNetId CreateSteamIDFromString(const FString SteamID64); + + // Retreives the local steam ID from steam + UFUNCTION(BlueprintPure, Category = "Online|AdvancedFriends|SteamAPI") + static FBPUniqueNetId GetLocalSteamIDFromSteam(); + + /* Gets the current game played by a friend - AppID is int32 even though steam ids are uint32, can't be helped in blueprint currently + * can use the AppID with the WebAPI GetAppList request. + */ + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|SteamAPI", meta = (ExpandEnumAsExecs = "Result")) + static void GetSteamFriendGamePlayed(const FBPUniqueNetId UniqueNetId, EBlueprintResultSwitch &Result/*, FString & GameName*/, int32 & AppID); + + // Get a full list of steam groups + UFUNCTION(BlueprintCallable, Category = "Online|SteamAPI|SteamGroups") + static void GetSteamGroups(TArray & SteamGroups); + + // Initializes text filtering (pre-loading dictonaries) + // Returns if it succeeded, false if filtering is unavailable for the games language + UFUNCTION(BlueprintCallable, Category = "Online|SteamAPI|TextFiltering") + static bool InitTextFiltering(); + + // Attempts to filter a string with the given filtering context + // Returns true if the text has been filtered, false if it hasn't (no filtering required or operation failed) + // If false it will still output the original text + // Textsource is the steam id that is the source of the text (player name / chat) + // Requires that InitTextFiltering be called first!! + UFUNCTION(BlueprintCallable, Category = "Online|SteamAPI|TextFiltering") + static bool FilterText(FString TextToFilter, EBPTextFilteringContext Context, const FBPUniqueNetId TextSourceID, FString& FilteredText); + + // Returns if steam is running in big picture mode + UFUNCTION(BlueprintPure, Category = "Online|SteamAPI") + static bool IsSteamInBigPictureMode(); +}; diff --git a/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/AdvancedSteamSessions.h b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/AdvancedSteamSessions.h new file mode 100644 index 0000000..4a49251 --- /dev/null +++ b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/AdvancedSteamSessions.h @@ -0,0 +1,12 @@ +#pragma once + +#include "CoreMinimal.h" +#include "Modules/ModuleManager.h" + +class AdvancedSteamSessions : public IModuleInterface +{ +public: + /** IModuleInterface implementation */ + void StartupModule(); + void ShutdownModule(); +}; \ No newline at end of file diff --git a/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/AdvancedSteamWorkshopLibrary.h b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/AdvancedSteamWorkshopLibrary.h new file mode 100644 index 0000000..db56b35 --- /dev/null +++ b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/AdvancedSteamWorkshopLibrary.h @@ -0,0 +1,351 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "BlueprintDataDefinitions.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "Online.h" +#include "OnlineSubsystem.h" +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED +#include "steam/isteamugc.h" +#include "steam/isteamremotestorage.h" +#endif +#include "Interfaces/OnlineSessionInterface.h" + +// @todo Steam: Steam headers trigger secure-C-runtime warnings in Visual C++. Rather than mess with _CRT_SECURE_NO_WARNINGS, we'll just +// disable the warnings locally. Remove when this is fixed in the SDK +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4996) +// #TODO check back on this at some point +#pragma warning(disable:4265) // SteamAPI CCallback< specifically, this warning is off by default but 4.17 turned it on.... +#endif + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + +#pragma push_macro("ARRAY_COUNT") +#undef ARRAY_COUNT + +#if USING_CODE_ANALYSIS +MSVC_PRAGMA(warning(push)) +MSVC_PRAGMA(warning(disable : ALL_CODE_ANALYSIS_WARNINGS)) +#endif // USING_CODE_ANALYSIS + +#include + +#if USING_CODE_ANALYSIS +MSVC_PRAGMA(warning(pop)) +#endif // USING_CODE_ANALYSIS + + +#pragma pop_macro("ARRAY_COUNT") + +#endif + +// @todo Steam: See above +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + +#include "AdvancedSteamWorkshopLibrary.generated.h" + + +//General Advanced Sessions Log +DECLARE_LOG_CATEGORY_EXTERN(AdvancedSteamWorkshopLog, Log, All); + + +// Using a custom struct because uint32 isn't blueprint supported and I don't want to cast to int32 +// due to the size of the workshop it could end up overflowing? +USTRUCT(BlueprintType) +struct FBPSteamWorkshopID +{ + GENERATED_USTRUCT_BODY() + +public: + + uint64 SteamWorkshopID; + + FBPSteamWorkshopID() + { + + } + + FBPSteamWorkshopID(uint64 ID) + { + SteamWorkshopID = ID; + } +}; + + +// General result codes - Copying steams version over +// Check these to future proof +UENUM(BlueprintType) +enum class FBPSteamResult : uint8 +{ + K_EResultInvalid = 0, + k_EResultOK = 1, // success + k_EResultFail = 2, // generic failure + k_EResultNoConnection = 3, // no/failed network connection + // k_EResultNoConnectionRetry = 4, // OBSOLETE - removed + k_EResultInvalidPassword = 5, // password/ticket is invalid + k_EResultLoggedInElsewhere = 6, // same user logged in elsewhere + k_EResultInvalidProtocolVer = 7, // protocol version is incorrect + k_EResultInvalidParam = 8, // a parameter is incorrect + k_EResultFileNotFound = 9, // file was not found + k_EResultBusy = 10, // called method busy - action not taken + k_EResultInvalidState = 11, // called object was in an invalid state + k_EResultInvalidName = 12, // name is invalid + k_EResultInvalidEmail = 13, // email is invalid + k_EResultDuplicateName = 14, // name is not unique + k_EResultAccessDenied = 15, // access is denied + k_EResultTimeout = 16, // operation timed out + k_EResultBanned = 17, // VAC2 banned + k_EResultAccountNotFound = 18, // account not found + k_EResultInvalidSteamID = 19, // steamID is invalid + k_EResultServiceUnavailable = 20, // The requested service is currently unavailable + k_EResultNotLoggedOn = 21, // The user is not logged on + k_EResultPending = 22, // Request is pending (may be in process, or waiting on third party) + k_EResultEncryptionFailure = 23, // Encryption or Decryption failed + k_EResultInsufficientPrivilege = 24, // Insufficient privilege + k_EResultLimitExceeded = 25, // Too much of a good thing + k_EResultRevoked = 26, // Access has been revoked (used for revoked guest passes) + k_EResultExpired = 27, // License/Guest pass the user is trying to access is expired + k_EResultAlreadyRedeemed = 28, // Guest pass has already been redeemed by account, cannot be acked again + k_EResultDuplicateRequest = 29, // The request is a duplicate and the action has already occurred in the past, ignored this time + k_EResultAlreadyOwned = 30, // All the games in this guest pass redemption request are already owned by the user + k_EResultIPNotFound = 31, // IP address not found + k_EResultPersistFailed = 32, // failed to write change to the data store + k_EResultLockingFailed = 33, // failed to acquire access lock for this operation + k_EResultLogonSessionReplaced = 34, + k_EResultConnectFailed = 35, + k_EResultHandshakeFailed = 36, + k_EResultIOFailure = 37, + k_EResultRemoteDisconnect = 38, + k_EResultShoppingCartNotFound = 39, // failed to find the shopping cart requested + k_EResultBlocked = 40, // a user didn't allow it + k_EResultIgnored = 41, // target is ignoring sender + k_EResultNoMatch = 42, // nothing matching the request found + k_EResultAccountDisabled = 43, + k_EResultServiceReadOnly = 44, // this service is not accepting content changes right now + k_EResultAccountNotFeatured = 45, // account doesn't have value, so this feature isn't available + k_EResultAdministratorOK = 46, // allowed to take this action, but only because requester is admin + k_EResultContentVersion = 47, // A Version mismatch in content transmitted within the Steam protocol. + k_EResultTryAnotherCM = 48, // The current CM can't service the user making a request, user should try another. + k_EResultPasswordRequiredToKickSession = 49,// You are already logged in elsewhere, this cached credential login has failed. + k_EResultAlreadyLoggedInElsewhere = 50, // You are already logged in elsewhere, you must wait + k_EResultSuspended = 51, // Long running operation (content download) suspended/paused + k_EResultCancelled = 52, // Operation canceled (typically by user: content download) + k_EResultDataCorruption = 53, // Operation canceled because data is ill formed or unrecoverable + k_EResultDiskFull = 54, // Operation canceled - not enough disk space. + k_EResultRemoteCallFailed = 55, // an remote call or IPC call failed + k_EResultPasswordUnset = 56, // Password could not be verified as it's unset server side + k_EResultExternalAccountUnlinked = 57, // External account (PSN, Facebook...) is not linked to a Steam account + k_EResultPSNTicketInvalid = 58, // PSN ticket was invalid + k_EResultExternalAccountAlreadyLinked = 59, // External account (PSN, Facebook...) is already linked to some other account, must explicitly request to replace/delete the link first + k_EResultRemoteFileConflict = 60, // The sync cannot resume due to a conflict between the local and remote files + k_EResultIllegalPassword = 61, // The requested new password is not legal + k_EResultSameAsPreviousValue = 62, // new value is the same as the old one ( secret question and answer ) + k_EResultAccountLogonDenied = 63, // account login denied due to 2nd factor authentication failure + k_EResultCannotUseOldPassword = 64, // The requested new password is not legal + k_EResultInvalidLoginAuthCode = 65, // account login denied due to auth code invalid + k_EResultAccountLogonDeniedNoMail = 66, // account login denied due to 2nd factor auth failure - and no mail has been sent + k_EResultHardwareNotCapableOfIPT = 67, // + k_EResultIPTInitError = 68, // + k_EResultParentalControlRestricted = 69, // operation failed due to parental control restrictions for current user + k_EResultFacebookQueryError = 70, // Facebook query returned an error + k_EResultExpiredLoginAuthCode = 71, // account login denied due to auth code expired + k_EResultIPLoginRestrictionFailed = 72, + k_EResultAccountLockedDown = 73, + k_EResultAccountLogonDeniedVerifiedEmailRequired = 74, + k_EResultNoMatchingURL = 75, + k_EResultBadResponse = 76, // parse failure, missing field, etc. + k_EResultRequirePasswordReEntry = 77, // The user cannot complete the action until they re-enter their password + k_EResultValueOutOfRange = 78, // the value entered is outside the acceptable range + k_EResultUnexpectedError = 79, // something happened that we didn't expect to ever happen + k_EResultDisabled = 80, // The requested service has been configured to be unavailable + k_EResultInvalidCEGSubmission = 81, // The set of files submitted to the CEG server are not valid ! + k_EResultRestrictedDevice = 82, // The device being used is not allowed to perform this action + k_EResultRegionLocked = 83, // The action could not be complete because it is region restricted + k_EResultRateLimitExceeded = 84, // Temporary rate limit exceeded, try again later, different from k_EResultLimitExceeded which may be permanent + k_EResultAccountLoginDeniedNeedTwoFactor = 85, // Need two-factor code to login + k_EResultItemDeleted = 86, // The thing we're trying to access has been deleted + k_EResultAccountLoginDeniedThrottle = 87, // login attempt failed, try to throttle response to possible attacker + k_EResultTwoFactorCodeMismatch = 88, // two factor code mismatch + k_EResultTwoFactorActivationCodeMismatch = 89, // activation code for two-factor didn't match + k_EResultAccountAssociatedToMultiplePartners = 90, // account has been associated with multiple partners + k_EResultNotModified = 91, // data not modified +}; + +// Check these to future proof +UENUM(BlueprintType) +enum class FBPWorkshopFileType : uint8 +{ + k_EWorkshopFileTypeCommunity = 0, + k_EWorkshopFileTypeMicrotransaction = 1, + k_EWorkshopFileTypeCollection = 2, + k_EWorkshopFileTypeArt = 3, + k_EWorkshopFileTypeVideo = 4, + k_EWorkshopFileTypeScreenshot = 5, + k_EWorkshopFileTypeGame = 6, + k_EWorkshopFileTypeSoftware = 7, + k_EWorkshopFileTypeConcept = 8, + k_EWorkshopFileTypeWebGuide = 9, + k_EWorkshopFileTypeIntegratedGuide = 10, + k_EWorkshopFileTypeMerch = 11, + k_EWorkshopFileTypeControllerBinding = 12, + k_EWorkshopFileTypeSteamworksAccessInvite = 13, + k_EWorkshopFileTypeSteamVideo = 14, + + // Update k_EWorkshopFileTypeMax if you add values. + k_EWorkshopFileTypeMax = 15 +}; + +// WorkshopItemDetails Struct +USTRUCT(BlueprintType) +struct FBPSteamWorkshopItemDetails +{ + GENERATED_USTRUCT_BODY() + +public: + + FBPSteamWorkshopItemDetails() + { + ResultOfRequest = FBPSteamResult::k_EResultOK; + FileType = FBPWorkshopFileType::k_EWorkshopFileTypeMax; + CreatorAppID = 0; + ConsumerAppID = 0; + VotesUp = 0; + VotesDown = 0; + CalculatedScore = 0.f; + bBanned = false; + bAcceptedForUse = false; + bTagsTruncated = false; + } + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + FBPSteamWorkshopItemDetails(SteamUGCDetails_t &hUGCDetails) + { + ResultOfRequest = (FBPSteamResult)hUGCDetails.m_eResult; + FileType = (FBPWorkshopFileType)hUGCDetails.m_eFileType; + CreatorAppID = (int32)hUGCDetails.m_nCreatorAppID; + ConsumerAppID = (int32)hUGCDetails.m_nConsumerAppID; + Title = FString(hUGCDetails.m_rgchTitle, k_cchPublishedDocumentTitleMax); + Description = FString(hUGCDetails.m_rgchDescription, k_cchPublishedDocumentDescriptionMax); + ItemUrl = FString(hUGCDetails.m_rgchURL, k_cchPublishedFileURLMax); + VotesUp = (int32)hUGCDetails.m_unVotesUp; + VotesDown = (int32)hUGCDetails.m_unVotesDown; + CalculatedScore = hUGCDetails.m_flScore; + bBanned = hUGCDetails.m_bBanned; + bAcceptedForUse = hUGCDetails.m_bAcceptedForUse; + bTagsTruncated = hUGCDetails.m_bTagsTruncated; + + CreatorSteamID = FString::Printf(TEXT("%llu"), hUGCDetails.m_ulSteamIDOwner); + } + + FBPSteamWorkshopItemDetails(const SteamUGCDetails_t &hUGCDetails) + { + ResultOfRequest = (FBPSteamResult)hUGCDetails.m_eResult; + FileType = (FBPWorkshopFileType)hUGCDetails.m_eFileType; + CreatorAppID = (int32)hUGCDetails.m_nCreatorAppID; + ConsumerAppID = (int32)hUGCDetails.m_nConsumerAppID; + Title = FString(hUGCDetails.m_rgchTitle, k_cchPublishedDocumentTitleMax); + Description = FString(hUGCDetails.m_rgchDescription, k_cchPublishedDocumentDescriptionMax); + ItemUrl = FString(hUGCDetails.m_rgchURL, k_cchPublishedFileURLMax); + VotesUp = (int32)hUGCDetails.m_unVotesUp; + VotesDown = (int32)hUGCDetails.m_unVotesDown; + CalculatedScore = hUGCDetails.m_flScore; + bBanned = hUGCDetails.m_bBanned; + bAcceptedForUse = hUGCDetails.m_bAcceptedForUse; + bTagsTruncated = hUGCDetails.m_bTagsTruncated; + + CreatorSteamID = FString::Printf(TEXT("%llu"), hUGCDetails.m_ulSteamIDOwner); + } +#endif + + // Result of obtaining the details + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + FBPSteamResult ResultOfRequest; + + // Type of file + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + FBPWorkshopFileType FileType; + + // These two are listed as baked to an int, but is stored as a uint, think its safe to keep int + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + int32 CreatorAppID; + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + int32 ConsumerAppID; + + // Title of item + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + FString Title; + + // Description of item + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + FString Description; + + //Url for a video of website + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + FString ItemUrl; + + // Votes will be unlikely to go above signed limited + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + int32 VotesUp; + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + int32 VotesDown; + + // Calculated score + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + float CalculatedScore; + + // whether the file was banned + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + bool bBanned; + + // developer has specifically flagged this item as accepted in the Workshop + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + bool bAcceptedForUse; + + // whether the list of tags was too long to be returned in the provided buffer + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + bool bTagsTruncated; + + // Steam ID of the user who created this content. + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + FString CreatorSteamID; + + /* + PublishedFileId_t m_nPublishedFileId; + uint32 m_rtimeCreated; // time when the published file was created + uint32 m_rtimeUpdated; // time when the published file was last updated + uint32 m_rtimeAddedToUserList; // time when the user added the published file to their list (not always applicable) + ERemoteStoragePublishedFileVisibility m_eVisibility; // visibility + char m_rgchTags[k_cchTagListMax]; // comma separated list of all tags associated with this file + // file/url information + UGCHandle_t m_hFile; // The handle of the primary file + UGCHandle_t m_hPreviewFile; // The handle of the preview file + char m_pchFileName[k_cchFilenameMax]; // The cloud filename of the primary file + int32 m_nFileSize; // Size of the primary file + int32 m_nPreviewFileSize; // Size of the preview file + uint32 m_unNumChildren; // if m_eFileType == k_EWorkshopFileTypeCollection, then this number will be the number of children contained within the collection + */ + +}; + +UCLASS() +class UAdvancedSteamWorkshopLibrary : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() +public: + + //********* Steam Functions *************// + + // Returns IDs for subscribed workshop items, TArray length dictates how many + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSteamWorkshop") + static TArray GetSubscribedWorkshopItems(int32 & NumberOfItems); + + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSteamWorkshop") + static void GetNumSubscribedWorkshopItems(int32 & NumberOfItems); + +}; diff --git a/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/SteamNotificationsSubsystem.h b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/SteamNotificationsSubsystem.h new file mode 100644 index 0000000..7b8641a --- /dev/null +++ b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/SteamNotificationsSubsystem.h @@ -0,0 +1,87 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Subsystems/GameInstanceSubsystem.h" + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + +#include + +#endif + +#include "SteamNotificationsSubsystem.generated.h" + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnSteamOverlayActivated, bool, bOverlayState); + +UCLASS() +class ADVANCEDSTEAMSESSIONS_API USteamNotificationsSubsystem : public UGameInstanceSubsystem +{ + GENERATED_BODY() + +public: + + // Event thrown when the steam overlay switches states + UPROPERTY(BlueprintAssignable, Category = "SteamEvents") + FOnSteamOverlayActivated OnSteamOverlayActivated_Bind; + + USteamNotificationsSubsystem() : Super() + { + + } + + class cSteamEventsStore + { + public: + USteamNotificationsSubsystem* ParentSubsystem = nullptr; + void Initialize(USteamNotificationsSubsystem* MyParent) + { + ParentSubsystem = MyParent; + } + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + cSteamEventsStore() : + OnExternalUITriggeredCallback(this, &cSteamEventsStore::OnExternalUITriggered) + { + + } +#else + //cSteamEventsStore() + //{ + + //} +#endif + + //~cSteamEventsStore(){} + + private: +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + STEAM_CALLBACK(cSteamEventsStore, OnExternalUITriggered, GameOverlayActivated_t, OnExternalUITriggeredCallback); +#endif + }; + + cSteamEventsStore MyEvents; + + /** Implement this for initialization of instances of the system */ + virtual void Initialize(FSubsystemCollectionBase& Collection) override + { + MyEvents.Initialize(this); + } + + /** Implement this for deinitialization of instances of the system */ + virtual void Deinitialize() override + { + + } +}; + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED +void USteamNotificationsSubsystem::cSteamEventsStore::OnExternalUITriggered(GameOverlayActivated_t* CallbackData) +{ + if (ParentSubsystem) + { + ParentSubsystem->OnSteamOverlayActivated_Bind.Broadcast((bool)CallbackData->m_bActive); + } +} +#endif \ No newline at end of file diff --git a/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/SteamRequestGroupOfficersCallbackProxy.h b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/SteamRequestGroupOfficersCallbackProxy.h new file mode 100644 index 0000000..73955dd --- /dev/null +++ b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/SteamRequestGroupOfficersCallbackProxy.h @@ -0,0 +1,100 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "CoreMinimal.h" +#include "BlueprintDataDefinitions.h" + +// This is taken directly from UE4 - OnlineSubsystemSteamPrivatePCH.h as a fix for the array_count macro + +// @todo Steam: Steam headers trigger secure-C-runtime warnings in Visual C++. Rather than mess with _CRT_SECURE_NO_WARNINGS, we'll just +// disable the warnings locally. Remove when this is fixed in the SDK +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4996) +// #TODO check back on this at some point +#pragma warning(disable:4265) // SteamAPI CCallback< specifically, this warning is off by default but 4.17 turned it on.... +#endif + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + +//#include "OnlineSubsystemSteam.h" + +#pragma push_macro("ARRAY_COUNT") +#undef ARRAY_COUNT + +#if USING_CODE_ANALYSIS +MSVC_PRAGMA(warning(push)) +MSVC_PRAGMA(warning(disable : ALL_CODE_ANALYSIS_WARNINGS)) +#endif // USING_CODE_ANALYSIS + +#include + +#if USING_CODE_ANALYSIS +MSVC_PRAGMA(warning(pop)) +#endif // USING_CODE_ANALYSIS + + +#pragma pop_macro("ARRAY_COUNT") + +#endif + +// @todo Steam: See above +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#include "SteamRequestGroupOfficersCallbackProxy.generated.h" + +USTRUCT(BlueprintType, Category = "Online|SteamAPI|SteamGroups") +struct FBPSteamGroupOfficer +{ + GENERATED_USTRUCT_BODY() + +public: + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|SteamAPI|SteamGroups") + FBPUniqueNetId OfficerUniqueNetID; // Uint64 representation + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|SteamAPI|SteamGroups") + bool bIsOwner = false; + +}; + + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBlueprintGroupOfficerDetailsDelegate, const TArray &, OfficerList); + +UCLASS(MinimalAPI) +class USteamRequestGroupOfficersCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + virtual ~USteamRequestGroupOfficersCallbackProxy(); + + // Called when there is a successful results return + UPROPERTY(BlueprintAssignable) + FBlueprintGroupOfficerDetailsDelegate OnSuccess; + + // Called when there is an unsuccessful results return + UPROPERTY(BlueprintAssignable) + FBlueprintGroupOfficerDetailsDelegate OnFailure; + + // Returns a list of steam group officers + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|SteamAPI|SteamGroups") + static USteamRequestGroupOfficersCallbackProxy* GetSteamGroupOfficerList(UObject* WorldContextObject, FBPUniqueNetId GroupUniqueNetID); + + // UOnlineBlueprintCallProxyBase interface + virtual void Activate() override; + // End of UOnlineBlueprintCallProxyBase interface + +private: + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + void OnRequestGroupOfficerDetails( ClanOfficerListResponse_t *pResult, bool bIOFailure); + CCallResult m_callResultGroupOfficerRequestDetails; + +#endif + +private: + + FBPUniqueNetId GroupUniqueID; + UObject* WorldContextObject; +}; diff --git a/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/SteamWSRequestUGCDetailsCallbackProxy.h b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/SteamWSRequestUGCDetailsCallbackProxy.h new file mode 100644 index 0000000..0adee7e --- /dev/null +++ b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Classes/SteamWSRequestUGCDetailsCallbackProxy.h @@ -0,0 +1,87 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "CoreMinimal.h" +#include "AdvancedSteamWorkshopLibrary.h" +#include "BlueprintDataDefinitions.h" + +// This is taken directly from UE4 - OnlineSubsystemSteamPrivatePCH.h as a fix for the array_count macro + +// @todo Steam: Steam headers trigger secure-C-runtime warnings in Visual C++. Rather than mess with _CRT_SECURE_NO_WARNINGS, we'll just +// disable the warnings locally. Remove when this is fixed in the SDK +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4996) +// #TODO check back on this at some point +#pragma warning(disable:4265) // SteamAPI CCallback< specifically, this warning is off by default but 4.17 turned it on.... +#endif + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + +//#include "OnlineSubsystemSteam.h" + +#pragma push_macro("ARRAY_COUNT") +#undef ARRAY_COUNT + +#if USING_CODE_ANALYSIS +MSVC_PRAGMA(warning(push)) +MSVC_PRAGMA(warning(disable : ALL_CODE_ANALYSIS_WARNINGS)) +#endif // USING_CODE_ANALYSIS + +#include + +#if USING_CODE_ANALYSIS +MSVC_PRAGMA(warning(pop)) +#endif // USING_CODE_ANALYSIS + + +#pragma pop_macro("ARRAY_COUNT") + +#endif + +// @todo Steam: See above +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + +#include "SteamWSRequestUGCDetailsCallbackProxy.generated.h" + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBlueprintWorkshopDetailsDelegate, const FBPSteamWorkshopItemDetails&, WorkShopDetails); + +UCLASS(MinimalAPI) +class USteamWSRequestUGCDetailsCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when there is a successful results return + UPROPERTY(BlueprintAssignable) + FBlueprintWorkshopDetailsDelegate OnSuccess; + + // Called when there is an unsuccessful results return + UPROPERTY(BlueprintAssignable) + FBlueprintWorkshopDetailsDelegate OnFailure; + + // Ends the current session + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedSteamWorkshop") + static USteamWSRequestUGCDetailsCallbackProxy* GetWorkshopItemDetails(UObject* WorldContextObject, FBPSteamWorkshopID WorkShopID); + + // UOnlineBlueprintCallProxyBase interface + virtual void Activate() override; + // End of UOnlineBlueprintCallProxyBase interface + +private: + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + // Internal callback when the operation completes, calls out to the public success/failure callbacks + + void OnUGCRequestUGCDetails(SteamUGCQueryCompleted_t *pResult, bool bIOFailure); + CCallResult m_callResultUGCRequestDetails; + +#endif + +private: + + FBPSteamWorkshopID WorkShopID; + UObject* WorldContextObject; +}; diff --git a/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Private/AdvancedSteamFriendsLibrary.cpp b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Private/AdvancedSteamFriendsLibrary.cpp new file mode 100644 index 0000000..85340e4 --- /dev/null +++ b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Private/AdvancedSteamFriendsLibrary.cpp @@ -0,0 +1,438 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "AdvancedSteamFriendsLibrary.h" +#include "OnlineSubSystemHeader.h" + +//General Log +DEFINE_LOG_CATEGORY(AdvancedSteamFriendsLog); + + +// Clan functions, add in soon +/*int32 UAdvancedSteamFriendsLibrary::GetFriendSteamLevel(const FBPUniqueNetId UniqueNetId) +{ + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + if (!UniqueNetId.IsValid() || !UniqueNetId.UniqueNetId->IsValid() || UniqueNetId.UniqueNetId->GetType() != STEAM_SUBSYSTEM) + { + UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("IsAFriend Had a bad UniqueNetId!")); + return 0; + } + + if (SteamAPI_Init()) + { + uint64 id = *((uint64*)UniqueNetId.UniqueNetId->GetBytes()); + + + // clan (group) iteration and access functions + //virtual int GetClanCount() = 0; + //virtual CSteamID GetClanByIndex(int iClan) = 0; + //virtual const char *GetClanName(CSteamID steamIDClan) = 0; + //virtual const char *GetClanTag(CSteamID steamIDClan) = 0; + // returns the most recent information we have about what's happening in a clan + //virtual bool GetClanActivityCounts(CSteamID steamIDClan, int *pnOnline, int *pnInGame, int *pnChatting) = 0; + // for clans a user is a member of, they will have reasonably up-to-date information, but for others you'll have to download the info to have the latest + //virtual SteamAPICall_t DownloadClanActivityCounts(ARRAY_COUNT(cClansToRequest) CSteamID *psteamIDClans, int cClansToRequest) = 0; + + // requests information about a clan officer list + // when complete, data is returned in ClanOfficerListResponse_t call result + // this makes available the calls below + // you can only ask about clans that a user is a member of + // note that this won't download avatars automatically; if you get an officer, + // and no avatar image is available, call RequestUserInformation( steamID, false ) to download the avatar + //virtual SteamAPICall_t RequestClanOfficerList(CSteamID steamIDClan) = 0; + + + // returns the steamID of the clan owner + //virtual CSteamID GetClanOwner(CSteamID steamIDClan) = 0; + // returns the number of officers in a clan (including the owner) + //virtual int GetClanOfficerCount(CSteamID steamIDClan) = 0; + // returns the steamID of a clan officer, by index, of range [0,GetClanOfficerCount) + //virtual CSteamID GetClanOfficerByIndex(CSteamID steamIDClan, int iOfficer) = 0; + + + return SteamFriends()->GetFriendSteamLevel(id); + } +#endif + + return 0; +}*/ + +void UAdvancedSteamFriendsLibrary::GetSteamGroups(TArray & SteamGroups) +{ + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + + if (SteamAPI_Init()) + { + int numClans = SteamFriends()->GetClanCount(); + + for (int i = 0; i < numClans; i++) + { + CSteamID SteamGroupID = SteamFriends()->GetClanByIndex(i); + + if(!SteamGroupID.IsValid()) + continue; + + FBPSteamGroupInfo GroupInfo; + + TSharedPtr ValueID(new const FUniqueNetIdSteam2(SteamGroupID)); + GroupInfo.GroupID.SetUniqueNetId(ValueID); + SteamFriends()->GetClanActivityCounts(SteamGroupID, &GroupInfo.numOnline, &GroupInfo.numInGame, &GroupInfo.numChatting); + GroupInfo.GroupName = FString(UTF8_TO_TCHAR(SteamFriends()->GetClanName(SteamGroupID))); + GroupInfo.GroupTag = FString(UTF8_TO_TCHAR(SteamFriends()->GetClanTag(SteamGroupID))); + + SteamGroups.Add(GroupInfo); + } + } +#endif + +} + +void UAdvancedSteamFriendsLibrary::GetSteamFriendGamePlayed(const FBPUniqueNetId UniqueNetId, EBlueprintResultSwitch &Result/*, FString & GameName*/, int32 & AppID) +{ + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + if (!UniqueNetId.IsValid() || !UniqueNetId.UniqueNetId->IsValid() || UniqueNetId.UniqueNetId->GetType() != STEAM_SUBSYSTEM) + { + UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("GetSteamFriendGamePlayed Had a bad UniqueNetId!")); + Result = EBlueprintResultSwitch::OnFailure; + return; + } + + if (SteamAPI_Init()) + { + uint64 id = *((uint64*)UniqueNetId.UniqueNetId->GetBytes()); + + FriendGameInfo_t GameInfo; + bool bIsInGame = SteamFriends()->GetFriendGamePlayed(id, &GameInfo); + + if (bIsInGame && GameInfo.m_gameID.IsValid()) + { + AppID = GameInfo.m_gameID.AppID(); + + // Forgot this test and left it in, it is incorrect, you would need restricted access + // And it would only find games in the local library anyway + /*char NameBuffer[512]; + int Len = SteamAppList()->GetAppName(GameInfo.m_gameID.AppID(), NameBuffer, 512); + + if (Len != -1) // Invalid + { + GameName = FString(UTF8_TO_TCHAR(NameBuffer)); + }*/ + + Result = EBlueprintResultSwitch::OnSuccess; + return; + } + + } +#endif + + Result = EBlueprintResultSwitch::OnFailure; +} + +int32 UAdvancedSteamFriendsLibrary::GetFriendSteamLevel(const FBPUniqueNetId UniqueNetId) +{ + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + if (!UniqueNetId.IsValid() || !UniqueNetId.UniqueNetId->IsValid() || UniqueNetId.UniqueNetId->GetType() != STEAM_SUBSYSTEM) + { + UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("IsAFriend Had a bad UniqueNetId!")); + return 0; + } + + if (SteamAPI_Init()) + { + uint64 id = *((uint64*)UniqueNetId.UniqueNetId->GetBytes()); + + return SteamFriends()->GetFriendSteamLevel(id); + } +#endif + + return 0; +} + +FString UAdvancedSteamFriendsLibrary::GetSteamPersonaName(const FBPUniqueNetId UniqueNetId) +{ + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + if (!UniqueNetId.IsValid() || !UniqueNetId.UniqueNetId->IsValid() || UniqueNetId.UniqueNetId->GetType() != STEAM_SUBSYSTEM) + { + UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("GetSteamPersonaName Had a bad UniqueNetId!")); + return FString(TEXT("")); + } + + if (SteamAPI_Init()) + { + uint64 id = *((uint64*)UniqueNetId.UniqueNetId->GetBytes()); + const char* PersonaName = SteamFriends()->GetFriendPersonaName(id); + return FString(UTF8_TO_TCHAR(PersonaName)); + } +#endif + + return FString(TEXT("")); +} + +FBPUniqueNetId UAdvancedSteamFriendsLibrary::CreateSteamIDFromString(const FString SteamID64) +{ + FBPUniqueNetId netId; + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + if (!(SteamID64.Len() > 0)) + { + UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("CreateSteamIDFromString Had a bad UniqueNetId!")); + return netId; + } + + if (SteamAPI_Init()) + { + // Already does the conversion + TSharedPtr ValueID(new const FUniqueNetIdSteam2(SteamID64)); + //FCString::Atoi64(*SteamID64)); + + netId.SetUniqueNetId(ValueID); + return netId; + } +#endif + + return netId; +} + +FBPUniqueNetId UAdvancedSteamFriendsLibrary::GetLocalSteamIDFromSteam() +{ + FBPUniqueNetId netId; + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + if (SteamAPI_Init()) + { + TSharedPtr SteamID(new const FUniqueNetIdSteam2(SteamUser()->GetSteamID())); + netId.SetUniqueNetId(SteamID); + } +#endif + + return netId; +} + +bool UAdvancedSteamFriendsLibrary::RequestSteamFriendInfo(const FBPUniqueNetId UniqueNetId, bool bRequireNameOnly) +{ +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + if (!UniqueNetId.IsValid() || !UniqueNetId.UniqueNetId->IsValid() || UniqueNetId.UniqueNetId->GetType() != STEAM_SUBSYSTEM) + { + UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("RequestSteamFriendInfo Had a bad UniqueNetId!")); + return false; + } + + if (SteamAPI_Init()) + { + uint64 id = *((uint64*)UniqueNetId.UniqueNetId->GetBytes()); + + return !SteamFriends()->RequestUserInformation(id, bRequireNameOnly); + } +#endif + + UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("RequestSteamFriendInfo Couldn't init steamAPI!")); + return false; +} + + +bool UAdvancedSteamFriendsLibrary::OpenSteamUserOverlay(const FBPUniqueNetId UniqueNetId, ESteamUserOverlayType DialogType) +{ +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + if (!UniqueNetId.IsValid() || !UniqueNetId.UniqueNetId->IsValid() || UniqueNetId.UniqueNetId->GetType() != STEAM_SUBSYSTEM) + { + UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("OpenSteamUserOverlay Had a bad UniqueNetId!")); + return false; + } + + if (SteamAPI_Init()) + { + uint64 id = *((uint64*)UniqueNetId.UniqueNetId->GetBytes()); + if (DialogType == ESteamUserOverlayType::invitetolobby) + { + SteamFriends()->ActivateGameOverlayInviteDialog(id); + } + else + { + FString DialogName = EnumToString("ESteamUserOverlayType", (uint8)DialogType); + SteamFriends()->ActivateGameOverlayToUser(TCHAR_TO_ANSI(*DialogName), id); + } + return true; + } +#endif + + UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("OpenSteamUserOverlay Couldn't init steamAPI!")); + return false; +} + +bool UAdvancedSteamFriendsLibrary::IsOverlayEnabled() +{ +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + if (SteamAPI_Init()) + { + return SteamUtils()->IsOverlayEnabled(); + } +#endif + + UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("OpenSteamUserOverlay Couldn't init steamAPI!")); + return false; +} + +UTexture2D * UAdvancedSteamFriendsLibrary::GetSteamFriendAvatar(const FBPUniqueNetId UniqueNetId, EBlueprintAsyncResultSwitch &Result, SteamAvatarSize AvatarSize) +{ +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + if (!UniqueNetId.IsValid() || !UniqueNetId.UniqueNetId->IsValid() || UniqueNetId.UniqueNetId->GetType() != STEAM_SUBSYSTEM) + { + UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("GetSteamFriendAvatar Had a bad UniqueNetId!")); + Result = EBlueprintAsyncResultSwitch::OnFailure; + return nullptr; + } + + uint32 Width = 0; + uint32 Height = 0; + + if (SteamAPI_Init()) + { + //Getting the PictureID from the SteamAPI and getting the Size with the ID + //virtual bool RequestUserInformation( CSteamID steamIDUser, bool bRequireNameOnly ) = 0; + + + uint64 id = *((uint64*)UniqueNetId.UniqueNetId->GetBytes()); + int Picture = 0; + + switch(AvatarSize) + { + case SteamAvatarSize::SteamAvatar_Small: Picture = SteamFriends()->GetSmallFriendAvatar(id); break; + case SteamAvatarSize::SteamAvatar_Medium: Picture = SteamFriends()->GetMediumFriendAvatar(id); break; + case SteamAvatarSize::SteamAvatar_Large: Picture = SteamFriends()->GetLargeFriendAvatar(id); break; + default: break; + } + + if (Picture == -1) + { + Result = EBlueprintAsyncResultSwitch::AsyncLoading; + return NULL; + } + + SteamUtils()->GetImageSize(Picture, &Width, &Height); + + // STOLEN FROM ANSWERHUB :p, then fixed because answerhub wasn't releasing the memory O.o + // Also fixed image pixel format and switched to a memcpy instead of manual iteration. + // At some point I should probably reply to that answerhub post with these fixes to prevent people killing their games..... + + if (Width > 0 && Height > 0) + { + //Creating the buffer "oAvatarRGBA" and then filling it with the RGBA Stream from the Steam Avatar + uint8 *oAvatarRGBA = new uint8[Width * Height * 4]; + + + //Filling the buffer with the RGBA Stream from the Steam Avatar and creating a UTextur2D to parse the RGBA Steam in + SteamUtils()->GetImageRGBA(Picture, (uint8*)oAvatarRGBA, 4 * Height * Width * sizeof(char)); + + + // Removed as I changed the image bit code to be RGB, I think the original author was unaware that there were different pixel formats + /* + //Swap R and B channels because for some reason the games whack + for (uint32 i = 0; i < (Width * Height * 4); i += 4) + { + uint8 Temp = oAvatarRGBA[i + 0]; + oAvatarRGBA[i + 0] = oAvatarRGBA[i + 2]; + oAvatarRGBA[i + 2] = Temp; + }*/ + + UTexture2D* Avatar = UTexture2D::CreateTransient(Width, Height, PF_R8G8B8A8); + // Switched to a Memcpy instead of byte by byte transer + + if (FTexturePlatformData* PlatformData = Avatar->GetPlatformData()) + { + uint8* MipData = (uint8*)PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE); + FMemory::Memcpy(MipData, (void*)oAvatarRGBA, Height * Width * 4); + PlatformData->Mips[0].BulkData.Unlock(); + + //Setting some Parameters for the Texture and finally returning it + PlatformData->SetNumSlices(1); + Avatar->NeverStream = true; + //Avatar->CompressionSettings = TC_EditorIcon; + } + + // Free RGBA buffer regardless of whether it was used or not + delete[] oAvatarRGBA; + + Avatar->UpdateResource(); + + Result = EBlueprintAsyncResultSwitch::OnSuccess; + return Avatar; + } + else + { + UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("Bad Height / Width with steam avatar!")); + } + + Result = EBlueprintAsyncResultSwitch::OnFailure; + return nullptr; + } +#endif + + UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("STEAM Couldn't be verified as initialized")); + Result = EBlueprintAsyncResultSwitch::OnFailure; + return nullptr; +} + +bool UAdvancedSteamFriendsLibrary::InitTextFiltering() +{ +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + + if (SteamAPI_Init()) + { + return SteamUtils()->InitFilterText(); + } + +#endif + + return false; +} + +bool UAdvancedSteamFriendsLibrary::FilterText(FString TextToFilter, EBPTextFilteringContext Context, const FBPUniqueNetId TextSourceID, FString& FilteredText) +{ +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + + if (SteamAPI_Init()) + { + uint32 BufferLen = TextToFilter.Len() + 10; // Docs say 1 byte excess min, going with 10 + char* OutText = new char[BufferLen]; + + uint64 id = 0; + + if (TextSourceID.IsValid()) + { + id = *((uint64*)TextSourceID.UniqueNetId->GetBytes()); + } + + int FilterCount = SteamUtils()->FilterText((ETextFilteringContext)Context, id, TCHAR_TO_ANSI(*TextToFilter), OutText, BufferLen); + + if (FilterCount > 0) + { + FilteredText = FString(UTF8_TO_TCHAR(OutText)); + delete[] OutText; + return true; + } + + delete[] OutText; + } + +#endif + + FilteredText = TextToFilter; + return false; +} + +bool UAdvancedSteamFriendsLibrary::IsSteamInBigPictureMode() +{ +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + + if (SteamAPI_Init()) + { + return SteamUtils()->IsSteamInBigPictureMode(); + } + +#endif + + return false; +} \ No newline at end of file diff --git a/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Private/AdvancedSteamSessions.cpp b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Private/AdvancedSteamSessions.cpp new file mode 100644 index 0000000..34d9ff5 --- /dev/null +++ b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Private/AdvancedSteamSessions.cpp @@ -0,0 +1,12 @@ +//#include "StandAlonePrivatePCH.h" +#include "AdvancedSteamSessions.h" + +void AdvancedSteamSessions::StartupModule() +{ +} + +void AdvancedSteamSessions::ShutdownModule() +{ +} + +IMPLEMENT_MODULE(AdvancedSteamSessions, AdvancedSteamSessions) \ No newline at end of file diff --git a/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Private/AdvancedSteamWorkshopLibrary.cpp b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Private/AdvancedSteamWorkshopLibrary.cpp new file mode 100644 index 0000000..03eb780 --- /dev/null +++ b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Private/AdvancedSteamWorkshopLibrary.cpp @@ -0,0 +1,69 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "AdvancedSteamWorkshopLibrary.h" +#include "OnlineSubSystemHeader.h" +//General Log +DEFINE_LOG_CATEGORY(AdvancedSteamWorkshopLog); + + +void UAdvancedSteamWorkshopLibrary::GetNumSubscribedWorkshopItems(int32 & NumberOfItems) +{ + NumberOfItems = 0; +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + + if (SteamAPI_Init()) + { + NumberOfItems = SteamUGC()->GetNumSubscribedItems(); + return; + } + else + { + UE_LOG(AdvancedSteamWorkshopLog, Warning, TEXT("Error in GetNumSubscribedWorkshopItemCount : SteamAPI is not Inited!")); + return; + } +#else + UE_LOG(AdvancedSteamWorkshopLog, Warning, TEXT("Error in GetNumSubscribedWorkshopItemCount : Called on an incompatible platform")); + return; +#endif +} + +TArray UAdvancedSteamWorkshopLibrary::GetSubscribedWorkshopItems(int32 & NumberOfItems) +{ + TArray outArray; + NumberOfItems = 0; + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + + if (SteamAPI_Init()) + { + uint32 NumItems = SteamUGC()->GetNumSubscribedItems(); + + if (NumItems == 0) + return outArray; + + // Not using the actual variable above in case someone somehow goes past int32 limits + // Don't want to go negative on the iteration. + NumberOfItems = NumItems; + + PublishedFileId_t *fileIds = new PublishedFileId_t[NumItems]; + + uint32 subItems = SteamUGC()->GetSubscribedItems(fileIds, NumItems); + + for (uint32 i = 0; i < subItems; ++i) + { + outArray.Add(FBPSteamWorkshopID(fileIds[i])); + } + + delete[] fileIds; + + return outArray; + } + else + { + UE_LOG(AdvancedSteamWorkshopLog, Warning, TEXT("Error in GetSubscribedWorkshopItemCount : SteamAPI is not Inited!")); + return outArray; + } +#else + UE_LOG(AdvancedSteamWorkshopLog, Warning, TEXT("Error in GetSubscribedWorkshopItemCount : Called on an incompatible platform")); + return outArray; +#endif +} diff --git a/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Private/SteamRequestGroupOfficersCallbackProxy.cpp b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Private/SteamRequestGroupOfficersCallbackProxy.cpp new file mode 100644 index 0000000..44bcc75 --- /dev/null +++ b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Private/SteamRequestGroupOfficersCallbackProxy.cpp @@ -0,0 +1,121 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. + +#include "SteamRequestGroupOfficersCallbackProxy.h" +#include "Online/CoreOnline.h" +#include "AdvancedSteamFriendsLibrary.h" +#include "OnlineSubSystemHeader.h" +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED +#include "steam/isteamfriends.h" +#endif +//#include "OnlineSubsystemSteamTypes.h" + +////////////////////////////////////////////////////////////////////////// +// UEndSessionCallbackProxy + +USteamRequestGroupOfficersCallbackProxy::USteamRequestGroupOfficersCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ +} + +USteamRequestGroupOfficersCallbackProxy::~USteamRequestGroupOfficersCallbackProxy() +{ +} + +USteamRequestGroupOfficersCallbackProxy* USteamRequestGroupOfficersCallbackProxy::GetSteamGroupOfficerList(UObject* WorldContextObject, FBPUniqueNetId GroupUniqueNetID) +{ + USteamRequestGroupOfficersCallbackProxy* Proxy = NewObject(); + + Proxy->GroupUniqueID = GroupUniqueNetID; + return Proxy; +} + +void USteamRequestGroupOfficersCallbackProxy::Activate() +{ +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + if (SteamAPI_Init()) + { + uint64 id = *((uint64*)GroupUniqueID.UniqueNetId->GetBytes()); + SteamAPICall_t hSteamAPICall = SteamFriends()->RequestClanOfficerList(id); + + m_callResultGroupOfficerRequestDetails.Set(hSteamAPICall, this, &USteamRequestGroupOfficersCallbackProxy::OnRequestGroupOfficerDetails); + return; + } +#endif + TArray EmptyArray; + OnFailure.Broadcast(EmptyArray); +} + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED +void USteamRequestGroupOfficersCallbackProxy::OnRequestGroupOfficerDetails(ClanOfficerListResponse_t *pResult, bool bIOFailure) +{ + TArray OfficerArray; + + //FOnlineSubsystemSteam* SteamSubsystem = (FOnlineSubsystemSteam*)(IOnlineSubsystem::Get(STEAM_SUBSYSTEM)); + + if (bIOFailure || !pResult || !pResult->m_bSuccess) + { + //if (SteamSubsystem != nullptr) + { + // SteamSubsystem->ExecuteNextTick([this]() + //{ + TArray FailureArray; + OnFailure.Broadcast(FailureArray); + //}); + } + //OnFailure.Broadcast(OfficerArray); + return; + } + + if (SteamAPI_Init()) + { + uint64 id = *((uint64*)GroupUniqueID.UniqueNetId->GetBytes()); + + FBPSteamGroupOfficer Officer; + CSteamID ClanOwner = SteamFriends()->GetClanOwner(id); + + Officer.bIsOwner = true; + + TSharedPtr ValueID(new const FUniqueNetIdSteam2(ClanOwner)); + Officer.OfficerUniqueNetID.SetUniqueNetId(ValueID); + OfficerArray.Add(Officer); + + for (int i = 0; i < pResult->m_cOfficers; i++) + { + CSteamID OfficerSteamID = SteamFriends()->GetClanOfficerByIndex(id, i); + + Officer.bIsOwner = false; + + TSharedPtr newValueID(new const FUniqueNetIdSteam2(OfficerSteamID)); + Officer.OfficerUniqueNetID.SetUniqueNetId(newValueID); + + OfficerArray.Add(Officer); + } + + //if (SteamSubsystem != nullptr) + //{ + //SteamSubsystem->ExecuteNextTick([OfficerArray, this]() + //{ + OnSuccess.Broadcast(OfficerArray); + //}); + //} + + //OnSuccess.Broadcast(OfficerArray); + return; + } + else + { + //if (SteamSubsystem != nullptr) + { + //SteamSubsystem->ExecuteNextTick([this]() + //{ + TArray FailureArray; + OnFailure.Broadcast(FailureArray); + //}); + } + } + + // Should never hit this anyway + //OnFailure.Broadcast(OfficerArray); +} +#endif + diff --git a/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Private/SteamWSRequestUGCDetailsCallbackProxy.cpp b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Private/SteamWSRequestUGCDetailsCallbackProxy.cpp new file mode 100644 index 0000000..daf3b07 --- /dev/null +++ b/Plugins/AdvancedSteamSessions/Source/AdvancedSteamSessions/Private/SteamWSRequestUGCDetailsCallbackProxy.cpp @@ -0,0 +1,101 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. + +#include "SteamWSRequestUGCDetailsCallbackProxy.h" +#include "OnlineSubSystemHeader.h" +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED +#include "steam/isteamugc.h" +#endif + +////////////////////////////////////////////////////////////////////////// +// UEndSessionCallbackProxy + +USteamWSRequestUGCDetailsCallbackProxy::USteamWSRequestUGCDetailsCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ +} + + +USteamWSRequestUGCDetailsCallbackProxy* USteamWSRequestUGCDetailsCallbackProxy::GetWorkshopItemDetails(UObject* WorldContextObject, FBPSteamWorkshopID WorkShopID/*, int32 NumSecondsBeforeTimeout*/) +{ + USteamWSRequestUGCDetailsCallbackProxy* Proxy = NewObject(); + + Proxy->WorkShopID = WorkShopID; + return Proxy; +} + +void USteamWSRequestUGCDetailsCallbackProxy::Activate() +{ +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED + if (SteamAPI_Init()) + { + // #TODO: Support arrays instead in the future? + UGCQueryHandle_t hQueryHandle = SteamUGC()->CreateQueryUGCDetailsRequest((PublishedFileId_t *)&WorkShopID.SteamWorkshopID, 1); + // #TODO: add search settings here by calling into the handle? + SteamAPICall_t hSteamAPICall = SteamUGC()->SendQueryUGCRequest(hQueryHandle); + + // Need to release the query + SteamUGC()->ReleaseQueryUGCRequest(hQueryHandle); + + if (hSteamAPICall == k_uAPICallInvalid) + { + OnFailure.Broadcast(FBPSteamWorkshopItemDetails()); + return; + } + + m_callResultUGCRequestDetails.Set(hSteamAPICall, this, &USteamWSRequestUGCDetailsCallbackProxy::OnUGCRequestUGCDetails); + return; + } +#endif + OnFailure.Broadcast(FBPSteamWorkshopItemDetails()); +} + +#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED +void USteamWSRequestUGCDetailsCallbackProxy::OnUGCRequestUGCDetails(SteamUGCQueryCompleted_t *pResult, bool bIOFailure) +{ + //FOnlineSubsystemSteam* SteamSubsystem = (FOnlineSubsystemSteam*)(IOnlineSubsystem::Get(STEAM_SUBSYSTEM)); + + if (bIOFailure || !pResult || pResult->m_unNumResultsReturned <= 0) + { + //if (SteamSubsystem != nullptr) + { + // SteamSubsystem->ExecuteNextTick([this]() + //{ + OnFailure.Broadcast(FBPSteamWorkshopItemDetails()); + //}); + } + //OnFailure.Broadcast(FBPSteamWorkshopItemDetails()); + return; + } + if (SteamAPI_Init()) + { + SteamUGCDetails_t Details; + if (SteamUGC()->GetQueryUGCResult(pResult->m_handle, 0, &Details)) + { + //if (SteamSubsystem != nullptr) + { + //SteamSubsystem->ExecuteNextTick([Details, this]() + //{ + OnSuccess.Broadcast(FBPSteamWorkshopItemDetails(Details)); + //}); + } + + //OnSuccess.Broadcast(FBPSteamWorkshopItemDetails(Details)); + return; + } + } + else + { + //if (SteamSubsystem != nullptr) + { + //SteamSubsystem->ExecuteNextTick([this]() + //{ + OnFailure.Broadcast(FBPSteamWorkshopItemDetails()); + //}); + } + } + + // Not needed, should never hit here + //OnFailure.Broadcast(FBPSteamWorkshopItemDetails()); +} +#endif + diff --git a/Plugins/OpenXRExpansionPlugin/Config/FilterPlugin.ini b/Plugins/OpenXRExpansionPlugin/Config/FilterPlugin.ini new file mode 100644 index 0000000..ccebca2 --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/Config/FilterPlugin.ini @@ -0,0 +1,8 @@ +[FilterPlugin] +; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and +; may include "...", "*", and "?" wildcards to match directories, files, and individual characters respectively. +; +; Examples: +; /README.txt +; /Extras/... +; /Binaries/ThirdParty/*.dll diff --git a/Plugins/OpenXRExpansionPlugin/OpenXRExpansionPlugin.uplugin b/Plugins/OpenXRExpansionPlugin/OpenXRExpansionPlugin.uplugin new file mode 100644 index 0000000..7232e3d --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/OpenXRExpansionPlugin.uplugin @@ -0,0 +1,53 @@ +{ + "FileVersion": 3, + "Version": 5.4, + "VersionName": "5.4", + "FriendlyName": "OpenXRExpansionPlugin", + "Description": "An set of utility functions for OpenXR", + "Category": "Virtual Reality", + "CreatedBy": "Joshua (MordenTral) Statzer", + "CreatedByURL": "http://www.vreue4.com", + "DocsURL": "http://www.vreue4.com", + "MarketplaceURL": "", + "SupportURL": "http://www.vreue4.com", + "EnabledByDefault": false, + "CanContainContent": false, + "IsBetaVersion": false, + "Installed": true, + "SupportedTargetPlatforms": [ + "Win64", + "Linux", + "Android", + "Mac", + "IOS" + ], + "Modules": [ + { + "Name": "OpenXRExpansionPlugin", + "Type": "Runtime", + "LoadingPhase": "PreDefault" + } + , + { + "Name": "OpenXRExpansionEditor", + "Type": "UnCookedOnly", + "LoadingPhase": "PreDefault" + } + ], + "Plugins": [ + { + "Name": "OpenXR", + "Enabled": true, + "PlatformAllowList": [ + "Win64", + "Linux", + "Android" + ] + }, + { + "Name": "XRBase", + "Enabled": true + } + ] +} + diff --git a/Plugins/OpenXRExpansionPlugin/Resources/Icon128.png b/Plugins/OpenXRExpansionPlugin/Resources/Icon128.png new file mode 100644 index 0000000..23fec31 --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/Resources/Icon128.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb8f329acc9d0c2815d28349d5a4144ebd337f7e2a93819cf1a7c3cc9b06ecea +size 16085 diff --git a/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionEditor/OpenXRExpansionEditor.Build.cs b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionEditor/OpenXRExpansionEditor.Build.cs new file mode 100644 index 0000000..36288b9 --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionEditor/OpenXRExpansionEditor.Build.cs @@ -0,0 +1,61 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +using System.IO; + +namespace UnrealBuildTool.Rules +{ + public class OpenXRExpansionEditor : ModuleRules + { + + public OpenXRExpansionEditor(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; + + PublicIncludePaths.AddRange( + new string[] { + // ... add public include paths required here ... + } + ); + + PrivateIncludePaths.AddRange( + new string[] { + // ... add other private include paths required here ... + } + ); + + PublicDependencyModuleNames.AddRange( + new string[] + { + // ... add other public dependencies that you statically link with here ... + "Engine", + "Core", + "CoreUObject" + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "UnrealEd", + "BlueprintGraph", + "AnimGraph", + "AnimGraphRuntime", + "SlateCore", + "Slate", + "InputCore", + "Engine", + "EditorStyle", + "AssetRegistry", + "OpenXRExpansionPlugin" + } + ); + + DynamicallyLoadedModuleNames.AddRange( + new string[] + { + // ... add any modules that your module loads dynamically here ... + } + ); + } + } +} \ No newline at end of file diff --git a/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionEditor/Private/AnimGraphNode_ApplyOpenXRHandPose.cpp b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionEditor/Private/AnimGraphNode_ApplyOpenXRHandPose.cpp new file mode 100644 index 0000000..1a109c9 --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionEditor/Private/AnimGraphNode_ApplyOpenXRHandPose.cpp @@ -0,0 +1,34 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "AnimGraphNode_ApplyOpenXRHandPose.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(AnimGraphNode_ApplyOpenXRHandPose) + +///////////////////////////////////////////////////// +// UAnimGraphNode_ModifyBSHand + +UAnimGraphNode_ApplyOpenXRHandPose::UAnimGraphNode_ApplyOpenXRHandPose(const FObjectInitializer& Initializer) + : Super(Initializer) +{ +} + +//Title Color! +FLinearColor UAnimGraphNode_ApplyOpenXRHandPose::GetNodeTitleColor() const +{ + return FLinearColor(12, 12, 0, 1); +} + +//Node Category +FString UAnimGraphNode_ApplyOpenXRHandPose::GetNodeCategory() const +{ + return FString("OpenXR"); +} +FText UAnimGraphNode_ApplyOpenXRHandPose::GetControllerDescription() const +{ + return FText::FromString("Apply OpenXR Hand Pose"); +} + +FText UAnimGraphNode_ApplyOpenXRHandPose::GetNodeTitle(ENodeTitleType::Type TitleType) const +{ + FText Result = GetControllerDescription(); + return Result; +} \ No newline at end of file diff --git a/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionEditor/Private/OpenXRExpansionEditor.cpp b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionEditor/Private/OpenXRExpansionEditor.cpp new file mode 100644 index 0000000..f22c5fc --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionEditor/Private/OpenXRExpansionEditor.cpp @@ -0,0 +1,16 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "OpenXRExpansionEditor.h" +#include "Editor/UnrealEdEngine.h" +#include "UnrealEdGlobals.h" + + +IMPLEMENT_MODULE(FOpenXRExpansionEditorModule, OpenXRExpansionEditor); + +void FOpenXRExpansionEditorModule::StartupModule() +{ +} + +void FOpenXRExpansionEditorModule::ShutdownModule() +{ +} \ No newline at end of file diff --git a/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionEditor/Public/AnimGraphNode_ApplyOpenXRHandPose.h b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionEditor/Public/AnimGraphNode_ApplyOpenXRHandPose.h new file mode 100644 index 0000000..b9d5db3 --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionEditor/Public/AnimGraphNode_ApplyOpenXRHandPose.h @@ -0,0 +1,34 @@ +#pragma once + +#include "AnimGraphDefinitions.h" +#include "Kismet2/BlueprintEditorUtils.h" +#include "Editor/AnimGraph/Public/AnimGraphNode_SkeletalControlBase.h" + +#include "AnimNode_ApplyOpenXRHandPose.h" +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "AnimGraphNode_ApplyOpenXRHandPose.generated.h" + +UCLASS(MinimalAPI) +class UAnimGraphNode_ApplyOpenXRHandPose : public UAnimGraphNode_SkeletalControlBase +{ + GENERATED_UCLASS_BODY() + + UPROPERTY(EditAnywhere, Category = Settings) + FAnimNode_ApplyOpenXRHandPose Node; + +public: + // UEdGraphNode interface + virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override; + virtual FLinearColor GetNodeTitleColor() const override; + virtual FString GetNodeCategory() const override; + // End of UEdGraphNode interface + +protected: + + // UAnimGraphNode_SkeletalControlBase protected interface + virtual FText GetControllerDescription() const; + virtual const FAnimNode_SkeletalControlBase* GetNode() const override { return &Node; } + // End of UAnimGraphNode_SkeletalControlBase protected interface + +}; \ No newline at end of file diff --git a/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionEditor/Public/OpenXRExpansionEditor.h b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionEditor/Public/OpenXRExpansionEditor.h new file mode 100644 index 0000000..92ed6bc --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionEditor/Public/OpenXRExpansionEditor.h @@ -0,0 +1,13 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "Runtime/Core/Public/Modules/ModuleInterface.h" + +class FOpenXRExpansionEditorModule : public IModuleInterface +{ +public: + + virtual void StartupModule() override; + virtual void ShutdownModule() override; +}; \ No newline at end of file diff --git a/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/OpenXRExpansionPlugin.Build.cs b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/OpenXRExpansionPlugin.Build.cs new file mode 100644 index 0000000..e7a0b33 --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/OpenXRExpansionPlugin.Build.cs @@ -0,0 +1,72 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +using UnrealBuildTool; +using System.IO; + +namespace UnrealBuildTool.Rules +{ + public class OpenXRExpansionPlugin: ModuleRules + { + public OpenXRExpansionPlugin(ReadOnlyTargetRules Target) + : base(Target) + { + SetupIrisSupport(Target); + + PublicDependencyModuleNames.AddRange( + new string[] + { + //"InputDevice", + //"LiveLink", + //"LiveLinkInterface" + } + ); + + var EngineDir = Path.GetFullPath(Target.RelativeEnginePath); + PrivateIncludePaths.AddRange( + new string[] { + EngineDir + "Plugins/Runtime/OpenXR/Source/OpenXRHMD/Private", + EngineDir + "/Source/ThirdParty/OpenXR/include", + // ... add other private include paths required here ... + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "NetCore", + "CoreUObject", + //"ApplicationCore", + "Engine", + //"InputDevice", + "InputCore", + "Slate", + "HeadMountedDisplay", + //"AnimGraph", + "AnimGraphRuntime", + "SlateCore", + "XRBase" + //"LiveLink", + //"LiveLinkInterface", + } + ); + + if (Target.Platform != UnrealTargetPlatform.Mac && Target.Platform != UnrealTargetPlatform.IOS) + { + PrivateDependencyModuleNames.AddRange( + new string[] + { + "OpenXRHMD" + } + ); + PrivateDefinitions.AddRange(new string[] { "OPENXR_SUPPORTED" }); + AddEngineThirdPartyPrivateStaticDependencies(Target, "OpenXR"); + } + + // if (Target.bBuildEditor == true) + // { + // PrivateDependencyModuleNames.Add("UnrealEd"); + // } + } + } +} diff --git a/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Private/AnimNode_ApplyOpenXRHandPose.cpp b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Private/AnimNode_ApplyOpenXRHandPose.cpp new file mode 100644 index 0000000..c086912 --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Private/AnimNode_ApplyOpenXRHandPose.cpp @@ -0,0 +1,488 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "AnimNode_ApplyOpenXRHandPose.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(AnimNode_ApplyOpenXRHandPose) + +//#include "EngineMinimal.h" +//#include "Engine/Engine.h" +//#include "CoreMinimal.h" +#include "OpenXRExpansionFunctionLibrary.h" +#include "AnimNode_ApplyOpenXRHandPose.h" +#include "AnimationRuntime.h" +#include "DrawDebugHelpers.h" +#include "OpenXRHandPoseComponent.h" +#include "Runtime/Engine/Public/Animation/AnimInstanceProxy.h" +#include "BoneControllers/AnimNode_SkeletalControlBase.h" + +FAnimNode_ApplyOpenXRHandPose::FAnimNode_ApplyOpenXRHandPose() + : FAnimNode_SkeletalControlBase() +{ + WorldIsGame = false; + Alpha = 1.f; + SkeletonType = EVROpenXRSkeletonType::OXR_SkeletonType_UE4Default_Right; + bIsOpenInputAnimationInstance = false; + bSkipRootBone = false; + bOnlyApplyWristTransform = false; + //WristAdjustment = FQuat::Identity; +} + +void FAnimNode_ApplyOpenXRHandPose::OnInitializeAnimInstance(const FAnimInstanceProxy* InProxy, const UAnimInstance* InAnimInstance) +{ + Super::OnInitializeAnimInstance(InProxy, InAnimInstance); + + if (const UOpenXRAnimInstance * OpenXRAnimInstance = Cast(InAnimInstance)) + { + bIsOpenInputAnimationInstance = true; + + if (OpenXRAnimInstance->AnimInstanceProxy.HandSkeletalActionData.Num()) + { + for (int i = 0; i < OpenXRAnimInstance->AnimInstanceProxy.HandSkeletalActionData.Num(); ++i) + { + EVRSkeletalHandIndex TargetHand = OpenXRAnimInstance->AnimInstanceProxy.HandSkeletalActionData[i].TargetHand; + + if (OpenXRAnimInstance->AnimInstanceProxy.HandSkeletalActionData[i].bMirrorLeftRight) + { + TargetHand = (TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Left) ? EVRSkeletalHandIndex::EActionHandIndex_Right : EVRSkeletalHandIndex::EActionHandIndex_Left; + } + + if (TargetHand == MappedBonePairs.TargetHand) + { + bIsMirroringHand = OpenXRAnimInstance->AnimInstanceProxy.HandSkeletalActionData[i].bMirrorLeftRight; + break; + } + } + } + } +} + +void FAnimNode_ApplyOpenXRHandPose::Initialize_AnyThread(const FAnimationInitializeContext& Context) +{ + Super::Initialize_AnyThread(Context); +} + +void FAnimNode_ApplyOpenXRHandPose::CacheBones_AnyThread(const FAnimationCacheBonesContext& Context) +{ + Super::CacheBones_AnyThread(Context); +} + +void FAnimNode_ApplyOpenXRHandPose::InitializeBoneReferences(const FBoneContainer& RequiredBones) +{ + UObject* OwningAsset = RequiredBones.GetAsset(); + if (!OwningAsset) + return; + + USkeleton* AssetSkeleton = RequiredBones.GetSkeletonAsset(); + + if (!AssetSkeleton) + return; + + if (!MappedBonePairs.bInitialized || OwningAsset->GetFName() != MappedBonePairs.LastInitializedName || SkeletonType != MappedBonePairs.LastInitializedSkeleton) + { + + // Trigger a full re-build if our asset changed + if (MappedBonePairs.bInitialized && (OwningAsset->GetFName() != MappedBonePairs.LastInitializedName || SkeletonType != MappedBonePairs.LastInitializedSkeleton)) + { + MappedBonePairs.ClearMapping(); + } + + MappedBonePairs.LastInitializedName = OwningAsset->GetFName(); + MappedBonePairs.LastInitializedSkeleton = SkeletonType; + MappedBonePairs.bInitialized = false; + + if (AssetSkeleton) + { + // If our bone pairs are empty, then setup our sane defaults + if (!MappedBonePairs.BonePairs.Num()) + { + + MappedBonePairs.ConstructDefaultMappings(SkeletonType, bSkipRootBone); + } + + // Construct a reverse map of our joints + MappedBonePairs.ConstructReverseMapping(); + + TArray RefBones = AssetSkeleton->GetReferenceSkeleton().GetRefBonePose(); + TArray RefBonesInfo = AssetSkeleton->GetReferenceSkeleton().GetRefBoneInfo(); + + for (FBPOpenXRSkeletalPair& BonePair : MappedBonePairs.BonePairs) + { + // Fill in the bone name for the reference + BonePair.ReferenceToConstruct.BoneName = BonePair.BoneToTarget; + + // Init the reference + BonePair.ReferenceToConstruct.Initialize(AssetSkeleton); + + BonePair.ReferenceToConstruct.CachedCompactPoseIndex = BonePair.ReferenceToConstruct.GetCompactPoseIndex(RequiredBones); + + if ((BonePair.ReferenceToConstruct.CachedCompactPoseIndex != INDEX_NONE)) + { + // Get our parent bones index + BonePair.ParentReference = RequiredBones.GetParentBoneIndex(BonePair.ReferenceToConstruct.CachedCompactPoseIndex); + } + } + + MappedBonePairs.bInitialized = true; + + if (SkeletonType == EVROpenXRSkeletonType::OXR_SkeletonType_OpenVRDefault_Left || SkeletonType == EVROpenXRSkeletonType::OXR_SkeletonType_OpenVRDefault_Right) + { + // We hard code this for now because I don't like their wrist being a different transform + MappedBonePairs.AdjustmentQuat = FRotator(0.f, 90.f, 180.f).Quaternion(); // Current one is incorrect without wrist + // Maybe do it in relative space? + } + else + { + CalculateSkeletalAdjustment(AssetSkeleton); + } + + } + } +} + +void FAnimNode_ApplyOpenXRHandPose::CalculateSkeletalAdjustment(USkeleton* AssetSkeleton) +{ + + TArray RefBones = AssetSkeleton->GetReferenceSkeleton().GetRefBonePose(); + TArray RefBonesInfo = AssetSkeleton->GetReferenceSkeleton().GetRefBoneInfo(); + + if (!MappedBonePairs.bInitialized || MappedBonePairs.BonePairs.Num() < 4 || !RefBones.Num()) + { + UE_LOG(LogTemp, Error, TEXT("Empty or incorrect mapping or skeleton data when calculating skeletal adjustment!")); + return; + } + + FBPOpenXRSkeletalPair KnuckleIndexPair = MappedBonePairs.BonePairs[MappedBonePairs.ReverseBonePairMap[(int8)EXRHandJointType::OXR_HAND_JOINT_INDEX_PROXIMAL_EXT]]; + FBPOpenXRSkeletalPair KnuckleMiddlePair = MappedBonePairs.BonePairs[MappedBonePairs.ReverseBonePairMap[(int8)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_PROXIMAL_EXT]]; + FBPOpenXRSkeletalPair KnuckleRingPair = MappedBonePairs.BonePairs[MappedBonePairs.ReverseBonePairMap[(int8)EXRHandJointType::OXR_HAND_JOINT_RING_PROXIMAL_EXT]]; + FBPOpenXRSkeletalPair KnucklePinkyPair = MappedBonePairs.BonePairs[MappedBonePairs.ReverseBonePairMap[(int8)EXRHandJointType::OXR_HAND_JOINT_LITTLE_PROXIMAL_EXT]]; + + FBPOpenXRSkeletalPair WristPair = MappedBonePairs.BonePairs[MappedBonePairs.ReverseBonePairMap[(int8)EXRHandJointType::OXR_HAND_JOINT_WRIST_EXT]]; + + FVector KnuckleAverage = GetRefBoneInCS(RefBones, RefBonesInfo, KnuckleIndexPair.ReferenceToConstruct.BoneIndex).GetTranslation(); + KnuckleAverage += GetRefBoneInCS(RefBones, RefBonesInfo, KnuckleMiddlePair.ReferenceToConstruct.BoneIndex).GetTranslation(); + KnuckleAverage += GetRefBoneInCS(RefBones, RefBonesInfo, KnuckleRingPair.ReferenceToConstruct.BoneIndex).GetTranslation(); + KnuckleAverage += GetRefBoneInCS(RefBones, RefBonesInfo, KnucklePinkyPair.ReferenceToConstruct.BoneIndex).GetTranslation(); + + // Get our average across the knuckles + KnuckleAverage /= 4.f; + + // Obtain the UE4 wrist Side & Forward directions from first animation frame and place in cache + FTransform WristTransform_UE = GetRefBoneInCS(RefBones, RefBonesInfo, WristPair.ReferenceToConstruct.BoneIndex); + FVector ToKnuckleAverage_UE = KnuckleAverage - WristTransform_UE.GetTranslation(); + ToKnuckleAverage_UE.Normalize(); + + + WristForwardLS_UE = WristTransform_UE.GetRotation().UnrotateVector(ToKnuckleAverage_UE); + SetVectorToMaxElement(WristForwardLS_UE); + WristSideDirectionLS = FVector::CrossProduct(WristForwardLS_UE, FVector::RightVector); + SetVectorToMaxElement(WristSideDirectionLS); + + CalculateOpenXRAdjustment(); +} + +void FAnimNode_ApplyOpenXRHandPose::CalculateOpenXRAdjustment() +{ + // Base implementation is like valves + + // Forward direction + static FVector OpenXRForwardDirection = FVector(1.0f, 0.f, 0.f); + + // Side direction + // Do I need to flip this for left hand? + + bool bUseLeftHandOffsets = false; + if ((!bIsMirroringHand && MappedBonePairs.TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Left) || + (bIsMirroringHand && MappedBonePairs.TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Right)) + { + bUseLeftHandOffsets = true; + } + + //static FVector OpenXRSideDirection = FVector(0.f, 1.f, 0.f); + FVector OpenXRSideDirection = bUseLeftHandOffsets ? FVector(0.f, -1.f, 0.f) : FVector(0.f, 1.f, 0.f); + + // Align forward vectors, openXR once in engine is X+ forward + FQuat AlignmentRot = FQuat::FindBetweenNormals(WristForwardLS_UE, OpenXRForwardDirection); + + // Rotate about the aligned forward direction to make the side directions align + FVector WristSideDirectionMS_UE = AlignmentRot * WristSideDirectionLS; + + // Rotate around, should the Side direction flip for openXR if its the left hand? + FQuat TwistRotation = CalcRotationAboutAxis(WristSideDirectionMS_UE, OpenXRSideDirection, OpenXRForwardDirection); + + FRotator Difference = (TwistRotation * AlignmentRot).Rotator(); + + MappedBonePairs.AdjustmentQuat = (TwistRotation * AlignmentRot).GetNormalized(); + +} + +void FAnimNode_ApplyOpenXRHandPose::ConvertHandTransformsSpace(TArray& OutTransforms, const TArray& WorldTransforms, FTransform AddTrans, bool bMirrorLeftRight, bool bMergeMissingUE4Bones) +{ + // Fail if the count is too low + if (WorldTransforms.Num() < EHandKeypointCount) + return; + + if (OutTransforms.Num() < WorldTransforms.Num()) + { + OutTransforms.Empty(WorldTransforms.Num()); + OutTransforms.AddUninitialized(WorldTransforms.Num()); + } + + TArray TempWorldTransforms = WorldTransforms; + + // Ensure add trans is normalized + AddTrans.NormalizeRotation(); + + // Bone/Parent map + int32 BoneParents[26] = + { + // Manually build the parent hierarchy starting at the wrist which has no parent (-1) + 1, // Palm -> Wrist + -1, // Wrist -> None + 1, // ThumbMetacarpal -> Wrist + 2, // ThumbProximal -> ThumbMetacarpal + 3, // ThumbDistal -> ThumbProximal + 4, // ThumbTip -> ThumbDistal + + 1, // IndexMetacarpal -> Wrist + 6, // IndexProximal -> IndexMetacarpal + 7, // IndexIntermediate -> IndexProximal + 8, // IndexDistal -> IndexIntermediate + 9, // IndexTip -> IndexDistal + + 1, // MiddleMetacarpal -> Wrist + 11, // MiddleProximal -> MiddleMetacarpal + 12, // MiddleIntermediate -> MiddleProximal + 13, // MiddleDistal -> MiddleIntermediate + 14, // MiddleTip -> MiddleDistal + + 1, // RingMetacarpal -> Wrist + 16, // RingProximal -> RingMetacarpal + 17, // RingIntermediate -> RingProximal + 18, // RingDistal -> RingIntermediate + 19, // RingTip -> RingDistal + + 1, // LittleMetacarpal -> Wrist + 21, // LittleProximal -> LittleMetacarpal + 22, // LittleIntermediate -> LittleProximal + 23, // LittleDistal -> LittleIntermediate + 24, // LittleTip -> LittleDistal + }; + + bool bUseAutoCalculatedRetarget = AddTrans.Equals(FTransform::Identity); + + // Convert transforms to parent space + // The hand tracking transforms are in world space. + + for (int32 Index = 0; Index < EHandKeypointCount; ++Index) + { + if (TempWorldTransforms[Index].ContainsNaN() || TempWorldTransforms[Index].Equals(FTransform::Identity)) + { + OutTransforms[Index] = FTransform::Identity; + //continue; + } + + // Ensure normalization + TempWorldTransforms[Index].NormalizeRotation(); + + if (bMirrorLeftRight) + { + TempWorldTransforms[Index].Mirror(EAxis::Y, EAxis::Y); + } + + if (bUseAutoCalculatedRetarget) + { + TempWorldTransforms[Index].ConcatenateRotation(MappedBonePairs.AdjustmentQuat); + //WorldTransforms[Index].ConcatenateRotation(MappedBonePairs.BonePairs[0].RetargetRot); + } + else + { + TempWorldTransforms[Index].ConcatenateRotation(AddTrans.GetRotation()); + } + } + + // Make this into a single loop, their structure always has children after parent + for (int32 Index = 0; Index < EHandKeypointCount; ++Index) + { + FTransform& BoneTransform = TempWorldTransforms[Index]; + //BoneTransform.NormalizeRotation(); + + int32 ParentIndex = BoneParents[Index]; + int32 ParentParent = -1; + + // Thumb keeps the metacarpal intact, we don't skip it + if (bMergeMissingUE4Bones) + { + if (Index != (int32)EXRHandJointType::OXR_HAND_JOINT_THUMB_PROXIMAL_EXT && ParentIndex > 0) + { + ParentParent = BoneParents[ParentIndex]; + } + } + + if (ParentIndex < 0) + { + // We are at the root, so use it. + OutTransforms[Index] = BoneTransform; + } + else + { + FTransform ParentTransform = FTransform::Identity; + + // Merging missing metacarpal bone into the transform + if (bMergeMissingUE4Bones && ParentParent == 1) // Wrist + { + ParentTransform = TempWorldTransforms[ParentParent]; + } + else + { + ParentTransform = TempWorldTransforms[ParentIndex]; + } + + //ParentTransform.NormalizeRotation(); + OutTransforms[Index] = BoneTransform.GetRelativeTransform(ParentTransform); + } + } +} + +void FAnimNode_ApplyOpenXRHandPose::EvaluateSkeletalControl_AnyThread(FComponentSpacePoseContext& Output, TArray& OutBoneTransforms) +{ + if (!MappedBonePairs.bInitialized) + return; + + + const FBoneContainer& BoneContainer = Output.Pose.GetPose().GetBoneContainer(); + + UObject* OwningAsset = BoneContainer.GetAsset(); + if (!OwningAsset) + return; + + // Trigger a full re-build if our asset or target skeleton changed, do it up here before finding the correct hand + if ((OwningAsset->GetFName() != MappedBonePairs.LastInitializedName || SkeletonType != MappedBonePairs.LastInitializedSkeleton)) + { + InitializeBoneReferences(BoneContainer); + } + + + /*const */FBPOpenXRActionSkeletalData *StoredActionInfoPtr = nullptr; + if (bIsOpenInputAnimationInstance) + { + /*const*/ FOpenXRAnimInstanceProxy* OpenXRAnimInstance = (FOpenXRAnimInstanceProxy*)Output.AnimInstanceProxy; + if (OpenXRAnimInstance->HandSkeletalActionData.Num()) + { + for (int i = 0; i HandSkeletalActionData.Num(); ++i) + { + EVRSkeletalHandIndex TargetHand = OpenXRAnimInstance->HandSkeletalActionData[i].TargetHand; + + if (OpenXRAnimInstance->HandSkeletalActionData[i].bMirrorLeftRight) + { + TargetHand = (TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Left) ? EVRSkeletalHandIndex::EActionHandIndex_Right : EVRSkeletalHandIndex::EActionHandIndex_Left; + } + + if (TargetHand == MappedBonePairs.TargetHand) + { + StoredActionInfoPtr = &OpenXRAnimInstance->HandSkeletalActionData[i]; + break; + } + } + } + } + + // If we have an empty hand pose but have a passed in custom one then use that + if (StoredActionInfoPtr == nullptr || !StoredActionInfoPtr->SkeletalTransforms.Num()) + { + StoredActionInfoPtr = &OptionalStoredActionInfo; + } + + if (!StoredActionInfoPtr->bHasValidData) + { + return; + } + + //MappedBonePairs.AdjustmentQuat = WristAdjustment; + + // Currently not blending correctly + const float BlendWeight = FMath::Clamp(ActualAlpha, 0.f, 1.f); + uint8 BoneTransIndex = 0; + uint8 NumBones = StoredActionInfoPtr ? StoredActionInfoPtr->SkeletalTransforms.Num() : 0; + + if (NumBones < 1) + { + // Early out, we don't have a valid data to work with + return; + } + + FTransform trans = FTransform::Identity; + OutBoneTransforms.Reserve(MappedBonePairs.BonePairs.Num()); + TArray TransBones; + FTransform AdditionTransform = StoredActionInfoPtr->AdditionTransform; + + FTransform TempTrans = FTransform::Identity; + FTransform ParentTrans = FTransform::Identity; + FTransform * ParentTransPtr = nullptr; + + //AdditionTransform.SetRotation(MappedBonePairs.AdjustmentQuat); + + TArray HandTransforms; + ConvertHandTransformsSpace(HandTransforms, StoredActionInfoPtr->SkeletalTransforms, AdditionTransform, StoredActionInfoPtr->bMirrorLeftRight, MappedBonePairs.bMergeMissingBonesUE4); + + for (const FBPOpenXRSkeletalPair& BonePair : MappedBonePairs.BonePairs) + { + BoneTransIndex = (int8)BonePair.OpenXRBone; + ParentTrans = FTransform::Identity; + + if (bSkipRootBone && BonePair.OpenXRBone == EXRHandJointType::OXR_HAND_JOINT_WRIST_EXT) + continue; + + if (BoneTransIndex >= NumBones || BonePair.ReferenceToConstruct.CachedCompactPoseIndex == INDEX_NONE) + continue; + + if (!BonePair.ReferenceToConstruct.IsValidToEvaluate(BoneContainer)) + { + continue; + } + + trans = Output.Pose.GetComponentSpaceTransform(BonePair.ReferenceToConstruct.CachedCompactPoseIndex); + + if (BonePair.ParentReference != INDEX_NONE) + { + ParentTrans = Output.Pose.GetComponentSpaceTransform(BonePair.ParentReference); + ParentTrans.SetScale3D(FVector(1.f)); + } + + EXRHandJointType CurrentBone = (EXRHandJointType)BoneTransIndex; + TempTrans = (HandTransforms[BoneTransIndex]); + //TempTrans.ConcatenateRotation(BonePair.RetargetRot); + + /*if (StoredActionInfoPtr->bMirrorHand) + { + FMatrix M = TempTrans.ToMatrixWithScale(); + M.Mirror(EAxis::Z, EAxis::X); + M.Mirror(EAxis::X, EAxis::Z); + TempTrans.SetFromMatrix(M); + }*/ + + TempTrans = TempTrans * ParentTrans; + + if (StoredActionInfoPtr->bAllowDeformingMesh || bOnlyApplyWristTransform) + trans.SetTranslation(TempTrans.GetTranslation()); + + trans.SetRotation(TempTrans.GetRotation()); + + TransBones.Add(FBoneTransform(BonePair.ReferenceToConstruct.CachedCompactPoseIndex, trans)); + + // Need to do it per bone so future bones are correct + // Only if in parent space though, can do it all at the end in component space + if (TransBones.Num()) + { + Output.Pose.LocalBlendCSBoneTransforms(TransBones, BlendWeight); + TransBones.Reset(); + } + + if (bOnlyApplyWristTransform && CurrentBone == EXRHandJointType::OXR_HAND_JOINT_WRIST_EXT) + { + break; // Early out of the loop, we only wanted to apply the wrist + } + } +} + +bool FAnimNode_ApplyOpenXRHandPose::IsValidToEvaluate(const USkeleton* Skeleton, const FBoneContainer& RequiredBones) +{ + return(/*MappedBonePairs.bInitialized && */MappedBonePairs.BonePairs.Num() > 0); +} diff --git a/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Private/OpenXRExpansionFunctionLibrary.cpp b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Private/OpenXRExpansionFunctionLibrary.cpp new file mode 100644 index 0000000..89c9aa1 --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Private/OpenXRExpansionFunctionLibrary.cpp @@ -0,0 +1,587 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "OpenXRExpansionFunctionLibrary.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(OpenXRExpansionFunctionLibrary) + +//#include "EngineMinimal.h" +#include "Engine/Engine.h" +#include +#include "CoreMinimal.h" +#include "IXRTrackingSystem.h" + +//General Log +DEFINE_LOG_CATEGORY(OpenXRExpansionFunctionLibraryLog); + +UOpenXRExpansionFunctionLibrary::UOpenXRExpansionFunctionLibrary(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ +} + +//============================================================================= +UOpenXRExpansionFunctionLibrary::~UOpenXRExpansionFunctionLibrary() +{ + +} + +void UOpenXRExpansionFunctionLibrary::GetXRMotionControllerType(FString& TrackingSystemName, EBPOpenXRControllerDeviceType& DeviceType, EBPXRResultSwitch& Result) +{ +#if defined(OPENXR_SUPPORTED) + DeviceType = EBPOpenXRControllerDeviceType::DT_UnknownController; + Result = EBPXRResultSwitch::OnFailed; + + if (FOpenXRHMD* pOpenXRHMD = GetOpenXRHMD()) + { + XrInstance XRInstance = pOpenXRHMD->GetInstance(); + XrSystemId XRSysID = pOpenXRHMD->GetSystem(); + + if (XRSysID && XRInstance) + { + XrSystemProperties systemProperties{ XR_TYPE_SYSTEM_PROPERTIES }; + systemProperties.next = nullptr; + + if (xrGetSystemProperties(XRInstance, XRSysID, &systemProperties) == XR_SUCCESS) + { + XrSession XRSesh = pOpenXRHMD->GetSession(); + + if (XRSesh) + { + XrPath myPath; + XrResult PathResult = xrStringToPath(XRInstance, "/user/hand/left", &myPath); + XrInteractionProfileState interactionProfile{ XR_TYPE_INTERACTION_PROFILE_STATE }; + interactionProfile.next = nullptr; + + XrResult QueryResult = xrGetCurrentInteractionProfile(XRSesh, myPath, &interactionProfile); + if (QueryResult == XR_SUCCESS) + { + char myPathy[XR_MAX_SYSTEM_NAME_SIZE]; + uint32_t outputsize; + xrPathToString(XRInstance, interactionProfile.interactionProfile, XR_MAX_SYSTEM_NAME_SIZE, &outputsize, myPathy); + + if (interactionProfile.interactionProfile == XR_NULL_PATH || outputsize < 1) + return; + + FString InteractionName(ANSI_TO_TCHAR(myPathy)); + if (InteractionName.Len() < 1) + return; + + /* + * Interaction profile paths [6.4] + An interaction profile identifies a collection of buttons and + other input sources, and is of the form: + /interaction_profiles// + Paths supported in the core 1.0 release + /interaction_profiles/khr/simple_control + /interaction_profiles/khr/simple_controller + /interaction_profiles/google/daydream_controller + /interaction_profiles/htc/vive_controller + /interaction_profiles/htc/vive_pro + /interaction_profiles/microsoft/motion_controller + /interaction_profiles/microsoft/xbox_controller + /interaction_profiles/oculus/go_controller + /interaction_profiles/oculus/touch_controller + /interaction_profiles/valve/index_controller + */ + + // Not working currently? + /*XrInputSourceLocalizedNameGetInfo InputSourceInfo{ XR_TYPE_INPUT_SOURCE_LOCALIZED_NAME_GET_INFO }; + InputSourceInfo.next = nullptr; + InputSourceInfo.whichComponents = XR_INPUT_SOURCE_LOCALIZED_NAME_INTERACTION_PROFILE_BIT; + InputSourceInfo.sourcePath = interactionProfile.interactionProfile; + + char buffer[XR_MAX_SYSTEM_NAME_SIZE]; + uint32_t usedBufferCount = 0; + if (xrGetInputSourceLocalizedName(XRSesh, &InputSourceInfo, XR_MAX_SYSTEM_NAME_SIZE, &usedBufferCount, (char*)&buffer) == XR_SUCCESS) + { + int g = 0; + }*/ + + + if (InteractionName.Find("touch_controller", ESearchCase::IgnoreCase) != INDEX_NONE) + { + DeviceType = EBPOpenXRControllerDeviceType::DT_OculusTouchController; + } + else if (InteractionName.Contains("index_controller", ESearchCase::IgnoreCase)) + { + DeviceType = EBPOpenXRControllerDeviceType::DT_ValveIndexController; + } + else if (InteractionName.Find("vive_controller", ESearchCase::IgnoreCase) != INDEX_NONE) + { + DeviceType = EBPOpenXRControllerDeviceType::DT_ViveController; + } + else if (InteractionName.Find("vive_pro", ESearchCase::IgnoreCase) != INDEX_NONE) + { + DeviceType = EBPOpenXRControllerDeviceType::DT_ViveProController; + } + else if (InteractionName.Find("simple_controller", ESearchCase::IgnoreCase) != INDEX_NONE) + { + DeviceType = EBPOpenXRControllerDeviceType::DT_SimpleController; + } + else if (InteractionName.Find("daydream_controller", ESearchCase::IgnoreCase) != INDEX_NONE) + { + DeviceType = EBPOpenXRControllerDeviceType::DT_DaydreamController; + } + else if (InteractionName.Find("motion_controller", ESearchCase::IgnoreCase) != INDEX_NONE) + { + DeviceType = EBPOpenXRControllerDeviceType::DT_MicrosoftMotionController; + } + else if (InteractionName.Find("xbox_controller", ESearchCase::IgnoreCase) != INDEX_NONE) + { + DeviceType = EBPOpenXRControllerDeviceType::DT_MicrosoftXboxController; + } + else if (InteractionName.Find("go_controller", ESearchCase::IgnoreCase) != INDEX_NONE) + { + DeviceType = EBPOpenXRControllerDeviceType::DT_OculusGoController; + } + else if (InteractionName.Find("neo3_controller", ESearchCase::IgnoreCase) != INDEX_NONE) + { + DeviceType = EBPOpenXRControllerDeviceType::DT_PicoNeo3Controller; + } + else if (InteractionName.Find("mixed_reality_controller", ESearchCase::IgnoreCase) != INDEX_NONE) + { + DeviceType = EBPOpenXRControllerDeviceType::DT_WMRController; + } + else + { + UE_LOG(OpenXRExpansionFunctionLibraryLog, Warning, TEXT("UNKNOWN OpenXR Interaction profile detected!!!: %s"), *InteractionName); + DeviceType = EBPOpenXRControllerDeviceType::DT_UnknownController; + } + + Result = EBPXRResultSwitch::OnSucceeded; + } + + TrackingSystemName = FString(ANSI_TO_TCHAR(systemProperties.systemName));// , XR_MAX_SYSTEM_NAME_SIZE); + //VendorID = systemProperties.vendorId; + return; + } + } + } + } +#endif + + TrackingSystemName.Empty(); + return; +} + +bool UOpenXRExpansionFunctionLibrary::GetOpenXRHandPose(FBPOpenXRActionSkeletalData& HandPoseContainer, UOpenXRHandPoseComponent* HandPoseComponent, bool bGetMockUpPose) +{ + FXRMotionControllerData MotionControllerData; + + if (bGetMockUpPose) + { + GetMockUpControllerData(MotionControllerData, HandPoseContainer); + return true; + } + + UHeadMountedDisplayFunctionLibrary::GetMotionControllerData((UObject*)HandPoseComponent, HandPoseContainer.TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Left ? EControllerHand::Left : EControllerHand::Right, MotionControllerData); + + if (MotionControllerData.bValid) + { + HandPoseContainer.SkeletalTransforms.Empty(MotionControllerData.HandKeyPositions.Num()); + FTransform ParentTrans = FTransform::Identity; + + if (MotionControllerData.DeviceVisualType == EXRVisualType::Controller) + { + ParentTrans = FTransform(MotionControllerData.GripRotation, MotionControllerData.GripPosition, FVector(1.f)); + } + else // EXRVisualType::Hand visual type + { + ParentTrans = FTransform(MotionControllerData.HandKeyRotations[(uint8)EHandKeypoint::Palm], MotionControllerData.HandKeyPositions[(uint8)EHandKeypoint::Palm], FVector(1.f)); + } + + for (int i = 0; i < MotionControllerData.HandKeyPositions.Num(); ++i) + { + // Convert to component space, we convert then to parent space later when applying it + HandPoseContainer.SkeletalTransforms.Add(FTransform(MotionControllerData.HandKeyRotations[i].GetNormalized(), MotionControllerData.HandKeyPositions[i], FVector(1.f)).GetRelativeTransform(ParentTrans)); + } + + //if (bGetCurlValues) + { + GetFingerCurlValues(HandPoseContainer.SkeletalTransforms, HandPoseContainer.FingerCurls); + } + + HandPoseContainer.bHasValidData = (HandPoseContainer.SkeletalTransforms.Num() == EHandKeypointCount); + return true; + } + + HandPoseContainer.bHasValidData = false; + return false; +} + +void UOpenXRExpansionFunctionLibrary::GetFingerCurlValues(TArray& TransformArray, TArray& CurlArray) +{ + // Fail if the count is too low + if (TransformArray.Num() < EHandKeypointCount) + return; + + if (CurlArray.Num() < 5) + { + CurlArray.AddZeroed(5); + } + + CurlArray[0] = GetCurlValueForBoneRoot(TransformArray, EHandKeypoint::ThumbMetacarpal); + CurlArray[1] = GetCurlValueForBoneRoot(TransformArray, EHandKeypoint::IndexProximal); + CurlArray[2] = GetCurlValueForBoneRoot(TransformArray, EHandKeypoint::MiddleProximal); + CurlArray[3] = GetCurlValueForBoneRoot(TransformArray, EHandKeypoint::RingProximal); + CurlArray[4] = GetCurlValueForBoneRoot(TransformArray, EHandKeypoint::LittleProximal); +} + +bool UOpenXRExpansionFunctionLibrary::GetOpenXRFingerCurlValuesForHand( + UObject* WorldContextObject, + EControllerHand TargetHand, + float& ThumbCurl, + float& IndexCurl, + float& MiddleCurl, + float& RingCurl, + float& PinkyCurl) +{ + FXRMotionControllerData MotionControllerData; + UHeadMountedDisplayFunctionLibrary::GetMotionControllerData(WorldContextObject, TargetHand, MotionControllerData); + + // Fail if the count is too low + if (MotionControllerData.HandKeyPositions.Num() < EHandKeypointCount) + return false; + + FTransform ParentTrans = FTransform::Identity; + + if (MotionControllerData.DeviceVisualType == EXRVisualType::Controller) + { + ParentTrans = FTransform(MotionControllerData.GripRotation, MotionControllerData.GripPosition, FVector(1.f)); + } + else // EXRVisualType::Hand visual type + { + ParentTrans = FTransform(MotionControllerData.HandKeyRotations[(uint8)EHandKeypoint::Palm], MotionControllerData.HandKeyPositions[(uint8)EHandKeypoint::Palm], FVector(1.f)); + } + + TArray TransformArray; + TransformArray.AddUninitialized(MotionControllerData.HandKeyPositions.Num()); + + for (int i = 0; i < MotionControllerData.HandKeyPositions.Num(); ++i) + { + // Convert to component space, we convert then to parent space later when applying it + TransformArray[i] = FTransform(MotionControllerData.HandKeyRotations[i].GetNormalized(), MotionControllerData.HandKeyPositions[i], FVector(1.f)).GetRelativeTransform(ParentTrans); + } + + ThumbCurl = GetCurlValueForBoneRoot(TransformArray, EHandKeypoint::ThumbMetacarpal); + IndexCurl = GetCurlValueForBoneRoot(TransformArray, EHandKeypoint::IndexProximal); + MiddleCurl = GetCurlValueForBoneRoot(TransformArray, EHandKeypoint::MiddleProximal); + RingCurl = GetCurlValueForBoneRoot(TransformArray, EHandKeypoint::RingProximal); + PinkyCurl = GetCurlValueForBoneRoot(TransformArray, EHandKeypoint::LittleProximal); + + return true; +} + +float UOpenXRExpansionFunctionLibrary::GetCurlValueForBoneRoot(TArray& TransformArray, EHandKeypoint RootBone) +{ + float Angle1 = 0.0f; + float Angle2 = 0.0f; + float Angle1Curl = 0.0f; + float Angle2Curl = 0.0f; + + if (RootBone == EHandKeypoint::ThumbMetacarpal) + { + FVector Prox = TransformArray[(uint8)RootBone].GetRotation().GetForwardVector(); + FVector Inter = TransformArray[(uint8)RootBone + 1].GetRotation().GetForwardVector(); + FVector Distal = TransformArray[(uint8)RootBone + 2].GetRotation().GetForwardVector(); + + Prox = FVector::VectorPlaneProject(Prox, FVector::UpVector); + Inter = FVector::VectorPlaneProject(Inter, FVector::UpVector); + Distal = FVector::VectorPlaneProject(Distal, FVector::UpVector); + + Angle1 = FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(Inter, Distal))); + Angle2 = FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(Prox, Inter))); + + Angle1Curl = (Angle1 - 10.0f) / 64.0f; + Angle2Curl = (Angle2 - 20.0f) / 42.0f; + } + else + { + FVector Prox = TransformArray[(uint8)RootBone].GetRotation().GetForwardVector(); + FVector Inter = TransformArray[(uint8)RootBone + 1].GetRotation().GetForwardVector(); + FVector Distal = TransformArray[(uint8)RootBone + 2].GetRotation().GetForwardVector(); + + + // We don't use the Y (splay) value, only X and Z plane + + Prox = FVector::VectorPlaneProject(Prox, FVector::RightVector); + Inter = FVector::VectorPlaneProject(Inter, FVector::RightVector); + Distal = FVector::VectorPlaneProject(Distal, FVector::RightVector); + + Angle1 = FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(Inter, Distal))); + Angle2 = FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(Prox, Inter))); + + Angle1Curl = (Angle1 - 10.0f) / 60.0f; + Angle2Curl = (Angle2 - 10.0f) / 100.0f; + } + + // Can lower number of variables by doing these + + float FinalAngleAvg = FMath::Clamp((Angle1Curl + Angle2Curl) / 2.0f, 0.0f, 1.0f); + + //GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Finger Curl %f"), IndexCurl)); + return FinalAngleAvg; + +} + +void UOpenXRExpansionFunctionLibrary::ConvertHandTransformsSpaceAndBack(TArray& OutTransforms, const TArray& WorldTransforms) +{ + // Fail if the count is too low + if (WorldTransforms.Num() < EHandKeypointCount) + return; + + if (OutTransforms.Num() < WorldTransforms.Num()) + { + OutTransforms.Empty(WorldTransforms.Num()); + OutTransforms.AddUninitialized(WorldTransforms.Num()); + } + + // Bone/Parent map + int32 BoneParents[26] = + { + // Manually build the parent hierarchy starting at the wrist which has no parent (-1) + 1, // Palm -> Wrist + -1, // Wrist -> None + 1, // ThumbMetacarpal -> Wrist + 2, // ThumbProximal -> ThumbMetacarpal + 3, // ThumbDistal -> ThumbProximal + 4, // ThumbTip -> ThumbDistal + + 1, // IndexMetacarpal -> Wrist + 6, // IndexProximal -> IndexMetacarpal + 7, // IndexIntermediate -> IndexProximal + 8, // IndexDistal -> IndexIntermediate + 9, // IndexTip -> IndexDistal + + 1, // MiddleMetacarpal -> Wrist + 11, // MiddleProximal -> MiddleMetacarpal + 12, // MiddleIntermediate -> MiddleProximal + 13, // MiddleDistal -> MiddleIntermediate + 14, // MiddleTip -> MiddleDistal + + 1, // RingMetacarpal -> Wrist + 16, // RingProximal -> RingMetacarpal + 17, // RingIntermediate -> RingProximal + 18, // RingDistal -> RingIntermediate + 19, // RingTip -> RingDistal + + 1, // LittleMetacarpal -> Wrist + 21, // LittleProximal -> LittleMetacarpal + 22, // LittleIntermediate -> LittleProximal + 23, // LittleDistal -> LittleIntermediate + 24, // LittleTip -> LittleDistal + }; + + // Convert transforms to parent space + // The hand tracking transforms are in world space. + for (int32 Index = 0; Index < EHandKeypointCount; ++Index) + { + FTransform BoneTransform = WorldTransforms[Index]; + BoneTransform.NormalizeRotation(); + int32 ParentIndex = BoneParents[Index]; + int32 ParentParent = -1; + + if (ParentIndex > 0) + { + ParentParent = BoneParents[ParentIndex]; + } + + if (ParentIndex < 0) + { + // We are at the root, so use it. + OutTransforms[Index] = BoneTransform; + } + else + { + + FTransform ParentTransform = FTransform::Identity; + + // Merging missing metacarpal bone into the transform + if (ParentParent == 1) // Wrist + { + ParentTransform = WorldTransforms[ParentParent]; + } + else + { + ParentTransform = WorldTransforms[ParentIndex]; + } + + ParentTransform.NormalizeRotation(); + OutTransforms[Index] = BoneTransform.GetRelativeTransform(ParentTransform); + } + } + + // Check on the easy component space conversion first + { + for (int32 Index = 0; Index < EHandKeypointCount; ++Index) + { + const FTransform& BoneTransform = WorldTransforms[Index]; + int32 ParentIndex = BoneParents[Index]; + int32 ParentParent = -1; + + if (ParentIndex > 0) + { + ParentParent = BoneParents[ParentIndex]; + } + + if (ParentIndex > 0) + { + if (ParentParent == 1) + { + OutTransforms[Index] = OutTransforms[Index] * OutTransforms[ParentParent]; + } + else + { + OutTransforms[Index] = OutTransforms[Index] * OutTransforms[ParentIndex]; + } + } + } + } +} + +void UOpenXRExpansionFunctionLibrary::GetMockUpControllerData(FXRMotionControllerData& MotionControllerData, FBPOpenXRActionSkeletalData& SkeletalMappingData, bool bOpenHand) +{ + + + TArray HandRotationsClosed = { + // Closed palm + FQuat(-6.9388939039072284e-18f,-2.7755575615628914e-17f,-5.5511151231257827e-17f,1.0000000181623150), + FQuat(0.0010158333104005046f,-0.031842494413126823f,0.0082646248419453450f,-0.99945823120983279), + FQuat(0.49284713488980170f,-0.22607130273287540f,-0.44054329019960731f,0.71548243409346490), + FQuat(-0.60572821120045273f,-0.017497510794223320f,0.10943807503774633f,-0.78791529705201735), + FQuat(-0.61281359708005512f,-0.23245447006924613f,-0.058766632856478873f,-0.75297472319193537), + FQuat(-0.61281359708005512f,-0.23245447006924613f,-0.058766632856478873f,-0.75297472319193537), + FQuat(-0.11514346379358367f,-0.029229397612833233f,-0.076351329575539195f,0.98997885626789228), + FQuat(0.079333339113826437f,-0.72590009974051883f,0.050346047334316274f,-0.68135202233808378), + FQuat(0.0032539550806410245f,-0.97123336736010268f,0.098921247251489333f,0.21658665949113542), + FQuat(-0.064585069112672477f,-0.57963374972897053f,0.075445998290538954f,0.80880246209406348), + FQuat(0.064585069112672477f,0.57963374972897053f,-0.075445998290538954f,-0.80880246209406348), + FQuat(-7.7702472130181111e-08f,9.8656527815210726e-08f,1.3838491007001075e-06f,1.0000000181613493), + FQuat(0.085300231549708214f,-0.74048187833139134f,0.058532016219761618f,-0.66406663653752407), + FQuat(0.011595964719175678f,-0.98786834549923641f,0.099110835214894707f,0.11899052159928070), + FQuat(-0.063530326287074640f,-0.56012988021281451f,0.076145543493668810f,0.82244775363868539), + FQuat(0.030477923994508188f,0.55662337489051250f,-0.098559802475379960f,-0.82433459003921772), + FQuat(-0.025910339872061101f,0.052311401725670628f,0.042953782692297438f,0.99737013210455761), + FQuat(0.11635892750396379f,-0.74717191584145570f,-0.026909776929005647f,-0.65381238012001353), + FQuat(0.098078041656806447f,-0.98532297068866348f,0.071135591008198620f,0.12024601945419003), + FQuat(0.0028091467060491482f,-0.52817558741956572f,0.11864668261714340f,0.84080060571895254), + FQuat(-0.0028091467060491482f,0.52817558741956572f,-0.11864668261714340f,-0.84080060571895254), + FQuat(-0.11913260527111892f,0.10934177100849747f,0.11664955310670821f,0.97992077106196507), + FQuat(-0.18696185363314571f,0.78123174637415782f,0.043590203318890380f,0.59398834520762267), + FQuat(0.15903913486884827f,-0.97287570092949460f,0.091728860868847406f,0.14073122087670015), + FQuat(0.035141532005084519f,-0.48251853052338572f,0.18910886397987722f,0.85450501128943579), + FQuat(0.035141532005084519f,-0.48251853052338572f,0.18910886397987722f,0.85450501128943579) + }; + TArray HandRotationsOpen = { + // Open Hand + FQuat(0.167000905f,-0.670308471f,0.304047525f,-0.656011939f), + FQuat(-0.129862994f,0.736467659f,-0.315623045f,0.584065497f), + FQuat(-0.030090153f,0.121532254f,-0.840178490f,0.527659237f), + FQuat(-0.126470163f,-0.262596279f,0.816956878f,-0.497623593f), + FQuat(-0.102322638f,-0.249194950f,0.821705163f,-0.502227187f), + FQuat(-0.102322638f,-0.249194950f,0.821705163f,-0.502227187f), + FQuat(-0.277370781f,0.686735749f,-0.258646101f,0.620130479f), + FQuat(0.193366051f,-0.808131576f,0.260262072f,-0.491728455f), + FQuat(0.145547777f,-0.854364336f,0.317562312f,-0.384749293f), + FQuat(0.107193023f,-0.879853010f,0.321882188f,-0.332806766f), + FQuat(0.107193023f,-0.879853010f,0.321882188f,-0.332806766f), + FQuat(0.166999936f,-0.670307159f,0.304047883f,-0.656013489f), + FQuat(0.206125781f,-0.815250278f,0.203173012f,-0.501596987f), + FQuat(0.164493740f,-0.890369833f,0.257293820f,-0.337613612f), + FQuat(0.114019498f,-0.937856555f,0.283619940f,-0.164267495f), + FQuat(0.107336335f,-0.925720870f,0.321023613f,-0.168710276f), + FQuat(0.156629071f,-0.719596088f,0.210793152f,-0.642817795f), + FQuat(0.194258988f,-0.858762920f,0.127883837f,-0.456546605f), + FQuat(0.166189745f,-0.930981100f,0.161785051f,-0.281922638f), + FQuat(0.119936436f,-0.970744252f,0.189072192f,-0.086731322f), + FQuat(0.119936436f,-0.970744252f,0.189072192f,-0.086731322f), + FQuat(0.160288095f,-0.812664807f,0.100923792f,-0.551087677f), + FQuat(0.207311243f,-0.870556056f,0.056644741f,-0.442656904f), + FQuat(0.191506147f,-0.944826961f,0.096772499f,-0.247511998f), + FQuat(0.116890728f,-0.981477261f,0.138804480f,-0.061412390f), + FQuat(0.116890728f,-0.981477261f,0.138804480f,-0.061412390f) + }; + + MotionControllerData.HandKeyRotations = /*SkeletalMappingData.TargetHand != EVRSkeletalHandIndex::EActionHandIndex_Left ? HandRotationsOpen :*/ HandRotationsClosed; + + TArray HandPositionsClosed = { + // Closed palm - Left + FVector(0.0000000000000000f,0.0000000000000000f,0.0000000000000000f), + FVector(-2.8690212431406792f,0.70708009295073815f,-0.47404338536985718f), + FVector(-1.1322360817697272f,-2.1125772981974671f,-1.2278703475596775f), + FVector(0.92697682070144727f,-5.5601677377459957f,-1.6753327187355360f), + FVector(4.0987554778339428f,-6.0520138168462640f,-2.1960898756852747f), + FVector(5.5854053809842918f,-5.4247506634349065f,-2.6631245417791525f), + FVector(-1.6026417502203387f,-1.4646945203797794f,-0.17057236434820122f), + FVector(5.7352432311721007f,-2.5389617545260998f,0.39061644722637634f), + FVector(5.4801464829170561f,-3.3344912297783416f,-3.8566611419550343f), + FVector(2.9179605371815693f,-3.2311985822561073f,-2.6652727318443148f), + FVector(3.2708935578922342f,-3.0117453368521279f,-1.6311186720587312f), + FVector(-1.1935619377191149f,-1.8034793735494103e-05f,1.4147048846974153e-06f), + FVector(5.9028526610092893f,1.3513666817788206e-05f,-4.3170989212359956e-06f), + FVector(5.4567759872551527f,-0.87968929643487392f,-4.1965100581882382f), + FVector(2.2252652348065158f,-0.87742006725177069f,-3.4067970851427791f), + FVector(2.6916877869696085f,-0.62360084690574125f,-2.2285708116727738f), + FVector(-1.1796822503165614f,1.3653411443775685f,-0.17694011615865479f), + FVector(5.3502831208188670f,1.9121382570769896f,-0.87930289382919313f), + FVector(4.8743654830862742f,1.3526757302541959f,-4.8457258101076217f), + FVector(2.1622015314362244f,0.85068796311660544f,-4.1307752690132205f), + FVector(2.6021369184528194f,1.0596020074600654f,-3.1860412064934174f), + FVector(-1.2905361603753163f,2.6108535683555365f,-0.46423293549223010f), + FVector(4.6820094577722964f,3.8858425146699327f,-1.9880098921962746f), + FVector(4.0115118130532306f,3.1678700881616777f,-4.8092930847360869f), + FVector(2.3757993445967389f,2.6579252395479291f,-4.2645319235961239f), + FVector(2.7329133227289351f,2.8811366857469527f,-3.6179750674182261f) + }; + + // Open Hand + TArray HandPositionsOpen = { + FVector(-1014.001f,-478.278f,212.902f), + FVector(-1013.516f,-476.006f,214.688f), + FVector(-1016.362f,-479.642f,215.119f), + FVector(-1018.145f,-483.254f,214.805f), + FVector(-1019.682f,-485.682f,213.284f), + FVector(-1020.480f,-486.982f,212.581f), + FVector(-1014.360f,-478.927f,215.169f), + FVector(-1014.932f,-484.146f,209.902f), + FVector(-1016.872f,-486.643f,206.852f), + FVector(-1018.771f,-488.058f,205.231f), + FVector(-1019.613f,-488.507f,204.655f), + FVector(-1013.901f,-477.534f,213.831f), + FVector(-1014.494f,-481.954f,208.310f), + FVector(-1016.269f,-484.282f,205.146f), + FVector(-1018.657f,-485.834f,203.427f), + FVector(-1019.846f,-486.231f,203.113f), + FVector(-1013.816f,-476.436f,213.006f), + FVector(-1014.637f,-479.707f,207.344f), + FVector(-1016.703f,-481.540f,204.355f), + FVector(-1018.962f,-482.692f,203.000f), + FVector(-1019.978f,-482.975f,202.870f), + FVector(-1013.845f,-475.325f,212.363f), + FVector(-1015.993f,-477.665f,206.928f), + FVector(-1017.571f,-478.907f,204.670f), + FVector(-1019.033f,-479.652f,203.887f), + FVector(-1019.778f,-479.842f,203.819f) + }; + + MotionControllerData.HandKeyPositions = /*SkeletalMappingData.TargetHand != EVRSkeletalHandIndex::EActionHandIndex_Left ? HandPositionsOpen : */HandPositionsClosed; + + if (SkeletalMappingData.TargetHand != EVRSkeletalHandIndex::EActionHandIndex_Left) + { + MotionControllerData.GripPosition = FVector(-1018.305f, -478.019f, 209.872f); + MotionControllerData.GripRotation = FQuat(-0.116352126f, 0.039430488f, -0.757644236f, 0.641001403f); + } + else + { + MotionControllerData.GripPosition = FVector(-1202.619f, -521.077f, 283.076f); + MotionControllerData.GripRotation = FQuat(0.040843058f, 0.116659224f, 0.980030060f, -0.155767411f); + } + + MotionControllerData.DeviceName = TEXT("OpenXR"); + + SkeletalMappingData.SkeletalTransforms.Empty(SkeletalMappingData.SkeletalTransforms.Num()); + FTransform ParentTrans = FTransform(MotionControllerData.GripRotation, MotionControllerData.GripPosition, FVector(1.f)); + for (int i = 0; i < MotionControllerData.HandKeyPositions.Num(); i++) + { + SkeletalMappingData.SkeletalTransforms.Add(FTransform(MotionControllerData.HandKeyRotations[i], MotionControllerData.HandKeyPositions[i], FVector(1.f)).GetRelativeTransform(ParentTrans)); + } + + SkeletalMappingData.bHasValidData = (SkeletalMappingData.SkeletalTransforms.Num() == EHandKeypointCount); +} \ No newline at end of file diff --git a/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Private/OpenXRExpansionPlugin.cpp b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Private/OpenXRExpansionPlugin.cpp new file mode 100644 index 0000000..47fac71 --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Private/OpenXRExpansionPlugin.cpp @@ -0,0 +1,24 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "OpenXRExpansionPlugin.h" +#include "OpenXRExpansionFunctionLibrary.h" + +#define LOCTEXT_NAMESPACE "FXRExpansionPluginModule" + +void FOpenXRExpansionPluginModule::StartupModule() +{ + // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module + //LoadOpenVRModule(); +} + +void FOpenXRExpansionPluginModule::ShutdownModule() +{ + // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, + // we call this function before unloading the module. +// UnloadOpenVRModule(); +} + + +#undef LOCTEXT_NAMESPACE + +IMPLEMENT_MODULE(FOpenXRExpansionPluginModule, OpenXRExpansionPlugin) \ No newline at end of file diff --git a/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Private/OpenXRHandPoseComponent.cpp b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Private/OpenXRHandPoseComponent.cpp new file mode 100644 index 0000000..cd6b6f9 --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Private/OpenXRHandPoseComponent.cpp @@ -0,0 +1,895 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "OpenXRHandPoseComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(OpenXRHandPoseComponent) + +#include "Net/UnrealNetwork.h" +#include "MotionControllerComponent.h" +#include "OpenXRExpansionFunctionLibrary.h" +#include "Engine/NetSerialization.h" +#include "Net/Core/PushModel/PushModel.h" + +#include "XRMotionControllerBase.h" // for GetHandEnumForSourceName() +//#include "EngineMinimal.h" + +UOpenXRHandPoseComponent::UOpenXRHandPoseComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + PrimaryComponentTick.bCanEverTick = true; + PrimaryComponentTick.bStartWithTickEnabled = true; + + ReplicationRateForSkeletalAnimations = 10.f; + bReplicateSkeletalData = false; + bSmoothReplicatedSkeletalData = true; + SkeletalNetUpdateCount = 0.f; + bDetectGestures = true; + SetIsReplicatedByDefault(true); + bGetMockUpPoseForDebugging = false; +} + +void UOpenXRHandPoseComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + FDoRepLifetimeParams SkipOwnerParams; + SkipOwnerParams.Condition = COND_SkipOwner; + SkipOwnerParams.bIsPushBased = true; + + // Skipping the owner with this as the owner will use the controllers location directly + DOREPLIFETIME_WITH_PARAMS_FAST(UOpenXRHandPoseComponent, LeftHandRep, SkipOwnerParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UOpenXRHandPoseComponent, RightHandRep, SkipOwnerParams); +} + +void UOpenXRHandPoseComponent::Server_SendSkeletalTransforms_Implementation(const FBPXRSkeletalRepContainer& SkeletalInfo) +{ + for (int i = 0; i < HandSkeletalActions.Num(); i++) + { + if (HandSkeletalActions[i].TargetHand == SkeletalInfo.TargetHand) + { + if (SkeletalInfo.TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Left) + { + if (bSmoothReplicatedSkeletalData) + { + LeftHandRepManager.PreCopyNewData(HandSkeletalActions[i], ReplicationRateForSkeletalAnimations, bUseExponentialSmoothing); + } + + FBPXRSkeletalRepContainer::CopyReplicatedTo(SkeletalInfo, HandSkeletalActions[i]); + LeftHandRep = SkeletalInfo; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UOpenXRHandPoseComponent, LeftHandRep, this); +#endif + + if (bSmoothReplicatedSkeletalData) + { + LeftHandRepManager.NotifyNewData(HandSkeletalActions[i], ReplicationRateForSkeletalAnimations, bUseExponentialSmoothing); + } + } + else + { + if (bSmoothReplicatedSkeletalData) + { + RightHandRepManager.PreCopyNewData(HandSkeletalActions[i], ReplicationRateForSkeletalAnimations, bUseExponentialSmoothing); + } + + FBPXRSkeletalRepContainer::CopyReplicatedTo(SkeletalInfo, HandSkeletalActions[i]); + RightHandRep = SkeletalInfo; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UOpenXRHandPoseComponent, RightHandRep, this); +#endif + + if (bSmoothReplicatedSkeletalData) + { + RightHandRepManager.NotifyNewData(HandSkeletalActions[i], ReplicationRateForSkeletalAnimations, bUseExponentialSmoothing); + } + } + + break; + } + } +} + +bool UOpenXRHandPoseComponent::Server_SendSkeletalTransforms_Validate(const FBPXRSkeletalRepContainer& SkeletalInfo) +{ + return true; +} + +void FOpenXRAnimInstanceProxy::PreUpdate(UAnimInstance* InAnimInstance, float DeltaSeconds) +{ + Super::PreUpdate(InAnimInstance, DeltaSeconds); + + if (UOpenXRAnimInstance* OwningInstance = Cast(InAnimInstance)) + { + if (OwningInstance->OwningPoseComp) + { + if (HandSkeletalActionData.Num() != OwningInstance->OwningPoseComp->HandSkeletalActions.Num()) + { + HandSkeletalActionData.Empty(OwningInstance->OwningPoseComp->HandSkeletalActions.Num()); + + for(FBPOpenXRActionSkeletalData& actionInfo : OwningInstance->OwningPoseComp->HandSkeletalActions) + { + HandSkeletalActionData.Add(actionInfo); + } + } + else + { + for (int i = 0; i < OwningInstance->OwningPoseComp->HandSkeletalActions.Num(); ++i) + { + HandSkeletalActionData[i] = OwningInstance->OwningPoseComp->HandSkeletalActions[i]; + } + } + } + } +} + +FOpenXRAnimInstanceProxy::FOpenXRAnimInstanceProxy(UAnimInstance* InAnimInstance) + : FAnimInstanceProxy(InAnimInstance) +{ +} + +void UOpenXRHandPoseComponent::BeginPlay() +{ + /*if (UMotionControllerComponent * MotionParent = Cast(GetAttachParent())) + { + EControllerHand HandType; + if (!FXRMotionControllerBase::GetHandEnumForSourceName(MotionParent->MotionSource, HandType)) + { + HandType = EControllerHand::Left; + } + + for (int i = 0; i < HandSkeletalActions.Num(); i++) + { + if (HandType == EControllerHand::Left || HandType == EControllerHand::AnyHand) + HandSkeletalActions[i].SkeletalData.TargetHand = EVRSkeletalHandIndex::EActionHandIndex_Left; + else + HandSkeletalActions[i].SkeletalData.TargetHand = EVRSkeletalHandIndex::EActionHandIndex_Right; + } + + }*/ + + Super::BeginPlay(); +} + +void UOpenXRHandPoseComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) +{ + if (!IsLocallyControlled()) + { + if (bReplicateSkeletalData) + { + // Handle bone lerping here if we are replicating + for (FBPOpenXRActionSkeletalData& actionInfo : HandSkeletalActions) + { + if (bSmoothReplicatedSkeletalData) + { + if (actionInfo.TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Left) + { + LeftHandRepManager.UpdateManager(DeltaTime, actionInfo, this); + } + else + { + RightHandRepManager.UpdateManager(DeltaTime, actionInfo, this); + } + } + } + } + } + else // Get data and process + { + bool bGetCompressedTransforms = false; + if (bReplicateSkeletalData && HandSkeletalActions.Num() > 0) + { + SkeletalNetUpdateCount += DeltaTime; + if (SkeletalNetUpdateCount >= (1.0f / ReplicationRateForSkeletalAnimations)) + { + SkeletalNetUpdateCount = 0.0f; + bGetCompressedTransforms = true; + } + } + + for (FBPOpenXRActionSkeletalData& actionInfo : HandSkeletalActions) + { + if (UOpenXRExpansionFunctionLibrary::GetOpenXRHandPose(actionInfo, this, bGetMockUpPoseForDebugging)) + { + if (bGetCompressedTransforms) + { + if (GetNetMode() == NM_Client) + { + if (actionInfo.bHasValidData) + { + FBPXRSkeletalRepContainer ContainerSend; + ContainerSend.CopyForReplication(actionInfo); + Server_SendSkeletalTransforms(ContainerSend); + } + } + else + { + if (actionInfo.bHasValidData) + { + if (actionInfo.TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Left) + LeftHandRep.CopyForReplication(actionInfo); + else + RightHandRep.CopyForReplication(actionInfo); + } + } + } + } + + if (bDetectGestures && actionInfo.bHasValidData && actionInfo.SkeletalTransforms.Num() > 0 && GesturesDB != nullptr && GesturesDB->Gestures.Num() > 0) + { + DetectCurrentPose(actionInfo); + } + } + } + + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); +} + +bool UOpenXRHandPoseComponent::SaveCurrentPose(FName RecordingName, EVRSkeletalHandIndex HandToSave) +{ + + if (!HandSkeletalActions.Num()) + return false; + + // Default to the first hand element so that single length arrays work as is. + FBPOpenXRActionSkeletalData* HandSkeletalAction = nullptr; + + // Now check for the specific passed in hand if this is a multi hand + for (int i = 0; i < HandSkeletalActions.Num(); ++i) + { + if (HandSkeletalActions[i].TargetHand == HandToSave) + { + HandSkeletalAction = &HandSkeletalActions[i]; + break; + } + } + + if (!HandSkeletalAction || !HandSkeletalAction->bHasValidData || HandSkeletalAction->SkeletalTransforms.Num() < EHandKeypointCount) + return false; + + if (GesturesDB) + { + FOpenXRGesture NewGesture; + + int32 FingerMap[5] = + { + (int32)EXRHandJointType::OXR_HAND_JOINT_THUMB_TIP_EXT, + (int32)EXRHandJointType::OXR_HAND_JOINT_INDEX_TIP_EXT, + (int32)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_TIP_EXT, + (int32)EXRHandJointType::OXR_HAND_JOINT_RING_TIP_EXT, + (int32)EXRHandJointType::OXR_HAND_JOINT_LITTLE_TIP_EXT + }; + + FVector WristLoc = FVector::ZeroVector; + + if (HandToSave == EVRSkeletalHandIndex::EActionHandIndex_Left) + { + WristLoc = HandSkeletalAction->SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_WRIST_EXT].GetLocation().MirrorByVector(FVector::RightVector); + } + else + { + WristLoc = HandSkeletalAction->SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_WRIST_EXT].GetLocation(); + } + + for (int i = 0; i < 5; ++i) + { + if (HandToSave == EVRSkeletalHandIndex::EActionHandIndex_Left) + { + NewGesture.FingerValues[i] = FOpenXRGestureFingerPosition(HandSkeletalAction->SkeletalTransforms[FingerMap[i]].GetLocation().MirrorByVector(FVector::RightVector) - WristLoc, (EXRHandJointType)FingerMap[i]); + } + else + { + NewGesture.FingerValues[i] = FOpenXRGestureFingerPosition(HandSkeletalAction->SkeletalTransforms[FingerMap[i]].GetLocation() - WristLoc, (EXRHandJointType)FingerMap[i]); + } + } + + NewGesture.Name = RecordingName; + GesturesDB->Gestures.Add(NewGesture); + + return true; + } + + return false; +} + + +bool UOpenXRHandPoseComponent::K2_DetectCurrentPose(UPARAM(ref) FBPOpenXRActionSkeletalData& SkeletalAction, FOpenXRGesture & GestureOut) +{ + if (!GesturesDB || GesturesDB->Gestures.Num() < 1) + return false; + + int32 FingerMap[5] = + { + (int32)EXRHandJointType::OXR_HAND_JOINT_THUMB_TIP_EXT, + (int32)EXRHandJointType::OXR_HAND_JOINT_INDEX_TIP_EXT, + (int32)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_TIP_EXT, + (int32)EXRHandJointType::OXR_HAND_JOINT_RING_TIP_EXT, + (int32)EXRHandJointType::OXR_HAND_JOINT_LITTLE_TIP_EXT + }; + + FVector WristLoc = FVector::ZeroVector; + + if (SkeletalAction.TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Left) + { + WristLoc = SkeletalAction.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_WRIST_EXT].GetLocation().MirrorByVector(FVector::RightVector); + } + else + { + WristLoc = SkeletalAction.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_WRIST_EXT].GetLocation(); + } + + // Early fill in an array to keep from performing math for each gesture + TArray CurrentTips; + CurrentTips.AddUninitialized(5); + for (int i = 0; i < 5; ++i) + { + if (SkeletalAction.TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Left) + { + CurrentTips[i] = SkeletalAction.SkeletalTransforms[FingerMap[i]].GetLocation().MirrorByVector(FVector::RightVector) - WristLoc; + } + else + { + CurrentTips[i] = SkeletalAction.SkeletalTransforms[FingerMap[i]].GetLocation() - WristLoc; + } + } + + for (const FOpenXRGesture& Gesture : GesturesDB->Gestures) + { + // If not enough indexs to match curl values, or if this gesture requires finger splay and the controller can't do it + if (Gesture.FingerValues.Num() < 5 || SkeletalAction.SkeletalTransforms.Num() < EHandKeypointCount) + continue; + + bool bDetectedPose = true; + for (int i = 0; i < 5; ++i) + { + FVector GestureV = Gesture.FingerValues[i].Value; + FVector CurrentV = CurrentTips[i]; + FVector Difference = GestureV - CurrentV; + + if (!Gesture.FingerValues[i].Value.Equals(CurrentTips[i], Gesture.FingerValues[i].Threshold)) + { + bDetectedPose = false; + break; + } + } + + if (bDetectedPose) + { + GestureOut = Gesture; + return true; + } + } + + return false; +} + +bool UOpenXRHandPoseComponent::DetectCurrentPose(FBPOpenXRActionSkeletalData &SkeletalAction) +{ + if (!GesturesDB || GesturesDB->Gestures.Num() < 1 || SkeletalAction.SkeletalTransforms.Num() < EHandKeypointCount) + return false; + + FTransform BoneTransform = FTransform::Identity; + + int32 FingerMap[5] = + { + (int32)EXRHandJointType::OXR_HAND_JOINT_THUMB_TIP_EXT, + (int32)EXRHandJointType::OXR_HAND_JOINT_INDEX_TIP_EXT, + (int32)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_TIP_EXT, + (int32)EXRHandJointType::OXR_HAND_JOINT_RING_TIP_EXT, + (int32)EXRHandJointType::OXR_HAND_JOINT_LITTLE_TIP_EXT + }; + + FVector WristLoc = FVector::ZeroVector; + + if (SkeletalAction.TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Left) + { + WristLoc = SkeletalAction.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_WRIST_EXT].GetLocation().MirrorByVector(FVector::RightVector); + } + else + { + WristLoc = SkeletalAction.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_WRIST_EXT].GetLocation(); + } + + // Early fill in an array to keep from performing math for each gesture + TArray CurrentTips; + CurrentTips.AddUninitialized(5); + for (int i = 0; i < 5; ++i) + { + if (SkeletalAction.TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Left) + { + CurrentTips[i] = SkeletalAction.SkeletalTransforms[FingerMap[i]].GetLocation().MirrorByVector(FVector::RightVector) - WristLoc; + } + else + { + CurrentTips[i] = SkeletalAction.SkeletalTransforms[FingerMap[i]].GetLocation() - WristLoc; + } + } + + for (auto GestureIterator = GesturesDB->Gestures.CreateConstIterator(); GestureIterator; ++GestureIterator) + { + const FOpenXRGesture &Gesture = *GestureIterator; + + // If not enough indexs to match curl values, or if this gesture requires finger splay and the controller can't do it + if (Gesture.FingerValues.Num() < 5 || SkeletalAction.SkeletalTransforms.Num() < EHandKeypointCount) + continue; + + bool bDetectedPose = true; + for (int i = 0; i < 5; ++i) + { + if (Gesture.FingerValues[i].Threshold <= 0.0f) + continue; + + if (!Gesture.FingerValues[i].Value.Equals(CurrentTips[i], Gesture.FingerValues[i].Threshold)) + { + bDetectedPose = false; + break; + } + } + + if (bDetectedPose) + { + if (SkeletalAction.LastHandGesture != Gesture.Name) + { + if (SkeletalAction.LastHandGesture != NAME_None) + OnGestureEnded.Broadcast(SkeletalAction.LastHandGesture, SkeletalAction.LastHandGestureIndex, SkeletalAction.TargetHand); + + SkeletalAction.LastHandGesture = Gesture.Name; + SkeletalAction.LastHandGestureIndex = GestureIterator.GetIndex(); + OnNewGestureDetected.Broadcast(SkeletalAction.LastHandGesture, SkeletalAction.LastHandGestureIndex, SkeletalAction.TargetHand); + + return true; + } + else + return false; // Same gesture + } + } + + if (SkeletalAction.LastHandGesture != NAME_None) + { + OnGestureEnded.Broadcast(SkeletalAction.LastHandGesture, SkeletalAction.LastHandGestureIndex, SkeletalAction.TargetHand); + SkeletalAction.LastHandGesture = NAME_None; + SkeletalAction.LastHandGestureIndex = INDEX_NONE; + } + + return false; +} + +UOpenXRHandPoseComponent::FTransformLerpManager::FTransformLerpManager() +{ + bReplicatedOnce = false; + bLerping = false; + UpdateCount = 0.0f; + UpdateRate = 0.0f; +} + +void UOpenXRHandPoseComponent::FTransformLerpManager::PreCopyNewData(FBPOpenXRActionSkeletalData& ActionInfo, int NetUpdateRate, bool bExponentialSmoothing) +{ + if (!bExponentialSmoothing) + { + if (ActionInfo.SkeletalTransforms.Num()) + { + OldTransforms = ActionInfo.SkeletalTransforms; + } + } +} + +void UOpenXRHandPoseComponent::FTransformLerpManager::NotifyNewData(FBPOpenXRActionSkeletalData& ActionInfo, int NetUpdateRate, bool bExponentialSmoothing) +{ + UpdateRate = (1.0f / NetUpdateRate); + + if (bReplicatedOnce) + { + bLerping = true; + UpdateCount = 0.0f; + NewTransforms = ActionInfo.SkeletalTransforms; + + ActionInfo.SkeletalTransforms = OldTransforms; + + } + else + { + if (bExponentialSmoothing) + { + OldTransforms = ActionInfo.SkeletalTransforms; + } + + bReplicatedOnce = true; + } +} + +void UOpenXRHandPoseComponent::FTransformLerpManager::UpdateManager(float DeltaTime, FBPOpenXRActionSkeletalData& ActionInfo, UOpenXRHandPoseComponent* ParentComp) +{ + if (!ActionInfo.bHasValidData || !OldTransforms.Num()) + return; + + if (bLerping) + { + bool bExponentialSmoothing = ParentComp->bUseExponentialSmoothing; + float LerpVal = 0.0f; + + if (!bExponentialSmoothing || ParentComp->InterpolationSpeed <= 0.f) + { + UpdateCount += DeltaTime; + + // Keep LerpVal + LerpVal = FMath::Clamp(UpdateCount / UpdateRate, 0.0f, 1.0f); + } + else + { + LerpVal = FMath::Clamp(DeltaTime * ParentComp->InterpolationSpeed, 0.f, 1.f); + } + + if (!bExponentialSmoothing && LerpVal >= 1.0f) + { + bLerping = false; + UpdateCount = 0.0f; + ActionInfo.SkeletalTransforms = NewTransforms; + } + else + { + int32 BoneCountAdjustment = 6 + (ActionInfo.bEnableUE4HandRepSavings ? 4 : 0); + if ((NewTransforms.Num() < (EHandKeypointCount - BoneCountAdjustment)) || (NewTransforms.Num() != ActionInfo.SkeletalTransforms.Num())) + { + return; + } + + ActionInfo.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_PALM_EXT] = FTransform::Identity; + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_WRIST_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_THUMB_METACARPAL_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_THUMB_PROXIMAL_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_THUMB_DISTAL_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + //BlendBone((uint8)EVROpenXRBones::eBone_Thumb3, ActionInfo, LerpVal); // Technically can be projected instead of blended + + if (!ActionInfo.bEnableUE4HandRepSavings) + { + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_INDEX_METACARPAL_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + } + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_INDEX_PROXIMAL_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_INDEX_INTERMEDIATE_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_INDEX_DISTAL_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + //BlendBone((uint8)EVROpenXRBones::eBone_IndexFinger4, ActionInfo, LerpVal); // Technically can be projected instead of blended + + if (!ActionInfo.bEnableUE4HandRepSavings) + { + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_METACARPAL_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + } + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_PROXIMAL_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_INTERMEDIATE_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_DISTAL_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + //BlendBone((uint8)EVROpenXRBones::eBone_IndexFinger4, ActionInfo, LerpVal); // Technically can be projected instead of blended + + if (!ActionInfo.bEnableUE4HandRepSavings) + { + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_RING_METACARPAL_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + } + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_RING_PROXIMAL_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_RING_INTERMEDIATE_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_RING_DISTAL_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + //BlendBone((uint8)EVROpenXRBones::eBone_IndexFinger4, ActionInfo, LerpVal); // Technically can be projected instead of blended + + if (!ActionInfo.bEnableUE4HandRepSavings) + { + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_LITTLE_METACARPAL_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + } + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_LITTLE_PROXIMAL_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_LITTLE_INTERMEDIATE_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + BlendBone((int32)EXRHandJointType::OXR_HAND_JOINT_LITTLE_DISTAL_EXT, ActionInfo, LerpVal, bExponentialSmoothing); + //BlendBone((uint8)EVROpenXRBones::eBone_IndexFinger4, ActionInfo, LerpVal); // Technically can be projected instead of blended + + // These are copied from the 3rd joints as they use the same transform but a different root + // Don't want to waste cpu time blending these + //ActionInfo.SkeletalTransforms[(uint8)EVROpenXRBones::eBone_Aux_Thumb] = ActionInfo.SkeletalData.SkeletalTransforms[(uint8)EVROpenXRBones::eBone_Thumb2]; + //ActionInfo.SkeletalTransforms[(uint8)EVROpenXRBones::eBone_Aux_IndexFinger] = ActionInfo.SkeletalData.SkeletalTransforms[(uint8)EVROpenXRBones::eBone_IndexFinger3]; + //ActionInfo.SkeletalTransforms[(uint8)EVROpenXRBones::eBone_Aux_MiddleFinger] = ActionInfo.SkeletalData.SkeletalTransforms[(uint8)EVROpenXRBones::eBone_MiddleFinger3]; + //ActionInfo.SkeletalTransforms[(uint8)EVROpenXRBones::eBone_Aux_RingFinger] = ActionInfo.SkeletalData.SkeletalTransforms[(uint8)EVROpenXRBones::eBone_RingFinger3]; + //ActionInfo.SkeletalTransforms[(uint8)EVROpenXRBones::eBone_Aux_PinkyFinger] = ActionInfo.SkeletalData.SkeletalTransforms[(uint8)EVROpenXRBones::eBone_PinkyFinger3]; + } + } +} + +void FBPXRSkeletalRepContainer::CopyForReplication(FBPOpenXRActionSkeletalData& Other) +{ + TargetHand = Other.TargetHand; + + if (!Other.bHasValidData) + return; + + bAllowDeformingMesh = Other.bAllowDeformingMesh; + bEnableUE4HandRepSavings = Other.bEnableUE4HandRepSavings; + + // Instead of doing this, we likely need to lerp but this is for testing + //SkeletalTransforms = Other.SkeletalData.SkeletalTransforms; + + if (Other.SkeletalTransforms.Num() < EHandKeypointCount) + { + SkeletalTransforms.Empty(); + return; + } + + int32 BoneCountAdjustment = 6 + (bEnableUE4HandRepSavings ? 4 : 0); + + if (SkeletalTransforms.Num() != EHandKeypointCount - BoneCountAdjustment) + { + SkeletalTransforms.Reset(EHandKeypointCount - BoneCountAdjustment); // Minus bones we don't need + SkeletalTransforms.AddUninitialized(EHandKeypointCount - BoneCountAdjustment); + } + + int32 idx = 0; + // Root is always identity + //SkeletalTransforms[0] = Other.SkeletalData.SkeletalTransforms[(uint8)EVROpenInputBones::eBone_Root]; // This has no pos right? Need to skip pos on it + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_WRIST_EXT]; + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_THUMB_METACARPAL_EXT]; + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_THUMB_PROXIMAL_EXT]; + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_THUMB_DISTAL_EXT]; + + if (!bEnableUE4HandRepSavings) + { + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_INDEX_METACARPAL_EXT]; + } + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_INDEX_PROXIMAL_EXT]; + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_INDEX_INTERMEDIATE_EXT]; + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_INDEX_DISTAL_EXT]; + + if (!bEnableUE4HandRepSavings) + { + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_METACARPAL_EXT]; + } + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_PROXIMAL_EXT]; + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_INTERMEDIATE_EXT]; + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_DISTAL_EXT]; + + if (!bEnableUE4HandRepSavings) + { + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_RING_METACARPAL_EXT]; + } + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_RING_PROXIMAL_EXT]; + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_RING_INTERMEDIATE_EXT]; + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_RING_DISTAL_EXT]; + + if (!bEnableUE4HandRepSavings) + { + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_LITTLE_METACARPAL_EXT]; + } + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_LITTLE_PROXIMAL_EXT]; + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_LITTLE_INTERMEDIATE_EXT]; + SkeletalTransforms[idx++] = Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_LITTLE_DISTAL_EXT]; +} + +void FBPXRSkeletalRepContainer::CopyReplicatedTo(const FBPXRSkeletalRepContainer& Container, FBPOpenXRActionSkeletalData& Other) +{ + int32 BoneCountAdjustment = 6 + (Container.bEnableUE4HandRepSavings ? 4 : 0); + if (Container.SkeletalTransforms.Num() < (EHandKeypointCount - BoneCountAdjustment)) + { + Other.SkeletalTransforms.Empty(); + Other.bHasValidData = false; + return; + } + + Other.bAllowDeformingMesh = Container.bAllowDeformingMesh; + Other.bEnableUE4HandRepSavings = Container.bEnableUE4HandRepSavings; + + // Instead of doing this, we likely need to lerp but this is for testing + //Other.SkeletalData.SkeletalTransforms = Container.SkeletalTransforms; + + if (Other.SkeletalTransforms.Num() != EHandKeypointCount) + { + Other.SkeletalTransforms.Reset(EHandKeypointCount); + Other.SkeletalTransforms.AddUninitialized(EHandKeypointCount); + } + + int32 idx = 0; + + // Only fill in the ones that we care about + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_PALM_EXT] = FTransform::Identity; // Always identity + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_WRIST_EXT] = Container.SkeletalTransforms[idx++]; + + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_THUMB_METACARPAL_EXT] = Container.SkeletalTransforms[idx++]; + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_THUMB_PROXIMAL_EXT] = Container.SkeletalTransforms[idx++]; + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_THUMB_DISTAL_EXT] = Container.SkeletalTransforms[idx++]; + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_THUMB_TIP_EXT] = FTransform::Identity; + + if (!Container.bEnableUE4HandRepSavings) + { + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_INDEX_METACARPAL_EXT] = Container.SkeletalTransforms[idx++]; + } + else + { + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_INDEX_METACARPAL_EXT] = FTransform::Identity; + } + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_INDEX_PROXIMAL_EXT] = Container.SkeletalTransforms[idx++]; + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_INDEX_INTERMEDIATE_EXT] = Container.SkeletalTransforms[idx++]; + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_INDEX_DISTAL_EXT] = Container.SkeletalTransforms[idx++]; + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_INDEX_TIP_EXT] = FTransform::Identity; + + if (!Container.bEnableUE4HandRepSavings) + { + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_METACARPAL_EXT] = Container.SkeletalTransforms[idx++]; + } + else + { + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_METACARPAL_EXT] = FTransform::Identity; + } + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_PROXIMAL_EXT] = Container.SkeletalTransforms[idx++]; + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_INTERMEDIATE_EXT] = Container.SkeletalTransforms[idx++]; + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_DISTAL_EXT] = Container.SkeletalTransforms[idx++]; + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_MIDDLE_TIP_EXT] = FTransform::Identity; + + if (!Container.bEnableUE4HandRepSavings) + { + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_RING_METACARPAL_EXT] = Container.SkeletalTransforms[idx++]; + } + else + { + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_RING_METACARPAL_EXT] = FTransform::Identity; + } + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_RING_PROXIMAL_EXT] = Container.SkeletalTransforms[idx++]; + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_RING_INTERMEDIATE_EXT] = Container.SkeletalTransforms[idx++]; + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_RING_DISTAL_EXT] = Container.SkeletalTransforms[idx++]; + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_RING_TIP_EXT] = FTransform::Identity; + + if (!Container.bEnableUE4HandRepSavings) + { + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_LITTLE_METACARPAL_EXT] = Container.SkeletalTransforms[idx++]; + } + else + { + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_LITTLE_METACARPAL_EXT] = FTransform::Identity; + } + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_LITTLE_PROXIMAL_EXT] = Container.SkeletalTransforms[idx++]; + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_LITTLE_INTERMEDIATE_EXT] = Container.SkeletalTransforms[idx++]; + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_LITTLE_DISTAL_EXT] = Container.SkeletalTransforms[idx++]; + Other.SkeletalTransforms[(int32)EXRHandJointType::OXR_HAND_JOINT_LITTLE_TIP_EXT] = FTransform::Identity; + + Other.bHasValidData = true; +} + +bool FBPXRSkeletalRepContainer::NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) +{ + bOutSuccess = true; + + Ar.SerializeBits(&TargetHand, 1); + Ar.SerializeBits(&bAllowDeformingMesh, 1); + Ar.SerializeBits(&bEnableUE4HandRepSavings, 1); + + int32 BoneCountAdjustment = 6 + (bEnableUE4HandRepSavings ? 4 : 0); + uint8 TransformCount = EHandKeypointCount - BoneCountAdjustment; + + bool bHasValidData = SkeletalTransforms.Num() >= TransformCount; + Ar.SerializeBits(&bHasValidData, 1); + + //Ar << TransformCount; + + if (Ar.IsLoading()) + { + SkeletalTransforms.Reset(TransformCount); + } + + FVector Position = FVector::ZeroVector; + FRotator Rot = FRotator::ZeroRotator; + + if (bHasValidData) + { + for (int i = 0; i < TransformCount; i++) + { + if (Ar.IsSaving()) + { + if (bAllowDeformingMesh) + Position = SkeletalTransforms[i].GetLocation(); + + Rot = SkeletalTransforms[i].Rotator(); + } + + if (bAllowDeformingMesh) + bOutSuccess &= SerializePackedVector<10, 11>(Position, Ar); + + Rot.SerializeCompressed(Ar); // Short? 10 bit? + + if (Ar.IsLoading()) + { + if (bAllowDeformingMesh) + SkeletalTransforms.Add(FTransform(Rot, Position)); + else + SkeletalTransforms.Add(FTransform(Rot)); + } + } + } + + return bOutSuccess; +} + +void UOpenXRAnimInstance::NativeBeginPlay() +{ + Super::NativeBeginPlay(); + + AActor* Owner = GetOwningComponent()->GetOwner(); + UActorComponent* HandPoseComp = nullptr; + + if (Owner) + { + HandPoseComp = Owner->GetComponentByClass(UOpenXRHandPoseComponent::StaticClass()); + + if (!HandPoseComp) + { + // We are also checking owner->owner in case hand mesh is in a sub actor + if (Owner->GetOwner()) + { + HandPoseComp = Owner->GetOwner()->GetComponentByClass(UOpenXRHandPoseComponent::StaticClass()); + } + } + } + + if (!HandPoseComp) + { + return; + } + + if (UOpenXRHandPoseComponent* HandComp = Cast(HandPoseComp)) + { + OwningPoseComp = HandComp; + } +} + +/*void UOpenXRAnimInstance::NativeInitializeAnimation() +{ + Super::NativeInitializeAnimation(); + + AActor* Owner = GetOwningComponent()->GetOwner(); + UActorComponent* HandPoseComp = nullptr; + + if (Owner) + { + HandPoseComp = Owner->GetComponentByClass(UOpenXRHandPoseComponent::StaticClass()); + + if (!HandPoseComp) + { + // We are also checking owner->owner in case hand mesh is in a sub actor + if (Owner->GetOwner()) + { + HandPoseComp = Owner->GetOwner()->GetComponentByClass(UOpenXRHandPoseComponent::StaticClass()); + } + } + } + + if (!HandPoseComp) + { + return; + } + + if (UOpenXRHandPoseComponent* HandComp = Cast(HandPoseComp)) + { + OwningPoseComp = HandComp; + } +}*/ + +void UOpenXRAnimInstance::InitializeCustomBoneMapping(UPARAM(ref) FBPOpenXRSkeletalMappingData& SkeletalMappingData) +{ + USkeleton* AssetSkeleton = this->CurrentSkeleton;//RequiredBones.GetSkeletonAsset(); + + if (AssetSkeleton) + { + FBoneContainer& RequiredBones = this->GetRequiredBones(); + for (FBPOpenXRSkeletalPair& BonePair : SkeletalMappingData.BonePairs) + { + // Fill in the bone name for the reference + BonePair.ReferenceToConstruct.BoneName = BonePair.BoneToTarget; + + // Init the reference + BonePair.ReferenceToConstruct.Initialize(AssetSkeleton); + BonePair.ReferenceToConstruct.CachedCompactPoseIndex = BonePair.ReferenceToConstruct.GetCompactPoseIndex(RequiredBones); + + if ((BonePair.ReferenceToConstruct.CachedCompactPoseIndex != INDEX_NONE)) + { + // Get our parent bones index + BonePair.ParentReference = RequiredBones.GetParentBoneIndex(BonePair.ReferenceToConstruct.CachedCompactPoseIndex); + } + } + + if (UObject* OwningAsset = RequiredBones.GetAsset()) + { + SkeletalMappingData.LastInitializedName = OwningAsset->GetFName(); + } + + SkeletalMappingData.bInitialized = true; + return; + } + + SkeletalMappingData.bInitialized = false; +} \ No newline at end of file diff --git a/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Public/AnimNode_ApplyOpenXRHandPose.h b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Public/AnimNode_ApplyOpenXRHandPose.h new file mode 100644 index 0000000..7f35919 --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Public/AnimNode_ApplyOpenXRHandPose.h @@ -0,0 +1,121 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "Runtime/AnimGraphRuntime/Public/BoneControllers/AnimNode_SkeletalControlBase.h" +#include "OpenXRExpansionTypes.h" +//#include "Skeleton/BodyStateSkeleton.h" +//#include "BodyStateAnimInstance.h" + +#include "AnimNode_ApplyOpenXRHandPose.generated.h" + + +USTRUCT() +struct OPENXREXPANSIONPLUGIN_API FAnimNode_ApplyOpenXRHandPose : public FAnimNode_SkeletalControlBase +{ + GENERATED_USTRUCT_BODY() + +public: + + FVector WristForwardLS_UE; + FVector WristSideDirectionLS; + + // Generally used when not passing in custom bone mappings, defines the auto mapping style + UPROPERTY(EditAnywhere, Category = Skeletal, meta = (PinShownByDefault)) + EVROpenXRSkeletonType SkeletonType; + + // If your hand is part of a full body or arm skeleton and you don't have a proxy bone to retain the position enable this + UPROPERTY(EditAnywhere, Category = Skeletal, meta = (PinShownByDefault)) + bool bSkipRootBone; + + // If you only want to use the wrist transform part of this + // This will also automatically add the deform to the wrist as it doesn't make much sense without it + UPROPERTY(EditAnywhere, Category = Skeletal, meta = (PinShownByDefault)) + bool bOnlyApplyWristTransform; + + // Generally used when not passing in custom bone mappings, defines the auto mapping style + UPROPERTY(EditAnywhere, Category = Skeletal, meta = (PinShownByDefault)) + FBPOpenXRActionSkeletalData OptionalStoredActionInfo; + + // MappedBonePairs, if you leave it blank then they will auto generate based off of the SkeletonType + // Otherwise, fill out yourself. + UPROPERTY(EditAnywhere, Category = Skeletal, meta = (PinHiddenByDefault)) + FBPOpenXRSkeletalMappingData MappedBonePairs; + + bool bIsOpenInputAnimationInstance = false; + bool bIsMirroringHand = false; + + void ConvertHandTransformsSpace(TArray& OutTransforms, const TArray& WorldTransforms, FTransform AddTrans, bool bMirrorLeftRight, bool bMergeMissingUE4Bones); + + void CalculateSkeletalAdjustment(USkeleton* AssetSkeleton); + void CalculateOpenXRAdjustment(); + + FQuat CalcRotationAboutAxis(const FVector& FromDirection, const FVector& ToDirection, const FVector& Axis) + { + FVector FromDirectionCp = FVector::CrossProduct(Axis, FromDirection); + FVector ToDirectionCp = FVector::CrossProduct(Axis, ToDirection); + + return FQuat::FindBetweenVectors(FromDirectionCp, ToDirectionCp); + } + + FTransform GetRefBoneInCS(TArray& RefBones, TArray& RefBonesInfo, int32 BoneIndex) + { + FTransform BoneTransform; + + if (BoneIndex >= 0) + { + BoneTransform = RefBones[BoneIndex]; + if (RefBonesInfo[BoneIndex].ParentIndex >= 0) + { + BoneTransform *= GetRefBoneInCS(RefBones, RefBonesInfo, RefBonesInfo[BoneIndex].ParentIndex); + } + } + + return BoneTransform; + } + + void SetVectorToMaxElement(FVector& vec) + { + FVector absVal = vec.GetAbs(); + if (absVal.X > absVal.Y && absVal.X > absVal.Z) + { + vec = vec.GetSignVector() * FVector(1.0f, 0.f, 0.f); + vec.Normalize(); + } + else if (absVal.Y > absVal.X && absVal.Y > absVal.Z) + { + vec = vec.GetSignVector() * FVector(0.0f, 1.f, 0.f); + vec.Normalize(); + } + else if (absVal.Z > absVal.X && absVal.Z > absVal.Y) + { + vec = vec.GetSignVector() * FVector(0.0f, 0.f, 1.f); + vec.Normalize(); + } + else + { + vec.Normalize(); + } + } + + // FAnimNode_SkeletalControlBase interface + //virtual void UpdateInternal(const FAnimationUpdateContext& Context) override; + virtual void EvaluateSkeletalControl_AnyThread(FComponentSpacePoseContext& Output, TArray& OutBoneTransforms) override; + virtual bool IsValidToEvaluate(const USkeleton* Skeleton, const FBoneContainer& RequiredBones) override; + // End of FAnimNode_SkeletalControlBase interface + virtual void OnInitializeAnimInstance(const FAnimInstanceProxy* InProxy, const UAnimInstance* InAnimInstance) override; + virtual bool NeedsOnInitializeAnimInstance() const override { return true; } + virtual void InitializeBoneReferences(const FBoneContainer& RequiredBones) override; + + virtual void Initialize_AnyThread(const FAnimationInitializeContext& Context) override; + virtual void CacheBones_AnyThread(const FAnimationCacheBonesContext& Context) override; + + // Constructor + FAnimNode_ApplyOpenXRHandPose(); + +protected: + bool WorldIsGame; + AActor* OwningActor; + +private: +}; \ No newline at end of file diff --git a/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Public/OpenXRExpansionFunctionLibrary.h b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Public/OpenXRExpansionFunctionLibrary.h new file mode 100644 index 0000000..dbac085 --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Public/OpenXRExpansionFunctionLibrary.h @@ -0,0 +1,102 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "UObject/ObjectMacros.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "UObject/Object.h" +#include "Engine/EngineTypes.h" +#include "HeadMountedDisplayTypes.h" +#if defined(OPENXR_SUPPORTED) +#include "OpenXRCore.h" +#include "OpenXRHMD.h" +#endif +#include "OpenXRExpansionTypes.h" +#include "HeadMountedDisplayFunctionLibrary.h" + +#include "Misc/FileHelper.h" +#include "Misc/Paths.h" + +#include "OpenXRExpansionFunctionLibrary.generated.h" + +#if !defined(OPENXR_SUPPORTED) +class FOpenXRHMD; +#endif + +DECLARE_LOG_CATEGORY_EXTERN(OpenXRExpansionFunctionLibraryLog, Log, All); + +// This needs to be updated as the original gets changed, that or hope they make the original blueprint accessible. +UENUM(Blueprintable) +enum class EBPOpenXRControllerDeviceType : uint8 +{ + DT_SimpleController, + DT_ValveIndexController, + DT_ViveController, + DT_ViveProController, + //DT_CosmosController, + DT_DaydreamController, + DT_OculusTouchController, + DT_OculusGoController, + DT_MicrosoftMotionController, + DT_MicrosoftXboxController, + DT_PicoNeo3Controller, + DT_WMRController, + DT_UnknownController +}; + +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent)) +class OPENXREXPANSIONPLUGIN_API UOpenXRExpansionFunctionLibrary : public UBlueprintFunctionLibrary +{ + //GENERATED_BODY() + GENERATED_BODY() + +public: + UOpenXRExpansionFunctionLibrary(const FObjectInitializer& ObjectInitializer); + + ~UOpenXRExpansionFunctionLibrary(); +public: + + static FOpenXRHMD* GetOpenXRHMD() + { +#if defined(OPENXR_SUPPORTED) + static FName SystemName(TEXT("OpenXR")); + if (GEngine->XRSystem.IsValid() && (GEngine->XRSystem->GetSystemName() == SystemName)) + { + return static_cast(GEngine->XRSystem.Get()); + } +#endif + + return nullptr; + } + + UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|OpenXR", meta = (bIgnoreSelf = "true")) + static bool GetOpenXRHandPose(FBPOpenXRActionSkeletalData& HandPoseContainer, UOpenXRHandPoseComponent* HandPoseComponent, bool bGetMockUpPose = false); + + //UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|OpenXR", meta = (bIgnoreSelf = "true")) + static void GetFingerCurlValues(TArray& TransformArray, TArray& CurlArray); + + // Get the estimated curl values from hand tracking + // Will return true if it was able to get the curls, false if it could not (hand tracking not enabled or no data for the tracked index) + UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|OpenXR", meta = (WorldContext = "WorldContextObject")) + static bool GetOpenXRFingerCurlValuesForHand( + UObject* WorldContextObject, + EControllerHand TargetHand, + float& ThumbCurl, + float& IndexCurl, + float& MiddleCurl, + float& RingCurl, + float& PinkyCurl); + + static float GetCurlValueForBoneRoot(TArray& TransformArray, EHandKeypoint RootBone); + + //UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|OpenXR", meta = (bIgnoreSelf = "true")) + static void ConvertHandTransformsSpaceAndBack(TArray& OutTransforms, const TArray& WorldTransforms); + + UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|OpenXR", meta = (bIgnoreSelf = "true")) + static void GetMockUpControllerData(FXRMotionControllerData& MotionControllerData, FBPOpenXRActionSkeletalData& SkeletalMappingData, bool bOpenHand = false); + + // Get a list of all currently tracked devices and their types, index in the array is their device index + // Returns failed if the openXR query failed (no interaction profile yet or openXR is not running) + UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|OpenXR", meta = (bIgnoreSelf = "true", ExpandEnumAsExecs = "Result")) + static void GetXRMotionControllerType(FString& TrackingSystemName, EBPOpenXRControllerDeviceType& DeviceType, EBPXRResultSwitch &Result); +}; \ No newline at end of file diff --git a/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Public/OpenXRExpansionPlugin.h b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Public/OpenXRExpansionPlugin.h new file mode 100644 index 0000000..23d057c --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Public/OpenXRExpansionPlugin.h @@ -0,0 +1,18 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "Modules/ModuleManager.h" + +class FOpenXRExpansionPluginModule : public IModuleInterface +{ +public: + + FOpenXRExpansionPluginModule() + { + } + + /** IModuleInterface implementation */ + virtual void StartupModule() override; + virtual void ShutdownModule() override; +}; \ No newline at end of file diff --git a/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Public/OpenXRExpansionTypes.h b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Public/OpenXRExpansionTypes.h new file mode 100644 index 0000000..6da369d --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Public/OpenXRExpansionTypes.h @@ -0,0 +1,479 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "UObject/ObjectMacros.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "UObject/Object.h" +#include "Engine/EngineTypes.h" + +#include "OpenXRExpansionTypes.generated.h" + +// This makes a lot of the blueprint functions cleaner +UENUM() +enum class EBPXRResultSwitch : uint8 +{ + // On Success + OnSucceeded, + // On Failure + OnFailed +}; + +UENUM(BlueprintType) +enum class EVRSkeletalHandIndex : uint8 +{ + EActionHandIndex_Left = 0, + EActionHandIndex_Right +}; + +UENUM(BlueprintType) +enum class EXRHandJointType : uint8 +{ + OXR_HAND_JOINT_PALM_EXT = 0, + OXR_HAND_JOINT_WRIST_EXT = 1, + OXR_HAND_JOINT_THUMB_METACARPAL_EXT = 2, + OXR_HAND_JOINT_THUMB_PROXIMAL_EXT = 3, + OXR_HAND_JOINT_THUMB_DISTAL_EXT = 4, + OXR_HAND_JOINT_THUMB_TIP_EXT = 5, + OXR_HAND_JOINT_INDEX_METACARPAL_EXT = 6, + OXR_HAND_JOINT_INDEX_PROXIMAL_EXT = 7, + OXR_HAND_JOINT_INDEX_INTERMEDIATE_EXT = 8, + OXR_HAND_JOINT_INDEX_DISTAL_EXT = 9, + OXR_HAND_JOINT_INDEX_TIP_EXT = 10, + OXR_HAND_JOINT_MIDDLE_METACARPAL_EXT = 11, + OXR_HAND_JOINT_MIDDLE_PROXIMAL_EXT = 12, + OXR_HAND_JOINT_MIDDLE_INTERMEDIATE_EXT = 13, + OXR_HAND_JOINT_MIDDLE_DISTAL_EXT = 14, + OXR_HAND_JOINT_MIDDLE_TIP_EXT = 15, + OXR_HAND_JOINT_RING_METACARPAL_EXT = 16, + OXR_HAND_JOINT_RING_PROXIMAL_EXT = 17, + OXR_HAND_JOINT_RING_INTERMEDIATE_EXT = 18, + OXR_HAND_JOINT_RING_DISTAL_EXT = 19, + OXR_HAND_JOINT_RING_TIP_EXT = 20, + OXR_HAND_JOINT_LITTLE_METACARPAL_EXT = 21, + OXR_HAND_JOINT_LITTLE_PROXIMAL_EXT = 22, + OXR_HAND_JOINT_LITTLE_INTERMEDIATE_EXT = 23, + OXR_HAND_JOINT_LITTLE_DISTAL_EXT = 24, + OXR_HAND_JOINT_LITTLE_TIP_EXT = 25, + OXR_HAND_JOINT_MAX_ENUM_EXT = 0xFF +}; + +UENUM(BlueprintType) +enum class EVROpenXRSkeletonType : uint8 +{ + // UE4 Skeletal Right hand + OXR_SkeletonType_UE4Default_Right, + // UE4 Skeletal Left hand + OXR_SkeletonType_UE4Default_Left, + + // OpenVR Skeletal Right hand + OXR_SkeletonType_OpenVRDefault_Right, + + // OpenVR Skeletal Left hand + OXR_SkeletonType_OpenVRDefault_Left, + + // UE5 Skeletal Right hand + OXR_SkeletonType_UE5Default_Right, + // UE5 Skeletal Left hand + OXR_SkeletonType_UE5Default_Left, + + // OpenXR Skeletal Right hand + OXR_SkeletonType_OpenXRDefault_Right, + // OpenXR Skeletal Left hand + OXR_SkeletonType_OpenXRDefault_Left, + + OXR_SkeletonType_Custom +}; + + + +USTRUCT(BlueprintType, Category = "VRExpansionFunctions|OpenXR|HandSkeleton") +struct OPENXREXPANSIONPLUGIN_API FBPOpenXRActionSkeletalData +{ + GENERATED_BODY() +public: + + UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadWrite, Category = Default) + EVRSkeletalHandIndex TargetHand; + + // A world scale override that will replace the engines current value and force into the tracked data if non zero + UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadWrite, Category = Default) + float WorldScaleOverride; + + UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadWrite, Category = Default) + bool bAllowDeformingMesh; + + // If true then the bones will be mirrored from left/right, to allow you to swap a hand mesh to the other hand + UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadWrite, Category = Default) + bool bMirrorLeftRight; + + // List of aproximated curls for each finger + UPROPERTY(BlueprintReadOnly, NotReplicated, Transient, Category = Default) + TArray FingerCurls; + + UPROPERTY(BlueprintReadOnly, NotReplicated, Transient, Category = Default) + TArray SkeletalTransforms; + + // If true we will assume that the target skeleton does not have the metacarpal bones and we will not replicate them + // Only really used for the old UE4 skeleton + UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadWrite, Category = Default) + bool bEnableUE4HandRepSavings; + + //UPROPERTY(BlueprintReadOnly, NotReplicated, Transient, Category = Default) + //TArray OldSkeletalTransforms; + + // The rotation required to rotate the finger bones back to X+ + // The animation node attempts to auto calculate it, if you have a non standard hand you may need to fill + // This in by yourself + UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadWrite, Category = Default) + FTransform AdditionTransform; + + UPROPERTY(NotReplicated, BlueprintReadOnly, Category = Default) + bool bHasValidData; + + FName LastHandGesture; + int32 LastHandGestureIndex; + + FBPOpenXRActionSkeletalData() + { + //bGetTransformsInParentSpace = false; + AdditionTransform = FTransform::Identity;// FTransform(FRotator(180.f, 0.f, -90.f), FVector::ZeroVector, FVector(1.f));//FTransform(FRotator(0.f, 90.f, 90.f), FVector::ZeroVector, FVector(1.f)); + WorldScaleOverride = 0.0f; + bAllowDeformingMesh = true; + bMirrorLeftRight = false; + bEnableUE4HandRepSavings = false; + TargetHand = EVRSkeletalHandIndex::EActionHandIndex_Right; + bHasValidData = false; + LastHandGestureIndex = INDEX_NONE; + LastHandGesture = NAME_None; + } +}; + +USTRUCT(BlueprintType, Category = "VRExpansionFunctions|SteamVR|HandSkeleton") +struct OPENXREXPANSIONPLUGIN_API FBPOpenXRSkeletalPair +{ + GENERATED_BODY() +public: + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Default") + EXRHandJointType OpenXRBone; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Default") + FName BoneToTarget; + + FBoneReference ReferenceToConstruct; + FCompactPoseBoneIndex ParentReference; + FQuat RetargetRot; + + FBPOpenXRSkeletalPair() : + ParentReference(INDEX_NONE) + { + OpenXRBone = EXRHandJointType::OXR_HAND_JOINT_WRIST_EXT; + BoneToTarget = NAME_None; + RetargetRot = FQuat::Identity; + } + + FBPOpenXRSkeletalPair(EXRHandJointType Bone, FString TargetBone) : + ParentReference(INDEX_NONE) + { + OpenXRBone = Bone; + BoneToTarget = FName(*TargetBone); + ReferenceToConstruct.BoneName = BoneToTarget; + RetargetRot = FQuat::Identity; + } + + FORCEINLINE bool operator==(const int32& Other) const + { + return ReferenceToConstruct.CachedCompactPoseIndex.GetInt() == Other; + //return ReferenceToConstruct.BoneIndex == Other; + } +}; + +USTRUCT(BlueprintType, Category = "VRExpansionFunctions|SteamVR|HandSkeleton") +struct OPENXREXPANSIONPLUGIN_API FBPOpenXRSkeletalMappingData +{ + GENERATED_BODY() +public: + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Default") + TArray BonePairs; + + TArray ReverseBonePairMap; + + // Merge the transforms of bones that are missing from the OpenVR skeleton to the UE4 one. + // This should be always enabled for UE4 skeletons generally. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Default") + bool bMergeMissingBonesUE4; + + // The hand data to get, if not using a custom bone mapping then this value will be auto filled + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Default") + EVRSkeletalHandIndex TargetHand; + + FQuat AdjustmentQuat; + bool bInitialized; + + FName LastInitializedName; + EVROpenXRSkeletonType LastInitializedSkeleton; + + void ClearMapping() + { + bInitialized = false; + LastInitializedName = NAME_None; + AdjustmentQuat = FQuat::Identity; + LastInitializedSkeleton = EVROpenXRSkeletonType::OXR_SkeletonType_Custom; + + BonePairs.Empty(); + ReverseBonePairMap.Empty(); + } + + void ConstructReverseMapping() + { + int32 MaxElements = ((uint8)EXRHandJointType::OXR_HAND_JOINT_LITTLE_TIP_EXT) + 1; + ReverseBonePairMap.Empty(MaxElements); + ReverseBonePairMap.AddUninitialized(MaxElements); + FMemory::Memset(ReverseBonePairMap.GetData(), 0, MaxElements * sizeof(int32)); + + + for (int i = 0; i < BonePairs.Num(); ++i) + { + // Just in case someone messed up the mapping file + if (i < MaxElements) + { + ReverseBonePairMap[(uint8)BonePairs[i].OpenXRBone] = i; + } + } + } + + void ConstructDefaultMappings(EVROpenXRSkeletonType SkeletonType, bool bSkipRootBone) + { + switch (SkeletonType) + { + + case EVROpenXRSkeletonType::OXR_SkeletonType_OpenVRDefault_Left: + case EVROpenXRSkeletonType::OXR_SkeletonType_OpenVRDefault_Right: + { + bMergeMissingBonesUE4 = false; + SetDefaultOpenVRInputs(SkeletonType, bSkipRootBone); + }break; + case EVROpenXRSkeletonType::OXR_SkeletonType_UE4Default_Left: + case EVROpenXRSkeletonType::OXR_SkeletonType_UE4Default_Right: + { + bMergeMissingBonesUE4 = true; + SetDefaultUE4Inputs(SkeletonType, bSkipRootBone); + }break; + case EVROpenXRSkeletonType::OXR_SkeletonType_UE5Default_Left: + case EVROpenXRSkeletonType::OXR_SkeletonType_UE5Default_Right: + { + bMergeMissingBonesUE4 = false; + SetDefaultUE5Inputs(SkeletonType, bSkipRootBone); + }break; + case EVROpenXRSkeletonType::OXR_SkeletonType_OpenXRDefault_Left: + case EVROpenXRSkeletonType::OXR_SkeletonType_OpenXRDefault_Right: + { + bMergeMissingBonesUE4 = false; + SetDefaultOpenXRInputs(SkeletonType, bSkipRootBone); + }break; + } + } + + void SetDefaultOpenVRInputs(EVROpenXRSkeletonType cSkeletonType, bool bSkipRootBone) + { + // Don't map anything if the end user already has + if (BonePairs.Num()) + return; + + bool bIsRightHand = cSkeletonType != EVROpenXRSkeletonType::OXR_SkeletonType_OpenVRDefault_Left; + FString HandDelimiterS = !bIsRightHand ? "l" : "r"; + const TCHAR* HandDelimiter = *HandDelimiterS; + + TargetHand = bIsRightHand ? EVRSkeletalHandIndex::EActionHandIndex_Right : EVRSkeletalHandIndex::EActionHandIndex_Left; + + // Default OpenVR bones mapping + //if (!bSkipRootBone) + //{ + //BonePairs.Add(FBPOpenVRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_PALM_EXT, FString::Printf(TEXT("Root"), HandDelimiter))); + //} + + //if (!bSkipRootBone) + { + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_WRIST_EXT, FString::Printf(TEXT("wrist_%s"), HandDelimiter))); + } + + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_THUMB_METACARPAL_EXT, FString::Printf(TEXT("finger_thumb_0_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_THUMB_PROXIMAL_EXT, FString::Printf(TEXT("finger_thumb_1_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_THUMB_DISTAL_EXT, FString::Printf(TEXT("finger_thumb_2_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_THUMB_TIP_EXT, FString::Printf(TEXT("finger_thumb_%s_end"), HandDelimiter))); + + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_INDEX_METACARPAL_EXT, FString::Printf(TEXT("finger_index_meta_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_INDEX_PROXIMAL_EXT, FString::Printf(TEXT("finger_index_0_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_INDEX_INTERMEDIATE_EXT, FString::Printf(TEXT("finger_index_1_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_INDEX_DISTAL_EXT, FString::Printf(TEXT("finger_index_2_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_INDEX_TIP_EXT, FString::Printf(TEXT("finger_index_%s_end"), HandDelimiter))); + + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_MIDDLE_METACARPAL_EXT, FString::Printf(TEXT("finger_middle_meta_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_MIDDLE_PROXIMAL_EXT, FString::Printf(TEXT("finger_middle_0_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_MIDDLE_INTERMEDIATE_EXT, FString::Printf(TEXT("finger_middle_1_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_MIDDLE_DISTAL_EXT, FString::Printf(TEXT("finger_middle_2_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_MIDDLE_TIP_EXT, FString::Printf(TEXT("finger_middle_%s_end"), HandDelimiter))); + + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_RING_METACARPAL_EXT, FString::Printf(TEXT("finger_ring_meta_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_RING_PROXIMAL_EXT, FString::Printf(TEXT("finger_ring_0_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_RING_INTERMEDIATE_EXT, FString::Printf(TEXT("finger_ring_1_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_RING_DISTAL_EXT, FString::Printf(TEXT("finger_ring_2_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_RING_TIP_EXT, FString::Printf(TEXT("finger_ring_%s_end"), HandDelimiter))); + + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_LITTLE_METACARPAL_EXT, FString::Printf(TEXT("finger_pinky_meta_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_LITTLE_PROXIMAL_EXT, FString::Printf(TEXT("finger_pinky_0_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_LITTLE_INTERMEDIATE_EXT, FString::Printf(TEXT("finger_pinky_1_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_LITTLE_DISTAL_EXT, FString::Printf(TEXT("finger_pinky_2_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_LITTLE_TIP_EXT, FString::Printf(TEXT("finger_pinky_%s_end"), HandDelimiter))); + + // Aux bones share the final knuckles location / rotation + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_THUMB_DISTAL_EXT, FString::Printf(TEXT("finger_thumb_%s_aux"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_INDEX_DISTAL_EXT, FString::Printf(TEXT("finger_index_%s_aux"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_MIDDLE_DISTAL_EXT, FString::Printf(TEXT("finger_middle_%s_aux"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_RING_DISTAL_EXT, FString::Printf(TEXT("finger_ring_%s_aux"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_LITTLE_DISTAL_EXT, FString::Printf(TEXT("finger_pinky_%s_aux"), HandDelimiter))); + } + + void SetDefaultUE4Inputs(EVROpenXRSkeletonType cSkeletonType, bool bSkipRootBone) + { + // Don't map anything if the end user already has + if (BonePairs.Num()) + return; + + bool bIsRightHand = cSkeletonType != EVROpenXRSkeletonType::OXR_SkeletonType_UE4Default_Left; + FString HandDelimiterS = !bIsRightHand ? "l" : "r"; + const TCHAR* HandDelimiter = *HandDelimiterS; + + TargetHand = bIsRightHand ? EVRSkeletalHandIndex::EActionHandIndex_Right : EVRSkeletalHandIndex::EActionHandIndex_Left; + + // Default ue4 skeleton hand to the OpenVR bones, skipping the extra joint and the aux joints + //if (!bSkipRootBone) + { + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_WRIST_EXT, FString::Printf(TEXT("hand_%s"), HandDelimiter))); + } + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_INDEX_PROXIMAL_EXT, FString::Printf(TEXT("index_01_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_INDEX_INTERMEDIATE_EXT, FString::Printf(TEXT("index_02_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_INDEX_DISTAL_EXT, FString::Printf(TEXT("index_03_%s"), HandDelimiter))); + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_MIDDLE_PROXIMAL_EXT, FString::Printf(TEXT("middle_01_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_MIDDLE_INTERMEDIATE_EXT, FString::Printf(TEXT("middle_02_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_MIDDLE_DISTAL_EXT, FString::Printf(TEXT("middle_03_%s"), HandDelimiter))); + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_LITTLE_PROXIMAL_EXT, FString::Printf(TEXT("pinky_01_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_LITTLE_INTERMEDIATE_EXT, FString::Printf(TEXT("pinky_02_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_LITTLE_DISTAL_EXT, FString::Printf(TEXT("pinky_03_%s"), HandDelimiter))); + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_RING_PROXIMAL_EXT, FString::Printf(TEXT("ring_01_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_RING_INTERMEDIATE_EXT, FString::Printf(TEXT("ring_02_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_RING_DISTAL_EXT, FString::Printf(TEXT("ring_03_%s"), HandDelimiter))); + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_THUMB_METACARPAL_EXT, FString::Printf(TEXT("thumb_01_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_THUMB_PROXIMAL_EXT, FString::Printf(TEXT("thumb_02_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_THUMB_DISTAL_EXT, FString::Printf(TEXT("thumb_03_%s"), HandDelimiter))); + + } + + void SetDefaultUE5Inputs(EVROpenXRSkeletonType cSkeletonType, bool bSkipRootBone) + { + // Don't map anything if the end user already has + if (BonePairs.Num()) + return; + + bool bIsRightHand = cSkeletonType != EVROpenXRSkeletonType::OXR_SkeletonType_UE5Default_Left; + FString HandDelimiterS = !bIsRightHand ? "l" : "r"; + const TCHAR* HandDelimiter = *HandDelimiterS; + + TargetHand = bIsRightHand ? EVRSkeletalHandIndex::EActionHandIndex_Right : EVRSkeletalHandIndex::EActionHandIndex_Left; + + // Default ue5 skeleton hand to the OpenVR bones, skipping the extra joint and the aux joints + //if (!bSkipRootBone) + { + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_WRIST_EXT, FString::Printf(TEXT("hand_%s"), HandDelimiter))); + } + + // There are inner and outer wrist elements to this, going to be anoying to map that to a single wrist index.... + //OXR_HAND_JOINT_WRIST_EXT = 1, + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_INDEX_PROXIMAL_EXT, FString::Printf(TEXT("index_01_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_INDEX_INTERMEDIATE_EXT, FString::Printf(TEXT("index_02_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_INDEX_DISTAL_EXT, FString::Printf(TEXT("index_03_%s"), HandDelimiter))); + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_MIDDLE_PROXIMAL_EXT, FString::Printf(TEXT("middle_01_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_MIDDLE_INTERMEDIATE_EXT, FString::Printf(TEXT("middle_02_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_MIDDLE_DISTAL_EXT, FString::Printf(TEXT("middle_03_%s"), HandDelimiter))); + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_LITTLE_PROXIMAL_EXT, FString::Printf(TEXT("pinky_01_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_LITTLE_INTERMEDIATE_EXT, FString::Printf(TEXT("pinky_02_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_LITTLE_DISTAL_EXT, FString::Printf(TEXT("pinky_03_%s"), HandDelimiter))); + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_RING_PROXIMAL_EXT, FString::Printf(TEXT("ring_01_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_RING_INTERMEDIATE_EXT, FString::Printf(TEXT("ring_02_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_RING_DISTAL_EXT, FString::Printf(TEXT("ring_03_%s"), HandDelimiter))); + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_THUMB_METACARPAL_EXT, FString::Printf(TEXT("thumb_01_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_THUMB_PROXIMAL_EXT, FString::Printf(TEXT("thumb_02_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_THUMB_DISTAL_EXT, FString::Printf(TEXT("thumb_03_%s"), HandDelimiter))); + + } + + void SetDefaultOpenXRInputs(EVROpenXRSkeletonType cSkeletonType, bool bSkipRootBone) + { + // Don't map anything if the end user already has + if (BonePairs.Num()) + return; + + bool bIsRightHand = cSkeletonType != EVROpenXRSkeletonType::OXR_SkeletonType_OpenXRDefault_Left; + FString HandDelimiterS = !bIsRightHand ? "l" : "r"; + const TCHAR* HandDelimiter = *HandDelimiterS; + + TargetHand = bIsRightHand ? EVRSkeletalHandIndex::EActionHandIndex_Right : EVRSkeletalHandIndex::EActionHandIndex_Left; + + // Default ue5 skeleton hand to the OpenVR bones, skipping the extra joint and the aux joints + //if (!bSkipRootBone) + { + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_WRIST_EXT, FString::Printf(TEXT("hand_%s"), HandDelimiter))); + } + + // There are inner and outer wrist elements to this, going to be anoyying to map that to a single wrist index.... + //OXR_HAND_JOINT_WRIST_EXT = 1, + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_INDEX_PROXIMAL_EXT, FString::Printf(TEXT("index_01_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_INDEX_INTERMEDIATE_EXT, FString::Printf(TEXT("index_02_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_INDEX_DISTAL_EXT, FString::Printf(TEXT("index_03_%s"), HandDelimiter))); + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_MIDDLE_PROXIMAL_EXT, FString::Printf(TEXT("middle_01_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_MIDDLE_INTERMEDIATE_EXT, FString::Printf(TEXT("middle_02_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_MIDDLE_DISTAL_EXT, FString::Printf(TEXT("middle_03_%s"), HandDelimiter))); + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_LITTLE_PROXIMAL_EXT, FString::Printf(TEXT("pinky_01_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_LITTLE_INTERMEDIATE_EXT, FString::Printf(TEXT("pinky_02_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_LITTLE_DISTAL_EXT, FString::Printf(TEXT("pinky_03_%s"), HandDelimiter))); + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_RING_PROXIMAL_EXT, FString::Printf(TEXT("ring_01_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_RING_INTERMEDIATE_EXT, FString::Printf(TEXT("ring_02_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_RING_DISTAL_EXT, FString::Printf(TEXT("ring_03_%s"), HandDelimiter))); + + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_THUMB_METACARPAL_EXT, FString::Printf(TEXT("thumb_01_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_THUMB_PROXIMAL_EXT, FString::Printf(TEXT("thumb_02_%s"), HandDelimiter))); + BonePairs.Add(FBPOpenXRSkeletalPair(EXRHandJointType::OXR_HAND_JOINT_THUMB_DISTAL_EXT, FString::Printf(TEXT("thumb_03_%s"), HandDelimiter))); + + } + + FBPOpenXRSkeletalMappingData() + { + AdjustmentQuat = FQuat::Identity; + bInitialized = false; + bMergeMissingBonesUE4 = false; + TargetHand = EVRSkeletalHandIndex::EActionHandIndex_Right; + LastInitializedName = NAME_None; + LastInitializedSkeleton = EVROpenXRSkeletonType::OXR_SkeletonType_Custom; + } +}; diff --git a/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Public/OpenXRHandPoseComponent.h b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Public/OpenXRHandPoseComponent.h new file mode 100644 index 0000000..b27ff0f --- /dev/null +++ b/Plugins/OpenXRExpansionPlugin/Source/OpenXRExpansionPlugin/Public/OpenXRHandPoseComponent.h @@ -0,0 +1,377 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "UObject/Object.h" +#include "Engine/Texture.h" +#include "Engine/EngineTypes.h" +#include "HeadMountedDisplayTypes.h" +//#include "Runtime/Launch/Resources/Version.h" + +#include "Animation/AnimInstanceProxy.h" +#include "OpenXRExpansionTypes.h" +#include "Engine/DataAsset.h" + +#include "OpenXRHandPoseComponent.generated.h" + +USTRUCT(BlueprintType, Category = "VRExpansionFunctions|OpenXR|HandSkeleton") +struct OPENXREXPANSIONPLUGIN_API FBPXRSkeletalRepContainer +{ + GENERATED_BODY() +public: + + UPROPERTY(Transient, NotReplicated) + EVRSkeletalHandIndex TargetHand; + + UPROPERTY(Transient, NotReplicated) + bool bAllowDeformingMesh; + + // If true we will skip sending the 4 metacarpal bones that ue4 doesn't need, (STEAMVR skeletons need this disabled!) + // Only really used for the older UE4 skeleton + UPROPERTY(Transient, NotReplicated) + bool bEnableUE4HandRepSavings; + + UPROPERTY(Transient, NotReplicated) + TArray SkeletalTransforms; + + UPROPERTY(Transient, NotReplicated) + uint8 BoneCount; + + + FBPXRSkeletalRepContainer() + { + TargetHand = EVRSkeletalHandIndex::EActionHandIndex_Left; + bAllowDeformingMesh = false; + bEnableUE4HandRepSavings = false; + BoneCount = 0; + } + + bool bHasValidData() + { + return SkeletalTransforms.Num() > 0; + } + + void CopyForReplication(FBPOpenXRActionSkeletalData& Other); + static void CopyReplicatedTo(const FBPXRSkeletalRepContainer& Container, FBPOpenXRActionSkeletalData& Other); + + bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess); +}; + +template<> +struct TStructOpsTypeTraits< FBPXRSkeletalRepContainer > : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithNetSerializer = true + }; +}; + +USTRUCT(BlueprintType, Category = "VRGestures") +struct OPENXREXPANSIONPLUGIN_API FOpenXRGestureFingerPosition +{ + GENERATED_BODY() +public: + + // The Finger index, not editable + UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "VRGesture") + EXRHandJointType IndexType; + + // The locational value of this element 0.f - 1.f + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGesture") + FVector Value; + + // The threshold within which this finger value will be detected as matching (1.0 would be always matching, IE: finger doesn't count) + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGesture", meta = (ClampMin = "0.0", ClampMax = "100.0", UIMin = "0.0", UIMax = "100.0")) + float Threshold; + + FOpenXRGestureFingerPosition(FVector TipLoc, EXRHandJointType Type) + { + IndexType = Type; + Value = TipLoc; + Threshold = 5.0f; + } + FOpenXRGestureFingerPosition() + { + IndexType = EXRHandJointType::OXR_HAND_JOINT_INDEX_TIP_EXT; + Value = FVector(0.f); + Threshold = 5.0f; + } +}; + +USTRUCT(BlueprintType, Category = "VRGestures") +struct OPENXREXPANSIONPLUGIN_API FOpenXRGesture +{ + GENERATED_BODY() +public: + + // Name of the recorded gesture + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGesture") + FName Name; + + // Samples in the recorded gesture + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGesture") + TArray FingerValues; + + FOpenXRGesture() + { + InitPoseValues(); + Name = NAME_None; + } + + void InitPoseValues() + { + FingerValues.Add(FOpenXRGestureFingerPosition(FVector::ZeroVector, EXRHandJointType::OXR_HAND_JOINT_THUMB_TIP_EXT)); + FingerValues.Add(FOpenXRGestureFingerPosition(FVector::ZeroVector, EXRHandJointType::OXR_HAND_JOINT_INDEX_TIP_EXT)); + FingerValues.Add(FOpenXRGestureFingerPosition(FVector::ZeroVector, EXRHandJointType::OXR_HAND_JOINT_MIDDLE_TIP_EXT)); + FingerValues.Add(FOpenXRGestureFingerPosition(FVector::ZeroVector, EXRHandJointType::OXR_HAND_JOINT_RING_TIP_EXT)); + FingerValues.Add(FOpenXRGestureFingerPosition(FVector::ZeroVector, EXRHandJointType::OXR_HAND_JOINT_LITTLE_TIP_EXT)); + } +}; + +/** +* Items Database DataAsset, here we can save all of our game items +*/ +UCLASS(BlueprintType, Category = "VRGestures") +class OPENXREXPANSIONPLUGIN_API UOpenXRGestureDatabase : public UDataAsset +{ + GENERATED_BODY() +public: + + // Gestures in this database + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures") + TArray Gestures; + + UOpenXRGestureDatabase() + { + } +}; + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOpenXRGestureDetected, const FName &, GestureDetected, int32, GestureIndex, EVRSkeletalHandIndex, ActionHandType); +DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOpenXRGestureEnded, const FName &, GestureEnded, int32, GestureIndex, EVRSkeletalHandIndex, ActionHandType); + +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent)) +class OPENXREXPANSIONPLUGIN_API UOpenXRHandPoseComponent : public UActorComponent +{ + GENERATED_BODY() + +public: + UOpenXRHandPoseComponent(const FObjectInitializer& ObjectInitializer); + + // Says whether we should run gesture detection + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures") + bool bDetectGestures; + + UFUNCTION(BlueprintCallable, Category = "VRGestures") + void SetDetectGestures(bool bNewDetectGestures) + { + bDetectGestures = bNewDetectGestures; + } + + UPROPERTY(BlueprintAssignable, Category = "VRGestures") + FOpenXRGestureDetected OnNewGestureDetected; + + UPROPERTY(BlueprintAssignable, Category = "VRGestures") + FOpenXRGestureEnded OnGestureEnded; + + // Known sequences + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures") + UOpenXRGestureDatabase *GesturesDB; + + UFUNCTION(BlueprintCallable, Category = "VRGestures") + bool SaveCurrentPose(FName RecordingName, EVRSkeletalHandIndex HandToSave = EVRSkeletalHandIndex::EActionHandIndex_Right); + + UFUNCTION(BlueprintCallable, Category = "VRGestures", meta = (DisplayName = "DetectCurrentPose")) + bool K2_DetectCurrentPose(UPARAM(ref) FBPOpenXRActionSkeletalData& SkeletalAction, FOpenXRGesture & GestureOut); + + // This version throws events + bool DetectCurrentPose(FBPOpenXRActionSkeletalData& SkeletalAction); + + // Need this as I can't think of another way for an actor component to make sure it isn't on the server + inline bool IsLocallyControlled() const + { +#if ENGINE_MAJOR_VERSION > 4 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 22) + const AActor* MyOwner = GetOwner(); + return MyOwner->HasLocalNetOwner(); +#else + // I like epics new authority check more than mine + const AActor* MyOwner = GetOwner(); + const APawn* MyPawn = Cast(MyOwner); + + return MyPawn ? MyPawn->IsLocallyControlled() : (MyOwner && MyOwner->GetLocalRole() == ENetRole::ROLE_Authority); +#endif + } + + // Using tick and not timers because skeletal components tick anyway, kind of a waste to make another tick by adding a timer over that + void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; + + + //virtual void OnUnregister() override; + virtual void BeginPlay() override; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SkeletalData|Actions") + bool bGetMockUpPoseForDebugging; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SkeletalData|Actions") + TArray HandSkeletalActions; + + UPROPERTY(Replicated, Transient, ReplicatedUsing = OnRep_SkeletalTransformLeft) + FBPXRSkeletalRepContainer LeftHandRep; + + UPROPERTY(Replicated, Transient, ReplicatedUsing = OnRep_SkeletalTransformRight) + FBPXRSkeletalRepContainer RightHandRep; + + UFUNCTION(Unreliable, Server, WithValidation) + void Server_SendSkeletalTransforms(const FBPXRSkeletalRepContainer& SkeletalInfo); + + bool bLerpingPositionLeft; + bool bLerpingPositionRight; + + struct FTransformLerpManager + { + bool bReplicatedOnce; + bool bLerping; + float UpdateCount; + float UpdateRate; + TArray OldTransforms; + TArray NewTransforms; + + FTransformLerpManager(); + void PreCopyNewData(FBPOpenXRActionSkeletalData& ActionInfo, int NetUpdateRate, bool bExponentialSmoothing); + void NotifyNewData(FBPOpenXRActionSkeletalData& ActionInfo, int NetUpdateRate, bool bExponentialSmoothing); + + FORCEINLINE void BlendBone(uint8 BoneToBlend, FBPOpenXRActionSkeletalData& ActionInfo, float& LerpVal, bool bExponentialSmoothing) + { + ActionInfo.SkeletalTransforms[BoneToBlend].Blend(OldTransforms[BoneToBlend], NewTransforms[BoneToBlend], LerpVal); + + if (bExponentialSmoothing) + { + // Saving base back out for exponential + OldTransforms[BoneToBlend] = ActionInfo.SkeletalTransforms[BoneToBlend]; + } + } + + void UpdateManager(float DeltaTime, FBPOpenXRActionSkeletalData& ActionInfo, UOpenXRHandPoseComponent * ParentComp); + + }; + + FTransformLerpManager LeftHandRepManager; + FTransformLerpManager RightHandRepManager; + + UFUNCTION() + virtual void OnRep_SkeletalTransformLeft() + { + for (int i = 0; i < HandSkeletalActions.Num(); i++) + { + if (HandSkeletalActions[i].TargetHand == LeftHandRep.TargetHand) + { + if (bSmoothReplicatedSkeletalData) + { + LeftHandRepManager.PreCopyNewData(HandSkeletalActions[i], ReplicationRateForSkeletalAnimations, bUseExponentialSmoothing); + } + + FBPXRSkeletalRepContainer::CopyReplicatedTo(LeftHandRep, HandSkeletalActions[i]); + + if (bSmoothReplicatedSkeletalData) + { + LeftHandRepManager.NotifyNewData(HandSkeletalActions[i], ReplicationRateForSkeletalAnimations, bUseExponentialSmoothing); + } + + break; + } + } + } + + UFUNCTION() + virtual void OnRep_SkeletalTransformRight() + { + for (int i = 0; i < HandSkeletalActions.Num(); i++) + { + if (HandSkeletalActions[i].TargetHand == RightHandRep.TargetHand) + { + if (bSmoothReplicatedSkeletalData) + { + RightHandRepManager.PreCopyNewData(HandSkeletalActions[i], ReplicationRateForSkeletalAnimations, bUseExponentialSmoothing); + } + + FBPXRSkeletalRepContainer::CopyReplicatedTo(RightHandRep, HandSkeletalActions[i]); + + if (bSmoothReplicatedSkeletalData) + { + RightHandRepManager.NotifyNewData(HandSkeletalActions[i], ReplicationRateForSkeletalAnimations, bUseExponentialSmoothing); + } + break; + } + } + } + + // If we should replicate the skeletal transform data + UPROPERTY(EditAnywhere, Category = SkeletalData) + bool bReplicateSkeletalData; + + // If true we will lerp between updates of the skeletal mesh transforms and smooth the result + UPROPERTY(EditAnywhere, Category = SkeletalData) + bool bSmoothReplicatedSkeletalData; + + // If true then we will use exponential smoothing with buffered correction + UPROPERTY(EditAnywhere, Category = "SkeletalData", meta = (editcondition = "bSmoothReplicatedSkeletalData")) + bool bUseExponentialSmoothing = false; + + // Timestep of smoothing translation + UPROPERTY(EditAnywhere, Category = "SkeletalData", meta = (editcondition = "bUseExponentialSmoothing")) + float InterpolationSpeed = 25.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = SkeletalData) + float ReplicationRateForSkeletalAnimations; + + // Used in Tick() to accumulate before sending updates, didn't want to use a timer in this case, also used for remotes to lerp position + float SkeletalNetUpdateCount; + // Used in Tick() to accumulate before sending updates, didn't want to use a timer in this case, also used for remotes to lerp position + float SkeletalUpdateCount; +}; + +USTRUCT() +struct OPENXREXPANSIONPLUGIN_API FOpenXRAnimInstanceProxy : public FAnimInstanceProxy +{ +public: + GENERATED_BODY() + + FOpenXRAnimInstanceProxy() {} + FOpenXRAnimInstanceProxy(UAnimInstance* InAnimInstance); + + /** Called before update so we can copy any data we need */ + virtual void PreUpdate(UAnimInstance* InAnimInstance, float DeltaSeconds) override; + +public: + + EVRSkeletalHandIndex TargetHand; + TArray HandSkeletalActionData; + +}; + +UCLASS(transient, Blueprintable, hideCategories = AnimInstance, BlueprintType) +class OPENXREXPANSIONPLUGIN_API UOpenXRAnimInstance : public UAnimInstance +{ + GENERATED_BODY() + +public: + + UPROPERTY(transient) + UOpenXRHandPoseComponent * OwningPoseComp; + + FOpenXRAnimInstanceProxy AnimInstanceProxy; + + virtual FAnimInstanceProxy* CreateAnimInstanceProxy() override + { + return new FOpenXRAnimInstanceProxy(this); + //return &AnimInstanceProxy; + } + + virtual void NativeBeginPlay() override; + + //virtual void NativeInitializeAnimation() override; + + UFUNCTION(BlueprintCallable, Category = "BoneMappings") + void InitializeCustomBoneMapping(UPARAM(ref) FBPOpenXRSkeletalMappingData & SkeletalMappingData); + + +}; diff --git a/Plugins/SenseGlove/.clang-format b/Plugins/SenseGlove/.clang-format new file mode 100644 index 0000000..071b93f --- /dev/null +++ b/Plugins/SenseGlove/.clang-format @@ -0,0 +1,64 @@ +--- +Language: Cpp +BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignOperands: false +AlignTrailingComments: false +AlwaysBreakTemplateDeclarations: Yes +BraceWrapping: + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: false + BeforeCatch: true + BeforeElse: true + BeforeLambdaBody: true + BeforeWhile: true + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBraces: Custom +BreakConstructorInitializers: BeforeColon +ColumnLimit: 120 +IncludeCategories: + - Regex: '^<.*' + Priority: 1 + - Regex: '^".*' + Priority: 2 + - Regex: '.*' + Priority: 3 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IndentCaseBlocks: true +IndentWidth: 4 +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: All +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PointerAlignment: Left +ReflowComments: false +SpaceAfterCStyleCast: true +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 0 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +TabWidth: 4 +UseTab: Never +... diff --git a/Plugins/SenseGlove/.editorconfig b/Plugins/SenseGlove/.editorconfig new file mode 100644 index 0000000..e18ea6e --- /dev/null +++ b/Plugins/SenseGlove/.editorconfig @@ -0,0 +1,59 @@ +################################################################################ +# Generic Settings +################################################################################ + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 +insert_final_newline = false +max_line_length = 120 +tab_width = 4 +trim_trailing_whitespace = true +ij_continuation_indent_size = 8 +ij_formatter_off_tag = @formatter:off +ij_formatter_on_tag = @formatter:on +ij_formatter_tags_enabled = false +ij_smart_tabs = false +ij_visual_guides = none +ij_wrap_on_typing = false + +################################################################################ +# Markdown +################################################################################ + +[*.{.markdown,md,mdx}] +trim_trailing_whitespace = false +ij_markdown_force_one_space_after_blockquote_symbol = true +ij_markdown_force_one_space_after_header_symbol = true +ij_markdown_force_one_space_after_list_bullet = true +ij_markdown_force_one_space_between_words = true +ij_markdown_insert_quote_arrows_on_wrap = true +ij_markdown_keep_indents_on_empty_lines = false +ij_markdown_keep_line_breaks_inside_text_blocks = true +ij_markdown_max_lines_around_block_elements = 1 +ij_markdown_max_lines_around_header = 1 +ij_markdown_max_lines_between_paragraphs = 1 +ij_markdown_min_lines_around_block_elements = 1 +ij_markdown_min_lines_around_header = 1 +ij_markdown_min_lines_between_paragraphs = 1 +ij_markdown_wrap_text_if_long = true +ij_markdown_wrap_text_inside_blockquotes = true + +################################################################################ +# MSBuild +################################################################################ + +[*.{csproj,proj,projitems,shproj,fsproj,target,props}] +indent_style = space +indent_size = 2 + +################################################################################ +# Unreal Engine Project Files +################################################################################ + +[*.uproject] +indent_style = tab diff --git a/Plugins/SenseGlove/.gitattributes b/Plugins/SenseGlove/.gitattributes new file mode 100644 index 0000000..d2a0afb --- /dev/null +++ b/Plugins/SenseGlove/.gitattributes @@ -0,0 +1,50 @@ +# Keep CRLF out of the repository +* text=auto + +# In case the git binary/text auto-detection algorithm fails, in order to avoid +# line-ending normalization, treat these files as binary no matter what +*.{uasset,umap,3ds,fbx,flac,gif,jif,jiff,jpe,jpeg,jpg,m4a,mp3,mp4,ogg,png,psd,ttf,wav,webp,xcf} binary + +# LFS: UE4 file types +*.uasset filter=lfs diff=lfs merge=lfs -text +*.umap filter=lfs diff=lfs merge=lfs -text + +# LFS: raw content types +*.3ds filter=lfs diff=lfs merge=lfs -text +*.fbx filter=lfs diff=lfs merge=lfs -text +*.flac filter=lfs diff=lfs merge=lfs -text +*.gif filter=lfs diff=lfs merge=lfs -text +*.jif filter=lfs diff=lfs merge=lfs -text +*.jiff filter=lfs diff=lfs merge=lfs -text +*.jpe filter=lfs diff=lfs merge=lfs -text +*.jpeg filter=lfs diff=lfs merge=lfs -text +*.jpg filter=lfs diff=lfs merge=lfs -text +*.m4a filter=lfs diff=lfs merge=lfs -text +*.mp3 filter=lfs diff=lfs merge=lfs -text +*.mp4 filter=lfs diff=lfs merge=lfs -text +*.ogg filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.psd filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.wav filter=lfs diff=lfs merge=lfs -text +*.webp filter=lfs diff=lfs merge=lfs -text +*.xcf filter=lfs diff=lfs merge=lfs -text + +# LFS: everything under Content/ +Content/**/* filter=lfs diff=lfs merge=lfs -text + +# LFS: everything under Resources/ +Resources/**/* filter=lfs diff=lfs merge=lfs -text + +# LFS: everything under Source/ThirdParty/ +Source/ThirdParty/**/* filter=lfs diff=lfs merge=lfs -text + +# LFS: everything under Handbook/dist/ +Handbook/dist/**/* filter=lfs diff=lfs merge=lfs -text +# Except +.gitignore filter= diff= merge= text +.gitattributes filter= diff= merge= text + +# LFS: sgum-packager Linux and Windows binaries +Packager/sgum-packager filter=lfs diff=lfs merge=lfs -text +Packager/sgum-packager.exe filter=lfs diff=lfs merge=lfs -text \ No newline at end of file diff --git a/Plugins/SenseGlove/.gitignore b/Plugins/SenseGlove/.gitignore new file mode 100644 index 0000000..e7ba676 --- /dev/null +++ b/Plugins/SenseGlove/.gitignore @@ -0,0 +1,135 @@ +# Explcitly ignore annoying Windows files, regardless of where they are +[Dd]esktop.ini +Thumbs.db + +# Explcitly ignore annoying macOS files, regardless of where they are +.DS_Store + +# Makefile; only in the project root +/Makefile + +# CMake; only in the project root +/CMakeLists.txt + +# QMake / Qt Creator +*.pro +*Config.pri +*Defines.pri +*Header.pri +*Includes.pri +*Source.pri +.qmake.stash +*.autosave +*.pro.user +*.pro.user.* +CMakeLists.txt.user +CMakeLists.txt.user.* + +# Visual Studio +.vs/ +*.sln +*.suo +*.opensdf +*.sdf +*.VC.db +*.VC.opendb + +# Visual Studio Code +.vscode/ +*.code-workspace + +# Code::Blocks +*.workspace + +# CodeLite +*CodeLitePreProcessor.txt + +# KDevelop +.kdev4/ +*.kdev4 + +# CLion +*CodeCompletionFolders.txt + +# IntelliJ IDE +.idea/ + +# Xcode +*.xcodeproj +*.xcworkspace + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app +*.ipa + +# Precompiled Assets +SourceArt/**/*.png +SourceArt/**/*.tga + +# Binary Files +Binaries/* +Plugins/*/Binaries/* + +# Builds +Build/* + +# Whitelist PakBlacklist-.txt files +!Build/*/ +Build/*/** +!Build/*/PakBlacklist*.txt + +# Don't ignore icon files in Build +!Build/**/*.ico + +# Built data for maps +*_BuiltData.uasset + +# Configuration files generated by the Editor +Saved/* + +# Compiled source files for the engine to use +Intermediate/* +Plugins/*/Intermediate/* + +# Cache files for the editor to use +DerivedDataCache/* + +# Misc +.ignore + +# Do not ignore anything inside the ThirdParty directory at all +!Source/ThirdParty/**/* + +# The Handbook +Documentation/ +Handbook/book/ + +# sgum-packager +# Do not ignore the sgum-packager Windows binary +!Packager/sgum-packager.exe \ No newline at end of file diff --git a/Plugins/SenseGlove/Config/FilterPlugin.ini b/Plugins/SenseGlove/Config/FilterPlugin.ini new file mode 100644 index 0000000..b45ca7a --- /dev/null +++ b/Plugins/SenseGlove/Config/FilterPlugin.ini @@ -0,0 +1,5 @@ +[FilterPlugin] +/Config/FilterPlugin.ini +/Documentation/the-senseglove-unreal-engine-handbook.epub +/Documentation/the-senseglove-unreal-engine-handbook.pdf +/Documentation/the-senseglove-unreal-engine-handbook.zip diff --git a/Plugins/SenseGlove/Content/Materials/M_SenseGlove_VirtualHand.uasset b/Plugins/SenseGlove/Content/Materials/M_SenseGlove_VirtualHand.uasset new file mode 100644 index 0000000..960a80c --- /dev/null +++ b/Plugins/SenseGlove/Content/Materials/M_SenseGlove_VirtualHand.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ffc5ec37eff81f3298922c7cc4807144181289129485e3e7bbd0cd10b1186c52 +size 9219 diff --git a/Plugins/SenseGlove/README.md b/Plugins/SenseGlove/README.md new file mode 100644 index 0000000..4c869d3 --- /dev/null +++ b/Plugins/SenseGlove/README.md @@ -0,0 +1,47 @@ +# The SenseGlove Unreal Engine Plugin + +## Getting Started + +### Documentation + +For the official documentation please visit [the SenseGlove Unreal Engine Handbook](https://unreal.docs.senseglove.com/). + +### Extra Resources + +For examples, demo scenes, tutorials, and extra resources please check out [the Extra Resources section](Handbook/src/appendix/extra-resources.md) of [the SenseGlove Unreal Engine Handbook](Handbook/). + +### How to Download and Install + +Various instructions on [how to download and install the SenseGlove Unreal Engine Plugin](Handbook/src/getting-started/installation/README.md) are available. It could either be installed through [the Epic Games Launcher](Handbook/src/getting-started/installation/epic-games-launcher.md), or [through Microsoft Azure DevOps repositories](Handbook/src/getting-started/installation/microsoft-azure-devops-repositories.md). + +For more information, visit [the SenseGlove Unreal Engine Plugin on Fab](https://www.fab.com/listings/62bcdd2a-0bb1-4f34-b7b8-c5e7c9313099). + +### Platform Support Matrix + +We maintain [a platform support matrix](Handbook/src/appendix/platform-support-matrix.md) which constantly changes as we move toward our development goals. + +### Planned Features Completion Status + +We also maintain [a list of planned features and their completion status](Handbook/src/appendix/planned-features-completion-status.md) as a roadmap for this plugin. + +### Changelog + +[A detailed changelog for this project](Handbook/src/appendix/changelog.md) is also maintained. Please consult the changelog before upgrading to any newer release. + +### Directory Structure + +For the list of modules, directory structure, and how this plugin is organized please visit [the directory structure section](Handbook/src/appendix/directory-structure.md). + +## Licenses + +### SenseGlove Unreal Engine Plugin License + +The SenseGlove Unreal Engine Plugin is licensed under the terms of the [MIT License](Handbook/src/license/senseglove-unreal-engine-plugin.md). + +### SenseGlove Unreal Engine Handbook License + +The SenseGlove Unreal Engine Handbook is licensed under the terms of the [CC BY (Creative Commons Attribution) License](Handbook/src/license/senseglove-unreal-engine-handbook.md). + +### Third-Party Licenses + +Please note that while the SenseGlove Unreal Engine Plugin is made available under the MIT License, it utilizes a few third-party libraries with permissive free licenses as well, in order to power various components. For a list of these libraries and their own respective open-source licenses take a look at [the third-party licenses](Handbook/src/license/third-party.md), please. diff --git a/Plugins/SenseGlove/Resources/Icon128.png b/Plugins/SenseGlove/Resources/Icon128.png new file mode 100644 index 0000000..59687cb --- /dev/null +++ b/Plugins/SenseGlove/Resources/Icon128.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21dd03aae60812bdd01f6afe261accd4d3152be594e097c30f5abf0b5afa5d75 +size 11743 diff --git a/Plugins/SenseGlove/SenseGlove.uplugin b/Plugins/SenseGlove/SenseGlove.uplugin new file mode 100644 index 0000000..0d1843f --- /dev/null +++ b/Plugins/SenseGlove/SenseGlove.uplugin @@ -0,0 +1,292 @@ +{ + "FileVersion": 3, + "Version": 1, + "VersionName": "2.3.2", + "FriendlyName": "SenseGlove", + "Description": "Integrating the SenseGlove haptic controller into Unreal Engine", + "Category": "Virtual Reality", + "CreatedBy": "SenseGlove", + "CreatedByURL": "https://www.senseglove.com/", + "DocsURL": "https://unreal.docs.senseglove.com/", + "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/5e1d408f517b4966a269ec1035de0b9e", + "SupportURL": "https://www.senseglove.com/support/", + "EngineVersion": "5.4.0", + "CanContainContent": true, + "IsBetaVersion": false, + "IsExperimentalVersion": false, + "Installed": false, + "SupportedTargetPlatforms": [ + "Android", + "Linux", + "Win64" + ], + "Modules": [ + { + "Name": "SenseGlove", + "Type": "Runtime", + "LoadingPhase": "Default", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveAndroid", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveBackend", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveBackendKismet", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveBuildHacks", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveConnect", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveConnectImpl", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveConnectKismet", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveCore", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveCoreImpl", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveCoreKismet", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveDebug", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveDebugKismet", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveEditor", + "Type": "Editor", + "LoadingPhase": "PostEngineInit", + "WhitelistPlatforms": [ + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveInterop", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveKismet", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveLog", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveSettings", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveSettingsKismet", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveTracking", + "Type": "Runtime", + "LoadingPhase": "PostConfigInit", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveTrackingKismet", + "Type": "Runtime", + "LoadingPhase": "PostConfigInit", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveTypes", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + }, + { + "Name": "SenseGloveUtils", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": [ + "Android", + "Linux", + "LinuxArm64", + "Win64" + ] + } + ], + "Plugins": [ + { + "Name": "AndroidPermission", + "Enabled": true + }, + { + "Name": "OpenXR", + "Enabled": true, + "PlatformAllowList": [ + "Android", + "Linux", + "Win64" + ] + } + ] +} diff --git a/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove.cpp b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove.cpp new file mode 100644 index 0000000..b23d712 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGlove.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveModule.h" + +IMPLEMENT_MODULE(FSenseGloveModule, SenseGlove) diff --git a/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove.h b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove.h new file mode 100644 index 0000000..ab121d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" diff --git a/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Animation/SGVirtualHandAnimInstance.cpp b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Animation/SGVirtualHandAnimInstance.cpp new file mode 100644 index 0000000..c6a2e7a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Animation/SGVirtualHandAnimInstance.cpp @@ -0,0 +1,46 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGlove/Animation/SGVirtualHandAnimInstance.h" + +USGVirtualHandAnimInstance::USGVirtualHandAnimInstance(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ +} + +FSGVirtualHandAnimInstanceProxy* USGVirtualHandAnimInstance::CreateAnimInstanceProxy() +{ + return new FSGVirtualHandAnimInstanceProxy(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.cpp b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.cpp new file mode 100644 index 0000000..fc86196 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.cpp @@ -0,0 +1,260 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.h" + +#include "Animation/Skeleton.h" +#include "BoneContainer.h" +#include "BoneControllers/AnimNode_ModifyBone.h" +#include "BonePose.h" +#include "Containers/Array.h" +#include "Containers/Map.h" +#include "Containers/UnrealString.h" +#include "Engine/SkeletalMesh.h" +#include "Math/Rotator.h" + +#include "SenseGlove/Components/SGVirtualHandComponent.h" + +FSGVirtualHandAnimInstanceProxy::FSGVirtualHandAnimInstanceProxy() + : FAnimInstanceProxy{} +{ + VirtualHand = nullptr; + HandMeshAsset = nullptr; + HandSkeleton = nullptr; + + bVirtualHandVisible = false; + bMarkRenderStateDirty = false; + + bShouldAnimationApplyBoneLocation = false; +} + +FSGVirtualHandAnimInstanceProxy::FSGVirtualHandAnimInstanceProxy(UAnimInstance* Instance) + : FAnimInstanceProxy{Instance} +{ + VirtualHand = nullptr; + HandMeshAsset = nullptr; + HandSkeleton = nullptr; + + bVirtualHandVisible = false; + bMarkRenderStateDirty = false; + + bShouldAnimationApplyBoneLocation = false; +} + +void FSGVirtualHandAnimInstanceProxy::PreEvaluateAnimation(UAnimInstance* InAnimInstance) +{ + FAnimInstanceProxy::PreEvaluateAnimation(InAnimInstance); + + if (!IsValid(InAnimInstance)) + { + return; + } + + VirtualHand = Cast(GetSkelMeshComponent()); + if (!IsValid(VirtualHand)) + { + return; + } + + HandMeshAsset = VirtualHand->GetSkeletalMeshAsset(); + if (!IsValid(HandMeshAsset)) + { + return; + } + + HandSkeleton = HandMeshAsset->GetSkeleton(); + if (!IsValid(HandSkeleton)) + { + return; + } + + bVirtualHandVisible = VirtualHand->IsVisible() && VirtualHand->GetVisibleFlag(); + if (!bVirtualHandVisible) + { + return; + } + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + const bool bGotHandTrackingState = VirtualHand->GetHandTrackingState( + EXRSpaceType::UnrealWorldSpace, HandTrackingState); + if (!bGotHandTrackingState || !HandTrackingState.bValid) + { + return; + } + ensureAlwaysMsgf(HandTrackingState.HandKeyLocations.Num() == HandTrackingState.HandKeyRotations.Num(), + TEXT("Mismatched hand tracking state locations and rotations!")); +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + const bool bGotMotionControllerData = VirtualHand->GetMotionControllerData(MotionControllerData); + if (!bGotMotionControllerData || !MotionControllerData.bValid) + { + return; + } + ensureAlwaysMsgf(MotionControllerData.HandKeyPositions.Num() == MotionControllerData.HandKeyRotations.Num(), + TEXT("Mismatched motion controller data positions and rotations!")); +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + + + BoneNamesMap.Empty(); + for (TArray::SizeType HandKeyIndex = 0; + HandKeyIndex < +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + HandTrackingState.HandKeyRotations.Num() +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + MotionControllerData.HandKeyRotations.Num() +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + ; ++HandKeyIndex) + { + const FName& BoneName{VirtualHand->GetHandBoneName(HandKeyIndex)}; + BoneNamesMap.Add(HandKeyIndex, BoneName); + } + + const FSGVirtualHandAnimationSettings AnimationSettings{VirtualHand->GetVirtualHandSettings().AnimationSettings}; + AnimationBoneCorrectionOffsetTransform = FTransform{AnimationSettings.AnimationBoneRotationCorrectionOffset}; + bShouldAnimationApplyBoneLocation = AnimationSettings.bShouldAnimationApplyBoneLocation; +} + +bool FSGVirtualHandAnimInstanceProxy::Evaluate(FPoseContext& Output) +{ + if (!bVirtualHandVisible) + { + return FAnimInstanceProxy::Evaluate(Output); + } + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + if (!HandTrackingState.bValid) + { + return FAnimInstanceProxy::Evaluate(Output); + } +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + if (!MotionControllerData.bValid) + { + return FAnimInstanceProxy::Evaluate(Output); + } +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + + FComponentSpacePoseContext PoseContext{Output.AnimInstanceProxy}; + PoseContext.Pose.InitPose(Output.Pose); + + for (const TTuple::SizeType, FName>& Bone: BoneNamesMap) + { + const TArray::SizeType HandKeyIndex = Bone.Key; + const FName& BoneName{Bone.Value}; + if (BoneName == NAME_None) + { + continue; + } + + const int32 BoneIndex = GetRequiredBones().GetPoseBoneIndexForBoneName(BoneName); + if (BoneIndex == INDEX_NONE) + { + continue; + } + + FBoneReference BoneReference; + BoneReference.BoneName = BoneName; + BoneReference.BoneIndex = BoneIndex; + BoneReference.bUseSkeletonIndex = true; + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + const FVector& HandKeyLocation{HandTrackingState.HandKeyLocations[HandKeyIndex]}; + const FQuat& HandKeyRotation{HandTrackingState.HandKeyRotations[HandKeyIndex]}; + const FTransform HandKeyTransform{HandKeyRotation, HandKeyLocation}; +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + const FVector& HandKeyPosition{MotionControllerData.HandKeyPositions[HandKeyIndex]}; + const FQuat& HandKeyRotation{MotionControllerData.HandKeyRotations[HandKeyIndex]}; + const FTransform HandKeyTransform{HandKeyRotation, HandKeyPosition}; +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + + const FTransform BoneTransform{AnimationBoneCorrectionOffsetTransform * HandKeyTransform}; + FRotator BoneRotation{BoneTransform.GetRotation().Rotator()}; + + FAnimNode_ModifyBone BoneController; + BoneController.BoneToModify = MoveTemp(BoneReference); + BoneController.Rotation = MoveTemp(BoneRotation); + BoneController.RotationMode = EBoneModificationMode::BMM_Replace; + BoneController.RotationSpace = EBoneControlSpace::BCS_WorldSpace; + BoneController.ScaleMode = EBoneModificationMode::BMM_Ignore; + + if (bShouldAnimationApplyBoneLocation) + { + FVector BoneTranslation{BoneTransform.GetLocation()}; + BoneController.TranslationMode = EBoneModificationMode::BMM_Replace; + BoneController.TranslationSpace = EBoneControlSpace::BCS_WorldSpace; + BoneController.Translation = MoveTemp(BoneTranslation); + } + else + { + BoneController.TranslationMode = EBoneModificationMode::BMM_Ignore; + } + + const bool bValidToEvaluate = + BoneController.IsValidToEvaluate(HandSkeleton, Output.Pose.GetBoneContainer()); + if (!bValidToEvaluate) + { + continue; + } + + TArray BoneTransforms; + BoneController.EvaluateSkeletalControl_AnyThread(PoseContext, BoneTransforms); + + const TArray::SizeType BoneTransformsNum = BoneTransforms.Num(); + if (BoneTransformsNum > 0) + { + PoseContext.Pose.LocalBlendCSBoneTransforms(BoneTransforms, 1.0f); + PoseContext.Pose.ConvertComponentPosesToLocalPoses(PoseContext.Pose, Output.Pose); + + bMarkRenderStateDirty = true; + } + } + + return true; +} + +void FSGVirtualHandAnimInstanceProxy::PostEvaluate(UAnimInstance* InAnimInstance) +{ + FAnimInstanceProxy::PostEvaluate(InAnimInstance); + + if (!bMarkRenderStateDirty) + { + return; + } + + if (!IsValid(VirtualHand)) + { + return; + } + + VirtualHand->MarkRenderStateDirty(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Components/SGGrabComponent.cpp b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Components/SGGrabComponent.cpp new file mode 100644 index 0000000..7ed72f5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Components/SGGrabComponent.cpp @@ -0,0 +1,177 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGlove/Components/SGGrabComponent.h" + +#include "Components/PrimitiveComponent.h" +#include "GameFramework/Actor.h" + +#include "SGSettings/SGSettings.h" + +struct USGGrabComponent::FImpl +{ + /************************ + * Static methods + ************************/ + + FORCEINLINE static const FName& GetDefaultGrabAttachPointSocketName() + { + const USGSettings* Settings{USGSettings::GetInstance()}; + const FName& SocketName{Settings->GetVirtualHandSettings().GrabSettings.GrabAttachPointSocketName}; + return SocketName; + } + + /************************ + * Owner object + ************************/ + + USGGrabComponent* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGGrabComponent* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; + + /************************ + * Methods + ************************/ +}; + +USGGrabComponent* USGGrabComponent::GetGrabComponent(const AActor* Actor) +{ + if (!ensureAlwaysMsgf(IsValid(Actor), TEXT("%s"), TEXT("ERROR: invalid actor!"))) + { + return nullptr; + } + + USGGrabComponent* GrabComponent = Cast( + Actor->GetComponentByClass(USGGrabComponent::StaticClass())); + return GrabComponent; +} + +bool USGGrabComponent::IsGrabbable(const AActor* Actor) +{ + if (!ensureAlwaysMsgf(IsValid(Actor), TEXT("%s"), TEXT("ERROR: invalid actor!"))) + { + return false; + } + + const USGGrabComponent* GrabComponent = Cast( + Actor->GetComponentByClass(USGGrabComponent::StaticClass())); + if (!IsValid(GrabComponent)) + { + return false; + } + + return true; +} + +USGGrabComponent::USGGrabComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + AttachmentLocationRule = EAttachmentRule::SnapToTarget; + AttachmentRotationRule = EAttachmentRule::KeepRelative; + AttachmentScaleRule = EAttachmentRule::KeepWorld; + bAttachmentWeldSimulatedBodies = true; + + AttachmentSocketName = FImpl::GetDefaultGrabAttachPointSocketName(); + + DetachmentLocationRule = EDetachmentRule::KeepWorld; + DetachmentRotationRule = EDetachmentRule::KeepWorld; + DetachmentScaleRule = EDetachmentRule::KeepWorld; + bDetachmentCallModify = false; + + bAffectPhysicsState = true; +} + +USGGrabComponent::FImpl::FImpl(USGGrabComponent* InOwner) + : Owner(InOwner) +{ +} + +USGGrabComponent::FImpl::~FImpl() = default; + +void USGGrabComponent::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} + +void USGGrabComponent::SimulatePhysics(const bool bSimulatePhysics) const +{ + const AActor* OwnerActor{GetOwner()}; + if (!ensureAlwaysMsgf(IsValid(OwnerActor), TEXT("Invalid OwnerActor!"))) + { + return; + } + + UPrimitiveComponent* ActorRootComponent{Cast(OwnerActor->GetRootComponent())}; + if (!ensureAlwaysMsgf(IsValid(ActorRootComponent), + TEXT("RootComponent is not a valid UPrimativeComponent!"))) + { + return; + } + + ActorRootComponent->SetEnableGravity(bSimulatePhysics); + ActorRootComponent->SetSimulatePhysics(bSimulatePhysics); + + if (bSimulatePhysics) + { + ActorRootComponent->WakeRigidBody(); + } + else + { + ActorRootComponent->PutRigidBodyToSleep(); + } +} + +void USGGrabComponent::BeginPlay() +{ + Super::BeginPlay(); + + if (bAffectPhysicsState) + { + SimulatePhysics(true); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Components/SGTouchComponent.cpp b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Components/SGTouchComponent.cpp new file mode 100644 index 0000000..51372e1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Components/SGTouchComponent.cpp @@ -0,0 +1,120 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGlove/Components/SGTouchComponent.h" + +#include "GameFramework/Actor.h" + +struct USGTouchComponent::FImpl +{ + /************************ + * Static methods + ************************/ + + /************************ + * Owner object + ************************/ + + USGTouchComponent* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGTouchComponent* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; + + /************************ + * Methods + ************************/ +}; + +USGTouchComponent* USGTouchComponent::GetTouchComponent(const AActor* Actor) +{ + if (!ensureAlwaysMsgf(IsValid(Actor), TEXT("%s"), TEXT("ERROR: invalid actor!"))) + { + return nullptr; + } + + USGTouchComponent* TouchComponent = Cast( + Actor->GetComponentByClass(USGTouchComponent::StaticClass())); + return TouchComponent; +} + +bool USGTouchComponent::IsTouchable(const AActor* Actor) +{ + if (!ensureAlwaysMsgf(IsValid(Actor), TEXT("%s"), TEXT("ERROR: invalid actor!"))) + { + return false; + } + + const USGTouchComponent* TouchComponent = Cast( + Actor->GetComponentByClass(USGTouchComponent::StaticClass())); + if (!IsValid(TouchComponent)) + { + return false; + } + + return true; +} + +USGTouchComponent::USGTouchComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + ForceFeedbackLevel = 1.0f; + + VibrotactileDuration = 0.25f; + VibrotactileLevel = 0.0f; +} + +USGTouchComponent::FImpl::FImpl(USGTouchComponent* InOwner) + : Owner(InOwner) +{ +} + +USGTouchComponent::FImpl::~FImpl() = default; + +void USGTouchComponent::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Components/SGVirtualHandComponent.cpp b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Components/SGVirtualHandComponent.cpp new file mode 100644 index 0000000..8ef92e4 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Components/SGVirtualHandComponent.cpp @@ -0,0 +1,913 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGlove/Components/SGVirtualHandComponent.h" + +#include "HeadMountedDisplayTypes.h" +#include "Animation/Skeleton.h" +#include "Components/SkeletalMeshComponent.h" +#include "Engine/Engine.h" +#include "Engine/EngineTypes.h" +#include "Engine/SkeletalMesh.h" +#include "InputCoreTypes.h" +#include "IXRTrackingSystem.h" +#include "Templates/UnrealTypeTraits.h" +#include "UObject/ConstructorHelpers.h" + +#include "SenseGlove/Animation/SGVirtualHandAnimInstance.h" +#include "SenseGlove/Components/SGWristTrackerComponent.h" +#include "SGCore/SGHapticGlove.h" +#include "SGDebug/SGDebugVirtualHand.h" +#include "SGLog/SGLog.h" +#include "SGSettings/SGSettings.h" +#include "SGTracking/SGGloveTracker.h" +#include "SGTracking/SGXRTracker.h" + +struct USGVirtualHandComponent::FImpl +{ + /************************ + * Static methods + ************************/ + + static FName ParseVirtualHandSettingsOverridesPropertyName(const FName& PropertyName); + + FORCEINLINE static const FSGVirtualHandSettings& GetPluginVirtualHandSettings() + { + const USGSettings* Settings{USGSettings::GetInstance()}; + ensureAlwaysMsgf(Settings, TEXT("The settings subsystem has not been initialized!")); + return Settings->GetVirtualHandSettings(); + } + + FORCEINLINE static const FString& GetDefaultLeftHandMeshPath() + { + return GetPluginVirtualHandSettings().MeshSettings.DefaultLeftHandMeshPath; + } + + FORCEINLINE static const FString& GetDefaultLeftHandMeshPathOnly() + { + return GetPluginVirtualHandSettings().MeshSettings.DefaultLeftHandMeshPathOnly; + } + + FORCEINLINE static const FString& GetDefaultRightHandMeshPath() + { + return GetPluginVirtualHandSettings().MeshSettings.DefaultRightHandMeshPath; + } + + FORCEINLINE static const FString& GetDefaultRightHandMeshPathOnly() + { + return GetPluginVirtualHandSettings().MeshSettings.DefaultRightHandMeshPathOnly; + } + + /************************ + * Member variables + ************************/ + + bool bOverridePluginSettingsPropertyAlreadyModified; + + bool bCachedGenerateOverlapEvents; + ECollisionEnabled::Type CachedCollisionEnabled; + FCollisionResponseContainer CachedCollisionResponse; + + /************************ + * Owner object + ************************/ + + USGVirtualHandComponent* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGVirtualHandComponent* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; + + /************************ + * Methods + ************************/ + + bool IsEditor() const; + + void RightPropertyChanged(); + void OverridePluginSettingsPropertyChanged(); + + FString GetDefaultMeshPath() const; + bool IsUsingDefaultMesh() const; + bool IsUsingUserMesh() const; + USkeletalMesh* LoadDefaultMesh() const; + void SetDefaultMesh() const; + + USkeletalMesh* GetMesh() const; + USkeleton* GetSkeleton() const; + const FReferenceSkeleton& GetRefSkeleton() const; + + void DisableCollisionResponse(); + void RestoreCollisionResponse() const; + + void SetVisibility(const bool bInVisible); + void UpdateVisibility(); + + FORCEINLINE bool ShouldDrawDebugVirtualHand() const + { + const FSGVirtualHandDebuggingSettings& Settings{Owner->GetVirtualHandSettings().DebuggingSettings}; + const bool bDraw = Settings.bDrawDebugVirtualHand + && Settings.DrawingMode != ESGDebugVirtualHandDrawingMode::None; + return bDraw; + } + + void DrawDebugVirtualHand() const; + + void TriggerHandVisibilityChangedEvent(bool bNewVisibility) const; +}; + +FName USGVirtualHandComponent::FImpl::ParseVirtualHandSettingsOverridesPropertyName(const FName& PropertyName) +{ + static const UStruct* Struct{FSGVirtualHandSettingsOverrides::StaticStruct()}; + if (!ensureAlwaysMsgf(Struct, TEXT("Invalid Struct!"))) + { + return NAME_None; + } + + // +3 because of :: + static const int32 StructNameLength = Struct->GetFName().ToString().Len() + 3; + + const FString PropertyString{PropertyName.ToString()}; + const int32 PropertyStringLength = PropertyString.Len(); + const int32 PropertyNameLength = PropertyStringLength - StructNameLength; + + const FName ParsedName{*PropertyString.Right(PropertyNameLength)}; + return ParsedName; +} + +const TArray& USGVirtualHandComponent::GetLeftHandBoneNames() +{ + return FImpl::GetPluginVirtualHandSettings().MeshSettings.LeftHandBoneNames; +} + +const TArray& USGVirtualHandComponent::GetRightHandBoneNames() +{ + return FImpl::GetPluginVirtualHandSettings().MeshSettings.RightHandBoneNames; +} + +const FName& USGVirtualHandComponent::GetLeftHandBoneName(const int32 Joint) +{ + const TArray& BoneNames{GetLeftHandBoneNames()}; + + ensureAlwaysMsgf(Joint < BoneNames.Num(), TEXT("Joint index is out of bound!")); + + const FName& BoneName{BoneNames[Joint]}; + return BoneName; +} + +const FName& USGVirtualHandComponent::GetRightHandBoneName(const int32 Joint) +{ + const TArray& BoneNames{GetRightHandBoneNames()}; + + ensureAlwaysMsgf(Joint < BoneNames.Num(), TEXT("Joint index is out of bound!")); + + const FName& BoneName{BoneNames[Joint]}; + return BoneName; +} + +USGVirtualHandComponent::USGVirtualHandComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + PrimaryComponentTick.bTickEvenWhenPaused = false; + PrimaryComponentTick.bCanEverTick = true; + PrimaryComponentTick.bStartWithTickEnabled = true; + bTickInEditor = true; + bNeverNeedsRenderUpdate = false; + bAllowConcurrentTick = true; + SetUpdateAnimationInEditor(true); + + SetCastShadow(true); + SetCastHiddenShadow(false); + bCastDynamicShadow = true; + SetOnlyOwnerSee(false); + SetReceivesDecals(true); + SetCanEverAffectNavigation(false); + Super::SetCollisionObjectType(ECC_WorldDynamic); + Super::SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); + Super::SetCollisionResponseToAllChannels(ECR_Overlap); + Super::SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Block); + Super::SetCollisionResponseToChannel(ECC_WorldDynamic, ECR_Block); + Super::SetCollisionResponseToChannel(ECC_Pawn, ECR_Block); + Super::SetCollisionResponseToChannel(ECC_Visibility, ECR_Block); + Super::SetCollisionResponseToChannel(ECC_PhysicsBody, ECR_Block); + Super::SetCollisionResponseToChannel(ECC_Vehicle, ECR_Block); + Super::SetCollisionResponseToChannel(ECC_Destructible, ECR_Block); + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + Super::SetAnimInstanceClass(USGVirtualHandAnimInstance::StaticClass()); +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + Super::SetAnimClass(USGVirtualHandAnimInstance::StaticClass()); +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + + bRight = true; + + Super::SetSkeletalMesh(nullptr, true); + + WristTracker = nullptr; +} + +void USGVirtualHandComponent::OnHandVisibilityChanged_Implementation(bool bNewVisibility) +{ +} + +void USGVirtualHandComponent::SetRight(const bool bInRight) +{ + bRight = bInRight; + + if (!Pimpl->IsUsingUserMesh()) + { + Pimpl->SetDefaultMesh(); + } +} + +void USGVirtualHandComponent::SetVirtualHandSettingsOverrides( + const FSGVirtualHandSettingsOverrides& InVirtualHandSettingsOverrides) +{ + VirtualHandSettingsOverrides = InVirtualHandSettingsOverrides; +} + +FSGVirtualHandSettings USGVirtualHandComponent::GetVirtualHandSettings() const +{ + const USGSettings* Settings{USGSettings::GetInstance()}; + if (!IsValid(Settings)) + { + return FSGVirtualHandSettings{}; + } + + const FSGVirtualHandSettings& PluginVirtualHandSettings{Settings->GetVirtualHandSettings()}; + if (!OverridesPluginVirtualHandSettings()) + { + return PluginVirtualHandSettings; + } + + const FSGVirtualHandSettings VirtualHandSettings{ + VirtualHandSettingsOverrides.bVisibleWhenHandDataUnavailable, + VirtualHandSettingsOverrides.AnimationSettings, + VirtualHandSettingsOverrides.DebuggingSettings, + VirtualHandSettingsOverrides.GrabSettings, + VirtualHandSettingsOverrides.HapticsSettings, + PluginVirtualHandSettings.MeshSettings, + VirtualHandSettingsOverrides.TouchSettings + }; + return VirtualHandSettings; +} + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 +void USGVirtualHandComponent::SetAnimInstanceClass(UClass* NewClass) +{ + ensureAlwaysMsgf((TIsDerivedFrom::IsDerived), + TEXT("The AnimInstance class must be a subclass of USGVirtualHandAnimInstance!")); + + Super::SetAnimInstanceClass(NewClass); +} +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ +void USGVirtualHandComponent::SetAnimClass(UClass* NewClass) +{ + ensureAlwaysMsgf((TIsDerivedFrom::IsDerived), + TEXT("The AnimInstance class must be a subclass of USGVirtualHandAnimInstance!")); + + Super::SetAnimClass(NewClass); +} +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + +void USGVirtualHandComponent::PostInitProperties() +{ + Super::PostInitProperties(); + + if (!Pimpl->IsUsingUserMesh()) + { + Pimpl->SetDefaultMesh(); + } +} + +#if WITH_EDITOR +void USGVirtualHandComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) +{ + Super::PostEditChangeProperty(PropertyChangedEvent); + + const FName PropertyName{ + PropertyChangedEvent.Property + ? PropertyChangedEvent.Property->GetFName() + : NAME_None + }; + + static const FName RightName{ + GET_MEMBER_NAME_CHECKED(USGVirtualHandComponent, bRight) + }; + + static const FName OverridePluginSettingsName{ + FImpl::ParseVirtualHandSettingsOverridesPropertyName( + GET_MEMBER_NAME_CHECKED(FSGVirtualHandSettingsOverrides, + FSGVirtualHandSettingsOverrides::bOverridePluginSettings)) + }; + + if (PropertyName == RightName) + { + Pimpl->RightPropertyChanged(); + return; + } + + if (PropertyName == OverridePluginSettingsName) + { + Pimpl->OverridePluginSettingsPropertyChanged(); + return; + } +} +#endif /* WITH_EDITOR */ + +void USGVirtualHandComponent::InitializeComponent() +{ + Super::InitializeComponent(); + + if (!Pimpl->IsUsingUserMesh()) + { + Pimpl->SetDefaultMesh(); + } + + Pimpl->UpdateVisibility(); +} + +void USGVirtualHandComponent::UninitializeComponent() +{ + Super::UninitializeComponent(); + + const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance(GetOuter())}; + USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(IsRight()) : nullptr}; + const bool bAutoStopHaptics = GetVirtualHandSettings().HapticsSettings.bAutoStopAllHapticsOnEndPlay; + if (IsValid(Glove) && Glove->IsConnected() && bAutoStopHaptics) + { + Glove->StopHaptics(); + } +} + +void USGVirtualHandComponent::BeginPlay() +{ + Super::BeginPlay(); + + Pimpl->UpdateVisibility(); +} + +void USGVirtualHandComponent::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + Super::EndPlay(EndPlayReason); + + const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance(GetOuter())}; + USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(IsRight()) : nullptr}; + const bool bAutoStopHaptics = GetVirtualHandSettings().HapticsSettings.bAutoStopAllHapticsOnEndPlay; + if (IsValid(Glove) && Glove->IsConnected() && bAutoStopHaptics) + { + Glove->StopHaptics(); + } +} + +void USGVirtualHandComponent::TickComponent( + const float DeltaTime, const ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) +{ +#if WITH_EDITOR + if (Pimpl->IsEditor()) + { + EditorTick(DeltaTime, TickType, ThisTickFunction); + return; + } +#endif /* WITH_EDITOR */ + + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + Pimpl->UpdateVisibility(); + + if (Pimpl->ShouldDrawDebugVirtualHand()) + { + Pimpl->DrawDebugVirtualHand(); + } +} + +void USGVirtualHandComponent::SetSkeletalMesh(USkeletalMesh* NewMesh, const bool bReinitPose) +{ + if (IsValid(NewMesh)) + { + Super::SetSkeletalMesh(NewMesh, bReinitPose); + } + else + { + Super::SetSkeletalMesh(Pimpl->LoadDefaultMesh(), bReinitPose); + } +} + +void USGVirtualHandComponent::EditorTick( + const float DeltaTime, const ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) +{ + Pimpl->UpdateVisibility(); + + if (Pimpl->ShouldDrawDebugVirtualHand()) + { + Pimpl->DrawDebugVirtualHand(); + } +} + +bool USGVirtualHandComponent::IsGloveConnected() const +{ + const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance(GetOuter())}; + const USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(IsRight()) : nullptr}; + return IsValid(Glove); +} + +USGHapticGlove* USGVirtualHandComponent::GetConnectedGlove() const +{ + const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance(GetOuter())}; + USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(IsRight()) : nullptr}; + return Glove; +} + +bool USGVirtualHandComponent::GetMotionControllerData(FXRMotionControllerData& OutMotionControllerData) +{ + OutMotionControllerData.bValid = false; + + const EControllerHand Hand = IsRight() ? EControllerHand::Right : EControllerHand::Left; + PRAGMA_DISABLE_DEPRECATION_WARNINGS + const bool bGotMotionControllerData = + FSGXRTracker::GetMotionControllerData(this, Hand, OutMotionControllerData); + PRAGMA_ENABLE_DEPRECATION_WARNINGS + if (!bGotMotionControllerData || !OutMotionControllerData.bValid) + { + return false; + } + + return OutMotionControllerData.bValid; +} + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + +bool USGVirtualHandComponent::GetMotionControllerState( + const EXRSpaceType XRSpaceType, const EXRControllerPoseType XRControllerPoseType, + FXRMotionControllerState& OutMotionControllerState) +{ + OutMotionControllerState.bValid = false; + + const EControllerHand Hand = IsRight() ? EControllerHand::Right : EControllerHand::Left; + const bool bGotMotionControllerState = + FSGXRTracker::GetMotionControllerState( + this, XRSpaceType, Hand, XRControllerPoseType, OutMotionControllerState); + if (!bGotMotionControllerState || !OutMotionControllerState.bValid) + { + return false; + } + + return OutMotionControllerState.bValid; +} + +bool USGVirtualHandComponent::GetHandTrackingState( + const EXRSpaceType XRSpaceType, + FXRHandTrackingState& OutHandTrackingState) +{ + OutHandTrackingState.bValid = false; + + const EControllerHand Hand = IsRight() ? EControllerHand::Right : EControllerHand::Left; + const bool bGotHandTrackingState = + FSGXRTracker::GetHandTrackingState( + this, XRSpaceType, Hand, OutHandTrackingState); + if (!bGotHandTrackingState || !OutHandTrackingState.bValid) + { + return false; + } + + return OutHandTrackingState.bValid; +} + +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + +const TArray& USGVirtualHandComponent::GetHandBoneNames() const +{ + const TArray& Names{ + IsRight() + ? GetRightHandBoneNames() + : GetLeftHandBoneNames() + }; + return Names; +} + +const FName& USGVirtualHandComponent::GetHandBoneName(const int32 Joint) const +{ + const FName& Name{ + IsRight() + ? GetRightHandBoneName(Joint) + : GetLeftHandBoneName(Joint) + }; + return Name; +} + +const FTransform& USGVirtualHandComponent::GetHandBoneRefTransform(const FName& BoneName) const +{ + const FReferenceSkeleton& ReferenceSkeleton{Pimpl->GetRefSkeleton()}; + const int32 BoneIndex = ReferenceSkeleton.FindBoneIndex(BoneName); + + if (BoneIndex == INDEX_NONE) + { + SGLOG_WARNING(FString::Printf(TEXT("Could not find a bone index for the '%s' joint!"), + *BoneName.ToString())); + return FTransform::Identity; + } + + const FTransform& BoneTransform{ReferenceSkeleton.GetRefBonePose()[BoneIndex]}; + return BoneTransform; +} + +const FTransform& USGVirtualHandComponent::GetHandRootBoneRefTransform() const +{ + static constexpr int32 WristKeypointIndex = static_cast(EHandKeypoint::Wrist); + const FTransform& BoneTransform{GetHandBoneRefTransform(WristKeypointIndex)}; + return BoneTransform; +} + +const FTransform& USGVirtualHandComponent::GetHandBoneRefTransform(const int32 Joint) const +{ + const FName& BoneName{GetHandBoneName(Joint)}; + return GetHandBoneRefTransform(BoneName); +} + +FRotator USGVirtualHandComponent::GetHandBoneRefRotation(const FName& BoneName) const +{ + const FTransform BoneTransform{GetHandBoneRefTransform(BoneName)}; + const FRotator BoneRotation{BoneTransform.GetRotation().Rotator()}; + return BoneRotation; +} + +FRotator USGVirtualHandComponent::GetHandBoneRefRotation(const int32 Joint) const +{ + const FTransform BoneTransform{GetHandBoneRefTransform(Joint)}; + const FRotator BoneRotation{BoneTransform.GetRotation().Rotator()}; + return BoneRotation; +} + +USGVirtualHandComponent::FImpl::FImpl(USGVirtualHandComponent* InOwner) + : bOverridePluginSettingsPropertyAlreadyModified(false), + bCachedGenerateOverlapEvents(InOwner->GetGenerateOverlapEvents()), + CachedCollisionEnabled(InOwner->GetCollisionEnabled()), + Owner(InOwner) + +{ +} + +USGVirtualHandComponent::FImpl::~FImpl() = default; + +bool USGVirtualHandComponent::FImpl::IsEditor() const +{ + const UWorld* World{Owner->GetWorld()}; + if (World && (World->WorldType == EWorldType::Editor || World->WorldType == EWorldType::EditorPreview)) + { + return true; + } + + return false; +} + +void USGVirtualHandComponent::FImpl::RightPropertyChanged() +{ + if (!IsUsingUserMesh()) + { + SetDefaultMesh(); + } +} + +void USGVirtualHandComponent::FImpl::OverridePluginSettingsPropertyChanged() +{ + if (bOverridePluginSettingsPropertyAlreadyModified) + { + return; + } + + bOverridePluginSettingsPropertyAlreadyModified = true; + + if (!Owner->VirtualHandSettingsOverrides.bOverridePluginSettings) + { + return; + } + + const USGSettings* Settings{USGSettings::GetInstance()}; + if (!ensureAlwaysMsgf(IsValid(Settings), TEXT("The settings subsystem has not been initialized!"))) + { + return; + } + + const FSGVirtualHandSettings& PluginVirtualHandSettings{Settings->GetVirtualHandSettings()}; + Owner->VirtualHandSettingsOverrides.bVisibleWhenHandDataUnavailable = + PluginVirtualHandSettings.bVisibleWhenHandDataUnavailable; + Owner->VirtualHandSettingsOverrides.AnimationSettings = PluginVirtualHandSettings.AnimationSettings; + Owner->VirtualHandSettingsOverrides.DebuggingSettings = PluginVirtualHandSettings.DebuggingSettings; + Owner->VirtualHandSettingsOverrides.GrabSettings = PluginVirtualHandSettings.GrabSettings; + Owner->VirtualHandSettingsOverrides.HapticsSettings = PluginVirtualHandSettings.HapticsSettings; + Owner->VirtualHandSettingsOverrides.TouchSettings = PluginVirtualHandSettings.TouchSettings; +} + +FString USGVirtualHandComponent::FImpl::GetDefaultMeshPath() const +{ + FString SkeletalMeshPath; + + if (Owner->IsRight()) + { + SkeletalMeshPath = GetDefaultRightHandMeshPath(); + } + else + { + SkeletalMeshPath = GetDefaultLeftHandMeshPath(); + } + + return SkeletalMeshPath; +} + +bool USGVirtualHandComponent::FImpl::IsUsingDefaultMesh() const +{ + const USkeletalMesh* CurrentMesh{GetMesh()}; + if (!IsValid(CurrentMesh)) + { + return false; + } + + const FString CurrentMeshPath{CurrentMesh->GetPathName()}; + const FString LeftHandDefaultMeshPath{GetDefaultLeftHandMeshPath()}; + const FString LeftHandDefaultMeshPathOnly{GetDefaultLeftHandMeshPathOnly()}; + const FString RightHandDefaultMeshPath{GetDefaultRightHandMeshPath()}; + const FString RightHandDefaultMeshPathOnly{GetDefaultRightHandMeshPathOnly()}; + if (CurrentMeshPath == LeftHandDefaultMeshPath + || CurrentMeshPath == LeftHandDefaultMeshPathOnly + || CurrentMeshPath == RightHandDefaultMeshPath + || CurrentMeshPath == RightHandDefaultMeshPathOnly) + { + return true; + } + + return false; +} + +bool USGVirtualHandComponent::FImpl::IsUsingUserMesh() const +{ + const USkeletalMesh* CurrentMesh{GetMesh()}; + if (!IsValid(CurrentMesh)) + { + return false; + } + + const FString CurrentMeshPath{CurrentMesh->GetPathName()}; + const FString LeftHandDefaultMeshPath{GetDefaultLeftHandMeshPath()}; + const FString LeftHandDefaultMeshPathOnly{GetDefaultLeftHandMeshPathOnly()}; + const FString RightHandDefaultMeshPath{GetDefaultRightHandMeshPath()}; + const FString RightHandDefaultMeshPathOnly{GetDefaultRightHandMeshPathOnly()}; + if (CurrentMeshPath == LeftHandDefaultMeshPath + || CurrentMeshPath == LeftHandDefaultMeshPathOnly + || CurrentMeshPath == RightHandDefaultMeshPath + || CurrentMeshPath == RightHandDefaultMeshPathOnly) + { + return false; + } + + return true; +} + +USkeletalMesh* USGVirtualHandComponent::FImpl::LoadDefaultMesh() const +{ + // FIXME + // Disable this warning altogether as it results in polluting the packaging logs, at least until we ship a set of + // virtual hand meshes again. + // const FString DefaultMeshPath{GetDefaultMeshPath()}; + // USkeletalMesh* DefaultMesh{ + // Cast(StaticLoadObject(USkeletalMesh::StaticClass(), nullptr, *DefaultMeshPath)) + // }; + + // FIXME + // Disable this warning altogether as it results in polluting the packaging logs, at least until we ship a set of + // virtual hand meshes again. + // if (!IsValid(DefaultMesh)) + // { + // SGLOG_WARNING(FString::Printf(TEXT("Failed to load the default skeletal mesh: '%s'"), *DefaultMeshPath)); + // } + + // FIXME + //return DefaultMesh; + + return nullptr; +} + +void USGVirtualHandComponent::FImpl::SetDefaultMesh() const +{ + // FIXME + // Since we don't ship a default virtual hand mesh at the moment, calling SetDefaultMesh causes the following + // failed assertion due the fact that the engine won't be able to find the asset at the default location: + // Assertion failed: IsInGameThread() + // Unable to load /SenseGlove/Meshes/SK_SenseGlove_VirtualHand_*. Objects and Packages can only be loaded from the + // game thread with the currently active loader '%s'. + // One workaround would be disabling the async loading or as an alternative simply disabling this portion of the + // code should be a good-enough fix until we address this issue in its own time. + //Owner->SetSkeletalMesh(LoadDefaultMesh(), true); + // Temporary hack to make it work inside the Blueprint Editor. +#if WITH_EDITOR + // FIXME + //Owner->SetSkeletalMesh(LoadDefaultMesh(), true); + // Instead + Owner->SetSkeletalMesh(nullptr, true); +#endif /* WITH_EDITOR */ +} + +USkeletalMesh* USGVirtualHandComponent::FImpl::GetMesh() const +{ + return Owner->GetSkeletalMeshAsset(); +} + +USkeleton* USGVirtualHandComponent::FImpl::GetSkeleton() const +{ + USkeletalMesh* Mesh{GetMesh()}; + ensureAlwaysMsgf(IsValid(Mesh), TEXT("Invalid SkeletalMesh object!")); + return Mesh->GetSkeleton(); +} + +const FReferenceSkeleton& USGVirtualHandComponent::FImpl::GetRefSkeleton() const +{ + const USkeletalMesh* Mesh{GetMesh()}; + ensureAlwaysMsgf(IsValid(Mesh), TEXT("Invalid SkeletalMesh object!")); + return Mesh->GetRefSkeleton(); +} + +void USGVirtualHandComponent::FImpl::DisableCollisionResponse() +{ + bCachedGenerateOverlapEvents = Owner->GetGenerateOverlapEvents(); + CachedCollisionEnabled = Owner->GetCollisionEnabled(); + CachedCollisionResponse = Owner->GetCollisionResponseToChannels(); + Owner->SetGenerateOverlapEvents(false); + Owner->SetCollisionEnabled(ECollisionEnabled::NoCollision); + Owner->SetCollisionResponseToAllChannels(ECR_Ignore); +} + +void USGVirtualHandComponent::FImpl::RestoreCollisionResponse() const +{ + Owner->SetGenerateOverlapEvents(bCachedGenerateOverlapEvents); + Owner->SetCollisionEnabled(CachedCollisionEnabled); + Owner->SetCollisionResponseToChannels(CachedCollisionResponse); +} + +void USGVirtualHandComponent::FImpl::SetVisibility(const bool bInVisible) +{ + Owner->SetHiddenInGame(!bInVisible, false); + + if (bInVisible) + { + RestoreCollisionResponse(); + } + else + { + DisableCollisionResponse(); + } + + TriggerHandVisibilityChangedEvent(bInVisible); +} + +void USGVirtualHandComponent::FImpl::UpdateVisibility() +{ +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + FXRHandTrackingState HandTrackingState; + const bool bGotHandTrackingState = + Owner->GetHandTrackingState(EXRSpaceType::UnrealWorldSpace, HandTrackingState); +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + FXRMotionControllerData MotionControllerData; + const bool bGotMotionControllerData = Owner->GetMotionControllerData(MotionControllerData); +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + + const bool bHandDataAvailable = +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + bGotHandTrackingState + && HandTrackingState.bValid +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + bGotMotionControllerData + && MotionControllerData.bValid + && MotionControllerData.DeviceVisualType == EXRVisualType::Hand +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + ; + const bool bHandVisible = Owner->IsVisible(); + const bool bShouldBeVisibleWhenHandDataUnavailable = + Owner->GetVirtualHandSettings().bVisibleWhenHandDataUnavailable; + + bool bSetNewVisibility = false; + + if (bHandDataAvailable) + { + if (bHandVisible) + { + bSetNewVisibility = false; + } + else + { + bSetNewVisibility = true; + } + } + else + { + if (bHandVisible) + { + if (bShouldBeVisibleWhenHandDataUnavailable) + { + bSetNewVisibility = false; + } + else + { + bSetNewVisibility = true; + } + } + else + { + if (bShouldBeVisibleWhenHandDataUnavailable) + { + bSetNewVisibility = true; + } + else + { + bSetNewVisibility = false; + } + } + } + + if (bSetNewVisibility) + { + SetVisibility(bHandDataAvailable); + } +} + +void USGVirtualHandComponent::FImpl::DrawDebugVirtualHand() const +{ + const UWorld* World{Owner->GetWorld()}; + + if (!IsValid(Owner->WristTracker)) + { + return; + } + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + FXRHandTrackingState HandTrackingState; + const bool bGotHandTrackingState = Owner->GetHandTrackingState(EXRSpaceType::UnrealWorldSpace, HandTrackingState); + if (!bGotHandTrackingState || !HandTrackingState.bValid) + { + return; + } + + FSGDebugVirtualHand::Draw(World, HandTrackingState, Owner->GetVirtualHandSettings().DebuggingSettings); +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + FXRMotionControllerData MotionControllerData; + const bool bGotMotionControllerData = Owner->GetMotionControllerData(MotionControllerData); + if (!bGotMotionControllerData || !MotionControllerData.bValid) + { + return; + } + + FSGDebugVirtualHand::Draw(World, MotionControllerData, Owner->GetVirtualHandSettings().DebuggingSettings); +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ +} + +void USGVirtualHandComponent::FImpl::TriggerHandVisibilityChangedEvent(const bool bNewVisibility) const +{ + Owner->HandVisibilityChangedEvent.Broadcast(bNewVisibility); + Owner->OnHandVisibilityChanged(bNewVisibility); +} + +void USGVirtualHandComponent::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Components/SGWristTrackerComponent.cpp b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Components/SGWristTrackerComponent.cpp new file mode 100644 index 0000000..89313f1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Components/SGWristTrackerComponent.cpp @@ -0,0 +1,407 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGlove/Components/SGWristTrackerComponent.h" + +#include "IXRTrackingSystem.h" +#include "MotionDelayBuffer.h" + +#include "SGDebug/SGDebugGizmo.h" +#include "SGSettings/SGSettings.h" +#include "SGTracking/SGXRTracker.h" + +struct USGWristTrackerComponent::FImpl +{ + /************************ + * Static methods + ************************/ + + static FName ParseWristTrackingSettingsOverridesPropertyName(const FName& PropertyName); + + /************************ + * Member variables + ************************/ + + bool bOverridePluginSettingsPropertyAlreadyModified; + + /************************ + * Owner object + ************************/ + + USGWristTrackerComponent* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGWristTrackerComponent* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; + + /************************ + * Methods + ************************/ + + bool IsEditor() const; + + void OverridePluginSettingsPropertyChanged(); + + void UpdateMotionSource() const; + void UpdateWristTrackingData() const; + void DrawDebugWristTracker() const; +}; + +USGWristTrackerComponent::USGWristTrackerComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + PrimaryComponentTick.bTickEvenWhenPaused = false; + PrimaryComponentTick.bCanEverTick = true; + PrimaryComponentTick.bStartWithTickEnabled = true; + bTickInEditor = true; + bNeverNeedsRenderUpdate = true; + bAllowConcurrentTick = true; + + SetCastShadow(false); + SetCastHiddenShadow(false); + bCastDynamicShadow = false; + SetOnlyOwnerSee(false); + SetReceivesDecals(false); + SetCanEverAffectNavigation(false); + + bRight = true; + + WristLocation = FVector::ZeroVector; + WristRotation = FRotator::ZeroRotator; +} + +FName USGWristTrackerComponent::FImpl::ParseWristTrackingSettingsOverridesPropertyName(const FName& PropertyName) +{ + static const UStruct* Struct{FSGWristTrackingSettingsOverrides::StaticStruct()}; + if (!ensureAlwaysMsgf(Struct, TEXT("Invalid Struct!"))) + { + return NAME_None; + } + + // +3 because of :: + static const int32 StructNameLength = Struct->GetFName().ToString().Len() + 3; + + const FString PropertyString{PropertyName.ToString()}; + const int32 PropertyStringLength = PropertyString.Len(); + const int32 PropertyNameLength = PropertyStringLength - StructNameLength; + + const FName ParsedName{*PropertyString.Right(PropertyNameLength)}; + return ParsedName; +} + +void USGWristTrackerComponent::SetRight(const bool bInRight) +{ + bRight = bInRight; + Pimpl->UpdateMotionSource(); +} + +void USGWristTrackerComponent::SetWristTrackingSettingsOverrides( + const FSGWristTrackingSettingsOverrides& InWristTrackingSettingsOverrides) +{ + WristTrackingSettingsOverrides = InWristTrackingSettingsOverrides; +} + +FSGWristTrackingSettings USGWristTrackerComponent::GetWristTrackingSettings() const +{ + const USGSettings* Settings{USGSettings::GetInstance()}; + if (!IsValid(Settings)) + { + return FSGWristTrackingSettings{}; + } + + const FSGWristTrackingSettings& PluginWristTrackingSettings{Settings->GetTrackingSettings().WristTrackingSettings}; + if (!OverridesPluginWristTrackingSettings()) + { + return PluginWristTrackingSettings; + } + + const FSGWristTrackingSettings WristTrackingSettings{ + PluginWristTrackingSettings.OpenXRPositionalTrackingProvider, + PluginWristTrackingSettings.TrackingHardware, + PluginWristTrackingSettings.TrackingHardwareLocationOffsetLeftHand, + PluginWristTrackingSettings.TrackingHardwareLocationOffsetRightHand, + PluginWristTrackingSettings.TrackingHardwareRotationOffsetLeftHand, + PluginWristTrackingSettings.TrackingHardwareRotationOffsetRightHand, + PluginWristTrackingSettings.LeftHandMotionSource, + PluginWristTrackingSettings.RightHandMotionSource, + WristTrackingSettingsOverrides.DebuggingSettings, + }; + return WristTrackingSettings; +} + +#if WITH_EDITOR +void USGWristTrackerComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) +{ + Super::PostEditChangeProperty(PropertyChangedEvent); + + const FName PropertyName{ + PropertyChangedEvent.Property + ? PropertyChangedEvent.Property->GetFName() + : NAME_None + }; + + static const FName OverridePluginSettingsName{ + FImpl::ParseWristTrackingSettingsOverridesPropertyName( + GET_MEMBER_NAME_CHECKED(FSGWristTrackingSettingsOverrides, + FSGWristTrackingSettingsOverrides::bOverridePluginSettings)) + }; + + if (PropertyName == OverridePluginSettingsName) + { + Pimpl->OverridePluginSettingsPropertyChanged(); + return; + } +} +#endif /* WITH_EDITOR */ + +void USGWristTrackerComponent::InitializeComponent() +{ + Super::InitializeComponent(); + + Pimpl->UpdateWristTrackingData(); + + Pimpl->UpdateMotionSource(); +} + +void USGWristTrackerComponent::BeginPlay() +{ + Super::BeginPlay(); + + Pimpl->UpdateWristTrackingData(); + + Pimpl->UpdateMotionSource(); +} + +void USGWristTrackerComponent::TickComponent( + const float DeltaTime, const ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) +{ +#if WITH_EDITOR + if (Pimpl->IsEditor()) + { + EditorTick(DeltaTime, TickType, ThisTickFunction); + return; + } +#endif /* WITH_EDITOR */ + + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + if (GetWristTrackingSettings().DebuggingSettings.bDrawDebugWristTracker) + { + Pimpl->DrawDebugWristTracker(); + } + + Pimpl->UpdateWristTrackingData(); +} + + +void USGWristTrackerComponent::EditorTick( + const float DeltaTime, const ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) +{ + Pimpl->UpdateWristTrackingData(); +} + +bool USGWristTrackerComponent::GetMotionControllerData(FXRMotionControllerData& OutMotionControllerData) +{ + OutMotionControllerData.bValid = false; + + const EControllerHand Hand = IsRight() ? EControllerHand::Right : EControllerHand::Left; + PRAGMA_DISABLE_DEPRECATION_WARNINGS + const bool bGotMotionControllerData = + FSGXRTracker::GetMotionControllerData(this, Hand, OutMotionControllerData); + PRAGMA_ENABLE_DEPRECATION_WARNINGS + + if (!bGotMotionControllerData || !OutMotionControllerData.bValid) + { + return false; + } + + return OutMotionControllerData.bValid; +} + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + +bool USGWristTrackerComponent::GetMotionControllerState( + const EXRSpaceType XRSpaceType, const EXRControllerPoseType XRControllerPoseType, + FXRMotionControllerState& OutMotionControllerState) +{ + OutMotionControllerState.bValid = false; + + const EControllerHand Hand = IsRight() ? EControllerHand::Right : EControllerHand::Left; + const bool bGotMotionControllerState = + FSGXRTracker::GetMotionControllerState( + this, XRSpaceType, Hand, XRControllerPoseType, OutMotionControllerState); + if (!bGotMotionControllerState || !OutMotionControllerState.bValid) + { + return false; + } + + return OutMotionControllerState.bValid; +} + +bool USGWristTrackerComponent::GetHandTrackingState( + const EXRSpaceType XRSpaceType, + FXRHandTrackingState& OutHandTrackingState) +{ + OutHandTrackingState.bValid = false; + + const EControllerHand Hand = IsRight() ? EControllerHand::Right : EControllerHand::Left; + const bool bGotHandTrackingState = + FSGXRTracker::GetHandTrackingState( + this, XRSpaceType, Hand, OutHandTrackingState); + if (!bGotHandTrackingState || !OutHandTrackingState.bValid) + { + return false; + } + + return OutHandTrackingState.bValid; +} + +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + +USGWristTrackerComponent::FImpl::FImpl(USGWristTrackerComponent* InOwner) + : bOverridePluginSettingsPropertyAlreadyModified(false), + Owner(InOwner) +{ +} + +USGWristTrackerComponent::FImpl::~FImpl() = default; + +bool USGWristTrackerComponent::FImpl::IsEditor() const +{ + const UWorld* World{Owner->GetWorld()}; + if (World && (World->WorldType == EWorldType::Editor || World->WorldType == EWorldType::EditorPreview)) + { + return true; + } + + return false; +} + +void USGWristTrackerComponent::FImpl::OverridePluginSettingsPropertyChanged() +{ + if (bOverridePluginSettingsPropertyAlreadyModified) + { + return; + } + + bOverridePluginSettingsPropertyAlreadyModified = true; + + if (!Owner->WristTrackingSettingsOverrides.bOverridePluginSettings) + { + return; + } + + const USGSettings* Settings{USGSettings::GetInstance()}; + if (!ensureAlwaysMsgf(IsValid(Settings), TEXT("The settings subsystem has not been initialized!"))) + { + return; + } + + const FSGWristTrackingSettings& PluginWristTrackingSettings{Settings->GetTrackingSettings().WristTrackingSettings}; + Owner->WristTrackingSettingsOverrides.DebuggingSettings = PluginWristTrackingSettings.DebuggingSettings; +} + +void USGWristTrackerComponent::FImpl::UpdateMotionSource() const +{ + if (!GEngine) + { + return; + } + + const FName& TrackingMotionSource{ + Owner->IsRight() + ? Owner->GetWristTrackingSettings().RightHandMotionSource + : Owner->GetWristTrackingSettings().LeftHandMotionSource + }; + Owner->SetTrackingMotionSource(TrackingMotionSource); +} + +void USGWristTrackerComponent::FImpl::UpdateWristTrackingData() const +{ + FVector NewWristLocation{Owner->GetComponentLocation()}; + FRotator NewWristRotation{Owner->GetComponentRotation()}; + + const bool bLocationUpdated = !Owner->WristLocation.Equals(NewWristLocation, SMALL_NUMBER); + const bool bRotationUpdated = !Owner->WristRotation.Equals(NewWristRotation, SMALL_NUMBER); + + if (bLocationUpdated) + { + Owner->WristLocation = MoveTemp(NewWristLocation); + } + + if (bRotationUpdated) + { + Owner->WristRotation = MoveTemp(NewWristRotation); + } + + if (bLocationUpdated && Owner->WristLocationChangedEvent.IsBound()) + { + Owner->WristLocationChangedEvent.Broadcast(Owner->WristLocation); + } + + if (bRotationUpdated && Owner->WristRotationChangedEvent.IsBound()) + { + Owner->WristRotationChangedEvent.Broadcast(Owner->WristRotation); + } + + if ((bLocationUpdated && bRotationUpdated) && Owner->WristLocationAndRotationChangedEvent.IsBound()) + { + Owner->WristLocationAndRotationChangedEvent.Broadcast(Owner->WristLocation, Owner->WristRotation); + } +} + +void USGWristTrackerComponent::FImpl::DrawDebugWristTracker() const +{ + const UWorld* World{Owner->GetWorld()}; + const FSGWristTrackingDebuggingSettings& DebuggingSettings{Owner->GetWristTrackingSettings().DebuggingSettings}; + + FSGDebugGizmo::Draw(World, Owner->WristLocation, Owner->WristRotation, DebuggingSettings.DebugWristTrackerSettings); +} + +void USGWristTrackerComponent::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Engine/SGGameInstance.cpp b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Engine/SGGameInstance.cpp new file mode 100644 index 0000000..748135e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Engine/SGGameInstance.cpp @@ -0,0 +1,97 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGlove/Engine/SGGameInstance.h" + +#include "Engine/Engine.h" + +#include "SenseGlove/GameFramework/SGGameUserSettings.h" +#include "SGLog/SGLog.h" + +void USGGameInstance::SG_GetEngineScalabilitySettings() +{ + const USGGameUserSettings* GameUserSettings{USGGameUserSettings::GetInstance()}; + ensureAlwaysMsgf(GameUserSettings, TEXT("Invalid GameUserSettings!")); + + static UEnum* EnumPtr{StaticEnum()}; + ensureAlwaysMsgf(EnumPtr, TEXT("Failed to find the ESGEngineScalabilitySettings enum!")); + + const ESGEngineScalabilitySettings Scalability = GameUserSettings->GetEngineScalabilitySettings(); + const FName ScalabilityName{ + EnumPtr->GetNameByValue(static_cast(Scalability)) + }; + + SGLOG("Get Engine Scalability Settings", ScalabilityName); +} + +void USGGameInstance::SG_SetEngineScalabilitySettings(const ESGEngineScalabilitySettings Scalability) +{ + USGGameUserSettings* GameUserSettings{USGGameUserSettings::GetInstance()}; + ensureAlwaysMsgf(GameUserSettings, TEXT("Invalid GameUserSettings!")); + + static UEnum* EnumPtr{StaticEnum()}; + ensureAlwaysMsgf(EnumPtr, TEXT("Failed to find the ESGEngineScalabilitySettings enum!")); + + GameUserSettings->SetEngineScalabilitySettings(Scalability); + + const FName ScalabilityName{ + EnumPtr->GetNameByValue(static_cast(Scalability)) + }; + + SGLOG("Set Engine Scalability Settings", ScalabilityName); +} + +USGGameInstance::USGGameInstance(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ +} + +void USGGameInstance::Init() +{ + Super::Init(); + + SGLOG("Initializing the SenseGlove GameInstance...") + + SGLOG("The SenseGlove GameInstance has been initialized successfully!") +} + +void USGGameInstance::Shutdown() +{ + Super::Shutdown(); + + SGLOG("Shutting down the SenseGlove GameInstance...") + + SGLOG("The SenseGlove GameInstance has been shutdown successfully!") +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/GameFramework/SGGameModeBase.cpp b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/GameFramework/SGGameModeBase.cpp new file mode 100644 index 0000000..a58adc5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/GameFramework/SGGameModeBase.cpp @@ -0,0 +1,46 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGlove/GameFramework/SGGameModeBase.h" + +#include "SenseGlove/GameFramework/SGPawn.h" +#include "SenseGlove/GameFramework/SGPlayerController.h" + +ASGGameModeBase::ASGGameModeBase(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + DefaultPawnClass = ASGPawn::StaticClass(); + PlayerControllerClass = ASGPlayerController::StaticClass(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/GameFramework/SGGameUserSettings.cpp b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/GameFramework/SGGameUserSettings.cpp new file mode 100644 index 0000000..1f399d7 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/GameFramework/SGGameUserSettings.cpp @@ -0,0 +1,307 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGlove/GameFramework/SGGameUserSettings.h" + +#include "Engine/Engine.h" +#include "HAL/IConsoleManager.h" +#include "Misc/ConfigCacheIni.h" +#include "Runtime/Launch/Resources/Version.h" +#include "Scalability.h" + +#include "SGSettings/SGSettings.h" + +struct USGGameUserSettings::FImpl +{ + /************************ + * Static methods + ************************/ + + static float GetRenderScaleLevelFromQualityLevel( + int32 InQualityLevel, + Scalability::EQualityLevelBehavior Behavior = Scalability::EQualityLevelBehavior::EAbsolute); + + /************************ + * Owner object + ************************/ + + USGGameUserSettings* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGGameUserSettings* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; + + /************************ + * Methods + ************************/ + + bool DoesCurrentSettingsMatch(ESGEngineScalabilitySettings Scalability) const; +}; + +float USGGameUserSettings::FImpl::GetRenderScaleLevelFromQualityLevel( + const int32 InQualityLevel, const Scalability::EQualityLevelBehavior Behavior) +{ + if (!ensureAlwaysMsgf(GConfig, TEXT("Invalid GConfig!"))) + { + return 0.0f; + } + + TArray ResolutionValueStrings; + GConfig->GetSingleLineArray(TEXT("ScalabilitySettings"), TEXT("PerfIndexValues_ResolutionQuality"), + ResolutionValueStrings, GScalabilityIni); + + if (ResolutionValueStrings.Num() == 0) + { + UE_LOG(LogConsoleResponse, Display, + TEXT("Failed to find resolution value strings in scalability ini. Falling back to the default.")); + return 100.0f; + } + + // No negative levels! + int32 QualityLevel = FMath::Max(0, InQualityLevel); + if (Behavior == Scalability::EQualityLevelBehavior::ERelativeToMax) + { + QualityLevel = FMath::Max(ResolutionValueStrings.Num() - 1 - QualityLevel, 0); + } + else + { + QualityLevel = FMath::Clamp(QualityLevel, 0, ResolutionValueStrings.Num() - 1); + } + + return FCString::Atof(*ResolutionValueStrings[QualityLevel]); +} + +USGGameUserSettings::USGGameUserSettings(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +USGGameUserSettings* USGGameUserSettings::GetInstance() +{ + USGGameUserSettings* Instance{GEngine ? Cast(GEngine->GetGameUserSettings()) : nullptr}; + ensureAlwaysMsgf(Instance, TEXT("Invalid GameUserSettings!")); + return Instance; +} + +ESGEngineScalabilitySettings USGGameUserSettings::GetEngineScalabilitySettings() const +{ + const bool bDoesCurrentSettingsMatchLow = Pimpl->DoesCurrentSettingsMatch(ESGEngineScalabilitySettings::Low); + if (bDoesCurrentSettingsMatchLow) + { + return ESGEngineScalabilitySettings::Low; + } + + const bool bDoesCurrentSettingsMatchMedium = Pimpl->DoesCurrentSettingsMatch(ESGEngineScalabilitySettings::Medium); + if (bDoesCurrentSettingsMatchMedium) + { + return ESGEngineScalabilitySettings::Medium; + } + + const bool bDoesCurrentSettingsMatchHigh = Pimpl->DoesCurrentSettingsMatch(ESGEngineScalabilitySettings::High); + if (bDoesCurrentSettingsMatchHigh) + { + return ESGEngineScalabilitySettings::High; + } + + const bool bDoesCurrentSettingsMatchEpic = Pimpl->DoesCurrentSettingsMatch(ESGEngineScalabilitySettings::Epic); + if (bDoesCurrentSettingsMatchEpic) + { + return ESGEngineScalabilitySettings::Epic; + } + + const bool bDoesCurrentSettingsMatchCinematic = Pimpl->DoesCurrentSettingsMatch( + ESGEngineScalabilitySettings::Cinematic); + if (bDoesCurrentSettingsMatchCinematic) + { + return ESGEngineScalabilitySettings::Cinematic; + } + + return ESGEngineScalabilitySettings::Custom; +} + +void USGGameUserSettings::SetEngineScalabilitySettings(ESGEngineScalabilitySettings Scalability) +{ + if (!ensureAlwaysMsgf(Scalability != ESGEngineScalabilitySettings::Custom, + TEXT("Cannot set the engine scalability directly to custom!" + " It should be either: Low, Medium, High, Epic, Cinematic," + " or Auto (determined by hardware benchmarking)!"))) + { + return; + } + + const FSGHardwareBenchmarkingSettings& Settings{ + USGSettings::GetInstance()->GetGameUserSettings().HardwareBenchmarkingSettings + }; + + if (IsDirty()) + { + ValidateSettings(); + ConfirmVideoMode(); + } + + if (Scalability != ESGEngineScalabilitySettings::Auto) + { + const int32 ScalabilityValue = static_cast(Scalability); + + const float ResolutionScaleNormalized = FImpl::GetRenderScaleLevelFromQualityLevel( + ScalabilityValue, Scalability::EQualityLevelBehavior::EAbsolute); + SetResolutionScaleNormalized(ResolutionScaleNormalized); + + ScalabilityQuality.SetViewDistanceQuality(ScalabilityValue); + ScalabilityQuality.SetAntiAliasingQuality(ScalabilityValue); + ScalabilityQuality.SetShadowQuality(ScalabilityValue); + ScalabilityQuality.SetGlobalIlluminationQuality(ScalabilityValue); + ScalabilityQuality.SetReflectionQuality(ScalabilityValue); + ScalabilityQuality.SetPostProcessQuality(ScalabilityValue); + ScalabilityQuality.SetTextureQuality(ScalabilityValue); + ScalabilityQuality.SetEffectsQuality(ScalabilityValue); + ScalabilityQuality.SetFoliageQuality(ScalabilityValue); + ScalabilityQuality.SetShadingQuality(ScalabilityValue); +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4 + ScalabilityQuality.SetLandscapeQuality(ScalabilityValue); +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4 */ + } + else + { + RunHardwareBenchmark( + Settings.WorkScale, + Settings.CPUMultiplier, + Settings.GPUMultiplier); + ApplyHardwareBenchmarkResults(); + } + + ConfirmVideoMode(); + ApplySettings(false); +} + +USGGameUserSettings::FImpl::FImpl(USGGameUserSettings* InOwner) + : Owner(InOwner) +{ +} + +USGGameUserSettings::FImpl::~FImpl() = default; + +bool USGGameUserSettings::FImpl::DoesCurrentSettingsMatch(const ESGEngineScalabilitySettings Scalability) const +{ + static const float ResolutionScaleNormalizedLow = FImpl::GetRenderScaleLevelFromQualityLevel( + static_cast(ESGEngineScalabilitySettings::Low)); + static const float ResolutionScaleNormalizedMedium = FImpl::GetRenderScaleLevelFromQualityLevel( + static_cast(ESGEngineScalabilitySettings::Medium)); + static const float ResolutionScaleNormalizedHigh = FImpl::GetRenderScaleLevelFromQualityLevel( + static_cast(ESGEngineScalabilitySettings::High)); + static const float ResolutionScaleNormalizedEpic = FImpl::GetRenderScaleLevelFromQualityLevel( + static_cast(ESGEngineScalabilitySettings::Epic)); + static const float ResolutionScaleNormalizedCinematic = FImpl::GetRenderScaleLevelFromQualityLevel( + static_cast(ESGEngineScalabilitySettings::Cinematic)); + + float ResolutionScaleNormalized = 0.0f; + switch (Scalability) + { + case ESGEngineScalabilitySettings::Low: + ResolutionScaleNormalized = ResolutionScaleNormalizedLow; + break; + case ESGEngineScalabilitySettings::Medium: + ResolutionScaleNormalized = ResolutionScaleNormalizedMedium; + break; + case ESGEngineScalabilitySettings::High: + ResolutionScaleNormalized = ResolutionScaleNormalizedHigh; + break; + case ESGEngineScalabilitySettings::Epic: + ResolutionScaleNormalized = ResolutionScaleNormalizedEpic; + break; + case ESGEngineScalabilitySettings::Cinematic: + ResolutionScaleNormalized = ResolutionScaleNormalizedCinematic; + break; + default: + ensureAlwaysMsgf(false, TEXT("Login Error: the execution flow should never reach here!")); + break; + } + + const int32 ScalabilityValue = static_cast(Scalability); + + const float CurrentResolutionScaleNormalized = FImpl::GetRenderScaleLevelFromQualityLevel( + ScalabilityValue, Scalability::EQualityLevelBehavior::EAbsolute); + + const int32 CurrentViewDistanceQuality = Owner->ScalabilityQuality.ViewDistanceQuality; + const int32 CurrentAntiAliasingQuality = Owner->ScalabilityQuality.AntiAliasingQuality; + const int32 CurrentShadowQuality = Owner->ScalabilityQuality.ShadowQuality; + const int32 CurrentGlobalIlluminationQuality = Owner->ScalabilityQuality.GlobalIlluminationQuality; + const int32 CurrentReflectionQuality = Owner->ScalabilityQuality.ReflectionQuality; + const int32 CurrentPostProcessingQuality = Owner->ScalabilityQuality.PostProcessQuality; + const int32 CurrentTextureQuality = Owner->ScalabilityQuality.TextureQuality; + const int32 CurrentEffectQuality = Owner->ScalabilityQuality.EffectsQuality; + const int32 CurrentFoliageQuality = Owner->ScalabilityQuality.FoliageQuality; + const int32 CurrentShadingQuality = Owner->ScalabilityQuality.ShadingQuality; +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4 + const int32 CurrentLandscapeQuality = Owner->ScalabilityQuality.LandscapeQuality; +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4 */ + + if (FMath::IsNearlyEqual(CurrentResolutionScaleNormalized, ResolutionScaleNormalized) + && CurrentViewDistanceQuality == ScalabilityValue + && CurrentAntiAliasingQuality == ScalabilityValue + && CurrentShadowQuality == ScalabilityValue + && CurrentGlobalIlluminationQuality == ScalabilityValue + && CurrentReflectionQuality == ScalabilityValue + && CurrentPostProcessingQuality == ScalabilityValue + && CurrentTextureQuality == ScalabilityValue + && CurrentEffectQuality == ScalabilityValue + && CurrentFoliageQuality == ScalabilityValue + && CurrentShadingQuality == ScalabilityValue +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4 + && CurrentLandscapeQuality == ScalabilityValue +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4 */ + ) + { + return true; + } + + return false; +} + +void USGGameUserSettings::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp new file mode 100644 index 0000000..319adc6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPawn.cpp @@ -0,0 +1,2285 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGlove/GameFramework/SGPawn.h" + +#include "Camera/CameraComponent.h" +#include "Components/PrimitiveComponent.h" +#include "Components/SphereComponent.h" +#include "Kismet/KismetMathLibrary.h" +#include "Runtime/Launch/Resources/Version.h" +#include "UObject/UObjectGlobals.h" +#include "XRDeviceVisualizationComponent.h" + +#include "SenseGlove/Components/SGGrabComponent.h" +#include "SenseGlove/Components/SGTouchComponent.h" +#include "SenseGlove/Components/SGVirtualHandComponent.h" +#include "SenseGlove/Components/SGWristTrackerComponent.h" +#include "SGSettings/SGSettings.h" +#include "SGLog/SGLog.h" + +struct ASGPawn::FImpl +{ + /************************ + * Static methods + ************************/ + + /************************ + * Owner object + ************************/ + + ASGPawn* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(ASGPawn* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; + + /************************ + * Methods + ************************/ + + void BindRealHandsOverlapEvents(); + void UnbindRealHandsOverlapEvents(); + + void BindFingerGrabOverlapEvents(); + void UnbindFingerGrabOverlapEvents(); + + void BindFingerTouchOverlapEvents(); + void UnbindFingerTouchOverlapEvents(); + + void SetVisibility(USceneComponent* SceneComponent, const bool bVisibility) const; + + void UpdateHandLocation(const bool bRight, const FVector& Location, const bool bUpdateVirtualHand) const; + void UpdateLeftHandLocation(const FVector& Location, const bool bUpdateVirtualHand) const; + void UpdateRightHandLocation(const FVector& Location, const bool bUpdateVirtualHand) const; + + void UpdateHandRotation(const bool bRight, const FRotator& Rotation, const bool bUpdateVirtualHand); + void UpdateLeftHandRotation(const FRotator& Rotation, const bool bUpdateVirtualHand); + void UpdateRightHandRotation(const FRotator& Rotation, const bool bUpdateVirtualHand); + + void UpdateHandLocationAndRotation( + const bool bRight, const FVector& Location, const FRotator& Rotation, const bool bUpdateVirtualHand); + void UpdateLeftHandLocationAndRotation( + const FVector& Location, const FRotator& Rotation, const bool bUpdateVirtualHand); + void UpdateRightHandLocationAndRotation( + const FVector& Location, const FRotator& Rotation, const bool bUpdateVirtualHand); + + void SetFingerColliderCollisionEnabled(USphereComponent* Collider, bool bEnabled) const; + void SetAllFingersColliderCollisionEnabled(bool bRight, bool bEnabled) const; + + FORCEINLINE void RegisterLeftHandOverlappedActor(const AActor* Actor) const + { + Owner->LeftHandOverlappedActors.AddUnique(Actor); + } + + FORCEINLINE void UnregisterLeftHandOverlappedActor(const AActor* Actor) const + { + Owner->LeftHandOverlappedActors.Remove(Actor); + } + + FORCEINLINE void RegisterRightHandOverlappedActor(const AActor* Actor) const + { + Owner->RightHandOverlappedActors.AddUnique(Actor); + } + + FORCEINLINE void UnregisterRightHandOverlappedActor(const AActor* Actor) const + { + Owner->RightHandOverlappedActors.Remove(Actor); + } + + FORCEINLINE bool IsLeftHandOverlappingWithAnyActor() const + { + return Owner->LeftHandOverlappedActors.Num() > 0; + } + + FORCEINLINE bool IsRightHandOverlappingWithAnyActor() const + { + return Owner->RightHandOverlappedActors.Num() > 0; + } + + void ApplyHandVelocityToGrabbedActor(const FSGGrabState& GrabState) const; + + void SetGrabbedActor(FSGGrabState& GrabState, AActor* Actor) const; + void SetLeftHandGrabbedActor(AActor* Actor) const; + void SetRightHandGrabbedActor(AActor* Actor) const; + + void RecordHandVelocity(FSGGrabState& GrabState, const float DeltaSeconds) const; + + void Release(FSGGrabState& GrabState) const; + + void TriggerGrabStateUpdatedEvent(const FSGGrabState& GrabState) const; + void TriggerTouchStateUpdatedEvent(const FSGTouchState& TouchState) const; + void TriggerActorGrabbedEvent(const USGVirtualHandComponent* Hand, const AActor* Actor) const; + void TriggerActorReleasedEvent(const USGVirtualHandComponent* Hand, const AActor* Actor) const; + void TriggerBeginTouch(const USGVirtualHandComponent* Hand, const AActor* Actor) const; + void TriggerEndTouch(const USGVirtualHandComponent* Hand, const AActor* Actor) const; +}; + +ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + PrimaryActorTick.bCanEverTick = true; + + SceneRoot = ObjectInitializer.CreateDefaultSubobject(this, TEXT("SceneRoot")); + SetRootComponent(SceneRoot); + + Camera = ObjectInitializer.CreateDefaultSubobject(this, TEXT("Camera")); + Camera->SetupAttachment(GetRootComponent()); + Camera->SetCanEverAffectNavigation(false); + + WristTrackerLeft = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("WristTrackerLeft")); + WristTrackerLeft->SetupAttachment(GetRootComponent()); + WristTrackerLeft->SetRight(false); + + ControllerVisualizerLeft = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("ControllerVisualizerLeft")); + ControllerVisualizerLeft->SetupAttachment(WristTrackerLeft); + ControllerVisualizerLeft->SetDisplayModelSource(FName("OpenXR")); + + HandLeft = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("HandLeft")); + HandLeft->SetupAttachment(GetRootComponent()); + HandLeft->SetCanEverAffectNavigation(false); + HandLeft->SetGenerateOverlapEvents(true); + HandLeft->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + HandLeft->SetCollisionObjectType(ECC_Pawn); + HandLeft->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); + HandLeft->SetCollisionResponseToAllChannels(ECR_Block); + HandLeft->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Block); + HandLeft->SetCollisionResponseToChannel(ECC_WorldDynamic, ECR_Block); + HandLeft->SetCollisionResponseToChannel(ECC_Pawn, ECR_Block); + HandLeft->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block); + HandLeft->SetCollisionResponseToChannel(ECC_PhysicsBody, ECR_Block); + HandLeft->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Block); + HandLeft->SetCollisionResponseToChannel(ECC_Destructible, ECR_Block); + HandLeft->SetRight(false); + + const FSGVirtualHandSettings LeftHandSettings{HandLeft->GetVirtualHandSettings()}; + HandLeft->SetRelativeRotation(LeftHandSettings.MeshSettings.RootBoneRotationCorrection, + false, nullptr, ETeleportType::None); + HandLeft->SetRelativeLocation(FVector{30.0f, -20.0f, -10.0f}, + false, nullptr, ETeleportType::None); + HandLeft->SetWristTracker(WristTrackerLeft); + + RealHandLeft = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("RealHandLeft")); + RealHandLeft->SetupAttachment(GetRootComponent()); + RealHandLeft->SetCanEverAffectNavigation(false); + RealHandLeft->SetGenerateOverlapEvents(true); + RealHandLeft->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + RealHandLeft->SetCollisionObjectType(ECC_Pawn); + RealHandLeft->SetCollisionEnabled(ECollisionEnabled::QueryOnly); + RealHandLeft->SetCollisionResponseToAllChannels(ECR_Overlap); + RealHandLeft->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Overlap); + RealHandLeft->SetCollisionResponseToChannel(ECC_WorldDynamic, ECR_Overlap); + RealHandLeft->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap); + RealHandLeft->SetCollisionResponseToChannel(ECC_Visibility, ECR_Overlap); + RealHandLeft->SetCollisionResponseToChannel(ECC_PhysicsBody, ECR_Overlap); + RealHandLeft->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Overlap); + RealHandLeft->SetCollisionResponseToChannel(ECC_Destructible, ECR_Overlap); + RealHandLeft->SetRight(false); + Pimpl->SetVisibility(RealHandLeft, false); + + const FSGVirtualHandMeshSettings RealLeftHandMeshSettings{HandLeft->GetVirtualHandSettings().MeshSettings}; + RealHandLeft->SetRelativeRotation(RealLeftHandMeshSettings.RootBoneRotationCorrection, + false, nullptr, ETeleportType::None); + RealHandLeft->SetRelativeLocation(FVector{30.0f, -20.0f, -10.0f}, + false, nullptr, ETeleportType::None); + RealHandLeft->SetWristTracker(WristTrackerLeft); + + LeftThumbFingertipGrabCollider = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("LeftThumbFingertipGrabCollider")); + LeftThumbFingertipGrabCollider->SetRelativeScale3D(LeftHandSettings.GrabSettings.DefaultColliderSize); + LeftThumbFingertipGrabCollider->SetupAttachment(HandLeft, LeftHandSettings.GrabSettings.ThumbColliderSocketName); + LeftThumbFingertipGrabCollider->SetCastShadow(false); + LeftThumbFingertipGrabCollider->bCastDynamicShadow = false; + LeftThumbFingertipGrabCollider->SetReceivesDecals(true); + LeftThumbFingertipGrabCollider->SetCanEverAffectNavigation(false); + LeftThumbFingertipGrabCollider->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + LeftThumbFingertipGrabCollider->SetCollisionObjectType(ECC_Pawn); + Pimpl->SetFingerColliderCollisionEnabled(LeftThumbFingertipGrabCollider, true); + + LeftIndexFingertipGrabCollider = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("LeftIndexFingertipGrabCollider")); + LeftIndexFingertipGrabCollider->SetRelativeScale3D(LeftHandSettings.GrabSettings.DefaultColliderSize); + LeftIndexFingertipGrabCollider->SetupAttachment(HandLeft, LeftHandSettings.GrabSettings.IndexColliderSocketName); + LeftIndexFingertipGrabCollider->SetCastShadow(false); + LeftIndexFingertipGrabCollider->bCastDynamicShadow = false; + LeftIndexFingertipGrabCollider->SetReceivesDecals(true); + LeftIndexFingertipGrabCollider->SetCanEverAffectNavigation(false); + LeftIndexFingertipGrabCollider->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + LeftIndexFingertipGrabCollider->SetCollisionObjectType(ECC_Pawn); + Pimpl->SetFingerColliderCollisionEnabled(LeftIndexFingertipGrabCollider, true); + + LeftMiddleFingertipGrabCollider = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("LeftMiddleFingertipGrabCollider")); + LeftMiddleFingertipGrabCollider->SetRelativeScale3D(LeftHandSettings.GrabSettings.DefaultColliderSize); + LeftMiddleFingertipGrabCollider->SetupAttachment(HandLeft, LeftHandSettings.GrabSettings.MiddleColliderSocketName); + LeftMiddleFingertipGrabCollider->SetCastShadow(false); + LeftMiddleFingertipGrabCollider->bCastDynamicShadow = false; + LeftMiddleFingertipGrabCollider->SetReceivesDecals(true); + LeftMiddleFingertipGrabCollider->SetCanEverAffectNavigation(false); + LeftMiddleFingertipGrabCollider->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + LeftMiddleFingertipGrabCollider->SetCollisionObjectType(ECC_Pawn); + Pimpl->SetFingerColliderCollisionEnabled(LeftMiddleFingertipGrabCollider, true); + + LeftThumbFingertipTouchCollider = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("LeftThumbFingertipTouchCollider")); + LeftThumbFingertipTouchCollider->SetRelativeScale3D(LeftHandSettings.TouchSettings.DefaultColliderSize); + LeftThumbFingertipTouchCollider->SetupAttachment(HandLeft, LeftHandSettings.TouchSettings.ThumbColliderSocketName); + LeftThumbFingertipTouchCollider->SetCastShadow(false); + LeftThumbFingertipTouchCollider->bCastDynamicShadow = false; + LeftThumbFingertipTouchCollider->SetReceivesDecals(true); + LeftThumbFingertipTouchCollider->SetCanEverAffectNavigation(false); + LeftThumbFingertipTouchCollider->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + LeftThumbFingertipTouchCollider->SetCollisionObjectType(ECC_Pawn); + Pimpl->SetFingerColliderCollisionEnabled(LeftThumbFingertipTouchCollider, true); + + LeftIndexFingertipTouchCollider = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("LeftIndexFingertipTouchCollider")); + LeftIndexFingertipTouchCollider->SetRelativeScale3D(LeftHandSettings.TouchSettings.DefaultColliderSize); + LeftIndexFingertipTouchCollider->SetupAttachment(HandLeft, LeftHandSettings.TouchSettings.IndexColliderSocketName); + LeftIndexFingertipTouchCollider->SetCastShadow(false); + LeftIndexFingertipTouchCollider->bCastDynamicShadow = false; + LeftIndexFingertipTouchCollider->SetReceivesDecals(true); + LeftIndexFingertipTouchCollider->SetCanEverAffectNavigation(false); + LeftIndexFingertipTouchCollider->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + LeftIndexFingertipTouchCollider->SetCollisionObjectType(ECC_Pawn); + Pimpl->SetFingerColliderCollisionEnabled(LeftIndexFingertipTouchCollider, true); + + LeftMiddleFingertipTouchCollider = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("LeftMiddleFingertipTouchCollider")); + LeftMiddleFingertipTouchCollider->SetRelativeScale3D(LeftHandSettings.TouchSettings.DefaultColliderSize); + LeftMiddleFingertipTouchCollider->SetupAttachment( + HandLeft, LeftHandSettings.TouchSettings.MiddleColliderSocketName); + LeftMiddleFingertipTouchCollider->SetCastShadow(false); + LeftMiddleFingertipTouchCollider->bCastDynamicShadow = false; + LeftMiddleFingertipTouchCollider->SetReceivesDecals(true); + LeftMiddleFingertipTouchCollider->SetCanEverAffectNavigation(false); + LeftMiddleFingertipTouchCollider->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + LeftMiddleFingertipTouchCollider->SetCollisionObjectType(ECC_Pawn); + LeftMiddleFingertipTouchCollider->SetCollisionEnabled(ECollisionEnabled::QueryOnly); + Pimpl->SetFingerColliderCollisionEnabled(LeftMiddleFingertipTouchCollider, true); + + LeftRingFingertipTouchCollider = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("LeftRingFingertipTouchCollider")); + LeftRingFingertipTouchCollider->SetRelativeScale3D(LeftHandSettings.TouchSettings.DefaultColliderSize); + LeftRingFingertipTouchCollider->SetupAttachment(HandLeft, LeftHandSettings.TouchSettings.RingColliderSocketName); + LeftRingFingertipTouchCollider->SetCastShadow(false); + LeftRingFingertipTouchCollider->bCastDynamicShadow = false; + LeftRingFingertipTouchCollider->SetReceivesDecals(true); + LeftRingFingertipTouchCollider->SetCanEverAffectNavigation(false); + LeftRingFingertipTouchCollider->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + LeftRingFingertipTouchCollider->SetCollisionObjectType(ECC_Pawn); + Pimpl->SetFingerColliderCollisionEnabled(LeftRingFingertipTouchCollider, true); + + LeftPinkyFingertipTouchCollider = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("LeftPinkyFingertipTouchCollider")); + LeftPinkyFingertipTouchCollider->SetRelativeScale3D(LeftHandSettings.TouchSettings.DefaultColliderSize); + LeftPinkyFingertipTouchCollider->SetupAttachment(HandLeft, LeftHandSettings.TouchSettings.PinkyColliderSocketName); + LeftPinkyFingertipTouchCollider->SetCastShadow(false); + LeftPinkyFingertipTouchCollider->bCastDynamicShadow = false; + LeftPinkyFingertipTouchCollider->SetReceivesDecals(true); + LeftPinkyFingertipTouchCollider->SetCanEverAffectNavigation(false); + LeftPinkyFingertipTouchCollider->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + LeftPinkyFingertipTouchCollider->SetCollisionObjectType(ECC_Pawn); + Pimpl->SetFingerColliderCollisionEnabled(LeftPinkyFingertipTouchCollider, true); + + WristTrackerRight = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("WristTrackerRight")); + WristTrackerRight->SetupAttachment(GetRootComponent()); + WristTrackerRight->SetRight(true); + + ControllerVisualizerRight = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("ControllerVisualizerRight")); + ControllerVisualizerRight->SetupAttachment(WristTrackerRight); + ControllerVisualizerRight->SetDisplayModelSource(FName("OpenXR")); + + HandRight = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("HandRight")); + HandRight->SetupAttachment(GetRootComponent()); + HandRight->SetCanEverAffectNavigation(false); + HandRight->SetGenerateOverlapEvents(true); + HandRight->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + HandRight->SetCollisionObjectType(ECC_Pawn); + HandRight->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); + HandRight->SetCollisionResponseToAllChannels(ECR_Block); + HandRight->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Block); + HandRight->SetCollisionResponseToChannel(ECC_WorldDynamic, ECR_Block); + HandRight->SetCollisionResponseToChannel(ECC_Pawn, ECR_Block); + HandRight->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block); + HandRight->SetCollisionResponseToChannel(ECC_PhysicsBody, ECR_Block); + HandRight->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Block); + HandRight->SetCollisionResponseToChannel(ECC_Destructible, ECR_Block); + HandRight->SetRight(true); + + const FSGVirtualHandSettings RightHandSettings{HandRight->GetVirtualHandSettings()}; + HandRight->SetRelativeRotation(RightHandSettings.MeshSettings.RootBoneRotationCorrection, + false, nullptr, ETeleportType::None); + HandRight->SetRelativeLocation(FVector{30.0f, 20.0f, -10.0f}, + false, nullptr, ETeleportType::None); + HandRight->SetWristTracker(WristTrackerRight); + + RealHandRight = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("RealHandRight")); + RealHandRight->SetupAttachment(GetRootComponent()); + RealHandRight->SetCanEverAffectNavigation(false); + RealHandRight->SetGenerateOverlapEvents(true); + RealHandRight->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + RealHandRight->SetCollisionObjectType(ECC_Pawn); + RealHandRight->SetCollisionEnabled(ECollisionEnabled::QueryOnly); + RealHandRight->SetCollisionResponseToAllChannels(ECR_Overlap); + RealHandRight->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Overlap); + RealHandRight->SetCollisionResponseToChannel(ECC_WorldDynamic, ECR_Overlap); + RealHandRight->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap); + RealHandRight->SetCollisionResponseToChannel(ECC_Visibility, ECR_Overlap); + RealHandRight->SetCollisionResponseToChannel(ECC_PhysicsBody, ECR_Overlap); + RealHandRight->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Overlap); + RealHandRight->SetCollisionResponseToChannel(ECC_Destructible, ECR_Overlap); + RealHandRight->SetRight(true); + Pimpl->SetVisibility(RealHandRight, false); + + const FSGVirtualHandMeshSettings RealRightHandMeshSettings{HandRight->GetVirtualHandSettings().MeshSettings}; + RealHandRight->SetRelativeRotation(RealRightHandMeshSettings.RootBoneRotationCorrection, + false, nullptr, ETeleportType::None); + RealHandRight->SetRelativeLocation(FVector{30.0f, 20.0f, -10.0f}, + false, nullptr, ETeleportType::None); + RealHandRight->SetWristTracker(WristTrackerRight); + + RightThumbFingertipGrabCollider = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("RightThumbFingertipGrabCollider")); + RightThumbFingertipGrabCollider->SetRelativeScale3D(RightHandSettings.GrabSettings.DefaultColliderSize); + RightThumbFingertipGrabCollider->SetupAttachment(HandRight, RightHandSettings.GrabSettings.ThumbColliderSocketName); + RightThumbFingertipGrabCollider->SetCastShadow(false); + RightThumbFingertipGrabCollider->bCastDynamicShadow = false; + RightThumbFingertipGrabCollider->SetReceivesDecals(true); + RightThumbFingertipGrabCollider->SetCanEverAffectNavigation(false); + RightThumbFingertipGrabCollider->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + RightThumbFingertipGrabCollider->SetCollisionObjectType(ECC_Pawn); + Pimpl->SetFingerColliderCollisionEnabled(RightThumbFingertipGrabCollider, true); + + RightIndexFingertipGrabCollider = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("RightIndexFingertipGrabCollider")); + RightIndexFingertipGrabCollider->SetRelativeScale3D(RightHandSettings.GrabSettings.DefaultColliderSize); + RightIndexFingertipGrabCollider->SetupAttachment(HandRight, RightHandSettings.GrabSettings.IndexColliderSocketName); + RightIndexFingertipGrabCollider->SetCastShadow(false); + RightIndexFingertipGrabCollider->bCastDynamicShadow = false; + RightIndexFingertipGrabCollider->SetReceivesDecals(true); + RightIndexFingertipGrabCollider->SetCanEverAffectNavigation(false); + RightIndexFingertipGrabCollider->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + RightIndexFingertipGrabCollider->SetCollisionObjectType(ECC_Pawn); + Pimpl->SetFingerColliderCollisionEnabled(RightIndexFingertipGrabCollider, true); + + RightMiddleFingertipGrabCollider = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("RightMiddleFingertipGrabCollider")); + RightMiddleFingertipGrabCollider->SetRelativeScale3D(RightHandSettings.GrabSettings.DefaultColliderSize); + RightMiddleFingertipGrabCollider->SetupAttachment( + HandRight, RightHandSettings.GrabSettings.MiddleColliderSocketName); + RightMiddleFingertipGrabCollider->SetCastShadow(false); + RightMiddleFingertipGrabCollider->bCastDynamicShadow = false; + RightMiddleFingertipGrabCollider->SetReceivesDecals(true); + RightMiddleFingertipGrabCollider->SetCanEverAffectNavigation(false); + RightMiddleFingertipGrabCollider->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + RightMiddleFingertipGrabCollider->SetCollisionObjectType(ECC_Pawn); + Pimpl->SetFingerColliderCollisionEnabled(RightMiddleFingertipGrabCollider, true); + + RightThumbFingertipTouchCollider = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("RightThumbFingertipTouchCollider")); + RightThumbFingertipTouchCollider->SetRelativeScale3D(RightHandSettings.TouchSettings.DefaultColliderSize); + RightThumbFingertipTouchCollider->SetupAttachment( + HandRight, RightHandSettings.TouchSettings.ThumbColliderSocketName); + RightThumbFingertipTouchCollider->SetCastShadow(false); + RightThumbFingertipTouchCollider->bCastDynamicShadow = false; + RightThumbFingertipTouchCollider->SetReceivesDecals(true); + RightThumbFingertipTouchCollider->SetCanEverAffectNavigation(false); + RightThumbFingertipTouchCollider->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + RightThumbFingertipTouchCollider->SetCollisionObjectType(ECC_Pawn); + Pimpl->SetFingerColliderCollisionEnabled(RightThumbFingertipTouchCollider, true); + + RightIndexFingertipTouchCollider = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("RightIndexFingertipTouchCollider")); + RightIndexFingertipTouchCollider->SetRelativeScale3D(RightHandSettings.TouchSettings.DefaultColliderSize); + RightIndexFingertipTouchCollider->SetupAttachment( + HandRight, RightHandSettings.TouchSettings.IndexColliderSocketName); + RightIndexFingertipTouchCollider->SetCastShadow(false); + RightIndexFingertipTouchCollider->bCastDynamicShadow = false; + RightIndexFingertipTouchCollider->SetReceivesDecals(true); + RightIndexFingertipTouchCollider->SetCanEverAffectNavigation(false); + RightIndexFingertipTouchCollider->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + RightIndexFingertipTouchCollider->SetCollisionObjectType(ECC_Pawn); + Pimpl->SetFingerColliderCollisionEnabled(RightIndexFingertipTouchCollider, true); + + RightMiddleFingertipTouchCollider = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("RightMiddleFingertipTouchCollider")); + RightMiddleFingertipTouchCollider->SetRelativeScale3D(RightHandSettings.TouchSettings.DefaultColliderSize); + RightMiddleFingertipTouchCollider->SetupAttachment( + HandRight, RightHandSettings.TouchSettings.MiddleColliderSocketName); + RightMiddleFingertipTouchCollider->SetCastShadow(false); + RightMiddleFingertipTouchCollider->bCastDynamicShadow = false; + RightMiddleFingertipTouchCollider->SetReceivesDecals(true); + RightMiddleFingertipTouchCollider->SetCanEverAffectNavigation(false); + RightMiddleFingertipTouchCollider->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + RightMiddleFingertipTouchCollider->SetCollisionObjectType(ECC_Pawn); + Pimpl->SetFingerColliderCollisionEnabled(RightMiddleFingertipTouchCollider, true); + + RightRingFingertipTouchCollider = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("RightRingFingertipTouchCollider")); + RightRingFingertipTouchCollider->SetRelativeScale3D(RightHandSettings.TouchSettings.DefaultColliderSize); + RightRingFingertipTouchCollider->SetupAttachment(HandRight, RightHandSettings.TouchSettings.RingColliderSocketName); + RightRingFingertipTouchCollider->SetCastShadow(false); + RightRingFingertipTouchCollider->bCastDynamicShadow = false; + RightRingFingertipTouchCollider->SetReceivesDecals(true); + RightRingFingertipTouchCollider->SetCanEverAffectNavigation(false); + RightRingFingertipTouchCollider->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + RightRingFingertipTouchCollider->SetCollisionObjectType(ECC_Pawn); + Pimpl->SetFingerColliderCollisionEnabled(RightRingFingertipTouchCollider, true); + + RightPinkyFingertipTouchCollider = ObjectInitializer.CreateDefaultSubobject( + this, TEXT("RightPinkyFingertipTouchCollider")); + RightPinkyFingertipTouchCollider->SetRelativeScale3D(RightHandSettings.TouchSettings.DefaultColliderSize); + RightPinkyFingertipTouchCollider->SetupAttachment( + HandRight, RightHandSettings.TouchSettings.PinkyColliderSocketName); + RightPinkyFingertipTouchCollider->SetCastShadow(false); + RightPinkyFingertipTouchCollider->bCastDynamicShadow = false; + RightPinkyFingertipTouchCollider->SetReceivesDecals(true); + RightPinkyFingertipTouchCollider->SetCanEverAffectNavigation(false); + RightPinkyFingertipTouchCollider->CanCharacterStepUpOn = ECanBeCharacterBase::ECB_Owner; + RightPinkyFingertipTouchCollider->SetCollisionObjectType(ECC_Pawn); + Pimpl->SetFingerColliderCollisionEnabled(RightPinkyFingertipTouchCollider, true); + + MaxNumberOfHandVelocitySamples = 10; + + LeftHandGrabState = FSGGrabState{ + HandLeft, FVector::Zero(), {}, nullptr, nullptr, nullptr, nullptr + }; + LeftHandTouchState = FSGTouchState{ + HandLeft, nullptr, nullptr, nullptr, nullptr, nullptr + }; + + RightHandGrabState = FSGGrabState{ + HandRight, FVector::Zero(), {}, nullptr, nullptr, nullptr, nullptr + }; + RightHandTouchState = FSGTouchState{ + HandRight, nullptr, nullptr, nullptr, nullptr, nullptr + }; +} + +void ASGPawn::OnGrabStateUpdated_Implementation(const FSGGrabState& GrabState) +{ +} + +void ASGPawn::OnTouchStateUpdated_Implementation(const FSGTouchState& TouchState) +{ +} + +void ASGPawn::OnActorGrabbed_Implementation(const USGVirtualHandComponent* Hand, const AActor* Actor) +{ +} + +void ASGPawn::OnActorReleased_Implementation(const USGVirtualHandComponent* Hand, const AActor* Actor) +{ +} + +void ASGPawn::OnActorBeginTouch_Implementation(const USGVirtualHandComponent* Hand, const AActor* Actor) +{ +} + +void ASGPawn::OnActorEndTouch_Implementation(const USGVirtualHandComponent* Hand, const AActor* Actor) +{ +} + +void ASGPawn::BeginPlay() +{ + Super::BeginPlay(); + + ensureAlwaysMsgf( + WristTrackerLeft->IsLeft() && HandLeft->IsLeft(), + TEXT("The left hand and the left wrist do not track the left hand!")); + ensureAlwaysMsgf( + WristTrackerRight->IsRight() && HandRight->IsRight(), + TEXT("The right hand and the right wrist do not track the right hand!")); + + WristTrackerLeft->OnWristLocationChanged().AddWeakLambda(this, [&](const FVector& Location)-> void + { + Pimpl->UpdateLeftHandLocation(Location, !Pimpl->IsLeftHandOverlappingWithAnyActor()); + }); + + WristTrackerLeft->OnWristRotationChanged().AddWeakLambda(this, [&](const FRotator& Rotation)-> void + { + Pimpl->UpdateLeftHandRotation(Rotation, !Pimpl->IsLeftHandOverlappingWithAnyActor()); + }); + + WristTrackerRight->OnWristLocationChanged().AddWeakLambda(this, [&](const FVector& Location)-> void + { + Pimpl->UpdateRightHandLocation(Location, !Pimpl->IsRightHandOverlappingWithAnyActor()); + }); + + WristTrackerRight->OnWristRotationChanged().AddWeakLambda(this, [&](const FRotator& Rotation)-> void + { + Pimpl->UpdateRightHandRotation(Rotation, !Pimpl->IsRightHandOverlappingWithAnyActor()); + }); + + HandLeft->OnHandVisibilityChanged().AddWeakLambda(this, [&](const bool bNewVisibility)-> void + { + Pimpl->SetAllFingersColliderCollisionEnabled(false, bNewVisibility); + }); + + HandRight->OnHandVisibilityChanged().AddWeakLambda(this, [&](const bool bNewVisibility)-> void + { + Pimpl->SetAllFingersColliderCollisionEnabled(true, bNewVisibility); + }); + + Pimpl->BindRealHandsOverlapEvents(); + + Pimpl->BindFingerGrabOverlapEvents(); + Pimpl->BindFingerTouchOverlapEvents(); +} + +void ASGPawn::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + Super::EndPlay(EndPlayReason); + + Pimpl->UnbindRealHandsOverlapEvents(); + + Pimpl->UnbindFingerGrabOverlapEvents(); + Pimpl->UnbindFingerTouchOverlapEvents(); +} + +void ASGPawn::Tick(const float DeltaSeconds) +{ + Super::Tick(DeltaSeconds); + + Pimpl->RecordHandVelocity(LeftHandGrabState, DeltaSeconds); + Pimpl->RecordHandVelocity(RightHandGrabState, DeltaSeconds); +} + +void ASGPawn::PreInitializeComponents() +{ + Super::PreInitializeComponents(); + + WristTrackerLeft->SetRight(HandLeft->IsRight()); + WristTrackerRight->SetRight(HandRight->IsRight()); +} + +void ASGPawn::PostInitializeComponents() +{ + Super::PostInitializeComponents(); +} + +void ASGPawn::OnRealLeftHandOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (OtherActor == this) + { + return; + } + + Pimpl->RegisterLeftHandOverlappedActor(OtherActor); +} + +void ASGPawn::OnRealLeftHandOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (OtherActor == this) + { + return; + } + + Pimpl->UnregisterLeftHandOverlappedActor(OtherActor); +} + +void ASGPawn::OnRealRightHandOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (OtherActor == this) + { + return; + } + + Pimpl->RegisterRightHandOverlappedActor(OtherActor); +} + +void ASGPawn::OnRealRightHandOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (OtherActor == this) + { + return; + } + + Pimpl->UnregisterRightHandOverlappedActor(OtherActor); +} + +void ASGPawn::OnLeftThumbFingertipGrabColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (!IsValid(LeftHandGrabState.Hand)) + { + return; + } + + const bool bHandVisible = LeftHandGrabState.Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + if (!USGGrabComponent::IsGrabbable(OtherActor)) + { + return; + } + + LeftHandGrabState.ActorThumbCanGrab = OtherActor; + Pimpl->TriggerGrabStateUpdatedEvent(LeftHandGrabState); +} + +void ASGPawn::OnLeftThumbFingertipGrabColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (!IsValid(LeftHandGrabState.Hand)) + { + return; + } + + if (LeftHandGrabState.ActorThumbCanGrab != OtherActor) + { + return; + } + + LeftHandGrabState.ActorThumbCanGrab = nullptr; + Pimpl->TriggerGrabStateUpdatedEvent(LeftHandGrabState); +} + +void ASGPawn::OnLeftIndexFingertipGrabColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (!IsValid(LeftHandGrabState.Hand)) + { + return; + } + + const bool bHandVisible = LeftHandGrabState.Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + if (!USGGrabComponent::IsGrabbable(OtherActor)) + { + return; + } + + LeftHandGrabState.ActorIndexCanGrab = OtherActor; + Pimpl->TriggerGrabStateUpdatedEvent(LeftHandGrabState); +} + +void ASGPawn::OnLeftIndexFingertipGrabColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (!IsValid(LeftHandGrabState.Hand)) + { + return; + } + + if (LeftHandGrabState.ActorIndexCanGrab != OtherActor) + { + return; + } + + LeftHandGrabState.ActorIndexCanGrab = nullptr; + Pimpl->TriggerGrabStateUpdatedEvent(LeftHandGrabState); +} + +void ASGPawn::OnLeftMiddleFingertipGrabColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (!IsValid(LeftHandGrabState.Hand)) + { + return; + } + + const bool bHandVisible = LeftHandGrabState.Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + if (!USGGrabComponent::IsGrabbable(OtherActor)) + { + return; + } + + LeftHandGrabState.ActorMiddleCanGrab = OtherActor; + Pimpl->TriggerGrabStateUpdatedEvent(LeftHandGrabState); +} + +void ASGPawn::OnLeftMiddleFingertipGrabColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (!IsValid(LeftHandGrabState.Hand)) + { + return; + } + + if (LeftHandGrabState.ActorMiddleCanGrab != OtherActor) + { + return; + } + + LeftHandGrabState.ActorMiddleCanGrab = nullptr; + Pimpl->TriggerGrabStateUpdatedEvent(LeftHandGrabState); +} + +void ASGPawn::OnLeftThumbFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (!IsValid(LeftHandTouchState.Hand)) + { + return; + } + + const bool bHandVisible = LeftHandTouchState.Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + if (!USGTouchComponent::IsTouchable(OtherActor)) + { + return; + } + + LeftHandTouchState.ActorThumbTouching = OtherActor; + Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState); + Pimpl->TriggerBeginTouch(LeftHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnLeftThumbFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (!IsValid(LeftHandTouchState.Hand)) + { + return; + } + + if (LeftHandTouchState.ActorThumbTouching != OtherActor) + { + return; + } + + LeftHandTouchState.ActorThumbTouching = nullptr; + Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState); + Pimpl->TriggerEndTouch(LeftHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnLeftIndexFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (!IsValid(LeftHandTouchState.Hand)) + { + return; + } + + const bool bHandVisible = LeftHandTouchState.Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + if (!USGTouchComponent::IsTouchable(OtherActor)) + { + return; + } + + LeftHandTouchState.ActorIndexTouching = OtherActor; + Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState); + Pimpl->TriggerBeginTouch(LeftHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnLeftIndexFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (!IsValid(LeftHandTouchState.Hand)) + { + return; + } + + if (LeftHandTouchState.ActorIndexTouching != OtherActor) + { + return; + } + + LeftHandTouchState.ActorIndexTouching = nullptr; + Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState); + Pimpl->TriggerEndTouch(LeftHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnLeftMiddleFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (!IsValid(LeftHandTouchState.Hand)) + { + return; + } + + const bool bHandVisible = LeftHandTouchState.Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + if (!USGTouchComponent::IsTouchable(OtherActor)) + { + return; + } + + LeftHandTouchState.ActorMiddleTouching = OtherActor; + Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState); + Pimpl->TriggerBeginTouch(LeftHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnLeftMiddleFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (!IsValid(LeftHandTouchState.Hand)) + { + return; + } + + if (LeftHandTouchState.ActorMiddleTouching != OtherActor) + { + return; + } + + LeftHandTouchState.ActorMiddleTouching = nullptr; + Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState); + Pimpl->TriggerEndTouch(LeftHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnLeftRingFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (!IsValid(LeftHandTouchState.Hand)) + { + return; + } + + const bool bHandVisible = LeftHandTouchState.Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + if (!USGTouchComponent::IsTouchable(OtherActor)) + { + return; + } + + LeftHandTouchState.ActorRingTouching = OtherActor; + Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState); + Pimpl->TriggerBeginTouch(LeftHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnLeftRingFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (!IsValid(LeftHandTouchState.Hand)) + { + return; + } + + if (LeftHandTouchState.ActorRingTouching != OtherActor) + { + return; + } + + LeftHandTouchState.ActorRingTouching = nullptr; + Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState); + Pimpl->TriggerEndTouch(LeftHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnLeftPinkyFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (!IsValid(LeftHandTouchState.Hand)) + { + return; + } + + const bool bHandVisible = LeftHandTouchState.Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + if (!USGTouchComponent::IsTouchable(OtherActor)) + { + return; + } + + LeftHandTouchState.ActorPinkyTouching = OtherActor; + Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState); + Pimpl->TriggerBeginTouch(LeftHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnLeftPinkyFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (!IsValid(LeftHandTouchState.Hand)) + { + return; + } + + if (LeftHandTouchState.ActorPinkyTouching != OtherActor) + { + return; + } + + LeftHandTouchState.ActorPinkyTouching = nullptr; + Pimpl->TriggerTouchStateUpdatedEvent(LeftHandTouchState); + Pimpl->TriggerEndTouch(LeftHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnRightThumbFingertipGrabColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (!IsValid(RightHandGrabState.Hand)) + { + return; + } + + const bool bHandVisible = RightHandGrabState.Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + if (!USGGrabComponent::IsGrabbable(OtherActor)) + { + return; + } + + RightHandGrabState.ActorThumbCanGrab = OtherActor; + Pimpl->TriggerGrabStateUpdatedEvent(RightHandGrabState); +} + +void ASGPawn::OnRightThumbFingertipGrabColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (!IsValid(RightHandGrabState.Hand)) + { + return; + } + + if (RightHandGrabState.ActorThumbCanGrab != OtherActor) + { + return; + } + + RightHandGrabState.ActorThumbCanGrab = nullptr; + Pimpl->TriggerGrabStateUpdatedEvent(RightHandGrabState); +} + +void ASGPawn::OnRightIndexFingertipGrabColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (!IsValid(RightHandGrabState.Hand)) + { + return; + } + + const bool bHandVisible = RightHandGrabState.Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + if (!USGGrabComponent::IsGrabbable(OtherActor)) + { + return; + } + + RightHandGrabState.ActorIndexCanGrab = OtherActor; + Pimpl->TriggerGrabStateUpdatedEvent(RightHandGrabState); +} + +void ASGPawn::OnRightIndexFingertipGrabColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (!IsValid(RightHandGrabState.Hand)) + { + return; + } + + if (RightHandGrabState.ActorThumbCanGrab != OtherActor) + { + return; + } + + RightHandGrabState.ActorIndexCanGrab = nullptr; + Pimpl->TriggerGrabStateUpdatedEvent(RightHandGrabState); +} + +void ASGPawn::OnRightMiddleFingertipGrabColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (!IsValid(RightHandGrabState.Hand)) + { + return; + } + + const bool bHandVisible = RightHandGrabState.Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + if (!USGGrabComponent::IsGrabbable(OtherActor)) + { + return; + } + + RightHandGrabState.ActorMiddleCanGrab = OtherActor; + Pimpl->TriggerGrabStateUpdatedEvent(RightHandGrabState); +} + +void ASGPawn::OnRightMiddleFingertipGrabColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (!IsValid(RightHandGrabState.Hand)) + { + return; + } + + if (RightHandGrabState.ActorMiddleCanGrab != OtherActor) + { + return; + } + + RightHandGrabState.ActorMiddleCanGrab = nullptr; + Pimpl->TriggerGrabStateUpdatedEvent(RightHandGrabState); +} + +void ASGPawn::OnRightThumbFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (!IsValid(RightHandTouchState.Hand)) + { + return; + } + + const bool bHandVisible = RightHandTouchState.Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + if (!USGTouchComponent::IsTouchable(OtherActor)) + { + return; + } + + RightHandTouchState.ActorThumbTouching = OtherActor; + Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState); + Pimpl->TriggerBeginTouch(RightHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnRightThumbFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (!IsValid(RightHandTouchState.Hand)) + { + return; + } + + if (RightHandTouchState.ActorThumbTouching != OtherActor) + { + return; + } + + RightHandTouchState.ActorThumbTouching = nullptr; + Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState); + Pimpl->TriggerEndTouch(RightHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnRightIndexFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (!IsValid(RightHandTouchState.Hand)) + { + return; + } + + const bool bHandVisible = RightHandTouchState.Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + if (!USGTouchComponent::IsTouchable(OtherActor)) + { + return; + } + + RightHandTouchState.ActorIndexTouching = OtherActor; + Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState); + Pimpl->TriggerBeginTouch(RightHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnRightIndexFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (!IsValid(RightHandTouchState.Hand)) + { + return; + } + + if (RightHandTouchState.ActorIndexTouching != OtherActor) + { + return; + } + + RightHandTouchState.ActorIndexTouching = nullptr; + Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState); + Pimpl->TriggerEndTouch(RightHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnRightMiddleFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (!IsValid(RightHandTouchState.Hand)) + { + return; + } + + const bool bHandVisible = RightHandTouchState.Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + if (!USGTouchComponent::IsTouchable(OtherActor)) + { + return; + } + + RightHandTouchState.ActorMiddleTouching = OtherActor; + Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState); + Pimpl->TriggerBeginTouch(RightHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnRightMiddleFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (!IsValid(RightHandTouchState.Hand)) + { + return; + } + + if (RightHandTouchState.ActorMiddleTouching != OtherActor) + { + return; + } + + RightHandTouchState.ActorMiddleTouching = nullptr; + Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState); + Pimpl->TriggerEndTouch(RightHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnRightRingFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (!IsValid(RightHandTouchState.Hand)) + { + return; + } + + const bool bHandVisible = RightHandTouchState.Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + if (!USGTouchComponent::IsTouchable(OtherActor)) + { + return; + } + + RightHandTouchState.ActorRingTouching = OtherActor; + Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState); + Pimpl->TriggerBeginTouch(RightHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnRightRingFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (!IsValid(RightHandTouchState.Hand)) + { + return; + } + + if (RightHandTouchState.ActorRingTouching != OtherActor) + { + return; + } + + RightHandTouchState.ActorRingTouching = nullptr; + Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState); + Pimpl->TriggerEndTouch(RightHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnRightPinkyFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex, + const bool bFromSweep, + const FHitResult& SweepResult) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + (void) bFromSweep; + (void) SweepResult; + + if (!IsValid(RightHandTouchState.Hand)) + { + return; + } + + const bool bHandVisible = RightHandTouchState.Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + if (!USGTouchComponent::IsTouchable(OtherActor)) + { + return; + } + + RightHandTouchState.ActorPinkyTouching = OtherActor; + Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState); + Pimpl->TriggerBeginTouch(RightHandTouchState.Hand, OtherActor); +} + +void ASGPawn::OnRightPinkyFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + const int32 OtherBodyIndex) +{ + (void) OverlappedComponent; + (void) OtherComp; + (void) OtherBodyIndex; + + if (!IsValid(RightHandTouchState.Hand)) + { + return; + } + + if (RightHandTouchState.ActorPinkyTouching != OtherActor) + { + return; + } + + RightHandTouchState.ActorPinkyTouching = nullptr; + Pimpl->TriggerTouchStateUpdatedEvent(RightHandTouchState); + Pimpl->TriggerEndTouch(RightHandTouchState.Hand, OtherActor); +} + +bool ASGPawn::IsLeftHandGrabbing(AActor*& OutActor) const +{ + if (!IsValid(LeftHandGrabState.Hand)) + { + return false; + } + + if (!IsValid(LeftHandGrabState.GrabbedActor)) + { + return false; + } + + OutActor = LeftHandGrabState.GrabbedActor; + return true; +} + +bool ASGPawn::IsRightHandGrabbing(AActor*& OutActor) const +{ + if (!IsValid(RightHandGrabState.Hand)) + { + return false; + } + + if (!IsValid(RightHandGrabState.GrabbedActor)) + { + return false; + } + + OutActor = RightHandGrabState.GrabbedActor; + return true; +} + +bool ASGPawn::IsGrabbing(const USGVirtualHandComponent* Hand, AActor*& OutActor) const +{ + return Hand == HandLeft ? IsLeftHandGrabbing(OutActor) : IsRightHandGrabbing(OutActor); +} + +void ASGPawn::Grab(USGVirtualHandComponent* Hand, AActor* Actor) +{ + if (!ensureAlwaysMsgf(IsValid(Hand), TEXT("%s"), TEXT("ERROR: invalid hand!"))) + { + return; + } + + const bool bHandVisible = Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + if (!ensureAlwaysMsgf(IsValid(Actor), TEXT("%s"), TEXT("ERROR: invalid actor!"))) + { + return; + } + + const USGGrabComponent* GrabComponent{USGGrabComponent::GetGrabComponent(Actor)}; + if (!IsValid(GrabComponent)) + { + return; + } + + FAttachmentTransformRules AttachmentRules{ + FAttachmentTransformRules(GrabComponent->GetAttachmentLocationRule(), + GrabComponent->GetAttachmentRotationRule(), + GrabComponent->GetAttachmentScaleRule(), + GrabComponent->GetAttachmentWeldSimulatedBodies()) + }; + + const FName SocketName{GrabComponent->GetAttachmentSocketName()}; + ensureAlwaysMsgf(SocketName != NAME_None, TEXT("invalid attachment socket name!")); + + if (GrabComponent->GetAffectPhysicsState()) + { + GrabComponent->SimulatePhysics(false); + } + + if (Hand->IsRight()) + { + Pimpl->UnregisterRightHandOverlappedActor(Actor); + } + else + { + Pimpl->UnregisterLeftHandOverlappedActor(Actor); + } + + const bool bAttached = Actor->AttachToComponent(Hand, MoveTemp(AttachmentRules), SocketName); + if (bAttached) + { + if (Hand->IsRight()) + { + Pimpl->SetRightHandGrabbedActor(Actor); + } + else + { + Pimpl->SetLeftHandGrabbedActor(Actor); + } + } + else + { + if (Hand->IsRight()) + { + SGLOG_ERROR("Failed to grab the actor with the right hand!", Actor, SocketName); + } + else + { + SGLOG_ERROR("Failed to grab the actor with the left hand!", Actor, SocketName); + } + } + + Pimpl->TriggerActorGrabbedEvent(Hand, Actor); +} + +void ASGPawn::ReleaseLeft() +{ + Pimpl->Release(LeftHandGrabState); +} + +void ASGPawn::ReleaseRight() +{ + Pimpl->Release(RightHandGrabState); +} + +ASGPawn::FImpl::FImpl(ASGPawn* InOwner) + : Owner(InOwner) +{ +} + +ASGPawn::FImpl::~FImpl() = default; + +void ASGPawn::FImpl::BindRealHandsOverlapEvents() +{ + Owner->RealHandLeft->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnRealLeftHandOverlapBegins); + Owner->RealHandLeft->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnRealLeftHandOverlapEnds); + + Owner->RealHandRight->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnRealRightHandOverlapBegins); + Owner->RealHandRight->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnRealRightHandOverlapEnds); +} + +void ASGPawn::FImpl::UnbindRealHandsOverlapEvents() +{ + Owner->RealHandLeft->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRealLeftHandOverlapBegins); + Owner->RealHandLeft->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRealLeftHandOverlapEnds); + + Owner->RealHandRight->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRealRightHandOverlapBegins); + Owner->RealHandRight->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRealRightHandOverlapEnds); +} + +void ASGPawn::FImpl::BindFingerGrabOverlapEvents() +{ + Owner->LeftThumbFingertipGrabCollider->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnLeftThumbFingertipGrabColliderOverlapBegins); + Owner->LeftThumbFingertipGrabCollider->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnLeftThumbFingertipGrabColliderOverlapEnds); + + Owner->LeftIndexFingertipGrabCollider->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnLeftIndexFingertipGrabColliderOverlapBegins); + Owner->LeftIndexFingertipGrabCollider->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnLeftIndexFingertipGrabColliderOverlapEnds); + + Owner->LeftMiddleFingertipGrabCollider->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnLeftMiddleFingertipGrabColliderOverlapBegins); + Owner->LeftMiddleFingertipGrabCollider->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnLeftMiddleFingertipGrabColliderOverlapEnds); + + Owner->RightThumbFingertipGrabCollider->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnRightThumbFingertipGrabColliderOverlapBegins); + Owner->RightThumbFingertipGrabCollider->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnRightThumbFingertipGrabColliderOverlapEnds); + + Owner->RightIndexFingertipGrabCollider->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnRightIndexFingertipGrabColliderOverlapBegins); + Owner->RightIndexFingertipGrabCollider->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnRightIndexFingertipGrabColliderOverlapEnds); + + Owner->RightMiddleFingertipGrabCollider->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnRightMiddleFingertipGrabColliderOverlapBegins); + Owner->RightMiddleFingertipGrabCollider->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnRightMiddleFingertipGrabColliderOverlapEnds); +} + +void ASGPawn::FImpl::UnbindFingerGrabOverlapEvents() +{ + Owner->LeftThumbFingertipGrabCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnLeftThumbFingertipGrabColliderOverlapBegins); + Owner->LeftThumbFingertipGrabCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnLeftThumbFingertipGrabColliderOverlapEnds); + + Owner->LeftIndexFingertipGrabCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnLeftIndexFingertipGrabColliderOverlapBegins); + Owner->LeftIndexFingertipGrabCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnLeftIndexFingertipGrabColliderOverlapEnds); + + Owner->LeftMiddleFingertipGrabCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnLeftMiddleFingertipGrabColliderOverlapBegins); + Owner->LeftMiddleFingertipGrabCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnLeftMiddleFingertipGrabColliderOverlapEnds); + + Owner->RightThumbFingertipGrabCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightThumbFingertipGrabColliderOverlapBegins); + Owner->RightThumbFingertipGrabCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightThumbFingertipGrabColliderOverlapEnds); + + Owner->RightIndexFingertipGrabCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightIndexFingertipGrabColliderOverlapBegins); + Owner->RightIndexFingertipGrabCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightIndexFingertipGrabColliderOverlapEnds); + + Owner->RightMiddleFingertipGrabCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightMiddleFingertipGrabColliderOverlapBegins); + Owner->RightMiddleFingertipGrabCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightMiddleFingertipGrabColliderOverlapEnds); +} + +void ASGPawn::FImpl::BindFingerTouchOverlapEvents() +{ + Owner->LeftThumbFingertipTouchCollider->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnLeftThumbFingertipTouchColliderOverlapBegins); + Owner->LeftThumbFingertipTouchCollider->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnLeftThumbFingertipTouchColliderOverlapEnds); + + Owner->LeftIndexFingertipTouchCollider->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnLeftIndexFingertipTouchColliderOverlapBegins); + Owner->LeftIndexFingertipTouchCollider->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnLeftIndexFingertipTouchColliderOverlapEnds); + + Owner->LeftMiddleFingertipTouchCollider->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnLeftMiddleFingertipTouchColliderOverlapBegins); + Owner->LeftMiddleFingertipTouchCollider->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnLeftMiddleFingertipTouchColliderOverlapEnds); + + Owner->LeftRingFingertipTouchCollider->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnLeftRingFingertipTouchColliderOverlapBegins); + Owner->LeftRingFingertipTouchCollider->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnLeftRingFingertipTouchColliderOverlapEnds); + + Owner->LeftPinkyFingertipTouchCollider->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnLeftPinkyFingertipTouchColliderOverlapBegins); + Owner->LeftPinkyFingertipTouchCollider->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnLeftPinkyFingertipTouchColliderOverlapEnds); + + Owner->RightThumbFingertipTouchCollider->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnRightThumbFingertipTouchColliderOverlapBegins); + Owner->RightThumbFingertipTouchCollider->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnRightThumbFingertipTouchColliderOverlapEnds); + + Owner->RightIndexFingertipTouchCollider->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnRightIndexFingertipTouchColliderOverlapBegins); + Owner->RightIndexFingertipTouchCollider->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnRightIndexFingertipTouchColliderOverlapEnds); + + Owner->RightMiddleFingertipTouchCollider->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnRightMiddleFingertipTouchColliderOverlapBegins); + Owner->RightMiddleFingertipTouchCollider->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnRightMiddleFingertipTouchColliderOverlapEnds); + + Owner->RightRingFingertipTouchCollider->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnRightRingFingertipTouchColliderOverlapBegins); + Owner->RightRingFingertipTouchCollider->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnRightRingFingertipTouchColliderOverlapEnds); + + Owner->RightPinkyFingertipTouchCollider->OnComponentBeginOverlap.AddDynamic( + Owner, &ASGPawn::OnRightPinkyFingertipTouchColliderOverlapBegins); + Owner->RightPinkyFingertipTouchCollider->OnComponentEndOverlap.AddDynamic( + Owner, &ASGPawn::OnRightPinkyFingertipTouchColliderOverlapEnds); +} + +void ASGPawn::FImpl::UnbindFingerTouchOverlapEvents() +{ + Owner->LeftThumbFingertipTouchCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnLeftThumbFingertipTouchColliderOverlapBegins); + Owner->LeftThumbFingertipTouchCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnLeftThumbFingertipTouchColliderOverlapEnds); + + Owner->LeftIndexFingertipTouchCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnLeftIndexFingertipTouchColliderOverlapBegins); + Owner->LeftIndexFingertipTouchCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnLeftIndexFingertipTouchColliderOverlapEnds); + + Owner->LeftMiddleFingertipTouchCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnLeftMiddleFingertipTouchColliderOverlapBegins); + Owner->LeftMiddleFingertipTouchCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnLeftMiddleFingertipTouchColliderOverlapEnds); + + Owner->LeftRingFingertipTouchCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnLeftRingFingertipTouchColliderOverlapBegins); + Owner->LeftRingFingertipTouchCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnLeftRingFingertipTouchColliderOverlapEnds); + + Owner->LeftPinkyFingertipTouchCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnLeftPinkyFingertipTouchColliderOverlapBegins); + Owner->LeftPinkyFingertipTouchCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnLeftPinkyFingertipTouchColliderOverlapEnds); + + Owner->RightThumbFingertipGrabCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightThumbFingertipGrabColliderOverlapBegins); + Owner->RightThumbFingertipGrabCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightThumbFingertipGrabColliderOverlapEnds); + + Owner->RightIndexFingertipGrabCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightIndexFingertipGrabColliderOverlapBegins); + Owner->RightIndexFingertipGrabCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightIndexFingertipGrabColliderOverlapEnds); + + Owner->RightMiddleFingertipGrabCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightMiddleFingertipGrabColliderOverlapBegins); + Owner->RightMiddleFingertipGrabCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightMiddleFingertipGrabColliderOverlapEnds); + + Owner->RightThumbFingertipTouchCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightThumbFingertipTouchColliderOverlapBegins); + Owner->RightThumbFingertipTouchCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightThumbFingertipTouchColliderOverlapEnds); + + Owner->RightIndexFingertipTouchCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightIndexFingertipTouchColliderOverlapBegins); + Owner->RightIndexFingertipTouchCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightIndexFingertipTouchColliderOverlapEnds); + + Owner->RightMiddleFingertipTouchCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightMiddleFingertipTouchColliderOverlapBegins); + Owner->RightMiddleFingertipTouchCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightMiddleFingertipTouchColliderOverlapEnds); + + Owner->RightRingFingertipTouchCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightRingFingertipTouchColliderOverlapBegins); + Owner->RightRingFingertipTouchCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightRingFingertipTouchColliderOverlapEnds); + + Owner->RightPinkyFingertipTouchCollider->OnComponentBeginOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightPinkyFingertipTouchColliderOverlapBegins); + Owner->RightPinkyFingertipTouchCollider->OnComponentEndOverlap.RemoveDynamic( + Owner, &ASGPawn::OnRightPinkyFingertipTouchColliderOverlapEnds); +} + +void ASGPawn::FImpl::SetVisibility(USceneComponent* SceneComponent, const bool bVisibility) const +{ + if (!ensureAlwaysMsgf(IsValid(SceneComponent), TEXT("Invalid SceneComponent!"))) + { + return; + } + + SceneComponent->SetHiddenInGame(!bVisibility, false); +} + +void ASGPawn::FImpl::UpdateHandLocation(const bool bRight, const FVector& Location, const bool bUpdateVirtualHand) const +{ + if (bRight) + { + UpdateRightHandLocation(Location, bUpdateVirtualHand); + } + else + { + UpdateLeftHandLocation(Location, bUpdateVirtualHand); + } +} + +void ASGPawn::FImpl::UpdateLeftHandLocation(const FVector& Location, const bool bUpdateVirtualHand) const +{ + if (bUpdateVirtualHand) + { + Owner->HandLeft->SetWorldLocation(Location); + } + Owner->RealHandLeft->SetWorldLocation(Location); +} + +void ASGPawn::FImpl::UpdateRightHandLocation(const FVector& Location, const bool bUpdateVirtualHand) const +{ + if (bUpdateVirtualHand) + { + Owner->HandRight->SetWorldLocation(Location); + } + Owner->RealHandRight->SetWorldLocation(Location); +} + +void ASGPawn::FImpl::UpdateHandRotation(const bool bRight, const FRotator& Rotation, const bool bUpdateVirtualHand) +{ + if (bRight) + { + UpdateRightHandRotation(Rotation, bUpdateVirtualHand); + } + else + { + UpdateLeftHandRotation(Rotation, bUpdateVirtualHand); + } +} + +void ASGPawn::FImpl::UpdateLeftHandRotation(const FRotator& Rotation, const bool bUpdateVirtualHand) +{ + const FSGVirtualHandMeshSettings& MeshSettings{Owner->HandLeft->GetVirtualHandSettings().MeshSettings}; + const FQuat NewRotation{ + Rotation.Quaternion() * MeshSettings.RootBoneRotationCorrection.Quaternion() + }; + if (bUpdateVirtualHand) + { + Owner->HandLeft->SetWorldRotation(NewRotation); + } + Owner->RealHandLeft->SetWorldRotation(NewRotation); +} + +void ASGPawn::FImpl::UpdateRightHandRotation(const FRotator& Rotation, const bool bUpdateVirtualHand) +{ + const FSGVirtualHandMeshSettings& MeshSettings{Owner->HandLeft->GetVirtualHandSettings().MeshSettings}; + const FQuat NewRotation{ + Rotation.Quaternion() * MeshSettings.RootBoneRotationCorrection.Quaternion() + }; + if (bUpdateVirtualHand) + { + Owner->HandRight->SetWorldRotation(NewRotation); + } + Owner->RealHandRight->SetWorldRotation(NewRotation); +} + +void ASGPawn::FImpl::UpdateHandLocationAndRotation( + const bool bRight, const FVector& Location, const FRotator& Rotation, const bool bUpdateVirtualHand) +{ + if (bRight) + { + UpdateRightHandLocationAndRotation(Location, Rotation, bUpdateVirtualHand); + } + else + { + UpdateLeftHandLocationAndRotation(Location, Rotation, bUpdateVirtualHand); + } +} + +void ASGPawn::FImpl::UpdateLeftHandLocationAndRotation( + const FVector& Location, const FRotator& Rotation, const bool bUpdateVirtualHand) +{ + UpdateLeftHandLocation(Location, bUpdateVirtualHand); + UpdateLeftHandRotation(Rotation, bUpdateVirtualHand); +} + +void ASGPawn::FImpl::UpdateRightHandLocationAndRotation( + const FVector& Location, const FRotator& Rotation, const bool bUpdateVirtualHand) +{ + UpdateRightHandLocation(Location, bUpdateVirtualHand); + UpdateRightHandRotation(Rotation, bUpdateVirtualHand); +} + +void ASGPawn::FImpl::SetFingerColliderCollisionEnabled(USphereComponent* Collider, const bool bEnabled) const +{ + if (!ensureAlwaysMsgf(IsValid(Collider), TEXT("Invalid collider object!"))) + { + return; + } + + if (bEnabled) + { + Collider->SetGenerateOverlapEvents(true); + Collider->SetCollisionEnabled(ECollisionEnabled::QueryOnly); + Collider->SetCollisionResponseToAllChannels(ECR_Overlap); + Collider->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Overlap); + Collider->SetCollisionResponseToChannel(ECC_WorldDynamic, ECR_Overlap); + Collider->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap); + Collider->SetCollisionResponseToChannel(ECC_Visibility, ECR_Overlap); + Collider->SetCollisionResponseToChannel(ECC_PhysicsBody, ECR_Overlap); + Collider->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Overlap); + Collider->SetCollisionResponseToChannel(ECC_Destructible, ECR_Overlap); + } + else + { + Collider->SetGenerateOverlapEvents(false); + Collider->SetCollisionEnabled(ECollisionEnabled::NoCollision); + Collider->SetCollisionResponseToAllChannels(ECR_Ignore); + } +} + +void ASGPawn::FImpl::SetAllFingersColliderCollisionEnabled(const bool bRight, const bool bEnabled) const +{ + if (bRight) + { + SetFingerColliderCollisionEnabled(Owner->RightThumbFingertipGrabCollider, bEnabled); + SetFingerColliderCollisionEnabled(Owner->RightThumbFingertipTouchCollider, bEnabled); + SetFingerColliderCollisionEnabled(Owner->RightIndexFingertipGrabCollider, bEnabled); + SetFingerColliderCollisionEnabled(Owner->RightIndexFingertipTouchCollider, bEnabled); + SetFingerColliderCollisionEnabled(Owner->RightMiddleFingertipGrabCollider, bEnabled); + SetFingerColliderCollisionEnabled(Owner->RightMiddleFingertipTouchCollider, bEnabled); + SetFingerColliderCollisionEnabled(Owner->RightRingFingertipTouchCollider, bEnabled); + SetFingerColliderCollisionEnabled(Owner->RightPinkyFingertipTouchCollider, bEnabled); + } + else + { + SetFingerColliderCollisionEnabled(Owner->LeftThumbFingertipGrabCollider, bEnabled); + SetFingerColliderCollisionEnabled(Owner->LeftThumbFingertipTouchCollider, bEnabled); + SetFingerColliderCollisionEnabled(Owner->LeftIndexFingertipGrabCollider, bEnabled); + SetFingerColliderCollisionEnabled(Owner->LeftIndexFingertipTouchCollider, bEnabled); + SetFingerColliderCollisionEnabled(Owner->LeftMiddleFingertipGrabCollider, bEnabled); + SetFingerColliderCollisionEnabled(Owner->LeftMiddleFingertipTouchCollider, bEnabled); + SetFingerColliderCollisionEnabled(Owner->LeftRingFingertipTouchCollider, bEnabled); + SetFingerColliderCollisionEnabled(Owner->LeftPinkyFingertipTouchCollider, bEnabled); + } +} + +void ASGPawn::FImpl::ApplyHandVelocityToGrabbedActor(const FSGGrabState& GrabState) const +{ + if (!IsValid(GrabState.Hand)) + { + return; + } + + if (!IsValid(GrabState.GrabbedActor)) + { + return; + } + + UPrimitiveComponent* ActorRootComponent{Cast(GrabState.GrabbedActor->GetRootComponent())}; + if (!ensureAlwaysMsgf(IsValid(ActorRootComponent), TEXT("RootComponent is not a valid UPrimativeComponent!"))) + { + return; + } + + FVector HandVelocity{UKismetMathLibrary::GetVectorArrayAverage(GrabState.HandVelocityHistory)}; + + ActorRootComponent->SetPhysicsLinearVelocity(HandVelocity); + ActorRootComponent->AddImpulse(MoveTemp(HandVelocity), NAME_None, true); +} + +void ASGPawn::FImpl::SetGrabbedActor(FSGGrabState& GrabState, AActor* Actor) const +{ + GrabState.GrabbedActor = Actor; +} + +void ASGPawn::FImpl::SetLeftHandGrabbedActor(AActor* Actor) const +{ + SetGrabbedActor(Owner->LeftHandGrabState, Actor); +} + +void ASGPawn::FImpl::SetRightHandGrabbedActor(AActor* Actor) const +{ + SetGrabbedActor(Owner->RightHandGrabState, Actor); +} + +void ASGPawn::FImpl::RecordHandVelocity(FSGGrabState& GrabState, const float DeltaSeconds) const +{ + if (!IsValid(GrabState.Hand)) + { + return; + } + + FVector HandVelocity{ + (GrabState.Hand->GetComponentLocation() - GrabState.PreviousHandLocation) / DeltaSeconds + }; + + if (GrabState.HandVelocityHistory.Num() >= Owner->MaxNumberOfHandVelocitySamples) + { + if (GrabState.HandVelocityHistory.IsValidIndex(0)) + { + GrabState.HandVelocityHistory.RemoveAt(0, 1, +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + EAllowShrinking::No +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + false +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + ); + GrabState.HandVelocityHistory.Emplace(MoveTemp(HandVelocity)); + } + } + else + { + GrabState.HandVelocityHistory.Emplace(MoveTemp(HandVelocity)); + } + + GrabState.PreviousHandLocation = GrabState.Hand->GetComponentLocation(); +} + +void ASGPawn::FImpl::Release(FSGGrabState& GrabState) const +{ + if (!IsValid(GrabState.GrabbedActor)) + { + return; + } + + const USGGrabComponent* GrabComponent{USGGrabComponent::GetGrabComponent(GrabState.GrabbedActor)}; + if (!IsValid(GrabComponent)) + { + return; + } + + GrabState.GrabbedActor->DetachFromActor( + FDetachmentTransformRules(GrabComponent->GetDetachmentLocationRule(), + GrabComponent->GetDetachmentRotationRule(), + GrabComponent->GetDetachmentScaleRule(), + GrabComponent->GetDetachmentInCallModify()) + ); + + if (GrabComponent->GetAffectPhysicsState()) + { + GrabComponent->SimulatePhysics(true); + } + + ApplyHandVelocityToGrabbedActor(GrabState); + + TriggerActorReleasedEvent(GrabState.Hand, GrabState.GrabbedActor); + + SetGrabbedActor(GrabState, nullptr); +} + +void ASGPawn::FImpl::TriggerGrabStateUpdatedEvent(const FSGGrabState& GrabState) const +{ + Owner->GrabStateUpdatedEvent.Broadcast(GrabState); + Owner->OnGrabStateUpdated(GrabState); +} + +void ASGPawn::FImpl::TriggerTouchStateUpdatedEvent(const FSGTouchState& TouchState) const +{ + Owner->TouchStateUpdatedEvent.Broadcast(TouchState); + Owner->OnTouchStateUpdated(TouchState); +} + +void ASGPawn::FImpl::TriggerActorGrabbedEvent(const USGVirtualHandComponent* Hand, const AActor* Actor) const +{ + Owner->ActorGrabbedEvent.Broadcast(Hand, Actor); + Owner->OnActorGrabbed(Hand, Actor); +} + +void ASGPawn::FImpl::TriggerActorReleasedEvent(const USGVirtualHandComponent* Hand, const AActor* Actor) const +{ + Owner->ActorReleasedEvent.Broadcast(Hand, Actor); + Owner->OnActorReleased(Hand, Actor); +} + +void ASGPawn::FImpl::TriggerBeginTouch(const USGVirtualHandComponent* Hand, const AActor* Actor) const +{ + Owner->ActorBeginTouchEvent.Broadcast(Hand, Actor); + Owner->OnActorBeginTouch(Hand, Actor); +} + +void ASGPawn::FImpl::TriggerEndTouch(const USGVirtualHandComponent* Hand, const AActor* Actor) const +{ + Owner->ActorEndTouchEvent.Broadcast(Hand, Actor); + Owner->OnActorEndTouch(Hand, Actor); +} + +void ASGPawn::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPlayerController.cpp b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPlayerController.cpp new file mode 100644 index 0000000..9f638aa --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/GameFramework/SGPlayerController.cpp @@ -0,0 +1,405 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGlove/GameFramework/SGPlayerController.h" + +#include "Runtime/Launch/Resources/Version.h" +#include "Engine/TimerHandle.h" +#include "TimerManager.h" + +#include "SenseGlove/Components/SGTouchComponent.h" +#include "SenseGlove/Components/SGVirtualHandComponent.h" +#include "SenseGlove/GameFramework/SGPawn.h" +#include "SenseGlove/Haptics/SGGrabState.h" +#include "SenseGlove/Haptics/SGTouchState.h" +#include "SGBuildHacks/SGPlatform.h" +#include "SGCore/SGHapticGlove.h" + +struct ASGPlayerController::FImpl +{ + /************************ + * Static methods + ************************/ + + static float GetForceFeedbackLevel(const AActor* Actor); + + static float GetVibrotactileDuration(const AActor* ActorThumbTouching, const AActor* ActorIndexTouching, + const AActor* ActorMiddleTouching, const AActor* ActorRingTouching, + const AActor* ActorPinkyTouching); + static float GetVibrotactileLevel(const AActor* Actor); + + static TArray GetForceFeedbackLevels( + const AActor* ActorThumbTouching, + const AActor* ActorIndexTouching, + const AActor* ActorMiddleTouching, + const AActor* ActorRingTouching, + const AActor* ActorPinkyTouching); + + static TArray GetVibrotactileLevels( + const AActor* ActorThumbTouching, + const AActor* ActorIndexTouching, + const AActor* ActorMiddleTouching, + const AActor* ActorRingTouching, + const AActor* ActorPinkyTouching); + + /************************ + * Member variables + ************************/ + + FTimerHandle TouchVibrotactileStopTimer; + + /************************ + * Owner object + ************************/ + + ASGPlayerController* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(ASGPlayerController* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; + + /************************ + * Methods + ************************/ + + void UpdateHapticsFeedback(const FSGTouchState& TouchState); +}; + +float ASGPlayerController::FImpl::GetForceFeedbackLevel(const AActor* Actor) +{ + if (IsValid(Actor)) + { + const USGTouchComponent* TouchComponent = USGTouchComponent::GetTouchComponent(Actor); + if (IsValid(TouchComponent)) + { + return TouchComponent->GetForceFeedbackLevel(); + } + } + + return 0.0f; +} + +float ASGPlayerController::FImpl::GetVibrotactileDuration(const AActor* ActorThumbTouching, + const AActor* ActorIndexTouching, + const AActor* ActorMiddleTouching, + const AActor* ActorRingTouching, + const AActor* ActorPinkyTouching) +{ + if (IsValid(ActorThumbTouching)) + { + const USGTouchComponent* TouchComponent = USGTouchComponent::GetTouchComponent(ActorThumbTouching); + if (IsValid(TouchComponent)) + { + return TouchComponent->GetVibrotactileDuration(); + } + } + + if (IsValid(ActorIndexTouching)) + { + const USGTouchComponent* TouchComponent = USGTouchComponent::GetTouchComponent(ActorIndexTouching); + if (IsValid(TouchComponent)) + { + return TouchComponent->GetVibrotactileDuration(); + } + } + + if (IsValid(ActorMiddleTouching)) + { + const USGTouchComponent* TouchComponent = USGTouchComponent::GetTouchComponent(ActorMiddleTouching); + if (IsValid(TouchComponent)) + { + return TouchComponent->GetVibrotactileDuration(); + } + } + + if (IsValid(ActorRingTouching)) + { + const USGTouchComponent* TouchComponent = USGTouchComponent::GetTouchComponent(ActorRingTouching); + if (IsValid(TouchComponent)) + { + return TouchComponent->GetVibrotactileDuration(); + } + } + + if (IsValid(ActorPinkyTouching)) + { + const USGTouchComponent* TouchComponent = USGTouchComponent::GetTouchComponent(ActorPinkyTouching); + if (IsValid(TouchComponent)) + { + return TouchComponent->GetVibrotactileDuration(); + } + } + + return 0.0f; +} + +float ASGPlayerController::FImpl::GetVibrotactileLevel(const AActor* Actor) +{ + if (IsValid(Actor)) + { + const USGTouchComponent* TouchComponent = USGTouchComponent::GetTouchComponent(Actor); + if (IsValid(TouchComponent)) + { + return TouchComponent->GetVibrotactileLevel(); + } + } + + return 0.0f; +} + +TArray ASGPlayerController::FImpl::GetForceFeedbackLevels( + const AActor* ActorThumbTouching, + const AActor* ActorIndexTouching, + const AActor* ActorMiddleTouching, + const AActor* ActorRingTouching, + const AActor* ActorPinkyTouching) +{ + const float ThumbForceFeedbackLevel = GetForceFeedbackLevel(ActorThumbTouching); + const float IndexForceFeedbackLevel = GetForceFeedbackLevel(ActorIndexTouching); + const float MiddleForceFeedbackLevel = GetForceFeedbackLevel(ActorMiddleTouching); + const float RingForceFeedbackLevel = GetForceFeedbackLevel(ActorRingTouching); + const float PinkyForceFeedbackLevel = GetForceFeedbackLevel(ActorPinkyTouching); + + const TArray ForceFeedbackLevels{ + ThumbForceFeedbackLevel, + IndexForceFeedbackLevel, + MiddleForceFeedbackLevel, + RingForceFeedbackLevel, + PinkyForceFeedbackLevel, + }; + + return ForceFeedbackLevels; +} + +TArray ASGPlayerController::FImpl::GetVibrotactileLevels( + const AActor* ActorThumbTouching, + const AActor* ActorIndexTouching, + const AActor* ActorMiddleTouching, + const AActor* ActorRingTouching, + const AActor* ActorPinkyTouching) +{ + const float ThumbVibrotactileLevel = GetVibrotactileLevel(ActorThumbTouching); + const float IndexVibrotactileLevel = GetVibrotactileLevel(ActorIndexTouching); + const float MiddleVibrotactileLevel = GetVibrotactileLevel(ActorMiddleTouching); + const float RingVibrotactileLevel = GetVibrotactileLevel(ActorRingTouching); + const float PinkyVibrotactileLevel = GetVibrotactileLevel(ActorPinkyTouching); + + const TArray ForceFeedbackLevels{ + ThumbVibrotactileLevel, + IndexVibrotactileLevel, + MiddleVibrotactileLevel, + RingVibrotactileLevel, + PinkyVibrotactileLevel, + }; + + return ForceFeedbackLevels; +} + +ASGPlayerController::ASGPlayerController(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +void ASGPlayerController::BeginPlay() +{ + Super::BeginPlay(); + + ASGPawn* SGPawn = Cast(GetPawn()); + if (!ensureAlwaysMsgf(IsValid(SGPawn), TEXT("%s"), TEXT("ERROR: invalid SenseGlove pawn!"))) + { + return; + } + + SGPawn->OnGrabStateUpdated().AddWeakLambda( + this, [= SG_CAPTURE_THIS](const FSGGrabState& GrabState) -> void + { + if (!IsValid(SGPawn)) + { + return; + } + + if (!IsValid(GrabState.Hand)) + { + return; + } + + const bool bHandVisible = GrabState.Hand->IsVisible(); + if (!bHandVisible) + { + if (SGPawn->IsGrabbing(GrabState.Hand)) + { + SGPawn->Release(GrabState.Hand); + } + return; + } + + if (SGPawn->IsGrabbing(GrabState.Hand)) + { + if (!IsValid(GrabState.ActorThumbCanGrab) || + (GrabState.ActorIndexCanGrab != GrabState.ActorThumbCanGrab + && GrabState.ActorMiddleCanGrab != GrabState.ActorThumbCanGrab)) + { + SGPawn->Release(GrabState.Hand); + } + } + else + { + if (SGPawn->CanGrab(GrabState.Hand, GrabState.ActorThumbCanGrab)) + { + SGPawn->Grab(GrabState.Hand, GrabState.ActorThumbCanGrab); + } + } + }); + + SGPawn->OnTouchStateUpdated().AddWeakLambda( + this, [= SG_CAPTURE_THIS](const FSGTouchState& TouchState) -> void + { + if (!IsValid(SGPawn)) + { + return; + } + + if (!IsValid(TouchState.Hand)) + { + return; + } + + const bool bHandVisible = TouchState.Hand->IsVisible(); + if (!bHandVisible) + { + return; + } + + const bool bGloveConnected = TouchState.Hand->IsGloveConnected(); + if (!bGloveConnected) + { + return; + } + + Pimpl->UpdateHapticsFeedback(TouchState); + }); +} + +ASGPlayerController::FImpl::FImpl(ASGPlayerController* InOwner) + : Owner(InOwner) +{ +} + +ASGPlayerController::FImpl::~FImpl() = default; + +void ASGPlayerController::FImpl::UpdateHapticsFeedback(const FSGTouchState& TouchState) +{ + static const TArray VibrotactileOffCommand{0.0f, 0.0f, 0.0, 0.0, 0.0f}; + + if (!IsValid(TouchState.Hand)) + { + return; + } + + USGHapticGlove* Glove = TouchState.Hand->GetConnectedGlove(); + if (!IsValid(Glove)) + { + return; + } + + const bool bGloveConnected = Glove->IsConnected(); + if (!bGloveConnected) + { + return; + } + + // Queue the Force-Feedback command... + TArray ForceFeedbackLevels{ + GetForceFeedbackLevels( + TouchState.ActorThumbTouching, TouchState.ActorIndexTouching, TouchState.ActorMiddleTouching, + TouchState.ActorRingTouching, TouchState.ActorPinkyTouching) + }; + Glove->QueueForceFeedbackLevels(MoveTemp(ForceFeedbackLevels)); + + // Queue the Vibrotactile command... + TArray VibrotactileLevels{ + GetVibrotactileLevels( + TouchState.ActorThumbTouching, TouchState.ActorIndexTouching, TouchState.ActorMiddleTouching, + TouchState.ActorRingTouching, TouchState.ActorPinkyTouching) + }; + Glove->QueueVibroLevels(MoveTemp(VibrotactileLevels)); + + // Send the haptics commands! + Glove->SendHaptics(); + + // Stop the Vibrotactile command after the timeout if any haptic feedback is ongoing. + const float VibrotactileDuration = FImpl::GetVibrotactileDuration( + TouchState.ActorThumbTouching, TouchState.ActorIndexTouching, TouchState.ActorMiddleTouching, + TouchState.ActorRingTouching, TouchState.ActorPinkyTouching); + + Owner->GetWorldTimerManager().ClearTimer(TouchVibrotactileStopTimer); + + FTimerDelegate TouchVibrotactileStopHandler; + TouchVibrotactileStopHandler.BindLambda([= SG_CAPTURE_THIS]()-> void + { + if (!IsValid(Glove)) + { + return; + } + + const bool bGloveConnected = Glove->IsConnected(); + if (!bGloveConnected) + { + return; + } + + Glove->QueueVibroLevels(VibrotactileOffCommand); + Glove->SendHaptics(); + }); + + Owner->GetWorldTimerManager().SetTimer( + TouchVibrotactileStopTimer, TouchVibrotactileStopHandler, VibrotactileDuration, false, -1.0f); +} + +void ASGPlayerController::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Haptics/SGGrabState.cpp b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Haptics/SGGrabState.cpp new file mode 100644 index 0000000..895eb3e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Haptics/SGGrabState.cpp @@ -0,0 +1,68 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGlove/Haptics/SGGrabState.h" + +#include "GameFramework/Actor.h" + +#include "SenseGlove/Components/SGVirtualHandComponent.h" + +FSGGrabState::FSGGrabState() + : Hand(nullptr), + PreviousHandLocation(FVector::Zero()), + HandVelocityHistory{}, + ActorThumbCanGrab(nullptr), + ActorIndexCanGrab(nullptr), + ActorMiddleCanGrab(nullptr), + GrabbedActor(nullptr) +{ +} + +FSGGrabState::FSGGrabState(USGVirtualHandComponent* InHand, + const FVector& InPreviousHandLocation, + const TArray& InHandVelocityHistory, + AActor* InActorThumbCanGrab, + AActor* InActorIndexCanGrab, + AActor* InActorMiddleCanGrab, + AActor* InGrabbedActor) + : Hand(InHand), + PreviousHandLocation(InPreviousHandLocation), + HandVelocityHistory(InHandVelocityHistory), + ActorThumbCanGrab(InActorThumbCanGrab), + ActorIndexCanGrab(InActorIndexCanGrab), + ActorMiddleCanGrab(InActorMiddleCanGrab), + GrabbedActor(InGrabbedActor) +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Haptics/SGTouchState.cpp b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Haptics/SGTouchState.cpp new file mode 100644 index 0000000..3b5601b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGlove/Haptics/SGTouchState.cpp @@ -0,0 +1,65 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGlove/Haptics/SGTouchState.h" + +#include "GameFramework/Actor.h" + +#include "SenseGlove/Components/SGVirtualHandComponent.h" + +FSGTouchState::FSGTouchState() + : Hand(nullptr), + ActorThumbTouching(nullptr), + ActorIndexTouching(nullptr), + ActorMiddleTouching(nullptr), + ActorRingTouching(nullptr), + ActorPinkyTouching(nullptr) +{ +} + +FSGTouchState::FSGTouchState(USGVirtualHandComponent* InHand, + AActor* InActorThumbTouching, + AActor* InActorIndexTouching, + AActor* InActorMiddleTouching, + AActor* InActorRingTouching, + AActor* InActorPinkyTouching) + : Hand(InHand), + ActorThumbTouching(InActorThumbTouching), + ActorIndexTouching(InActorIndexTouching), + ActorMiddleTouching(InActorMiddleTouching), + ActorRingTouching(InActorRingTouching), + ActorPinkyTouching(InActorPinkyTouching) +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGloveModule.cpp b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGloveModule.cpp new file mode 100644 index 0000000..550bfdd --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGloveModule.cpp @@ -0,0 +1,221 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveModule.h" + +#include "Engine/Engine.h" +#include "GameMapsSettings.h" +#include "Misc/CoreDelegates.h" + +#include "SGLog/SGLog.h" +#include "SenseGlove/Engine/SGGameInstance.h" +#include "SenseGlove/GameFramework/SGGameModeBase.h" +#include "SenseGlove/GameFramework/SGGameUserSettings.h" +#include "SGSettings/SGSettings.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveModule" + +void FSenseGloveModule::StartupModule() +{ + SGLOG("Starting up the SenseGlove module..."); + + OnPostEngineInitHandle = FCoreDelegates::OnPostEngineInit.AddRaw( + this, &FSenseGloveModule::OnPostEngineInit); +} + +void FSenseGloveModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGlove module..."); +} + +void FSenseGloveModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGlove module has succeeded!"); +} + +void FSenseGloveModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGlove module..."); + + FCoreDelegates::OnPostEngineInit.Remove(OnPostEngineInitHandle); +} + +void FSenseGloveModule::OnPostEngineInit() const +{ + const FSGInitializationSettings& Settings{ + USGSettings::GetInstance()->GetInitializationSettings() + }; + if (!Settings.bValidateIfDefaultClassesAreSGCompliant) + { + SGLOG("Will not be checking whether the default classes are SenseGlove-compliant, or not since it's disabled!"); + return; + } + + SGLOG("Checking whether the default classes are SenseGlove-compliant, or not..."); + + SGLOG("Checking whether the GameMapsSettings is compliant with SenseGlove, or not..."); + + UGameMapsSettings* GameMapsSettings{UGameMapsSettings::GetGameMapsSettings()}; + if (ensureAlwaysMsgf(GameMapsSettings, TEXT("Invalid GameMapsSettings!"))) + { + /************************************************************************************************************* + * GameInstanceClass + *************************************************************************************************************/ + + { + SGLOG("Validating if the GameInstanceClass is a SenseGlove GameInstance..."); + + bool bValidGameInstance = false; + const UClass* CurrentGameInstanceClass{GameMapsSettings->GameInstanceClass.TryLoadClass()}; + if (CurrentGameInstanceClass) + { + if (CurrentGameInstanceClass->IsChildOf(USGGameInstance::StaticClass())) + { + bValidGameInstance = true; + SGLOG("The GameInstanceClass is a SenseGlove GameInstance, or a subclass."); + } + else + { + SGLOG("The GameInstanceClass is not a SenseGlove GameInstance, or a subclass."); + } + } + else + { + SGLOG_ERROR("Failed to construct a valid GameInstance from the current settings!"); + } + + if (!bValidGameInstance) + { + SGLOG("Setting the SenseGlove GameInstance as the GameInstanceClass..."); + + static const FSoftClassPath GameInstanceClassPath{TEXT("/Script/SenseGlove.SGGameInstance")}; + GameMapsSettings->GameInstanceClass = GameInstanceClassPath; + + SGLOG("Successfully set the SenseGlove GameInstance as the GameInstanceClass!"); + } + } + + /************************************************************************************************************* + * DefaultGameMode + *************************************************************************************************************/ + + { + SGLOG("Validating if the DefaultGameMode is a SenseGlove GameMode..."); + + bool bValidDefaultGameMode = false; + const FSoftClassPath CurrentDefaultGameModeClassPath{GameMapsSettings->GetGlobalDefaultGameMode()}; + const UClass* CurrentDefaultGameMode{CurrentDefaultGameModeClassPath.TryLoadClass()}; + if (CurrentDefaultGameMode) + { + if (CurrentDefaultGameMode->IsChildOf(ASGGameModeBase::StaticClass())) + { + bValidDefaultGameMode = true; + SGLOG("The DefaultGameMode is a SenseGlove GameMode, or a subclass."); + } + else + { + SGLOG("The DefaultGameMode is not a SenseGlove GameMode, or a subclass."); + } + } + else + { + SGLOG_ERROR("Failed to construct a valid GameMode from the current settings!"); + } + + if (!bValidDefaultGameMode) + { + SGLOG("Setting the SenseGlove GameMode as the DefaultGameMode..."); + + static const FString DefaultGameMode{TEXT("/Script/SenseGlove.SGGameModeBase")}; + GameMapsSettings->SetGlobalDefaultGameMode(DefaultGameMode); + + SGLOG("Successfully set the SenseGlove GameMode as the DefaultGameMode!"); + } + } + + /************************************************************************************************************* + * + *************************************************************************************************************/ + } + else + { + SGLOG_ERROR("Failed to check whether the GameMapsSettings is compliant with SenseGlove, or not!"); + } + + SGLOG("Checking whether the GameUserSettingsClass is compliant with SenseGlove, or not..."); + + if (ensureAlwaysMsgf(GEngine, TEXT("Invalid GEngine!"))) + { + SGLOG("Validating if the GameUserSettingsClass is a SenseGlove GameUserSettings..."); + + bool bValidGameUserSettings = false; + const UClass* CurrentGameUserSettingsClass{GEngine->GameUserSettingsClassName.TryLoadClass()}; + if (CurrentGameUserSettingsClass) + { + if (CurrentGameUserSettingsClass->IsChildOf(USGGameUserSettings::StaticClass())) + { + bValidGameUserSettings = true; + SGLOG("The GameUserSettingsClass is a SenseGlove GameUserSettings, or a subclass."); + } + else + { + SGLOG("The GameUserSettingsClass is not a SenseGlove GameUserSettings, or a subclass."); + } + } + else + { + SGLOG_ERROR("Failed to construct a valid GameUserSettings from the current settings!"); + } + + if (!bValidGameUserSettings) + { + SGLOG("Setting the SenseGlove GameUserSettings as the GameUserSettingsClass..."); + + static const FSoftClassPath GameUserSettingsClassPath{TEXT("/Script/SenseGlove.SGGameUserSettings")}; + GEngine->GameUserSettingsClassName = GameUserSettingsClassPath; + GEngine->GameUserSettingsClass = USGGameUserSettings::StaticClass(); + GEngine->GameUserSettings = NewObject(); + GEngine->GetGameUserSettings()->LoadSettings(true); + + SGLOG("Successfully set the SenseGlove GameInstance as the GameInstanceClass!"); + } + } + else + { + SGLOG_ERROR("Failed to check whether the GameUserSettings is compliant with SenseGlove, or not!"); + } +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGloveModule.h b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGloveModule.h new file mode 100644 index 0000000..63e0b89 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Private/SenseGloveModule.h @@ -0,0 +1,54 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Delegates/IDelegateInstance.h" +#include "Modules/ModuleInterface.h" + +class FSenseGloveModule : public IModuleInterface +{ +private: + FDelegateHandle OnPostEngineInitHandle; + +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; + +private: + void OnPostEngineInit() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Animation/SGVirtualHandAnimInstance.h b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Animation/SGVirtualHandAnimInstance.h new file mode 100644 index 0000000..fe4e44c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Animation/SGVirtualHandAnimInstance.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Animation/AnimInstance.h" + +#include "SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.h" + +#include "SGVirtualHandAnimInstance.generated.h" + +UCLASS(Transient, Blueprintable, BlueprintType, meta=(BlueprintThreadSafe), Within=SkeletalMeshComponent) +class SENSEGLOVE_API USGVirtualHandAnimInstance : public UAnimInstance +{ + GENERATED_UCLASS_BODY() + +protected: + virtual FSGVirtualHandAnimInstanceProxy* CreateAnimInstanceProxy() override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.h b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.h new file mode 100644 index 0000000..4e74335 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.h @@ -0,0 +1,145 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Animation/AnimInstanceProxy.h" +#include "Containers/Array.h" +#include "HeadMountedDisplayTypes.h" +#include "Math/Quat.h" +#include "Math/Transform.h" +#include "Runtime/Launch/Resources/Version.h" +#include "Templates/UniquePtr.h" +#include "UObject/NameTypes.h" + +#include "SGVirtualHandAnimInstanceProxy.generated.h" + +class USkeletalMesh; +class USkeleton; +class USGVirtualHandComponent; + +USTRUCT() +struct SENSEGLOVE_API FSGVirtualHandAnimInstanceProxy : public FAnimInstanceProxy +{ + GENERATED_USTRUCT_BODY() + +private: + UPROPERTY(Transient) + USGVirtualHandComponent* VirtualHand; + + UPROPERTY(Transient) + USkeletalMesh* HandMeshAsset; + + UPROPERTY(Transient) + USkeleton* HandSkeleton; + + bool bVirtualHandVisible; + bool bMarkRenderStateDirty; + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + FXRHandTrackingState HandTrackingState; +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + FXRMotionControllerData MotionControllerData; +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + + TMap::SizeType, FName> BoneNamesMap; + + FTransform AnimationBoneCorrectionOffsetTransform; + bool bShouldAnimationApplyBoneLocation; + +public: + FSGVirtualHandAnimInstanceProxy(); + FSGVirtualHandAnimInstanceProxy(UAnimInstance* Instance); + +protected: + FORCEINLINE bool IsVirtualHandVisible() const + { + return bVirtualHandVisible; + } + + FORCEINLINE USGVirtualHandComponent* GetVirtualHand() const + { + return VirtualHand; + } + + FORCEINLINE USkeletalMesh* GetHandMeshAsset() const + { + return HandMeshAsset; + } + + FORCEINLINE USkeleton* GetHandSkeleton() const + { + return HandSkeleton; + } + + FORCEINLINE bool IsRenderStateDirty() const + { + return bMarkRenderStateDirty; + } + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + FORCEINLINE const FXRHandTrackingState& GetHandTrackingState() const + { + return HandTrackingState; + } +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + FORCEINLINE const FXRMotionControllerData& GetMotionControllerData() const + { + return MotionControllerData; + } +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + + FORCEINLINE const TMap::SizeType, FName>& GetBoneNamesMap() const + { + return BoneNamesMap; + } + + FORCEINLINE const FTransform& GetAnimationBoneCorrectionOffsetTransform() const + { + return AnimationBoneCorrectionOffsetTransform; + } + + FORCEINLINE bool ShouldAnimationApplyBoneLocation() const + { + return bShouldAnimationApplyBoneLocation; + } + +protected: + virtual void PreEvaluateAnimation(UAnimInstance* InAnimInstance) override; + + virtual bool Evaluate(FPoseContext& Output) override; + + virtual void PostEvaluate(UAnimInstance* InAnimInstance) override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Components/SGGrabComponent.h b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Components/SGGrabComponent.h new file mode 100644 index 0000000..f1e1929 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Components/SGGrabComponent.h @@ -0,0 +1,205 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Components/SceneComponent.h" +#include "Engine/EngineTypes.h" +#include "Templates/UniquePtr.h" +#include "UObject/NameTypes.h" + +#include "SGGrabComponent.generated.h" + +class AActor; + +UCLASS(Blueprintable, BlueprintType, meta=(BlueprintSpawnableComponent)) +class SENSEGLOVE_API USGGrabComponent : public USceneComponent +{ + GENERATED_UCLASS_BODY() + +public: + static USGGrabComponent* GetGrabComponent(const AActor* Actor); + + static bool IsGrabbable(const AActor* Actor); + +private: + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + EAttachmentRule AttachmentLocationRule; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + EAttachmentRule AttachmentRotationRule; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + EAttachmentRule AttachmentScaleRule; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + bool bAttachmentWeldSimulatedBodies; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + FName AttachmentSocketName; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + EDetachmentRule DetachmentLocationRule; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + EDetachmentRule DetachmentRotationRule; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + EDetachmentRule DetachmentScaleRule; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + bool bDetachmentCallModify; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + bool bAffectPhysicsState; + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FORCEINLINE EAttachmentRule GetAttachmentLocationRule() const + { + return AttachmentLocationRule; + } + + FORCEINLINE void SetAttachmentLocationRule(const EAttachmentRule InAttachmentLocationRule) + { + AttachmentLocationRule = InAttachmentLocationRule; + } + + FORCEINLINE EAttachmentRule GetAttachmentRotationRule() const + { + return AttachmentRotationRule; + } + + FORCEINLINE void SetAttachmentRotationRule(const EAttachmentRule InAttachmentRotationRule) + { + AttachmentRotationRule = InAttachmentRotationRule; + } + + FORCEINLINE EAttachmentRule GetAttachmentScaleRule() const + { + return AttachmentScaleRule; + } + + FORCEINLINE void SetAttachmentScaleRule(const EAttachmentRule InAttachmentScaleRule) + { + AttachmentScaleRule = InAttachmentScaleRule; + } + + FORCEINLINE bool GetAttachmentWeldSimulatedBodies() const + { + return bAttachmentWeldSimulatedBodies; + } + + FORCEINLINE void SetAttachmentWeldSimulatedBodies(const bool bInAttachmentWeldSimulatedBodies) + { + bAttachmentWeldSimulatedBodies = bInAttachmentWeldSimulatedBodies; + } + + FORCEINLINE const FName& GetAttachmentSocketName() const + { + return AttachmentSocketName; + } + + FORCEINLINE void SetAttachmentSocketName(const FName& InAttachmentSocketName) + { + AttachmentSocketName = InAttachmentSocketName; + } + + FORCEINLINE EDetachmentRule GetDetachmentLocationRule() const + { + return DetachmentLocationRule; + } + + FORCEINLINE void SetDetachmentLocationRule(const EDetachmentRule InDetachmentLocationRule) + { + DetachmentLocationRule = InDetachmentLocationRule; + } + + FORCEINLINE EDetachmentRule GetDetachmentRotationRule() const + { + return DetachmentRotationRule; + } + + FORCEINLINE void SetDetachmentRotationRule(const EDetachmentRule InDetachmentRotationRule) + { + DetachmentRotationRule = InDetachmentRotationRule; + } + + FORCEINLINE EDetachmentRule GetDetachmentScaleRule() const + { + return DetachmentScaleRule; + } + + FORCEINLINE void SetDetachmentScaleRule(const EDetachmentRule InDetachmentScaleRule) + { + DetachmentScaleRule = InDetachmentScaleRule; + } + + FORCEINLINE bool GetDetachmentInCallModify() const + { + return bDetachmentCallModify; + } + + FORCEINLINE void SetDetachmentInCallModify(const bool bInDetachmentCallModify) + { + bDetachmentCallModify = bInDetachmentCallModify; + } + + FORCEINLINE bool GetAffectPhysicsState() const + { + return bAffectPhysicsState; + } + + FORCEINLINE void SetAffectPhysicsState(const bool bInAffectPhysicsState) + { + bAffectPhysicsState = bInAffectPhysicsState; + } + +public: + virtual void SimulatePhysics(bool bSimulatePhysics) const; + +public: + virtual void BeginPlay() override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Components/SGTouchComponent.h b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Components/SGTouchComponent.h new file mode 100644 index 0000000..814da10 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Components/SGTouchComponent.h @@ -0,0 +1,107 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Components/SceneComponent.h" +#include "Templates/UniquePtr.h" + +#include "SGTouchComponent.generated.h" + +class AActor; + +UCLASS(Blueprintable, BlueprintType, meta=(BlueprintSpawnableComponent)) +class SENSEGLOVE_API USGTouchComponent : public USceneComponent +{ + GENERATED_UCLASS_BODY() + +public: + static USGTouchComponent* GetTouchComponent(const AActor* Actor); + + static bool IsTouchable(const AActor* Actor); + +private: + UPROPERTY(EditAnywhere, Category="SenseGlove", + meta=(AllowPrivateAccess="false", ClampMin = "0.0", ClampMax = "1.0", UIMin = "0.0", UIMax = "1.0")) + float ForceFeedbackLevel; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false", ClampMin = "0.0", UIMin = "0.0")) + float VibrotactileDuration; + + UPROPERTY(EditAnywhere, Category="SenseGlove", + meta=(AllowPrivateAccess="false", ClampMin = "0.0", ClampMax = "100.0", UIMin = "0.0", UIMax = "100.0")) + float VibrotactileLevel; + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FORCEINLINE float GetForceFeedbackLevel() const + { + return ForceFeedbackLevel; + } + + FORCEINLINE void SetForceFeedbackLevel(const float Level) + { + ForceFeedbackLevel = Level; + } + + FORCEINLINE float GetVibrotactileDuration() const + { + return VibrotactileDuration; + } + + FORCEINLINE void SetVibrotactileDuration(const float Duration) + { + VibrotactileDuration = Duration; + } + FORCEINLINE float GetVibrotactileLevel() const + { + return VibrotactileLevel; + } + + FORCEINLINE void SetVibrotactileLevel(const float Level) + { + VibrotactileLevel = Level; + } +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Components/SGVirtualHandComponent.h b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Components/SGVirtualHandComponent.h new file mode 100644 index 0000000..b97213c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Components/SGVirtualHandComponent.h @@ -0,0 +1,206 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Components/SkeletalMeshComponent.h" +#include "Containers/Map.h" +#include "GameFramework/Actor.h" +#include "HeadMountedDisplayTypes.h" +#include "Math/Rotator.h" +#include "Math/Transform.h" +#include "Misc/AssertionMacros.h" +#include "ReferenceSkeleton.h" +#include "Runtime/Launch/Resources/Version.h" +#include "Templates/UniquePtr.h" +#include "UObject/NameTypes.h" + +#include "SGSettings/SGVirtualHandSettings.h" +#include "SGSettings/SGVirtualHandSettingsOverrides.h" + +#include "SGVirtualHandComponent.generated.h" + +class USphereComponent; +class USkeletalMesh; + +class USGHapticGlove; +class USGWristTrackerComponent; + +UCLASS(Config=Engine, Blueprintable, ClassGroup=(Rendering, Common), hidecategories=(Object, "Mesh|SkeletalAsset"), + editinlinenew, meta=(BlueprintSpawnableComponent)) +class SENSEGLOVE_API USGVirtualHandComponent : public USkeletalMeshComponent +{ + GENERATED_UCLASS_BODY() + +public: + DECLARE_EVENT_OneParam(USGVirtualHandComponent, FHandVisibilityChangedEvent, bool bNewVisibiliy); + + FHandVisibilityChangedEvent& OnHandVisibilityChanged() + { + return HandVisibilityChangedEvent; + }; + +private: + FHandVisibilityChangedEvent HandVisibilityChangedEvent; + +public: + static const TArray& GetLeftHandBoneNames(); + static const TArray& GetRightHandBoneNames(); + + static const FName& GetLeftHandBoneName(int32 Joint); + static const FName& GetRightHandBoneName(int32 Joint); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +private: + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + bool bRight; + + /** + * Overrides the plugin's virtual hand settings. + */ + UPROPERTY(EditAnywhere, Category = "SenseGlove", meta=(AllowPrivateAccess="false")) + FSGVirtualHandSettingsOverrides VirtualHandSettingsOverrides; + +private: + UPROPERTY(Transient) + USGWristTrackerComponent* WristTracker; + +protected: + UFUNCTION(BlueprintNativeEvent, Category="SenseGlove | Components | Virtual Hand Component") + void OnHandVisibilityChanged(bool bNewVisibility); + +public: + FORCEINLINE bool IsLeft() const + { + return !IsRight(); + } + + FORCEINLINE bool IsRight() const + { + return bRight; + } + + void SetRight(const bool bInRight); + + FORCEINLINE bool OverridesPluginVirtualHandSettings() const + { + return VirtualHandSettingsOverrides.bOverridePluginSettings; + } + + FORCEINLINE const FSGVirtualHandSettingsOverrides& GetVirtualHandSettingsOverrides() const + { + return VirtualHandSettingsOverrides; + } + + void SetVirtualHandSettingsOverrides(const FSGVirtualHandSettingsOverrides& InVirtualHandSettingsOverrides); + + FSGVirtualHandSettings GetVirtualHandSettings() const; + +public: + FORCEINLINE void SetWristTracker(USGWristTrackerComponent* InWristTracker) + { + WristTracker = InWristTracker; + } + +public: +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + virtual void SetAnimInstanceClass(class UClass* NewClass) override; +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + virtual void SetAnimClass(class UClass* NewClass) override; +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + + virtual void PostInitProperties() override; + +#if WITH_EDITOR + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; +#endif /* WITH_EDITOR */ + + virtual void InitializeComponent() override; + + virtual void UninitializeComponent() override; + + virtual void BeginPlay() override; + + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + + virtual void TickComponent(float DeltaTime, + enum ELevelTick TickType, + FActorComponentTickFunction* ThisTickFunction) override; + + virtual void SetSkeletalMesh(USkeletalMesh* NewMesh, bool bReinitPose = true) override; + +protected: + virtual void EditorTick(float DeltaTime, + enum ELevelTick TickType, + FActorComponentTickFunction* ThisTickFunction); + +public: + bool IsGloveConnected() const; + USGHapticGlove* GetConnectedGlove() const; + + bool GetMotionControllerData(FXRMotionControllerData& OutMotionControllerData); + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + bool GetMotionControllerState( + EXRSpaceType XRSpaceType, EXRControllerPoseType XRControllerPoseType, + FXRMotionControllerState& OutMotionControllerState); + bool GetHandTrackingState( + EXRSpaceType XRSpaceType, + FXRHandTrackingState& OutHandTrackingState); +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + +public: + const TArray& GetHandBoneNames() const; + const FName& GetHandBoneName(int32 Joint) const; + + const FTransform& GetHandBoneRefTransform(const FName& BoneName) const; + const FTransform& GetHandBoneRefTransform(int32 Joint) const; + + const FTransform& GetHandRootBoneRefTransform() const; + + FRotator GetHandBoneRefRotation(const FName& BoneName) const; + FRotator GetHandBoneRefRotation(int32 Joint) const; +}; diff --git a/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Components/SGWristTrackerComponent.h b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Components/SGWristTrackerComponent.h new file mode 100644 index 0000000..833d29c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Components/SGWristTrackerComponent.h @@ -0,0 +1,178 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "GameFramework/Actor.h" +#include "HeadMountedDisplayTypes.h" +#include "Math/Rotator.h" +#include "Math/Vector.h" +#include "MotionControllerComponent.h" +#include "Runtime/Launch/Resources/Version.h" +#include "Templates/UniquePtr.h" + +#include "SGSettings/SGWristTrackingSettings.h" +#include "SGSettings/SGWristTrackingSettingsOverrides.h" + +#include "SGWristTrackerComponent.generated.h" + +UCLASS(Blueprintable, ClassGroup = MotionController, meta = (BlueprintSpawnableComponent)) +class SENSEGLOVE_API USGWristTrackerComponent : public UMotionControllerComponent +{ + GENERATED_UCLASS_BODY() + +public: + DECLARE_EVENT_OneParam(USGWristTrackerComponent, FWristLocationChangedEvent, const FVector&) + + FWristLocationChangedEvent& OnWristLocationChanged() + { + return WristLocationChangedEvent; + }; + + DECLARE_EVENT_OneParam(USGWristTrackerComponent, FWristRotationChangedEvent, const FRotator&) + + FWristRotationChangedEvent& OnWristRotationChanged() + { + return WristRotationChangedEvent; + }; + + DECLARE_EVENT_TwoParams(USGWristTrackerComponent, FWristLocationAndRotationChangedEvent, + const FVector&, const FRotator&) + + FWristLocationAndRotationChangedEvent& OnWristLocationAndRotationChanged() + { + return WristLocationAndRotationChangedEvent; + }; + +private: + FWristLocationChangedEvent WristLocationChangedEvent; + FWristRotationChangedEvent WristRotationChangedEvent; + FWristLocationAndRotationChangedEvent WristLocationAndRotationChangedEvent; + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +private: + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + bool bRight; + + /** + * Overrides the plugin's wrist tracking settings. + */ + UPROPERTY(EditAnywhere, Category = "SenseGlove", meta=(AllowPrivateAccess="false")) + FSGWristTrackingSettingsOverrides WristTrackingSettingsOverrides; + +private: + UPROPERTY(Transient) + FVector WristLocation; + + UPROPERTY(Transient) + FRotator WristRotation; + +public: + FORCEINLINE bool IsLeft() const + { + return !IsRight(); + } + + FORCEINLINE bool IsRight() const + { + return bRight; + } + + void SetRight(const bool bInRight); + + FORCEINLINE bool OverridesPluginWristTrackingSettings() const + { + return WristTrackingSettingsOverrides.bOverridePluginSettings; + } + + FORCEINLINE const FSGWristTrackingSettingsOverrides& GetWristTrackingSettingsOverrides() const + { + return WristTrackingSettingsOverrides; + } + + void SetWristTrackingSettingsOverrides(const FSGWristTrackingSettingsOverrides& InWristTrackingSettingsOverrides); + + FSGWristTrackingSettings GetWristTrackingSettings() const; + + FORCEINLINE const FVector& GetWristLocation() const + { + return WristLocation; + } + + FORCEINLINE const FRotator& GetWristRotation() const + { + return WristRotation; + } + +public: +#if WITH_EDITOR + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; +#endif /* WITH_EDITOR */ + + virtual void InitializeComponent() override; + + virtual void BeginPlay() override; + + virtual void TickComponent(float DeltaTime, + enum ELevelTick TickType, + FActorComponentTickFunction* ThisTickFunction) override; + +protected: + virtual void EditorTick(float DeltaTime, + enum ELevelTick TickType, + FActorComponentTickFunction* ThisTickFunction); + +public: + bool GetMotionControllerData(FXRMotionControllerData& OutMotionControllerData); + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + bool GetMotionControllerState( + EXRSpaceType XRSpaceType, EXRControllerPoseType XRControllerPoseType, + FXRMotionControllerState& OutMotionControllerState); + bool GetHandTrackingState( + EXRSpaceType XRSpaceType, + FXRHandTrackingState& OutHandTrackingState); +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Engine/SGGameInstance.h b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Engine/SGGameInstance.h new file mode 100644 index 0000000..5fe02ae --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Engine/SGGameInstance.h @@ -0,0 +1,59 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Engine/GameInstance.h" + +#include "SGTypes/SGTypes.h" + +#include "SGGameInstance.generated.h" + +UCLASS(config=Game, Transient, BlueprintType, Blueprintable) +class SENSEGLOVE_API USGGameInstance : public UGameInstance +{ + GENERATED_UCLASS_BODY() + +public: + UFUNCTION(Exec, Category = "Console Command") + static void SG_GetEngineScalabilitySettings(); + + UFUNCTION(Exec, Category = "Console Command") + static void SG_SetEngineScalabilitySettings(ESGEngineScalabilitySettings Scalability); + +public: + virtual void Init() override; + virtual void Shutdown() override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/GameFramework/SGGameModeBase.h b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/GameFramework/SGGameModeBase.h new file mode 100644 index 0000000..c59b736 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/GameFramework/SGGameModeBase.h @@ -0,0 +1,46 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "GameFramework/GameModeBase.h" + +#include "SGGameModeBase.generated.h" + +UCLASS(Config=Game, NotPlaceable, BlueprintType, Blueprintable, Transient) +class SENSEGLOVE_API ASGGameModeBase : public AGameModeBase +{ + GENERATED_UCLASS_BODY() +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/GameFramework/SGGameUserSettings.h b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/GameFramework/SGGameUserSettings.h new file mode 100644 index 0000000..43caf66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/GameFramework/SGGameUserSettings.h @@ -0,0 +1,67 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "GameFramework/GameUserSettings.h" +#include "Templates/UniquePtr.h" + +#include "SGTypes/SGTypes.h" + +#include "SGGameUserSettings.generated.h" + +UCLASS(config=GameUserSettings, configdonotcheckdefaults, BlueprintType, Blueprintable) +class SENSEGLOVE_API USGGameUserSettings : public UGameUserSettings +{ + GENERATED_UCLASS_BODY() + +public: + static USGGameUserSettings* GetInstance(); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + ESGEngineScalabilitySettings GetEngineScalabilitySettings() const; + void SetEngineScalabilitySettings(ESGEngineScalabilitySettings Scalability); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h new file mode 100644 index 0000000..0f40d59 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPawn.h @@ -0,0 +1,750 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "GameFramework/Pawn.h" +#include "Runtime/Launch/Resources/Version.h" +#include "Templates/UniquePtr.h" + +#include "SenseGlove/Haptics/SGGrabState.h" +#include "SenseGlove/Haptics/SGTouchState.h" + +#include "SGPawn.generated.h" + +class UCameraComponent; +class UPrimitiveComponent; +class USphereComponent; +class UXRDeviceVisualizationComponent; + +class USGVirtualHandComponent; +class USGWristTrackerComponent; + +UCLASS(Config=Game, BlueprintType, Blueprintable) +class SENSEGLOVE_API ASGPawn : public APawn +{ + GENERATED_UCLASS_BODY() + +public: + DECLARE_EVENT_OneParam(ASGPawn, FGrabStateUpdatedEvent, const FSGGrabState& GrabState); + + FGrabStateUpdatedEvent& OnGrabStateUpdated() + { + return GrabStateUpdatedEvent; + }; + + DECLARE_EVENT_OneParam(ASGPawn, FTouchStateUpdatedEvent, const FSGTouchState& TouchState) + + FTouchStateUpdatedEvent& OnTouchStateUpdated() + { + return TouchStateUpdatedEvent; + }; + + DECLARE_EVENT_TwoParams(ASGPawn, FActorGrabbedEvent, const USGVirtualHandComponent* Hand, const AActor* Actor); + + FActorGrabbedEvent& OnGrabbed() + { + return ActorGrabbedEvent; + }; + + DECLARE_EVENT_TwoParams(ASGPawn, FActorReleasedEvent, const USGVirtualHandComponent* Hand, const AActor* Actor); + + FActorReleasedEvent& OnReleased() + { + return ActorReleasedEvent; + }; + + DECLARE_EVENT_TwoParams(ASGPawn, FActorBeginTouchEvent, const USGVirtualHandComponent* Hand, const AActor* Actor); + + FActorBeginTouchEvent& OnActorBeginTouch() + { + return ActorBeginTouchEvent; + }; + + DECLARE_EVENT_TwoParams(ASGPawn, FActorEndTouchEvent, const USGVirtualHandComponent* Hand, const AActor* Actor); + + FActorEndTouchEvent& OnActorEndTouch() + { + return ActorEndTouchEvent; + }; + +private: + FGrabStateUpdatedEvent GrabStateUpdatedEvent; + FTouchStateUpdatedEvent TouchStateUpdatedEvent; + FActorGrabbedEvent ActorGrabbedEvent; + FActorReleasedEvent ActorReleasedEvent; + FActorBeginTouchEvent ActorBeginTouchEvent; + FActorEndTouchEvent ActorEndTouchEvent; + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +private: + UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USceneComponent* SceneRoot; + + UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + UCameraComponent* Camera; + + UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USGWristTrackerComponent* WristTrackerLeft; + + UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + UXRDeviceVisualizationComponent* ControllerVisualizerLeft; + + UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USGVirtualHandComponent* HandLeft; + + UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USGVirtualHandComponent* RealHandLeft; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USphereComponent* LeftThumbFingertipGrabCollider; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USphereComponent* LeftIndexFingertipGrabCollider; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USphereComponent* LeftMiddleFingertipGrabCollider; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USphereComponent* LeftThumbFingertipTouchCollider; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USphereComponent* LeftIndexFingertipTouchCollider; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USphereComponent* LeftMiddleFingertipTouchCollider; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USphereComponent* LeftRingFingertipTouchCollider; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USphereComponent* LeftPinkyFingertipTouchCollider; + + UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USGWristTrackerComponent* WristTrackerRight; + + UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + UXRDeviceVisualizationComponent* ControllerVisualizerRight; + + UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USGVirtualHandComponent* HandRight; + + UPROPERTY(VisibleAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USGVirtualHandComponent* RealHandRight; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USphereComponent* RightThumbFingertipGrabCollider; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USphereComponent* RightIndexFingertipGrabCollider; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USphereComponent* RightMiddleFingertipGrabCollider; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USphereComponent* RightThumbFingertipTouchCollider; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USphereComponent* RightIndexFingertipTouchCollider; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USphereComponent* RightMiddleFingertipTouchCollider; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USphereComponent* RightRingFingertipTouchCollider; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + USphereComponent* RightPinkyFingertipTouchCollider; + + UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false")) + int32 MaxNumberOfHandVelocitySamples; + +private: + UPROPERTY(Transient) + FSGGrabState LeftHandGrabState; + + UPROPERTY(Transient) + FSGTouchState LeftHandTouchState; + + UPROPERTY(Transient) + FSGGrabState RightHandGrabState; + + UPROPERTY(Transient) + FSGTouchState RightHandTouchState; + + UPROPERTY(Transient) + TArray LeftHandOverlappedActors; + + UPROPERTY(Transient) + TArray RightHandOverlappedActors; + +protected: + UFUNCTION(BlueprintNativeEvent, Category="SenseGlove | Game Framework | Pawn") + void OnGrabStateUpdated(const FSGGrabState& GrabState); + + UFUNCTION(BlueprintNativeEvent, Category="SenseGlove | Game Framework | Pawn") + void OnTouchStateUpdated(const FSGTouchState& TouchState); + + UFUNCTION(BlueprintNativeEvent, Category="SenseGlove | Game Framework | Pawn") + void OnActorGrabbed(const USGVirtualHandComponent* Hand, const AActor* Actor); + + UFUNCTION(BlueprintNativeEvent, Category="SenseGlove | Game Framework | Pawn") + void OnActorReleased(const USGVirtualHandComponent* Hand, const AActor* Actor); + + UFUNCTION(BlueprintNativeEvent, Category="SenseGlove | Game Framework | Pawn") + void OnActorBeginTouch(const USGVirtualHandComponent* Hand, const AActor* Actor); + + UFUNCTION(BlueprintNativeEvent, Category="SenseGlove | Game Framework | Pawn") + void OnActorEndTouch(const USGVirtualHandComponent* Hand, const AActor* Actor); + +public: + FORCEINLINE UCameraComponent* GetCamera() const + { + return Camera; + } + + FORCEINLINE USGWristTrackerComponent* GetWristTrackerLeft() const + { + return WristTrackerLeft; + } + + FORCEINLINE UXRDeviceVisualizationComponent* GetControllerVisualizerLeft() const + { + return ControllerVisualizerLeft; + } + + FORCEINLINE USGVirtualHandComponent* GetHandLeft() const + { + return HandLeft; + } + + FORCEINLINE USGVirtualHandComponent* GetRealHandLeft() const + { + return RealHandLeft; + } + + FORCEINLINE USphereComponent* GetLeftThumbFingertipGrabCollider() const + { + return LeftThumbFingertipGrabCollider; + } + + FORCEINLINE USphereComponent* GetLeftIndexFingertipGrabCollider() const + { + return LeftIndexFingertipGrabCollider; + } + + FORCEINLINE USphereComponent* GetLeftMiddleFingertipGrabCollider() const + { + return LeftMiddleFingertipGrabCollider; + } + + FORCEINLINE USphereComponent* GetLeftThumbFingertipTouchCollider() const + { + return LeftThumbFingertipTouchCollider; + } + + FORCEINLINE USphereComponent* GetLeftIndexFingertipTouchCollider() const + { + return LeftIndexFingertipTouchCollider; + } + + FORCEINLINE USphereComponent* GetLeftMiddleFingertipTouchCollider() const + { + return LeftMiddleFingertipTouchCollider; + } + + FORCEINLINE USphereComponent* GetLeftRingFingertipTouchCollider() const + { + return LeftRingFingertipTouchCollider; + } + + FORCEINLINE USphereComponent* GetLeftPinkyFingertipTouchCollider() const + { + return LeftPinkyFingertipTouchCollider; + } + + FORCEINLINE USGWristTrackerComponent* GetWristTrackerRight() const + { + return WristTrackerRight; + } + + FORCEINLINE UXRDeviceVisualizationComponent* GetControllerVisualizerRight() const + { + return ControllerVisualizerLeft; + } + + FORCEINLINE USGVirtualHandComponent* GetHandRight() const + { + return HandRight; + } + + FORCEINLINE USGVirtualHandComponent* GetRealHandRight() const + { + return RealHandRight; + } + + FORCEINLINE USphereComponent* GetRightThumbFingertipGrabCollider() const + { + return RightThumbFingertipGrabCollider; + } + + FORCEINLINE USphereComponent* GetRightIndexFingertipGrabCollider() const + { + return RightIndexFingertipGrabCollider; + } + + FORCEINLINE USphereComponent* GetRightMiddleFingertipGrabCollider() const + { + return RightMiddleFingertipGrabCollider; + } + + FORCEINLINE USphereComponent* GetRightThumbFingertipTouchCollider() const + { + return RightThumbFingertipTouchCollider; + } + + FORCEINLINE USphereComponent* GetRightIndexFingertipTouchCollider() const + { + return RightIndexFingertipTouchCollider; + } + + FORCEINLINE USphereComponent* GetRightMiddleFingertipTouchCollider() const + { + return RightMiddleFingertipTouchCollider; + } + + FORCEINLINE USphereComponent* GetRightRingFingertipTouchCollider() const + { + return RightRingFingertipTouchCollider; + } + + FORCEINLINE USphereComponent* GetRightPinkyFingertipTouchCollider() const + { + return RightPinkyFingertipTouchCollider; + } + + FORCEINLINE int32 GetMaxNumberOfHandVelocitySamples() const + { + return MaxNumberOfHandVelocitySamples; + } + + FORCEINLINE void SetMaxNumberOfHandVelocitySamples(const int32 InMaxNumberOfHandVelocitySamples) + { + MaxNumberOfHandVelocitySamples = InMaxNumberOfHandVelocitySamples; + } + +public: + virtual void BeginPlay() override; + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + virtual void Tick(float DeltaSeconds) override; + virtual void PreInitializeComponents() override; + virtual void PostInitializeComponents() override; + +protected: + UFUNCTION() + virtual void OnRealLeftHandOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnRealLeftHandOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnRealRightHandOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnRealRightHandOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnLeftThumbFingertipGrabColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnLeftThumbFingertipGrabColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnLeftIndexFingertipGrabColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnLeftIndexFingertipGrabColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnLeftMiddleFingertipGrabColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnLeftMiddleFingertipGrabColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnLeftThumbFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnLeftThumbFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnLeftIndexFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnLeftIndexFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnLeftMiddleFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnLeftMiddleFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnLeftRingFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnLeftRingFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnLeftPinkyFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnLeftPinkyFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnRightThumbFingertipGrabColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnRightThumbFingertipGrabColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnRightIndexFingertipGrabColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnRightIndexFingertipGrabColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnRightMiddleFingertipGrabColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnRightMiddleFingertipGrabColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnRightThumbFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnRightThumbFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnRightIndexFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnRightIndexFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnRightMiddleFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnRightMiddleFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnRightRingFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnRightRingFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + virtual void OnRightPinkyFingertipTouchColliderOverlapBegins( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + virtual void OnRightPinkyFingertipTouchColliderOverlapEnds( + UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + +public: + FORCEINLINE bool CanLeftHandGrab(const AActor* Actor) const + { + return !IsLeftHandGrabbing() && ((IsValid(Actor) && Actor == LeftHandGrabState.ActorThumbCanGrab) + && (Actor == LeftHandGrabState.ActorIndexCanGrab || Actor == LeftHandGrabState.ActorMiddleCanGrab)); + } + + FORCEINLINE bool IsLeftHandGrabbing(const AActor* Actor) const + { + return IsValid(Actor) && LeftHandGrabState.GrabbedActor == Actor; + } + + bool IsLeftHandGrabbing(AActor*& OutActor) const; + + FORCEINLINE bool IsLeftHandGrabbing() const + { + return IsValid(LeftHandGrabState.GrabbedActor); + } + + FORCEINLINE bool CanRightHandGrab(const AActor* Actor) const + { + return !IsRightHandGrabbing() && ((IsValid(Actor) && Actor == RightHandGrabState.ActorThumbCanGrab) + && (Actor == RightHandGrabState.ActorIndexCanGrab || Actor == RightHandGrabState.ActorMiddleCanGrab)); + } + + FORCEINLINE bool IsRightHandGrabbing(const AActor* Actor) const + { + return IsValid(Actor) && RightHandGrabState.GrabbedActor == Actor; + } + + FORCEINLINE bool IsRightHandGrabbing() const + { + return IsValid(RightHandGrabState.GrabbedActor); + } + + bool IsRightHandGrabbing(AActor*& OutActor) const; + + FORCEINLINE bool CanGrab(const USGVirtualHandComponent* Hand, const AActor* Actor) const + { + return Hand == HandRight ? CanRightHandGrab(Actor) : CanLeftHandGrab(Actor); + } + + FORCEINLINE bool IsGrabbing(const USGVirtualHandComponent* Hand, const AActor* Actor) const + { + return Hand == HandRight ? IsRightHandGrabbing(Actor) : IsLeftHandGrabbing(Actor); + } + + bool IsGrabbing(const USGVirtualHandComponent* Hand, AActor*& OutActor) const; + + FORCEINLINE bool IsGrabbing(const USGVirtualHandComponent* Hand) const + { + return Hand == HandRight ? IsRightHandGrabbing() : IsLeftHandGrabbing(); + } + +public: + FORCEINLINE void GrabLeft(AActor* Actor) + { + Grab(HandLeft, Actor); + } + + FORCEINLINE void GrabRight(AActor* Actor) + { + Grab(HandRight, Actor); + } + + void Grab(USGVirtualHandComponent* Hand, AActor* Actor); + + void ReleaseLeft(); + + void ReleaseRight(); + + FORCEINLINE void Release(const USGVirtualHandComponent* Hand) + { + return Hand == HandRight ? ReleaseRight() : ReleaseLeft(); + } +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPlayerController.h b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPlayerController.h new file mode 100644 index 0000000..2ddb9e6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/GameFramework/SGPlayerController.h @@ -0,0 +1,61 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "GameFramework/PlayerController.h" +#include "Templates/UniquePtr.h" + +#include "SGPlayerController.generated.h" + +UCLASS(Config=Game, BlueprintType, Blueprintable) +class SENSEGLOVE_API ASGPlayerController : public APlayerController +{ + GENERATED_UCLASS_BODY() + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +protected: + virtual void BeginPlay() override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Haptics/SGGrabState.h b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Haptics/SGGrabState.h new file mode 100644 index 0000000..9c15b53 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Haptics/SGGrabState.h @@ -0,0 +1,86 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Math/Vector.h" +#include "UObject/ObjectMacros.h" + +#include "SGGrabState.generated.h" + +class AActor; +class UPrimitiveComponent; + +class USGVirtualHandComponent; + +USTRUCT(BlueprintType) +struct SENSEGLOVE_API FSGGrabState +{ + GENERATED_USTRUCT_BODY() + +public: + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") + USGVirtualHandComponent* Hand; + + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") + FVector PreviousHandLocation; + + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") + TArray HandVelocityHistory; + + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") + AActor* ActorThumbCanGrab; + + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") + AActor* ActorIndexCanGrab; + + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") + AActor* ActorMiddleCanGrab; + + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") + AActor* GrabbedActor; + +public: + FSGGrabState(); + + explicit FSGGrabState(USGVirtualHandComponent* InHand, + const FVector& InPreviousHandLocation, + const TArray& InHandVelocityHistory, + AActor* InActorThumbCanGrab, + AActor* InActorIndexCanGrab, + AActor* InActorMiddleCanGrab, + AActor* InGrabbedActor); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Haptics/SGTouchState.h b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Haptics/SGTouchState.h new file mode 100644 index 0000000..9e80aae --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/Public/SenseGlove/Haptics/SGTouchState.h @@ -0,0 +1,79 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "UObject/ObjectMacros.h" + +#include "SGTouchState.generated.h" + +class AActor; + +class USGVirtualHandComponent; + +USTRUCT(BlueprintType) +struct SENSEGLOVE_API FSGTouchState +{ + GENERATED_USTRUCT_BODY() + +public: + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") + USGVirtualHandComponent* Hand; + + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") + AActor* ActorThumbTouching; + + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") + AActor* ActorIndexTouching; + + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") + AActor* ActorMiddleTouching; + + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") + AActor* ActorRingTouching; + + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "SenseGlove") + AActor* ActorPinkyTouching; + +public: + FSGTouchState(); + + explicit FSGTouchState(USGVirtualHandComponent* InHand, + AActor* InActorThumbTouching, + AActor* InActorIndexTouching, + AActor* InActorMiddleTouching, + AActor* InActorRingTouching, + AActor* InActorPinkyTouching); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGlove/SenseGlove.Build.cs b/Plugins/SenseGlove/Source/SenseGlove/SenseGlove.Build.cs new file mode 100644 index 0000000..7d0053a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGlove/SenseGlove.Build.cs @@ -0,0 +1,85 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGlove : ModuleRules +{ + public SenseGlove(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "AnimGraphRuntime", + "Core", + "CoreUObject", + "Engine", + "EngineSettings", + "HeadMountedDisplay", + "InputCore", + "InputDevice", + "OpenXRHMD", + // NOTE + // UE 5.3+ provides UXRDeviceVisualizationComponent as part of the XRBase plugin. + // UE 5.2 provides UXRDeviceVisualizationComponent as part of the HeadMountDisplay module. +#if UE_5_3_OR_LATER + "XRBase", +#endif + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveCore", + "SenseGloveDebug", + "SenseGloveLog", + "SenseGloveSettings", + "SenseGloveTracking", + "SenseGloveTypes", + } + ); + + PrivateIncludePathModuleNames.AddRange( + new string[] + { + "SenseGloveBuildHacks", + } + ); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SGAndroid/SGAndroidPermissions.cpp b/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SGAndroid/SGAndroidPermissions.cpp new file mode 100644 index 0000000..8c04b83 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SGAndroid/SGAndroidPermissions.cpp @@ -0,0 +1,190 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGAndroid/SGAndroidPermissions.h" + +#include "AndroidPermissionCallbackProxy.h" +#include "AndroidPermissionFunctionLibrary.h" +#include "Engine/Engine.h" + +#include "SGLog/SGLog.h" + +struct USGAndroidPermissions::FImpl +{ + /************************ + * Member variables + ************************/ + + TFunction&, const TArray&)> PermissionsGrantedCallback; + + /************************ + * Owner object + ************************/ + + USGAndroidPermissions* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGAndroidPermissions* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGAndroidPermissions* USGAndroidPermissions::GetInstance() +{ + if (!ensureAlwaysMsgf(GEngine, TEXT("The engine has not been initialized!"))) + { + return nullptr; + } + + USGAndroidPermissions* Instance{GEngine->GetEngineSubsystem()}; + return Instance; +} + +USGAndroidPermissions::USGAndroidPermissions() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +void USGAndroidPermissions::Request( + const TFunction&, const TArray&)>& PermissionsGrantedCallback) +{ + TArray Permissions{ + "android.permission.ACCESS_BACKGROUND_LOCATION", + "android.permission.ACCESS_FINE_LOCATION", + "android.permission.BLUETOOTH", + "android.permission.BLUETOOTH_ADMIN", + "android.permission.BLUETOOTH_ADVERTISE", + "android.permission.BLUETOOTH_CONNECT", + "android.permission.BLUETOOTH_SCAN", + }; + + bool bHasAllRequiredPermissions = false; + for (const FString& Permission: Permissions) + { + const bool bHasPermission = UAndroidPermissionFunctionLibrary::CheckPermission(Permission); + bHasAllRequiredPermissions = bHasPermission; + if (!bHasAllRequiredPermissions) + { + break; + } + } + + if (!bHasAllRequiredPermissions) + { + Pimpl->PermissionsGrantedCallback = PermissionsGrantedCallback; + + UAndroidPermissionFunctionLibrary::AcquirePermissions( + MoveTemp(Permissions))->OnPermissionsGrantedDelegate.AddUObject( + this, &USGAndroidPermissions::OnPermissionsGranted); + } + else + { + TArray GrantedResults; + for (int32 i = 0; i < Permissions.Num(); ++i) + { + GrantedResults.Add(true); + } + PermissionsGrantedCallback(MoveTemp(Permissions), MoveTemp(GrantedResults)); + } +} + +void USGAndroidPermissions::OnPermissionsGranted(const TArray& Permissions, const TArray& GrantResults) +{ + if (!ensureAlwaysMsgf(Permissions.Num() == GrantResults.Num(), + TEXT("Mismatched number of Permissions and GrantedResults!"))) + { + return; + } + + for (int32 i = 0; i < Permissions.Num(); i++) + { + if (GrantResults[i]) + { + SGLOG("Permission Granted", Permissions[i]); + } + else + { + SGLOG("Permission Denied", Permissions[i]); + } + } + + Pimpl->PermissionsGrantedCallback(Permissions, GrantResults); +} + +bool USGAndroidPermissions::ShouldCreateSubsystem(UObject* Outer) const +{ + return true; +} + +void USGAndroidPermissions::Initialize(FSubsystemCollectionBase& Collection) +{ + SGLOG("Initializing the SenseGlove Android permissions singleton with the engine lifetime..."); + + Super::Initialize(Collection); + + SGLOG("The SenseGlove Android permissions singleton has been successfully initialized with the engine lifetime!"); +} + +void USGAndroidPermissions::Deinitialize() +{ + SGLOG("De-initializing the SenseGlove Android permissions singleton due to the engine lifetime expiration..."); + + Super::Deinitialize(); + + (void) Pimpl.Release(); + + SGLOG("The SenseGlove Android permissions singleton has been successfully de-initialized!"); +} + +USGAndroidPermissions::FImpl::FImpl(USGAndroidPermissions* InOwner) + : Owner(InOwner) +{ +} + +USGAndroidPermissions::FImpl::~FImpl() = default; + +void USGAndroidPermissions::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SGAndroid/SGConnectJNI.cpp b/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SGAndroid/SGConnectJNI.cpp new file mode 100644 index 0000000..10cfe51 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SGAndroid/SGConnectJNI.cpp @@ -0,0 +1,128 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGAndroid/SGConnectJNI.h" + +#if PLATFORM_ANDROID +#include "Android/AndroidApplication.h" +#include "Android/AndroidJava.h" +#endif /* PLATFORM_ANDROID */ + +#include "Misc/Paths.h" + +#if PLATFORM_ANDROID +#include "SGConnectImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_jclass.h" +#include "SGInterop/SGIC_jmethodID.h" +#include "SGInterop/SGIC_JNIEnv_Ptr.h" +#endif /* PLATFORM_ANDROID */ + +#include "SGLog/SGLog.h" + +int32 FSGConnectJNI::Initialize() +{ + int32 Result = -999999; + +#if PLATFORM_ANDROID + static constexpr char SGCONNECT_JAVA_CLASS_NAME[] = "com.senseglove.sgconnect.SGConnect"; + + SGLOG("FSGCoreJNI: attempting to get the Android JNI environment..."); + + JNIEnv* Env = FAndroidApplication::GetJavaEnv(); + FAndroidApplication::CheckJavaException(); + if (!Env) + { + SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI environmnet!"); + return -1999999; + } + FSGIC_JNIEnv_Ptr InEnvContainer{Env}; + + SGLOG("FSGCoreJNI: attempting to find the Android Java class..."); + + jclass Class = FAndroidApplication::FindJavaClass(SGCONNECT_JAVA_CLASS_NAME); + FAndroidApplication::CheckJavaException(); + if (Env->IsSameObject(Class, nullptr)) + { + SGLOG_ERROR("FSGCoreJNI: failed to get the Android Java class!"); + return -2999999; + } + Class = (jclass)Env->NewGlobalRef(Class); + FSGIC_jclass InClassContainer{Class}; + + SGLOG("FSGCoreJNI: attempting to find the Android JNI method 'Init'..."); + + jmethodID InitMethodID = Env->GetStaticMethodID(Class, "Init", "()I"); + FAndroidApplication::CheckJavaException(); + if (!InitMethodID) + { + SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI method 'Init'!"); + return -3999999; + } + FSGIC_jmethodID InInitMethodIDContainer{InitMethodID}; + + SGLOG("FSGCoreJNI: attempting to find the Android JNI method 'Dispose'..."); + + jmethodID DisposeMethodID = Env->GetStaticMethodID(Class, "Dispose", "()I"); + FAndroidApplication::CheckJavaException(); + if (!DisposeMethodID) + { + SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI method 'Dispose'!"); + return -4999999; + } + FSGIC_jmethodID InDisposeMethodIDContainer{DisposeMethodID}; + + SGLOG("FSGCoreJNI: attempting to find the Android JNI method 'GetLibraryVersion'..."); + + jmethodID GetLibraryVersionMethodID = Env->GetStaticMethodID(Class, "GetLibraryVersion", "()Ljava/lang/String;"); + FAndroidApplication::CheckJavaException(); + if (!GetLibraryVersionMethodID) + { + SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI method 'GetLibraryVersion'!"); + return -5999999; + } + FSGIC_jmethodID InGetLibraryVersionMethodIDContainer{GetLibraryVersionMethodID}; + + FSGIC_FString ProjectSavedDirContainer{FPaths::ProjectSavedDir()}; + + Result = SGConnectImpl_Android_Initialize(&InEnvContainer, &InClassContainer, + &InInitMethodIDContainer, + &InDisposeMethodIDContainer, + &InGetLibraryVersionMethodIDContainer, + &ProjectSavedDirContainer); +#endif /* PLATFORM_ANDROID */ + + return Result; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SGAndroid/SGCoreJNI.cpp b/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SGAndroid/SGCoreJNI.cpp new file mode 100644 index 0000000..0641ad6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SGAndroid/SGCoreJNI.cpp @@ -0,0 +1,140 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGAndroid/SGCoreJNI.h" + +#if PLATFORM_ANDROID +#include "Android/AndroidApplication.h" +#include "Android/AndroidJava.h" +#endif /* PLATFORM_ANDROID */ + +#include "Misc/Paths.h" + +#if PLATFORM_ANDROID +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_jclass.h" +#include "SGInterop/SGIC_jmethodID.h" +#include "SGInterop/SGIC_JNIEnv_Ptr.h" +#endif /* PLATFORM_ANDROID */ + +#include "SGLog/SGLog.h" + +int32 FSGCoreJNI::Initialize() +{ + int32 Result = -999999; + +#if PLATFORM_ANDROID + static constexpr char SGCONNECT_JAVA_CLASS_NAME[] = "com.senseglove.sgconnect.SGConnect"; + + SGLOG("FSGCoreJNI: attempting to get the Android JNI environment..."); + + JNIEnv* Env = FAndroidApplication::GetJavaEnv(); + FAndroidApplication::CheckJavaException(); + if (!Env) + { + SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI environmnet!"); + return -1999999; + } + FSGIC_JNIEnv_Ptr InEnvContainer{Env}; + + SGLOG("FSGCoreJNI: attempting to find the Android Java class..."); + + jclass Class = FAndroidApplication::FindJavaClass(SGCONNECT_JAVA_CLASS_NAME); + FAndroidApplication::CheckJavaException(); + if (Env->IsSameObject(Class, nullptr)) + { + SGLOG_ERROR("FSGCoreJNI: failed to get the Android Java class!"); + return -2999999; + } + Class = (jclass)Env->NewGlobalRef(Class); + FSGIC_jclass InClassContainer{Class}; + + SGLOG("FSGCoreJNI: attempting to find the Android JNI method 'ActiveDevices'..."); + + jmethodID ActiveDevicesMethodID = Env->GetStaticMethodID(Class, "ActiveDevices", "()I"); + FAndroidApplication::CheckJavaException(); + if (!ActiveDevicesMethodID) + { + SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI method 'ActiveDevices'!"); + return -3999999; + } + FSGIC_jmethodID InActiveDevicesMethodIDContainer{ActiveDevicesMethodID}; + + SGLOG("FSGCoreJNI: attempting to find the Android JNI method 'GetDeviceString'..."); + + jmethodID GetDeviceStringMethodID = Env->GetStaticMethodID(Class, "GetDeviceString", "(I)Ljava/lang/String;"); + FAndroidApplication::CheckJavaException(); + if (!GetDeviceStringMethodID) + { + SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI method 'GetDeviceString'!"); + return -4999999; + } + FSGIC_jmethodID InGetDeviceStringMethodIDContainer{GetDeviceStringMethodID}; + + SGLOG("FSGCoreJNI: attempting to find the Android JNI method 'GetSensorString'..."); + + jmethodID GetSensorStringMethodID = Env->GetStaticMethodID(Class, "GetSensorString", "(I)Ljava/lang/String;"); + FAndroidApplication::CheckJavaException(); + if (!GetSensorStringMethodID) + { + SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI method 'GetSensorString'!"); + return -5999999; + } + FSGIC_jmethodID InGetSensorStringMethodIDContainer{GetSensorStringMethodID}; + + SGLOG("FSGCoreJNI: attempting to find the Android JNI method 'WriteHaptics'..."); + + jmethodID WriteHapticsMethodID = Env->GetStaticMethodID(Class, "WriteHaptics", "(IILjava/lang/String;)I"); + FAndroidApplication::CheckJavaException(); + if (!WriteHapticsMethodID) + { + SGLOG_ERROR("FSGCoreJNI: failed to get the Android JNI method 'WriteHaptics'!"); + return -6999999; + } + FSGIC_jmethodID InWriteHapticsMethodIDContainer{WriteHapticsMethodID}; + + FSGIC_FString ProjectSavedDirContainer{FPaths::ProjectSavedDir()}; + + Result = SGCoreImpl_Android_Initialize(&InEnvContainer, &InClassContainer, + &InActiveDevicesMethodIDContainer, + &InGetDeviceStringMethodIDContainer, + &InGetSensorStringMethodIDContainer, + &InWriteHapticsMethodIDContainer, + &ProjectSavedDirContainer); +#endif /* PLATFORM_ANDROID */ + + return Result; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SenseGloveAndroid.cpp b/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SenseGloveAndroid.cpp new file mode 100644 index 0000000..d1b4ea4 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SenseGloveAndroid.cpp @@ -0,0 +1,41 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveAndroid.h" + +#include "Modules/ModuleManager.h" +#include "SenseGloveAndroidModule.h" + +IMPLEMENT_MODULE(FSenseGloveAndroidModule, SenseGloveAndroid) \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SenseGloveAndroid.h b/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SenseGloveAndroid.h new file mode 100644 index 0000000..a30ce66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SenseGloveAndroid.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SenseGloveAndroidModule.cpp b/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SenseGloveAndroidModule.cpp new file mode 100644 index 0000000..f126d5d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SenseGloveAndroidModule.cpp @@ -0,0 +1,95 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveAndroidModule.h" + +#include "Misc/CoreDelegates.h" + +#include "SGAndroid/SGAndroidPermissions.h" +#include "SGAndroid/SGConnectJNI.h" +#include "SGAndroid/SGCoreJNI.h" +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveAndroidModule" + +void FSenseGloveAndroidModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveAndroid module..."); + + OnPostEngineInitHandle = FCoreDelegates::OnPostEngineInit.AddRaw( + this, &FSenseGloveAndroidModule::OnPostEngineInit); +} + +void FSenseGloveAndroidModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveAndroid module..."); +} + +void FSenseGloveAndroidModule::PostLoadCallback() +{ + SGLOG("Loading the SenseGloveAndroid module has succeeded!"); +} + +void FSenseGloveAndroidModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveAndroid module..."); +} + +void FSenseGloveAndroidModule::OnPostEngineInit() const +{ +#if PLATFORM_ANDROID + USGAndroidPermissions::GetInstance()->Request( + [](const TArray& Permissions, const TArray& GrantResults) + { + const int32 R1 = FSGConnectJNI::Initialize(); + const int32 R2 = FSGCoreJNI::Initialize(); + + SGLOG("FSGConnectJNI::Initialize() return code", R1); + SGLOG("FSGCoreJNI::Initialize() return code", R2); + + ensureAlwaysMsgf(R1 == 0, + TEXT( + "Failed to initialize the SGConnect JNI bridge to SGConnect for Android! Status Code: %d" + ), R1); + + ensureAlwaysMsgf(R2 == 0, + TEXT("Failed to initialize the SGCore JNI bridge to SGConnect for Android! Status Code: %d" + ), R2); + + }); +#endif /* PLATFORM_ANDROID */ +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SenseGloveAndroidModule.h b/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SenseGloveAndroidModule.h new file mode 100644 index 0000000..d930683 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveAndroid/Private/SenseGloveAndroidModule.h @@ -0,0 +1,58 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Delegates/IDelegateInstance.h" +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveAndroid" + +class FSenseGloveAndroidModule : public IModuleInterface +{ +private: + FDelegateHandle OnPostEngineInitHandle; + +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; + +private: + void OnPostEngineInit() const; +}; + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveAndroid/Public/SGAndroid/SGAndroidPermissions.h b/Plugins/SenseGlove/Source/SenseGloveAndroid/Public/SGAndroid/SGAndroidPermissions.h new file mode 100644 index 0000000..2b31bc8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveAndroid/Public/SGAndroid/SGAndroidPermissions.h @@ -0,0 +1,82 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "Subsystems/EngineSubsystem.h" +#include "Templates/Function.h" +#include "Templates/SharedPointer.h" +#include "UObject/ObjectMacros.h" + +#include "SGAndroidPermissions.generated.h" + +UCLASS() +class SENSEGLOVEANDROID_API USGAndroidPermissions : public UEngineSubsystem +{ + GENERATED_BODY() + +public: + static USGAndroidPermissions* GetInstance(); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +private: + USGAndroidPermissions(); + +public: + void Request( + const TFunction&, const TArray&)>& PermissionsGrantedCallback); + +private: + void OnPermissionsGranted( + const TArray& Permissions, const TArray& GrantResults); + +public: + virtual bool ShouldCreateSubsystem(UObject* Outer) const override; + + virtual void Initialize(FSubsystemCollectionBase& Collection) override; + virtual void Deinitialize() override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveAndroid/Public/SGAndroid/SGConnectJNI.h b/Plugins/SenseGlove/Source/SenseGloveAndroid/Public/SGAndroid/SGConnectJNI.h new file mode 100644 index 0000000..0588326 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveAndroid/Public/SGAndroid/SGConnectJNI.h @@ -0,0 +1,49 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "UObject/ObjectMacros.h" + +#include "SGConnectJNI.generated.h" + +USTRUCT() +struct SENSEGLOVEANDROID_API FSGConnectJNI +{ + GENERATED_BODY() + +public: + static int32 Initialize(); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveAndroid/Public/SGAndroid/SGCoreJNI.h b/Plugins/SenseGlove/Source/SenseGloveAndroid/Public/SGAndroid/SGCoreJNI.h new file mode 100644 index 0000000..fac1b0e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveAndroid/Public/SGAndroid/SGCoreJNI.h @@ -0,0 +1,49 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "UObject/ObjectMacros.h" + +#include "SGCoreJNI.generated.h" + +USTRUCT() +struct SENSEGLOVEANDROID_API FSGCoreJNI +{ + GENERATED_BODY() + +public: + static int32 Initialize(); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveAndroid/SenseGloveAndroid.Build.cs b/Plugins/SenseGlove/Source/SenseGloveAndroid/SenseGloveAndroid.Build.cs new file mode 100644 index 0000000..9064d4b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveAndroid/SenseGloveAndroid.Build.cs @@ -0,0 +1,78 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using System.IO; +using UnrealBuildTool; + +public class SenseGloveAndroid : ModuleRules +{ + public SenseGloveAndroid(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "AndroidPermission", + "Core", + "CoreUObject", + "Engine", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveConnectImpl", + "SenseGloveCoreImpl", + "SenseGloveLog", + } + ); + + PrivateIncludePathModuleNames.AddRange( + new string[] + { + "SenseGloveInterop", + } + ); + + if (Target.Platform == UnrealTargetPlatform.Android) + { + AdditionalPropertiesForReceipt.Add("AndroidPlugin", + Path.Combine(ModuleDirectory, "SenseGloveAndroid_UPL.xml")); + } + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveAndroid/SenseGloveAndroid_UPL.xml b/Plugins/SenseGlove/Source/SenseGloveAndroid/SenseGloveAndroid_UPL.xml new file mode 100644 index 0000000..bcf9ad5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveAndroid/SenseGloveAndroid_UPL.xml @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + kapt.incremental.apt=true + + + + + + + + + + -dontwarn com.senseglove.** + -keep class com.senseglove.** { *; } + -keep interface com.senseglove.** { *; } + -keep public class com.senseglove.sgconnect.** { public protected *; } + + + + + + + + + + + + + + + + + + + + + + + + + + + ext { + android { + buildTypes { + release { + minifyEnabled false + } + } + } + } + + repositories { + mavenCentral() + } + + dependencies { + implementation files('libs/sgconnect.jar') + } + + + + + + + + + allprojects { + def mappings = [ + ] + beforeEvaluate { + } + } + + + + \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBackend/Private/SGBackend/SGBackend.cpp b/Plugins/SenseGlove/Source/SenseGloveBackend/Private/SGBackend/SGBackend.cpp new file mode 100644 index 0000000..d5348b1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBackend/Private/SGBackend/SGBackend.cpp @@ -0,0 +1,223 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBackend/SGBackend.h" + +#include "Engine/Engine.h" + +#if PLATFORM_ANDROID +#include "SGConnect/SGConnect.h" +#endif /* PLATFORM_ANDROID */ + +#include "SGCore/SGDeviceList.h" +#include "SGCore/SGHandLayer.h" +#include "SGLog/SGLog.h" + +struct USGBackend::FImpl +{ + /************************ + * Owner object + ************************/ + + USGBackend* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGBackend* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGBackend* USGBackend::GetInstance() +{ + if (!ensureAlwaysMsgf(GEngine, TEXT("The engine has not been initialized!"))) + { + return nullptr; + } + + USGBackend* Instance{GEngine->GetEngineSubsystem()}; + return Instance; +} + +USGBackend::USGBackend() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + bBackendInitialized = false; +} + +bool USGBackend::InitializeBackend() +{ + if (!IsBackendInitialized()) + { +#if PLATFORM_ANDROID + const int32 Result = FSGConnect::Init(); + switch (Result) + { + case -3: + SGLOG_ERROR("An Unexpected error occurred. Please try again."); + return false; + case -2: + SGLOG_ERROR("Device Scanning is already running within a different program."); + return false; + case -1: + SGLOG_ERROR("Device Scanning already being initialized (function called twice in short succession)."); + return false; + case 0: + SGLOG_ERROR("Device Scanning is already running within this program."); + return false; + case 1: + SGLOG("Successfully started up DeviceScanning from the current program."); + break; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled Init return status code!")); + return false; + } +#endif /* PLATFORM_ANDROID */ + + // Ensure that the device list is empty before doing anything. + FSGDeviceList::Dispose(); + FSGDeviceList::Reinitialize(); + + bBackendInitialized = true; + + return true; + } + + return false; +} + +bool USGBackend::UninitializeBackend() +{ + if (IsBackendInitialized()) + { + FSGDeviceList::Dispose(); + +#if PLATFORM_ANDROID + const int32 Result = FSGConnect::Dispose(); + switch (Result) + { + case -3: + SGLOG_ERROR("An Unexpected error occurred. Please try again."); + return false; + case -2: + SGLOG_ERROR("Not allowed to dispose of Device Scanning because this is not the program which started it."); + return false; + case -1: + SGLOG_ERROR("Device Scanning is currently being disposed off. This takes a second or two. (function called twice in short succession)."); + return false; + case 0: + SGLOG_ERROR("There is no deviceScanner running from any program, so disposing is skipped."); + return false; + case 1: + SGLOG("Successfully disposed of DeviceScanner resources."); + break; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled Dispose return status code!")); + return false; + } +#endif /* PLATFORM_ANDROID */ + + bBackendInitialized = false; + + return true; + } + + return false; +} + +bool USGBackend::ShouldCreateSubsystem(UObject* Outer) const +{ + return true; +} + +void USGBackend::Initialize(FSubsystemCollectionBase& Collection) +{ + SGLOG("Initializing the SenseGlove Backend singleton with the engine lifetime..."); + + Super::Initialize(Collection); + + SGLOG("Initializing the SenseGlove Backend singleton with the engine lifetime..."); + + if (InitializeBackend()) + { + SGLOG("The bridge to the SenseGlove Backend has been initialized successfully!") + } + else + { + SGLOG_ERROR("Failed to initialize the bridge to the SenseGlove Backend!") + } + + SGLOG("The SenseGlove Backend singleton has been successfully initialized with the engine lifetime!"); +} + +void USGBackend::Deinitialize() +{ + SGLOG("De-initializing the SenseGlove Backend singleton due to the engine lifetime expiration..."); + + Super::Deinitialize(); + + if (UninitializeBackend()) + { + SGLOG("The bridge to the SenseGlove Backend has been uninitialized successfully!") + } + else + { + SGLOG_ERROR("Failed to uninitialize the bridge to the SenseGlove Backend!") + } + + (void)Pimpl.Release(); + + SGLOG("The SenseGlove Backend singleton has been successfully de-initialized!"); +} + +USGBackend::FImpl::FImpl(USGBackend* InOwner) + : Owner(InOwner) +{ +} + +USGBackend::FImpl::~FImpl() = default; + +void USGBackend::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBackend/Private/SenseGloveBackend.cpp b/Plugins/SenseGlove/Source/SenseGloveBackend/Private/SenseGloveBackend.cpp new file mode 100644 index 0000000..3d97f18 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBackend/Private/SenseGloveBackend.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveBackend.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveBackendModule.h" + +IMPLEMENT_MODULE(FSenseGloveBackendModule, SenseGloveBackend) \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBackend/Private/SenseGloveBackend.h b/Plugins/SenseGlove/Source/SenseGloveBackend/Private/SenseGloveBackend.h new file mode 100644 index 0000000..a30ce66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBackend/Private/SenseGloveBackend.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBackend/Private/SenseGloveBackendModule.cpp b/Plugins/SenseGlove/Source/SenseGloveBackend/Private/SenseGloveBackendModule.cpp new file mode 100644 index 0000000..7eb6bb9 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBackend/Private/SenseGloveBackendModule.cpp @@ -0,0 +1,63 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveBackendModule.h" + +#include "SGLog/SGLog.h" +#include "SGBackend/SGBackend.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveBackendModule" + +void FSenseGloveBackendModule::StartupModule() +{ + SGLOG("Starting up SenseGloveBackend module..."); +} + +void FSenseGloveBackendModule::PreUnloadCallback() +{ + SGLOG("Unloading SenseGloveBackend module..."); +} + +void FSenseGloveBackendModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveBackend module has succeeded!"); +} + +void FSenseGloveBackendModule::ShutdownModule() +{ + SGLOG("Shutting down SenseGloveBackend module..."); +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBackend/Private/SenseGloveBackendModule.h b/Plugins/SenseGlove/Source/SenseGloveBackend/Private/SenseGloveBackendModule.h new file mode 100644 index 0000000..4814e9d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBackend/Private/SenseGloveBackendModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveBackend" + +class FSenseGloveBackendModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBackend/Public/SGBackend/SGBackend.h b/Plugins/SenseGlove/Source/SenseGloveBackend/Public/SGBackend/SGBackend.h new file mode 100644 index 0000000..f918c15 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBackend/Public/SGBackend/SGBackend.h @@ -0,0 +1,87 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Math/Color.h" +#include "Math/Rotator.h" +#include "Math/Vector.h" +#include "Subsystems/EngineSubsystem.h" +#include "Templates/UniquePtr.h" +#include "UObject/ObjectMacros.h" + +#include "SGBackend.generated.h" + +UCLASS() +class SENSEGLOVEBACKEND_API USGBackend : public UEngineSubsystem +{ + GENERATED_BODY() + +private: + UPROPERTY(Transient) + bool bBackendInitialized; + +public: + static USGBackend* GetInstance(); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +private: + USGBackend(); + +public: + FORCEINLINE bool IsBackendInitialized() const + { + return bBackendInitialized; + } + + bool InitializeBackend(); + bool UninitializeBackend(); + +public: + virtual bool ShouldCreateSubsystem(UObject* Outer) const override; + + virtual void Initialize(FSubsystemCollectionBase& Collection) override; + virtual void Deinitialize() override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBackend/SenseGloveBackend.Build.cs b/Plugins/SenseGlove/Source/SenseGloveBackend/SenseGloveBackend.Build.cs new file mode 100644 index 0000000..eaab1c6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBackend/SenseGloveBackend.Build.cs @@ -0,0 +1,65 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGloveBackend : ModuleRules +{ + public SenseGloveBackend(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + "InputCore", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveConnect", + "SenseGloveCore", + "SenseGloveLog", + "SenseGloveTypes", + } + ); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Private/SGBackendKismet/SGBackendKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Private/SGBackendKismet/SGBackendKismetLibrary.cpp new file mode 100644 index 0000000..fcd234f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Private/SGBackendKismet/SGBackendKismetLibrary.cpp @@ -0,0 +1,58 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBackendKismet/SGBackendKismetLibrary.h" + +#include "SGBackend/SGBackend.h" + +USGBackend* USGBackendKismetLibrary::GetInstance() +{ + return USGBackend::GetInstance(); +} + +bool USGBackendKismetLibrary::IsBackendInitialized(const USGBackend* Backend) +{ + return Backend->IsBackendInitialized(); +} + +bool USGBackendKismetLibrary::InitializeBackend(USGBackend* Backend) +{ + return Backend->InitializeBackend(); +} + +bool USGBackendKismetLibrary::UninitializeBackend(USGBackend* Backend) +{ + return Backend->UninitializeBackend(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Private/SenseGloveBackendKismet.cpp b/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Private/SenseGloveBackendKismet.cpp new file mode 100644 index 0000000..7f31765 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Private/SenseGloveBackendKismet.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveBackendKismet.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveBackendKismetModule.h" + +IMPLEMENT_MODULE(FSenseGloveBackendKismetModule, SenseGloveBackendKismet) diff --git a/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Private/SenseGloveBackendKismet.h b/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Private/SenseGloveBackendKismet.h new file mode 100644 index 0000000..a30ce66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Private/SenseGloveBackendKismet.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Private/SenseGloveBackendKismetModule.cpp b/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Private/SenseGloveBackendKismetModule.cpp new file mode 100644 index 0000000..f7b7fb1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Private/SenseGloveBackendKismetModule.cpp @@ -0,0 +1,62 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveBackendKismetModule.h" + +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveBackendKismetModule" + +void FSenseGloveBackendKismetModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveBackendKismet module..."); +} + +void FSenseGloveBackendKismetModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveBackendKismet module..."); +} + +void FSenseGloveBackendKismetModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveBackendKismet module has succeeded!"); +} + +void FSenseGloveBackendKismetModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveBackendKismet module..."); +} + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Private/SenseGloveBackendKismetModule.h b/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Private/SenseGloveBackendKismetModule.h new file mode 100644 index 0000000..9f2bf22 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Private/SenseGloveBackendKismetModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveBackendKismet" + +class FSenseGloveBackendKismetModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Public/SGBackendKismet/SGBackendKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Public/SGBackendKismet/SGBackendKismetLibrary.h new file mode 100644 index 0000000..debc48b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBackendKismet/Public/SGBackendKismet/SGBackendKismetLibrary.h @@ -0,0 +1,61 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" + +#include "SGBackendKismetLibrary.generated.h" + +class USGBackend; + +UCLASS(meta=(ScriptName = "SenseGloveBackendKismetLibrary")) +class SENSEGLOVEBACKENDKISMET_API USGBackendKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, Category="SenseGlove | Backend") + static USGBackend* GetInstance(); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Backend") + static bool IsBackendInitialized(const USGBackend* Backend); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Backend") + bool InitializeBackend(UPARAM(ref) USGBackend* Backend); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Backend") + bool UninitializeBackend(UPARAM(ref) USGBackend* Backend); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBackendKismet/SenseGloveBackendKismet.Build.cs b/Plugins/SenseGlove/Source/SenseGloveBackendKismet/SenseGloveBackendKismet.Build.cs new file mode 100644 index 0000000..6c76bcf --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBackendKismet/SenseGloveBackendKismet.Build.cs @@ -0,0 +1,64 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGloveBackendKismet : ModuleRules +{ + public SenseGloveBackendKismet(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveBackend", + "SenseGloveLog", + "SenseGloveKismet", + "SenseGloveTypes", + } + ); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGDisable_C4263.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGDisable_C4263.cpp new file mode 100644 index 0000000..7ae3b0f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGDisable_C4263.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGDisable_C4263.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGDisable_C4264.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGDisable_C4264.cpp new file mode 100644 index 0000000..b1b0614 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGDisable_C4264.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGDisable_C4264.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGDisable_C4706.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGDisable_C4706.cpp new file mode 100644 index 0000000..592dd8f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGDisable_C4706.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGDisable_C4706.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGDisable_C4800.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGDisable_C4800.cpp new file mode 100644 index 0000000..f248423 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGDisable_C4800.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGDisable_C4800.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Connect_Android.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Connect_Android.cpp new file mode 100644 index 0000000..5fe97cd --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Connect_Android.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Connect_Android.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Connect_SGConnect.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Connect_SGConnect.cpp new file mode 100644 index 0000000..370b2ad --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Connect_SGConnect.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Connect_SGConnect.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Anatomy.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Anatomy.cpp new file mode 100644 index 0000000..a77f626 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Anatomy.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_Anatomy.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Android.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Android.cpp new file mode 100644 index 0000000..6479ef1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Android.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_Android.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_BasicHandModel.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_BasicHandModel.cpp new file mode 100644 index 0000000..70c3d48 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_BasicHandModel.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_BasicHandModel.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_BetaDevice.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_BetaDevice.cpp new file mode 100644 index 0000000..1ae0f66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_BetaDevice.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_BetaDevice.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_CustomWaveform.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_CustomWaveform.cpp new file mode 100644 index 0000000..fb132fa --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_CustomWaveform.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_CustomWaveform.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_DeviceList.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_DeviceList.cpp new file mode 100644 index 0000000..710d3e7 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_DeviceList.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_DeviceList.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_DeviceModel.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_DeviceModel.cpp new file mode 100644 index 0000000..2d190b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_DeviceModel.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_DeviceModel.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Fingers.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Fingers.cpp new file mode 100644 index 0000000..39b07e7 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Fingers.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_Fingers.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_HandInterpolator.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_HandInterpolator.cpp new file mode 100644 index 0000000..8c9475c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_HandInterpolator.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_HandInterpolator.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_HandLayer.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_HandLayer.cpp new file mode 100644 index 0000000..24ff7fc --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_HandLayer.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_HandLayer.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_HandPose.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_HandPose.cpp new file mode 100644 index 0000000..4233b7c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_HandPose.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_HandPose.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_HapticChannelInfo.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_HapticChannelInfo.cpp new file mode 100644 index 0000000..7d34acd --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_HapticChannelInfo.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_HapticChannelInfo.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_HapticGlove.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_HapticGlove.cpp new file mode 100644 index 0000000..9a2e680 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_HapticGlove.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_HapticGlove.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_InterpolationSet.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_InterpolationSet.cpp new file mode 100644 index 0000000..45518f0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_InterpolationSet.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_InterpolationSet.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_JointKinematics.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_JointKinematics.cpp new file mode 100644 index 0000000..f1d86cf --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_JointKinematics.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_JointKinematics.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Library.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Library.cpp new file mode 100644 index 0000000..01e9319 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Library.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_Library.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_NormalizationState.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_NormalizationState.cpp new file mode 100644 index 0000000..ebfe9ec --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_NormalizationState.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_NormalizationState.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Nova2Glove.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Nova2Glove.cpp new file mode 100644 index 0000000..964f96f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Nova2Glove.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_Nova2Glove.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Nova2GloveSensorData.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Nova2GloveSensorData.cpp new file mode 100644 index 0000000..5776641 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Nova2GloveSensorData.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_Nova2GloveSensorData.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_NovaGlove.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_NovaGlove.cpp new file mode 100644 index 0000000..10de8f6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_NovaGlove.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_NovaGlove.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_NovaGloveInfo.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_NovaGloveInfo.cpp new file mode 100644 index 0000000..26aca11 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_NovaGloveInfo.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_NovaGloveInfo.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_NovaGloveSensorData.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_NovaGloveSensorData.cpp new file mode 100644 index 0000000..b93c5aa --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_NovaGloveSensorData.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_NovaGloveSensorData.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_NovaGloveVars.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_NovaGloveVars.cpp new file mode 100644 index 0000000..e13f197 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_NovaGloveVars.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_NovaGloveVars.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Quat.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Quat.cpp new file mode 100644 index 0000000..6832bac --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Quat.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_Quat.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SGDevice.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SGDevice.cpp new file mode 100644 index 0000000..b444ee6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SGDevice.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_SGDevice.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseCom.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseCom.cpp new file mode 100644 index 0000000..5360b66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseCom.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_SenseCom.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGlove.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGlove.cpp new file mode 100644 index 0000000..2a73e76 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGlove.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_SenseGlove.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGloveInfo.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGloveInfo.cpp new file mode 100644 index 0000000..f0d591f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGloveInfo.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_SenseGloveInfo.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGlovePose.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGlovePose.cpp new file mode 100644 index 0000000..0d794d8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGlovePose.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_SenseGlovePose.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGloveSensorData.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGloveSensorData.cpp new file mode 100644 index 0000000..feafb37 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGloveSensorData.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_SenseGloveSensorData.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGloveSensorNormalizer.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGloveSensorNormalizer.cpp new file mode 100644 index 0000000..d4fbba2 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGloveSensorNormalizer.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_SenseGloveSensorNormalizer.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGloveThumperCommand.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGloveThumperCommand.cpp new file mode 100644 index 0000000..3889007 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGloveThumperCommand.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_SenseGloveThumperCommand.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGloveVars.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGloveVars.cpp new file mode 100644 index 0000000..ed802c8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SenseGloveVars.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_SenseGloveVars.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SensorNormalization.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SensorNormalization.cpp new file mode 100644 index 0000000..e368026 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_SensorNormalization.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_SensorNormalization.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_ThresholdCommand.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_ThresholdCommand.cpp new file mode 100644 index 0000000..6722a2b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_ThresholdCommand.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_ThresholdCommand.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Tracking.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Tracking.cpp new file mode 100644 index 0000000..dcba2ce --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Tracking.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_Tracking.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Vect3D.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Vect3D.cpp new file mode 100644 index 0000000..f08c097 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Core_Vect3D.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Windows.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Windows.cpp new file mode 100644 index 0000000..1e89223 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGInclude_Windows.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGInclude_Windows.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGPlatform.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGPlatform.cpp new file mode 100644 index 0000000..c808010 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGPlatform.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGPlatform.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_C4263.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_C4263.cpp new file mode 100644 index 0000000..cc9c9b2 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_C4263.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGRestore_C4263.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_C4264.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_C4264.cpp new file mode 100644 index 0000000..c47d6a9 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_C4264.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGRestore_C4264.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_C4706.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_C4706.cpp new file mode 100644 index 0000000..e50941a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_C4706.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGRestore_C4706.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_C4800.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_C4800.cpp new file mode 100644 index 0000000..fe59e4a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_C4800.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGRestore_C4800.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_TEXT.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_TEXT.cpp new file mode 100644 index 0000000..33b8fd8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_TEXT.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_check.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_check.cpp new file mode 100644 index 0000000..dd3dde6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGRestore_check.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGRestore_check.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGUndef_TEXT.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGUndef_TEXT.cpp new file mode 100644 index 0000000..c2b7a11 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGUndef_TEXT.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGUndef_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGUndef_check.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGUndef_check.cpp new file mode 100644 index 0000000..c51272e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SGBuildHacks/SGUndef_check.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGBuildHacks/SGUndef_check.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SenseGloveBuildHacks.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SenseGloveBuildHacks.cpp new file mode 100644 index 0000000..cc6552e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SenseGloveBuildHacks.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveBuildHacks.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveBuildHacksModule.h" + +IMPLEMENT_MODULE(FSenseGloveBuildHacksModule, SenseGloveBuildHacks) \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SenseGloveBuildHacks.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SenseGloveBuildHacks.h new file mode 100644 index 0000000..a30ce66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SenseGloveBuildHacks.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SenseGloveBuildHacksModule.cpp b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SenseGloveBuildHacksModule.cpp new file mode 100644 index 0000000..01fbd1b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SenseGloveBuildHacksModule.cpp @@ -0,0 +1,61 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveBuildHacksModule.h" +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveBuildHacksModule" + +void FSenseGloveBuildHacksModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveBuildHacks module..."); +} + +void FSenseGloveBuildHacksModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveBuildHacks module..."); +} + +void FSenseGloveBuildHacksModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveBuildHacks module has succeeded!"); +} + +void FSenseGloveBuildHacksModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveBuildHacks module..."); +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SenseGloveBuildHacksModule.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SenseGloveBuildHacksModule.h new file mode 100644 index 0000000..14aff2c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Private/SenseGloveBuildHacksModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveBuildHacks" + +class FSenseGloveBuildHacksModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGDisable_C4263.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGDisable_C4263.h new file mode 100644 index 0000000..db29e07 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGDisable_C4263.h @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma warning(disable: 4263) \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGDisable_C4264.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGDisable_C4264.h new file mode 100644 index 0000000..429bbe8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGDisable_C4264.h @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma warning(disable: 4264) \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGDisable_C4706.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGDisable_C4706.h new file mode 100644 index 0000000..ed7f27d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGDisable_C4706.h @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma warning(disable: 4706) \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGDisable_C4800.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGDisable_C4800.h new file mode 100644 index 0000000..a7a19fb --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGDisable_C4800.h @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma warning(disable: 4800) \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGDisable_Woverloaded_virtual.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGDisable_Woverloaded_virtual.h new file mode 100644 index 0000000..eca25ba --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGDisable_Woverloaded_virtual.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#if ! PLATFORM_WINDOWS + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Woverloaded-virtual" + +#endif /* ! PLATFORM_WINDOWS */ \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Connect_Android.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Connect_Android.h new file mode 100644 index 0000000..d2f5f22 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Connect_Android.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Connect/Android.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Connect_SGConnect.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Connect_SGConnect.h new file mode 100644 index 0000000..f6bc301 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Connect_SGConnect.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Connect/SGConnect.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Anatomy.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Anatomy.h new file mode 100644 index 0000000..376e45e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Anatomy.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/Anatomy.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Android.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Android.h new file mode 100644 index 0000000..b733981 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Android.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/Android.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_BasicHandModel.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_BasicHandModel.h new file mode 100644 index 0000000..b9bfa21 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_BasicHandModel.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/BasicHandModel.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_BetaDevice.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_BetaDevice.h new file mode 100644 index 0000000..88763e8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_BetaDevice.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/BetaDevice.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_CustomWaveform.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_CustomWaveform.h new file mode 100644 index 0000000..20efe30 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_CustomWaveform.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/CustomWaveform.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_DeviceList.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_DeviceList.h new file mode 100644 index 0000000..72583ba --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_DeviceList.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/DeviceList.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_DeviceModel.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_DeviceModel.h new file mode 100644 index 0000000..3ffc13a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_DeviceModel.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/DeviceModel.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Fingers.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Fingers.h new file mode 100644 index 0000000..47d3b9d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Fingers.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/Fingers.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_HandInterpolator.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_HandInterpolator.h new file mode 100644 index 0000000..a23783a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_HandInterpolator.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/HandInterpolator.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_HandLayer.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_HandLayer.h new file mode 100644 index 0000000..57d6998 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_HandLayer.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/HandLayer.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_HandPose.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_HandPose.h new file mode 100644 index 0000000..3c57130 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_HandPose.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/HandPose.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_HapticChannelInfo.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_HapticChannelInfo.h new file mode 100644 index 0000000..7009350 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_HapticChannelInfo.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/HapticChannelInfo.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_HapticGlove.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_HapticGlove.h new file mode 100644 index 0000000..4350335 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_HapticGlove.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/HapticGlove.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_InterpolationSet.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_InterpolationSet.h new file mode 100644 index 0000000..d11727d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_InterpolationSet.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/InterpolationSet.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_JointKinematics.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_JointKinematics.h new file mode 100644 index 0000000..baf6f63 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_JointKinematics.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/JointKinematics.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Library.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Library.h new file mode 100644 index 0000000..67bb695 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Library.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/Library.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_NormalizationState.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_NormalizationState.h new file mode 100644 index 0000000..9a555e4 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_NormalizationState.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/NormalizationState.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Nova2Glove.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Nova2Glove.h new file mode 100644 index 0000000..75e8d2b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Nova2Glove.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/Nova2Glove.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Nova2GloveSensorData.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Nova2GloveSensorData.h new file mode 100644 index 0000000..c799756 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Nova2GloveSensorData.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/Nova2GloveSensorData.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_NovaGlove.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_NovaGlove.h new file mode 100644 index 0000000..98ad88c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_NovaGlove.h @@ -0,0 +1,52 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +#include "SGBuildHacks/SGDisable_C4263.h" +#include "SGBuildHacks/SGDisable_C4264.h" +#include "SGBuildHacks/SGDisable_Woverloaded_virtual.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/NovaGlove.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_C4263.h" +#include "SGBuildHacks/SGRestore_C4264.h" +#include "SGBuildHacks/SGRestore_Woverloaded_virtual.h" + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_NovaGloveInfo.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_NovaGloveInfo.h new file mode 100644 index 0000000..e380770 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_NovaGloveInfo.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/NovaGloveInfo.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_NovaGloveSensorData.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_NovaGloveSensorData.h new file mode 100644 index 0000000..dfabe1f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_NovaGloveSensorData.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/NovaGloveSensorData.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_NovaGloveVars.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_NovaGloveVars.h new file mode 100644 index 0000000..ff3812c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_NovaGloveVars.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/NovaGloveVars.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Quat.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Quat.h new file mode 100644 index 0000000..17fdb40 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Quat.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/Quat.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SGDevice.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SGDevice.h new file mode 100644 index 0000000..37469a2 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SGDevice.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/SGDevice.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseCom.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseCom.h new file mode 100644 index 0000000..d02fcd9 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseCom.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/SenseCom.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGlove.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGlove.h new file mode 100644 index 0000000..365a84c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGlove.h @@ -0,0 +1,52 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +#include "SGBuildHacks/SGDisable_C4263.h" +#include "SGBuildHacks/SGDisable_C4264.h" +#include "SGBuildHacks/SGDisable_Woverloaded_virtual.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/SenseGlove.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_C4263.h" +#include "SGBuildHacks/SGRestore_C4264.h" +#include "SGBuildHacks/SGRestore_Woverloaded_virtual.h" + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGloveInfo.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGloveInfo.h new file mode 100644 index 0000000..bfe3dc5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGloveInfo.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/SenseGloveInfo.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGlovePose.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGlovePose.h new file mode 100644 index 0000000..c5918a2 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGlovePose.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/SenseGlovePose.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGloveSensorData.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGloveSensorData.h new file mode 100644 index 0000000..c0a8765 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGloveSensorData.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/SenseGloveSensorData.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGloveSensorNormalizer.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGloveSensorNormalizer.h new file mode 100644 index 0000000..ebbdd8a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGloveSensorNormalizer.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/SenseGloveSensorNormalizer.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGloveThumperCommand.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGloveThumperCommand.h new file mode 100644 index 0000000..9649c22 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGloveThumperCommand.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/SenseGloveThumperCommand.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGloveVars.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGloveVars.h new file mode 100644 index 0000000..659832a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SenseGloveVars.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/SenseGloveVars.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SensorNormalization.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SensorNormalization.h new file mode 100644 index 0000000..585795e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_SensorNormalization.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/SensorNormalization.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_ThresholdCommand.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_ThresholdCommand.h new file mode 100644 index 0000000..6b99ff5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_ThresholdCommand.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/ThresholdCommand.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Tracking.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Tracking.h new file mode 100644 index 0000000..71131aa --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Tracking.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/Tracking.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Vect3D.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Vect3D.h new file mode 100644 index 0000000..75f1372 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Core_Vect3D.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGUndef_TEXT.h" + +THIRD_PARTY_INCLUDES_START +#include "SenseGlove/Core/Vect3D.hpp" +THIRD_PARTY_INCLUDES_END + +#include "SGBuildHacks/SGRestore_TEXT.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Windows.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Windows.h new file mode 100644 index 0000000..f541665 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGInclude_Windows.h @@ -0,0 +1,65 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#if PLATFORM_WINDOWS + +#include + +THIRD_PARTY_INCLUDES_START + +#include +#include +#include + +THIRD_PARTY_INCLUDES_END + +#undef CopyFile +#undef CreateDirectory +#undef DeleteFile +#undef DrawText +#undef GetObject +#undef InterlockedAdd +#undef InterlockedDecrement +#undef InterlockedExchange +#undef InterlockedIncrement +#undef MoveFile +#undef TEXT +#undef UpdateResource + +#include + +#endif /* PLATFORM_WINDOWS */ \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGPlatform.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGPlatform.h new file mode 100644 index 0000000..1b24c25 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGPlatform.h @@ -0,0 +1,60 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#if ( ( defined( _MSVC_LANG ) && _MSVC_LANG >= 201703L ) || __cplusplus >= 201703L ) +#define SG_CPP17 1 +#else /* ( ( defined( _MSVC_LANG ) && _MSVC_LANG >= 201703L ) || __cplusplus >= 201703L ) */ +#define SG_CPP17 0 +#endif /* ( ( defined( _MSVC_LANG ) && _MSVC_LANG >= 201703L ) || __cplusplus >= 201703L ) */ + +#if ( ( defined( _MSVC_LANG ) && _MSVC_LANG >= 202002L ) || __cplusplus >= 202002L ) +#define SG_CPP20 1 +#else /* ( ( defined( _MSVC_LANG ) && _MSVC_LANG >= 202002L ) || __cplusplus >= 202002L ) */ +#define SG_CPP20 0 +#endif /* ( ( defined( _MSVC_LANG ) && _MSVC_LANG >= 202002L ) || __cplusplus >= 202002L ) */ + +#if SG_CPP17 || SG_CPP20 +#define SG_NOEXCEPT noexcept +#else /* SG_CPP17 || SG_CPP20 */ +#define SG_NOEXCEPT +#endif /* SG_CPP17 || SG_CPP20 */ + +#if SG_CPP20 +#define SG_CAPTURE_THIS , this +#else /* SG_CPP17 || SG_CPP20 */ +#define SG_CAPTURE_THIS +#endif /* SG_CPP17 || SG_CPP20 */ \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_C4263.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_C4263.h new file mode 100644 index 0000000..ff6a9ef --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_C4263.h @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma warning(default: 4263) \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_C4264.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_C4264.h new file mode 100644 index 0000000..7d62c25 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_C4264.h @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma warning(default: 4264) \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_C4706.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_C4706.h new file mode 100644 index 0000000..691df74 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_C4706.h @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma warning(default: 4706) \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_C4800.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_C4800.h new file mode 100644 index 0000000..3636312 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_C4800.h @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma warning(default: 4800) \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_TEXT.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_TEXT.h new file mode 100644 index 0000000..bce7b28 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_TEXT.h @@ -0,0 +1,39 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#ifdef SENSEGLOVEBUILDHACKS_RESTORE_TEXT +#pragma pop_macro("TEXT") +#undef SENSEGLOVEBUILDHACKS_RESTORE_TEXT +#endif /* SENSEGLOVEBUILDHACKS_RESTORE_TEXT */ \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_Woverloaded_virtual.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_Woverloaded_virtual.h new file mode 100644 index 0000000..527b67c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_Woverloaded_virtual.h @@ -0,0 +1,42 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "HAL/Platform.h" + +#if ! PLATFORM_WINDOWS + +#pragma clang diagnostic pop + +#endif /* ! PLATFORM_WINDOWS */ \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_check.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_check.h new file mode 100644 index 0000000..3435e68 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGRestore_check.h @@ -0,0 +1,39 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#ifdef SENSEGLOVEBUILDHACKS_RESTORE_check +#pragma pop_macro("check") +#undef SENSEGLOVEBUILDHACKS_RESTORE_check +#endif /* SENSEGLOVEBUILDHACKS_RESTORE_check */ \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGUndef_TEXT.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGUndef_TEXT.h new file mode 100644 index 0000000..5ea77a4 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGUndef_TEXT.h @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#ifdef TEXT +#pragma push_macro("TEXT") +#undef TEXT +#define SENSEGLOVEBUILDHACKS_RESTORE_TEXT +#endif /* TEXT */ \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGUndef_check.h b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGUndef_check.h new file mode 100644 index 0000000..9b4d014 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/Public/SGBuildHacks/SGUndef_check.h @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#ifdef check +#pragma push_macro("check") +#undef check +#define SENSEGLOVEBUILDHACKS_RESTORE_check +#endif /* check */ \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveBuildHacks/SenseGloveBuildHacks.Build.cs b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/SenseGloveBuildHacks.Build.cs new file mode 100644 index 0000000..2239cab --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveBuildHacks/SenseGloveBuildHacks.Build.cs @@ -0,0 +1,77 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using System.IO; +using UnrealBuildTool; + +public class SenseGloveBuildHacks : ModuleRules +{ + public SenseGloveBuildHacks(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + bEnableExceptions = true; + bUseRTTI = true; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveLog", + } + ); + + AddConnectHeaders(); + } + + private void AddConnectHeaders() + { + string PluginRootDirectory = Path.GetFullPath(Path.Combine(ModuleDirectory, "..", "..")); + string SourceDirectory = Path.GetFullPath(Path.Combine(PluginRootDirectory, "Source")); + string ThirdPartyDirectory = Path.GetFullPath(Path.Combine(SourceDirectory, "ThirdParty")); + string IncludePath = Path.GetFullPath(Path.Combine(ThirdPartyDirectory, "include")); + + PrivateIncludePaths.Add(IncludePath); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveConnect/Private/SGConnect/SGConnect.cpp b/Plugins/SenseGlove/Source/SenseGloveConnect/Private/SGConnect/SGConnect.cpp new file mode 100644 index 0000000..b6fd6ec --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnect/Private/SGConnect/SGConnect.cpp @@ -0,0 +1,56 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGConnect/SGConnect.h" + +#include "SGConnectImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_FString.h" + +int32 FSGConnect::Init() +{ + return SGConnect_Init(); +} + +int32 FSGConnect::Dispose() +{ + return SGConnect_Dispose(); +} + +FString FSGConnect::GetLibraryVersion() +{ + FSGIC_FString Container; + SGConnect_GetLibraryVersion(&Container); + return Container.String; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveConnect/Private/SenseGloveConnect.cpp b/Plugins/SenseGlove/Source/SenseGloveConnect/Private/SenseGloveConnect.cpp new file mode 100644 index 0000000..c82e6b1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnect/Private/SenseGloveConnect.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveConnect.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveConnectModule.h" + +IMPLEMENT_MODULE(FSenseGloveConnectModule, SenseGloveConnect) \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveConnect/Private/SenseGloveConnect.h b/Plugins/SenseGlove/Source/SenseGloveConnect/Private/SenseGloveConnect.h new file mode 100644 index 0000000..a30ce66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnect/Private/SenseGloveConnect.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveConnect/Private/SenseGloveConnectModule.cpp b/Plugins/SenseGlove/Source/SenseGloveConnect/Private/SenseGloveConnectModule.cpp new file mode 100644 index 0000000..639a017 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnect/Private/SenseGloveConnectModule.cpp @@ -0,0 +1,65 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveConnectModule.h" +#include "Containers/UnrealString.h" +#include "SGConnect/SGConnect.h" +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveConnectModule" + +void FSenseGloveConnectModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveConnect module..."); + SGLOG(FString::Printf(TEXT("The Unreal Engine implementation of '%s' has been loaded successfully!"), + *FSGConnect::GetLibraryVersion())); +} + +void FSenseGloveConnectModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveConnect module..."); +} + +void FSenseGloveConnectModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveConnect module has succeeded!"); +} + +void FSenseGloveConnectModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveConnect module..."); +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveConnect/Private/SenseGloveConnectModule.h b/Plugins/SenseGlove/Source/SenseGloveConnect/Private/SenseGloveConnectModule.h new file mode 100644 index 0000000..9e60c00 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnect/Private/SenseGloveConnectModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveConnect" + +class FSenseGloveConnectModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveConnect/Public/SGConnect/SGConnect.h b/Plugins/SenseGlove/Source/SenseGloveConnect/Public/SGConnect/SGConnect.h new file mode 100644 index 0000000..f8c7ebb --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnect/Public/SGConnect/SGConnect.h @@ -0,0 +1,77 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "UObject/ObjectMacros.h" + +#include "SGConnect.generated.h" + +USTRUCT() +struct SENSEGLOVECONNECT_API FSGConnect +{ + GENERATED_BODY() + +public: + /** + * Begin Scanning for Sense Glove Devices and set up communications with them. + * + * @return + * -3 : An Unexpected error occured. Please try again. + * -2 : Device Scanning is already running within a different program. + * -1 : Device Scanning already being initialized (function called twice in short succession). + * 0 : Device Scanning is already running within this program. + * 1 : Successfully started up DeviceScanning from the current program. + */ + static int32 Init(); + + /** + * Dispose of unmanaged resources and finalize Sense Glove devices. + * + * @return + * -3 : An Unexpected error occured. Please try again. + * -2 : Not allowed to dispose of Device Scanning because this is not the program which started it. + * -1 : Device Scanning is currently being disposed off. This takes a second or two. (function called twice in short succession). + * 0 : There is no deviceScanner running from any program, so disposing is skipped. + * 1 : Successfully disposed of DeviceScanner resources. + * @remark If the Dispose function returns 1, the resources were neatly disposed of. Only a value of -3 is cause for concern. + */ + static int32 Dispose(); + + /** + * Check which version of SGConnect you are using. + */ + static FString GetLibraryVersion(); +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveConnect/SenseGloveConnect.Build.cs b/Plugins/SenseGlove/Source/SenseGloveConnect/SenseGloveConnect.Build.cs new file mode 100644 index 0000000..ea17dd2 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnect/SenseGloveConnect.Build.cs @@ -0,0 +1,80 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGloveConnect : ModuleRules +{ + public SenseGloveConnect(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveConnectImpl", + "SenseGloveLog", + "SenseGloveTypes", + } + ); + + if (Target.Platform == UnrealTargetPlatform.Android) + { + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveAndroid", + } + ); + } + + PrivateIncludePathModuleNames.AddRange( + new string[] + { + "SenseGloveInterop", + } + ); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SGConnectImpl/SGConnectImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SGConnectImpl/SGConnectImpl.cpp new file mode 100644 index 0000000..91b9a1a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SGConnectImpl/SGConnectImpl.cpp @@ -0,0 +1,59 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGConnectImpl/SGConnectImpl.h" + +#include + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Connect_SGConnect.h" + +int32 FSGConnectImpl::Init() +{ + return SGConnect::Init(); +} + +int32 FSGConnectImpl::Dispose() +{ + return SGConnect::Dispose(); +} + +FString FSGConnectImpl::GetLibraryVersion() +{ + std::string Version; + SGConnect::GetLibraryVersion(&Version); + return UTF8_TO_TCHAR(Version.c_str()); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SGConnectImpl/SGExportedFunctions.cpp b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SGConnectImpl/SGExportedFunctions.cpp new file mode 100644 index 0000000..43f3f3f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SGConnectImpl/SGExportedFunctions.cpp @@ -0,0 +1,94 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGConnectImpl/SGExportedFunctions.h" + +#include "Containers/StringConv.h" +#include "Templates/UnrealTemplate.h" + +#if PLATFORM_ANDROID +#include "SGBuildHacks/SGInclude_Connect_Android.h" +#endif /* PLATFORM_ANDROID */ + +#include "SGConnectImpl/SGConnectImpl.h" +#include "SGInterop/SGIC_FString.h" + +#if PLATFORM_ANDROID +#include "SGInterop/SGIC_jclass.h" +#include "SGInterop/SGIC_jmethodID.h" +#include "SGInterop/SGIC_JNIEnv_Ptr.h" +#endif /* PLATFORM_ANDROID */ + +/******************************************************************************* + * Exceptional function calls + ******************************************************************************/ + +#if PLATFORM_ANDROID +int32 SGConnectImpl_Android_Initialize( + void* InEnv, + void* InClass, + void* InInitMethodID, + void* InDisposeMethodID, + void* InGetLibraryVersionMethodID, + void* StoragePath) +{ + return SGConnect::Android::Initialize( + StaticCast(InEnv)->Ptr, + StaticCast(InClass)->Class, + StaticCast(InInitMethodID)->MethodID, + StaticCast(InDisposeMethodID)->MethodID, + StaticCast(InGetLibraryVersionMethodID)->MethodID, + std::string{TCHAR_TO_UTF8(*StaticCast(StoragePath)->String)}); +} +#endif /* PLATFORM_ANDROID */ + +/******************************************************************************* + * SGConnectImpl.h + ******************************************************************************/ + +int32 SGConnect_Init() +{ + return FSGConnectImpl::Init(); +} + +int32 SGConnect_Dispose() +{ + return FSGConnectImpl::Dispose(); +} + +void SGConnect_GetLibraryVersion(void* OutVersion) +{ + StaticCast(OutVersion)->String = FSGConnectImpl::GetLibraryVersion(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SenseGloveConnectImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SenseGloveConnectImpl.cpp new file mode 100644 index 0000000..4fa7a72 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SenseGloveConnectImpl.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveConnectImpl.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveConnectImplModule.h" + +IMPLEMENT_MODULE(FSenseGloveConnectImplModule, SenseGloveConnectImpl) diff --git a/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SenseGloveConnectImpl.h b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SenseGloveConnectImpl.h new file mode 100644 index 0000000..ab121d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SenseGloveConnectImpl.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SenseGloveConnectImplModule.cpp b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SenseGloveConnectImplModule.cpp new file mode 100644 index 0000000..a655c9a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SenseGloveConnectImplModule.cpp @@ -0,0 +1,65 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveConnectImplModule.h" +#include "Containers/UnrealString.h" +#include "SGConnectImpl/SGConnectImpl.h" +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveConnectImplModule" + +void FSenseGloveConnectImplModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveConnectImpl module..."); + SGLOG(FString::Printf(TEXT("The low-level implementation of '%s' has been loaded successfully!"), *FSGConnectImpl:: + GetLibraryVersion())); +} + +void FSenseGloveConnectImplModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveConnectImpl module..."); +} + +void FSenseGloveConnectImplModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveConnectImpl module has succeeded!"); +} + +void FSenseGloveConnectImplModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveConnectImpl module..."); +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SenseGloveConnectImplModule.h b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SenseGloveConnectImplModule.h new file mode 100644 index 0000000..cb0d0d9 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Private/SenseGloveConnectImplModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveConnectImpl" + +class FSenseGloveConnectImplModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Public/SGConnectImpl/SGConnectImpl.h b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Public/SGConnectImpl/SGConnectImpl.h new file mode 100644 index 0000000..c1fdc89 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Public/SGConnectImpl/SGConnectImpl.h @@ -0,0 +1,72 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" + +class SENSEGLOVECONNECTIMPL_API FSGConnectImpl +{ +public: + /** + * Begin Scanning for Sense Glove Devices and set up communications with them. + * + * @return + * -3 : An Unexpected error occured. Please try again. + * -2 : Device Scanning is already running within a different program. + * -1 : Device Scanning already being initialized (function called twice in short succession). + * 0 : Device Scanning is already running within this program. + * 1 : Successfully started up DeviceScanning from the current program. + */ + static int32 Init(); + + /** + * Dispose of unmanaged resources and finalize Sense Glove devices. + * + * @return + * -3 : An Unexpected error occured. Please try again. + * -2 : Not allowed to dispose of Device Scanning because this is not the program which started it. + * -1 : Device Scanning is currently being disposed off. This takes a second or two. (function called twice in short succession). + * 0 : There is no deviceScanner running from any program, so disposing is skipped. + * 1 : Successfully disposed of DeviceScanner resources. + * @remark If the Dispose function returns 1, the resources were neatly disposed of. Only a value of -3 is cause for concern. + */ + static int32 Dispose(); + + /** + * Check which version of SGConnect you are using. + */ + static FString GetLibraryVersion(); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Public/SGConnectImpl/SGExportedFunctions.h b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Public/SGConnectImpl/SGExportedFunctions.h new file mode 100644 index 0000000..0355d5b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/Public/SGConnectImpl/SGExportedFunctions.h @@ -0,0 +1,92 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +/* Defines a C++ like static_assert. */ +#if ! __cplusplus +#include +#endif /* ! __cplusplus */ + +/* Contains __bool_true_false_are_defined macro that can be used in order to + check whether boolean type is supported by the compiler or not. */ +#include + +#include "CoreTypes.h" + +/* Check at compile time whether the C compiler has support for bool, true, + and false macros. */ +static_assert(__bool_true_false_are_defined, "Error: bool, true, and false are not defined!"); + +#if defined ( SENSEGLOVE_BUILDING_CONNECT_IMPL_MODULE ) +#define SENSEGLOVECONNECTIMPL_PUBLIC_API DLLEXPORT +#else +#define SENSEGLOVECONNECTIMPL_PUBLIC_API DLLIMPORT +#endif /* defined ( SENSEGLOVE_BUILDING_CONNECT_IMPL_MODULE ) */ + +/* If C++ is used, switch to C mode in order to prevent the C++ name mangling of + method names. */ +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************* + * Exceptional function calls + ******************************************************************************/ + +#if PLATFORM_ANDROID +SENSEGLOVECONNECTIMPL_PUBLIC_API int32 SGConnectImpl_Android_Initialize( + void* InEnv, + void* InClass, + void* InInitMethodID, + void* InDisposeMethodID, + void* InGetLibraryVersionMethodID, + void* StoragePath); +#endif /* PLATFORM_ANDROID */ + +/******************************************************************************* + * SGConnectImpl.h + ******************************************************************************/ + +SENSEGLOVECONNECTIMPL_PUBLIC_API int32 SGConnect_Init(); +SENSEGLOVECONNECTIMPL_PUBLIC_API int32 SGConnect_Dispose(); +SENSEGLOVECONNECTIMPL_PUBLIC_API void SGConnect_GetLibraryVersion(void* OutVersion); + +/******************************************************************************* + ******************************************************************************/ + +#if __cplusplus +} +#endif /* __cplusplus */ \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveConnectImpl/SenseGloveConnectImpl.Build.cs b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/SenseGloveConnectImpl.Build.cs new file mode 100644 index 0000000..e944504 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnectImpl/SenseGloveConnectImpl.Build.cs @@ -0,0 +1,331 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using UnrealBuildTool; + +public class SenseGloveConnectImpl : ModuleRules +{ + public SenseGloveConnectImpl(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + bEnableExceptions = true; + bUseRTTI = true; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveLog", + "SenseGloveUtils", + "SenseGloveTypes", + } + ); + + PrivateIncludePathModuleNames.AddRange( + new string[] + { + "SenseGloveBuildHacks", + "SenseGloveInterop", + } + ); + + AddConnectLibrary(Target); + AddSerialLibrary(Target); + + PublicDefinitions.Add("SENSEGLOVE_BUILDING_CONNECT_IMPL_MODULE"); + PublicDefinitions.Add("SENSEGLOVE_UNREAL_ENGINE_PLUGIN"); + } + + private void AddConnectLibrary(ReadOnlyTargetRules Target) + { + string PluginRootDirectory = Path.GetFullPath(Path.Combine(ModuleDirectory, "..", "..")); + string SourceDirectory = Path.GetFullPath(Path.Combine(PluginRootDirectory, "Source")); + string ThirdPartyDirectory = Path.GetFullPath(Path.Combine(SourceDirectory, "ThirdParty")); + string LibraryPath = Path.GetFullPath(Path.Combine(ThirdPartyDirectory, "lib")); + string LibraryPathAnroidArm64 = ""; + string LibraryPathAnroidx64 = ""; + string LibraryName = "sgconnect"; + + bool bIsAndroid = Target.IsInPlatformGroup(UnrealPlatformGroup.Android); + bool bIsLinux = Target.Platform == UnrealTargetPlatform.Linux; + bool bIsLinuxArm64 = Target.Platform == UnrealTargetPlatform.LinuxArm64; + bool bIsWin64 = Target.IsInPlatformGroup(UnrealPlatformGroup.Windows) && + Target.WindowsPlatform.Architecture == UnrealArch.X64; + bool bIsDebugBuild = (Target.Configuration == UnrealTargetConfiguration.Debug); + + if (bIsAndroid) + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "android")); + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "r25b")); + + LibraryPathAnroidArm64 = Path.GetFullPath(Path.Combine(LibraryPath, "arm64")); + LibraryPathAnroidx64 = Path.GetFullPath(Path.Combine(LibraryPath, "x64")); + + LibraryName = string.Format("lib{0}.a", LibraryName); + } + else if (bIsLinux) + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "linux")); + LibraryName = string.Format("lib{0}.a", LibraryName); + +#if UE_5_5_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v23")); +#elif UE_5_3_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v22")); +#elif UE_5_2_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v21")); +#else + Debug.Assert(false, "Unsupported engine version or compiler!"); +#endif + + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "x86-64")); + } + else if (bIsLinuxArm64) + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "linux")); + LibraryName = string.Format("lib{0}.a", LibraryName); + +#if UE_5_5_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v23")); +#elif UE_5_3_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v22")); +#elif UE_5_2_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v21")); +#else + Debug.Assert(false, "Unsupported engine version or compiler!"); +#endif + + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "aarch64")); + } + else if (bIsWin64) + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "win64")); + switch (Target.WindowsPlatform.Compiler) + { + case WindowsCompiler.VisualStudio2022: + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "msvc143")); + break; +#if ! UE_5_4_OR_LATER + case WindowsCompiler.VisualStudio2019: + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "msvc142")); + break; +#endif + default: + Debug.Assert(false, "Unsupported engine version or compiler!"); + break; + } + + LibraryName = string.Format("{0}.lib", LibraryName); + } + else + { + Debug.Assert(false, "Unsupported platform!"); + } + + string IncludePath = Path.GetFullPath(Path.Combine(ThirdPartyDirectory, "include")); + PrivateIncludePaths.Add(IncludePath); + + if (bIsAndroid) + { + if (bIsDebugBuild) + { + LibraryPathAnroidArm64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidArm64, "debug")); + LibraryPathAnroidx64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidx64, "debug")); + } + else + { + LibraryPathAnroidArm64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidArm64, "release")); + LibraryPathAnroidx64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidx64, "release")); + } + + LibraryPathAnroidArm64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidArm64, LibraryName)); + LibraryPathAnroidx64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidx64, LibraryName)); + + PublicAdditionalLibraries.Add(LibraryPathAnroidArm64); + PublicAdditionalLibraries.Add(LibraryPathAnroidx64); + } + else + { + if (bIsDebugBuild) + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "debug")); + } + else + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "release")); + } + + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, LibraryName)); + PublicAdditionalLibraries.Add(LibraryPath); + } + } + + private void AddSerialLibrary(ReadOnlyTargetRules Target) + { + string PluginRootDirectory = Path.GetFullPath(Path.Combine(ModuleDirectory, "..", "..")); + string SourceDirectory = Path.GetFullPath(Path.Combine(PluginRootDirectory, "Source")); + string ThirdPartyDirectory = Path.GetFullPath(Path.Combine(SourceDirectory, "ThirdParty")); + string LibraryPath = Path.GetFullPath(Path.Combine(ThirdPartyDirectory, "lib")); + string LibraryPathAnroidArm64 = ""; + string LibraryPathAnroidx64 = ""; + string LibraryName = "serial"; + + bool bIsAndroid = Target.IsInPlatformGroup(UnrealPlatformGroup.Android); + bool bIsLinux = Target.Platform == UnrealTargetPlatform.Linux; + bool bIsLinuxArm64 = Target.Platform == UnrealTargetPlatform.LinuxArm64; + bool bIsWin64 = Target.IsInPlatformGroup(UnrealPlatformGroup.Windows) && + Target.WindowsPlatform.Architecture == UnrealArch.X64; + bool bIsDebugBuild = (Target.Configuration == UnrealTargetConfiguration.Debug); + + if (bIsAndroid) + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "android")); + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "r25b")); + + LibraryPathAnroidArm64 = Path.GetFullPath(Path.Combine(LibraryPath, "arm64")); + LibraryPathAnroidx64 = Path.GetFullPath(Path.Combine(LibraryPath, "x64")); + + LibraryName = string.Format("lib{0}.a", LibraryName); + } + else if (bIsLinux) + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "linux")); + LibraryName = string.Format("lib{0}.a", LibraryName); + +#if UE_5_5_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v23")); +#elif UE_5_3_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v22")); +#elif UE_5_2_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v21")); +#else + Debug.Assert(false, "Unsupported engine version or compiler!"); +#endif + + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "x86-64")); + } + else if (bIsLinuxArm64) + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "linux")); + LibraryName = string.Format("lib{0}.a", LibraryName); + +#if UE_5_5_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v23")); +#elif UE_5_3_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v22")); +#elif UE_5_2_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v21")); +#else + Debug.Assert(false, "Unsupported engine version or compiler!"); +#endif + + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "aarch64")); + } + else if (bIsWin64) + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "win64")); + switch (Target.WindowsPlatform.Compiler) + { + case WindowsCompiler.VisualStudio2022: + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "msvc143")); + break; +#if ! UE_5_4_OR_LATER + case WindowsCompiler.VisualStudio2019: + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "msvc142")); + break; +#endif + default: + Debug.Assert(false, "Unsupported engine version or compiler!"); + break; + } + + LibraryName = string.Format("{0}.lib", LibraryName); + } + else + { + Debug.Assert(false, "Unsupported platform!"); + } + + string IncludePath = Path.GetFullPath(Path.Combine(ThirdPartyDirectory, "include")); + PrivateIncludePaths.Add(IncludePath); + + if (bIsAndroid) + { + if (bIsDebugBuild) + { + LibraryPathAnroidArm64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidArm64, "debug")); + LibraryPathAnroidx64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidx64, "debug")); + } + else + { + LibraryPathAnroidArm64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidArm64, "release")); + LibraryPathAnroidx64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidx64, "release")); + } + + LibraryPathAnroidArm64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidArm64, LibraryName)); + LibraryPathAnroidx64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidx64, LibraryName)); + + PublicAdditionalLibraries.Add(LibraryPathAnroidArm64); + PublicAdditionalLibraries.Add(LibraryPathAnroidx64); + } + else + { + if (bIsDebugBuild) + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "debug")); + } + else + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "release")); + } + + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, LibraryName)); + PublicAdditionalLibraries.Add(LibraryPath); + } + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Private/SGConnectKismet/SGConnectKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Private/SGConnectKismet/SGConnectKismetLibrary.cpp new file mode 100644 index 0000000..188d34c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Private/SGConnectKismet/SGConnectKismetLibrary.cpp @@ -0,0 +1,53 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGConnectKismet/SGConnectKismetLibrary.h" + +#include "SGConnect/SGConnect.h" + +int32 USGConnectKismetLibrary::Init() +{ + return FSGConnect::Init(); +} + +int32 USGConnectKismetLibrary::Dispose() +{ + return FSGConnect::Dispose(); +} + +FString USGConnectKismetLibrary::GetLibraryVersion() +{ + return FSGConnect::GetLibraryVersion(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Private/SenseGloveConnectKismet.cpp b/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Private/SenseGloveConnectKismet.cpp new file mode 100644 index 0000000..0447835 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Private/SenseGloveConnectKismet.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveConnectKismet.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveConnectKismetModule.h" + +IMPLEMENT_MODULE(FSenseGloveConnectKismetModule, SenseGloveConnectKismet) diff --git a/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Private/SenseGloveConnectKismet.h b/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Private/SenseGloveConnectKismet.h new file mode 100644 index 0000000..ab121d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Private/SenseGloveConnectKismet.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Private/SenseGloveConnectKismetModule.cpp b/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Private/SenseGloveConnectKismetModule.cpp new file mode 100644 index 0000000..9b2ceda --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Private/SenseGloveConnectKismetModule.cpp @@ -0,0 +1,61 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveConnectKismetModule.h" +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveConnectKismetModule" + +void FSenseGloveConnectKismetModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveConnectKismet module..."); +} + +void FSenseGloveConnectKismetModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveConnectKismet module..."); +} + +void FSenseGloveConnectKismetModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveConnectKismet module has succeeded!"); +} + +void FSenseGloveConnectKismetModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveConnectKismet module..."); +} + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Private/SenseGloveConnectKismetModule.h b/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Private/SenseGloveConnectKismetModule.h new file mode 100644 index 0000000..7119d32 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Private/SenseGloveConnectKismetModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveConnectKismet" + +class FSenseGloveConnectKismetModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Public/SGConnectKismet/SGConnectKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Public/SGConnectKismet/SGConnectKismetLibrary.h new file mode 100644 index 0000000..f0a65bd --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnectKismet/Public/SGConnectKismet/SGConnectKismetLibrary.h @@ -0,0 +1,84 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "HAL/Platform.h" + +#include "SGKismet/SGBlueprintFunctionLibrary.h" + +#include "SGConnectKismetLibrary.generated.h" + +UCLASS(meta=(ScriptName = "SenseGloveConnectKismetLibrary")) +class SENSEGLOVECONNECTKISMET_API USGConnectKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: +public: + /** + * Begin Scanning for Sense Glove Devices and set up communications with them. + * + * @return + * -3 : An Unexpected error occured. Please try again. + * -2 : Device Scanning is already running within a different program. + * -1 : Device Scanning already being initialized (function called twice in short succession). + * 0 : Device Scanning is already running in within this program. + * 1 : Successfully started up DeviceScanning from the current program. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Connect") + static int32 Init(); + + /** + * Dispose of unmanaged resources and finalize Sense Glove devices. + * + * @return + * -3 : An Unexpected error occured. Please try again. + * -2 : Not allowed to dispose of Device Scanning because this is not the program which started it. + * -1 : Device Scanning is currently being disposed off. This takes a second or two. (function called twice in short succession). + * 0 : There is no deviceScanner running from any program, so disposing is skipped. + * 1 : Successfully disposed of DeviceScanner resources. + * @remark If the Dispose function returns 1, the resources were neatly disposed of. Only a value of -3 is cause for concern. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Connect") + static int32 Dispose(); + + /** + * Check which version of SGConnect you are using. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Connect") + static FString GetLibraryVersion(); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveConnectKismet/SenseGloveConnectKismet.Build.cs b/Plugins/SenseGlove/Source/SenseGloveConnectKismet/SenseGloveConnectKismet.Build.cs new file mode 100644 index 0000000..64311e3 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveConnectKismet/SenseGloveConnectKismet.Build.cs @@ -0,0 +1,64 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGloveConnectKismet : ModuleRules +{ + public SenseGloveConnectKismet(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveConnect", + "SenseGloveKismet", + "SenseGloveLog", + "SenseGloveTypes", + } + ); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGAnatomy.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGAnatomy.cpp new file mode 100644 index 0000000..36c41dd --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGAnatomy.cpp @@ -0,0 +1,113 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGAnatomy.h" + +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_TArray_TArray_FVector.h" + +float FSGAnatomy::GetTotalFingerFlexion() +{ + return SGCoreImpl_FSGAnatomyImpl_GetTotalFingerFlexion(); +} + +float FSGAnatomy::GetTotalFingerExtension() +{ + return SGCoreImpl_FSGAnatomyImpl_GetTotalFingerExtension(); +} + +float FSGAnatomy::GetTotalThumbFlexion() +{ + return SGCoreImpl_FSGAnatomyImpl_GetTotalThumbFlexion(); +} + +float FSGAnatomy::GetTotalThumbExtension() +{ + return SGCoreImpl_FSGAnatomyImpl_GetTotalThumbExtension(); +} + +float FSGAnatomy::GetFingerJointLimit(const bool bRightHanded, const int32 Joint, const int32 Movement, const bool bMax) +{ + return SGCoreImpl_FSGAnatomyImpl_GetFingerJointLimit(bRightHanded, Joint, Movement, bMax); +} + +float FSGAnatomy::GetThumbJointLimit(const bool bRightHanded, const int32 Joint, const int32 Movement, const bool bMax) +{ + return SGCoreImpl_FSGAnatomyImpl_GetThumbJointLimit(bRightHanded, Joint, Movement, bMax); +} + +float FSGAnatomy::ClampJointAngle( + const float Value, const int32 Finger, const bool bRightHand, const int32 Joint, const int32 Movement) +{ + return SGCoreImpl_FSGAnatomyImpl_ClampJointAngle(Value, Finger, bRightHand, Joint, Movement); +} + +float FSGAnatomy::NormalizeFingerFlexion(const float FlexionInDegrees) +{ + return SGCoreImpl_FSGAnatomyImpl_NormalizeFingerFlexion(FlexionInDegrees); +} + +float FSGAnatomy::NormalizeThumbFlexion(const float FlexionInDegrees) +{ + return SGCoreImpl_FSGAnatomyImpl_NormalizeThumbFlexion(FlexionInDegrees); +} + +TArray> FSGAnatomy::GetDefaultHandAngles(const bool bRightHanded) +{ + FSGIC_TArray_TArray_FVector OutAnglesContainer; + SGCoreImpl_FSGAnatomyImpl_GetDefaultHandAngles(&OutAnglesContainer, bRightHanded); + return OutAnglesContainer.Array; +} + +TArray> FSGAnatomy::GetFlatHandAngles(const bool bRightHanded) +{ + FSGIC_TArray_TArray_FVector OutAnglesContainer; + SGCoreImpl_FSGAnatomyImpl_GetFlatHandAngles(&OutAnglesContainer, bRightHanded); + return OutAnglesContainer.Array; +} + +TArray> FSGAnatomy::GetThumbsUpHandAngles(const bool bRightHanded) +{ + FSGIC_TArray_TArray_FVector OutAnglesContainer; + SGCoreImpl_FSGAnatomyImpl_GetThumbsUpHandAngles(&OutAnglesContainer, bRightHanded); + return OutAnglesContainer.Array; +} + +TArray> FSGAnatomy::GetFistHandAngles(const bool bRightHanded) +{ + FSGIC_TArray_TArray_FVector OutAnglesContainer; + SGCoreImpl_FSGAnatomyImpl_GetFistHandAngles(&OutAnglesContainer, bRightHanded); + return OutAnglesContainer.Array; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGBasicHandModel.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGBasicHandModel.cpp new file mode 100644 index 0000000..cc213ab --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGBasicHandModel.cpp @@ -0,0 +1,568 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGBasicHandModel.h" + +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_ESGFinger.h" +#include "SGInterop/SGIC_FQuat.h" +#include "SGInterop/SGIC_FSGBasicHandModelImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_FVector.h" +#include "SGInterop/SGIC_TArray_float.h" +#include "SGInterop/SGIC_TArray_FQuat.h" +#include "SGInterop/SGIC_TArray_FVector.h" +#include "SGInterop/SGIC_TArray_TArray_float.h" +#include "SGUtils/SGArrayUtils.h" + +struct USGBasicHandModel::FImpl +{ + /************************ + * Member variables + ************************/ + + FSGBasicHandModelImpl BasicHandModelImpl; + + /************************ + * Owner object + ************************/ + + USGBasicHandModel* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGBasicHandModel* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGBasicHandModel* USGBasicHandModel::NewBasicHandModel(UObject* Outer, const FSGBasicHandModelImpl& BasicHandModelImpl) +{ + USGBasicHandModel* Instance = NewObject(Outer); + Instance->SetBasicHandModelImpl(BasicHandModelImpl); + return Instance; +} + +USGBasicHandModel* USGBasicHandModel::NewBasicHandModel(UObject* Outer) +{ + FSGIC_FSGBasicHandModelImpl OutBasicHandModelImplContainer; + SGCoreImpl_FSGBasicHandModelImpl_ctor(&OutBasicHandModelImplContainer); + + return NewBasicHandModel(Outer, MoveTemp(OutBasicHandModelImplContainer.BasicHandModelImpl)); +} + +USGBasicHandModel* USGBasicHandModel::NewBasicHandModel(UObject* Outer, const bool bRightHanded, + const TArray>& Lengths, + const TArray& StartPositions) +{ + FSGIC_FSGBasicHandModelImpl OutBasicHandModelImplContainer; + FSGIC_TArray_TArray_float LengthsContainer{Lengths}; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + SGCoreImpl_FSGBasicHandModelImpl_ctor_bRightHanded_Lengths_StartPosition( + &OutBasicHandModelImplContainer, bRightHanded, &LengthsContainer, &StartPositionsContainer); + + return NewBasicHandModel(Outer, MoveTemp(OutBasicHandModelImplContainer.BasicHandModelImpl)); +} + +USGBasicHandModel* USGBasicHandModel::NewBasicHandModel(UObject* Outer, const bool bRightHanded, + const TArray& Lengths, + const TArray& StartPositions) +{ + FSGIC_FSGBasicHandModelImpl OutBasicHandModelImplContainer; + FSGIC_TArray_TArray_float LengthsContainer{ + FSGArrayUtils::FromNestedBPArray(Lengths) + }; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + SGCoreImpl_FSGBasicHandModelImpl_ctor_bRightHanded_Lengths_StartPosition( + &OutBasicHandModelImplContainer, bRightHanded, &LengthsContainer, &StartPositionsContainer); + + return NewBasicHandModel(Outer, MoveTemp(OutBasicHandModelImplContainer.BasicHandModelImpl)); +} + +USGBasicHandModel* USGBasicHandModel::NewBasicHandModel(UObject* Outer, const bool bRightHanded, + const TArray>& Lengths, + const TArray& StartPositions, + const TArray& StartRotations) +{ + FSGIC_FSGBasicHandModelImpl OutBasicHandModelImplContainer; + FSGIC_TArray_TArray_float LengthsContainer{Lengths}; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + FSGIC_TArray_FQuat StartRotationsContainer{StartRotations}; + SGCoreImpl_FSGBasicHandModelImpl_ctor_bRightHanded_Lengths_StartPositions_StartRotations( + &OutBasicHandModelImplContainer, bRightHanded, &LengthsContainer, + &StartPositionsContainer, &StartRotationsContainer); + + return NewBasicHandModel(Outer, MoveTemp(OutBasicHandModelImplContainer.BasicHandModelImpl)); +} + +USGBasicHandModel* USGBasicHandModel::NewBasicHandModel(UObject* Outer, const bool bRightHanded, + const TArray>& Lengths, + const TArray& StartPositions, + const TArray& StartRotations) +{ + FSGIC_FSGBasicHandModelImpl OutBasicHandModelImplContainer; + FSGIC_TArray_TArray_float LengthsContainer{Lengths}; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + FSGIC_TArray_FQuat StartRotationsContainer{FSGArrayUtils::RotatorsToQuats(StartRotations)}; + SGCoreImpl_FSGBasicHandModelImpl_ctor_bRightHanded_Lengths_StartPositions_StartRotations( + &OutBasicHandModelImplContainer, bRightHanded, &LengthsContainer, + &StartPositionsContainer, &StartRotationsContainer); + + return NewBasicHandModel(Outer, MoveTemp(OutBasicHandModelImplContainer.BasicHandModelImpl)); +} + +USGBasicHandModel* USGBasicHandModel::NewBasicHandModel(UObject* Outer, const bool bRightHanded, + const TArray& Lengths, + const TArray& StartPositions, + const TArray& StartRotations) +{ + FSGIC_FSGBasicHandModelImpl OutBasicHandModelImplContainer; + FSGIC_TArray_TArray_float LengthsContainer{ + FSGArrayUtils::FromNestedBPArray(Lengths) + }; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + FSGIC_TArray_FQuat StartRotationsContainer{StartRotations}; + SGCoreImpl_FSGBasicHandModelImpl_ctor_bRightHanded_Lengths_StartPositions_StartRotations( + &OutBasicHandModelImplContainer, bRightHanded, &LengthsContainer, + &StartPositionsContainer, &StartRotationsContainer); + + return NewBasicHandModel(Outer, MoveTemp(OutBasicHandModelImplContainer.BasicHandModelImpl)); +} + +USGBasicHandModel* USGBasicHandModel::NewBasicHandModel(UObject* Outer, const bool bRightHanded, + const TArray& Lengths, + const TArray& StartPositions, + const TArray& StartRotations) +{ + FSGIC_FSGBasicHandModelImpl OutBasicHandModelImplContainer; + FSGIC_TArray_TArray_float LengthsContainer{ + FSGArrayUtils::FromNestedBPArray(Lengths) + }; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + FSGIC_TArray_FQuat StartRotationsContainer{FSGArrayUtils::RotatorsToQuats(StartRotations)}; + SGCoreImpl_FSGBasicHandModelImpl_ctor_bRightHanded_Lengths_StartPositions_StartRotations( + &OutBasicHandModelImplContainer, bRightHanded, &LengthsContainer, + &StartPositionsContainer, &StartRotationsContainer); + + return NewBasicHandModel(Outer, MoveTemp(OutBasicHandModelImplContainer.BasicHandModelImpl)); +} + +USGBasicHandModel* USGBasicHandModel::Default(UObject* Outer, const bool bRightHanded) +{ + FSGIC_FSGBasicHandModelImpl OutBasicHandModelImplContainer; + SGCoreImpl_FSGBasicHandModelImpl_Default(&OutBasicHandModelImplContainer, bRightHanded); + return NewBasicHandModel(Outer, MoveTemp(OutBasicHandModelImplContainer.BasicHandModelImpl)); +} + +USGBasicHandModel* USGBasicHandModel::Deserialize(UObject* Outer, const FString& SerializedString) +{ + FSGIC_FSGBasicHandModelImpl OutBasicHandModelContainer; + FSGIC_FString SerializedStringContainer{SerializedString}; + SGCoreImpl_FSGBasicHandModelImpl_Deserialize(&OutBasicHandModelContainer, &SerializedStringContainer); + return NewBasicHandModel(Outer, MoveTemp(OutBasicHandModelContainer.BasicHandModelImpl));; +} + +TArray> USGBasicHandModel::GetBaseFingerLengths() +{ + FSGIC_TArray_TArray_float OutLengthsContainer; + SGCoreImpl_FSGBasicHandModelImpl_GetBaseFingerLengths(&OutLengthsContainer); + return OutLengthsContainer.Array; +} + +TArray USGBasicHandModel::GetBaseJointPositions() +{ + FSGIC_TArray_FVector OutPositionsContainer; + SGCoreImpl_FSGBasicHandModelImpl_GetBaseJointPositions(&OutPositionsContainer); + return OutPositionsContainer.Array; +} + +TArray USGBasicHandModel::GetBaseJointAngles() +{ + FSGIC_TArray_FVector OutRotationsContainer; + SGCoreImpl_FSGBasicHandModelImpl_GetBaseJointAngles(&OutRotationsContainer); + return OutRotationsContainer.Array; +} + +USGBasicHandModel::USGBasicHandModel() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGBasicHandModelImpl OutBasicHandModelImplContainer; + SGCoreImpl_FSGBasicHandModelImpl_ctor(&OutBasicHandModelImplContainer); + + Pimpl->BasicHandModelImpl = MoveTemp(OutBasicHandModelImplContainer.BasicHandModelImpl); +} + +USGBasicHandModel::USGBasicHandModel(const bool bRightHanded, const TArray>& Lengths, + const TArray& StartPositions) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGBasicHandModelImpl OutBasicHandModelImplContainer; + FSGIC_TArray_TArray_float LengthsContainer{Lengths}; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + SGCoreImpl_FSGBasicHandModelImpl_ctor_bRightHanded_Lengths_StartPosition( + &OutBasicHandModelImplContainer, bRightHanded, &LengthsContainer, &StartPositionsContainer); + + Pimpl->BasicHandModelImpl = MoveTemp(OutBasicHandModelImplContainer.BasicHandModelImpl); +} + +USGBasicHandModel::USGBasicHandModel(bool bRightHanded, const TArray& Lengths, + const TArray& StartPositions) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGBasicHandModelImpl OutBasicHandModelImplContainer; + FSGIC_TArray_TArray_float LengthsContainer{ + FSGArrayUtils::FromNestedBPArray(Lengths) + }; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + SGCoreImpl_FSGBasicHandModelImpl_ctor_bRightHanded_Lengths_StartPosition( + &OutBasicHandModelImplContainer, bRightHanded, &LengthsContainer, &StartPositionsContainer); + + Pimpl->BasicHandModelImpl = MoveTemp(OutBasicHandModelImplContainer.BasicHandModelImpl); +} + +USGBasicHandModel::USGBasicHandModel(const bool bRightHanded, const TArray>& Lengths, + const TArray& StartPositions, const TArray& StartRotations) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGBasicHandModelImpl OutBasicHandModelImplContainer; + FSGIC_TArray_TArray_float LengthsContainer{Lengths}; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + FSGIC_TArray_FQuat StartRotationsContainer{StartRotations}; + SGCoreImpl_FSGBasicHandModelImpl_ctor_bRightHanded_Lengths_StartPositions_StartRotations( + &OutBasicHandModelImplContainer, bRightHanded, &LengthsContainer, + &StartPositionsContainer, &StartRotationsContainer); + + Pimpl->BasicHandModelImpl = MoveTemp(OutBasicHandModelImplContainer.BasicHandModelImpl); +} + +USGBasicHandModel::USGBasicHandModel(const bool bRightHanded, const TArray>& Lengths, + const TArray& StartPositions, const TArray& StartRotations) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGBasicHandModelImpl OutBasicHandModelImplContainer; + FSGIC_TArray_TArray_float LengthsContainer{Lengths}; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + FSGIC_TArray_FQuat StartRotationsContainer{FSGArrayUtils::RotatorsToQuats(StartRotations)}; + SGCoreImpl_FSGBasicHandModelImpl_ctor_bRightHanded_Lengths_StartPositions_StartRotations( + &OutBasicHandModelImplContainer, bRightHanded, &LengthsContainer, + &StartPositionsContainer, &StartRotationsContainer); + + Pimpl->BasicHandModelImpl = MoveTemp(OutBasicHandModelImplContainer.BasicHandModelImpl); +} + +USGBasicHandModel::USGBasicHandModel(const bool bRightHanded, const TArray& Lengths, + const TArray& StartPositions, const TArray& StartRotations) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGBasicHandModelImpl OutBasicHandModelImplContainer; + FSGIC_TArray_TArray_float LengthsContainer{ + FSGArrayUtils::FromNestedBPArray(Lengths) + }; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + FSGIC_TArray_FQuat StartRotationsContainer{StartRotations}; + SGCoreImpl_FSGBasicHandModelImpl_ctor_bRightHanded_Lengths_StartPositions_StartRotations( + &OutBasicHandModelImplContainer, bRightHanded, &LengthsContainer, + &StartPositionsContainer, &StartRotationsContainer); + + Pimpl->BasicHandModelImpl = MoveTemp(OutBasicHandModelImplContainer.BasicHandModelImpl); +} + +USGBasicHandModel::USGBasicHandModel(const bool bRightHanded, const TArray& Lengths, + const TArray& StartPositions, const TArray& StartRotations) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGBasicHandModelImpl OutBasicHandModelImplContainer; + FSGIC_TArray_TArray_float LengthsContainer{ + FSGArrayUtils::FromNestedBPArray(Lengths) + }; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + FSGIC_TArray_FQuat StartRotationsContainer{FSGArrayUtils::RotatorsToQuats(StartRotations)}; + SGCoreImpl_FSGBasicHandModelImpl_ctor_bRightHanded_Lengths_StartPositions_StartRotations( + &OutBasicHandModelImplContainer, bRightHanded, &LengthsContainer, + &StartPositionsContainer, &StartRotationsContainer); + + Pimpl->BasicHandModelImpl = MoveTemp(OutBasicHandModelImplContainer.BasicHandModelImpl); +} + +USGBasicHandModel::USGBasicHandModel(const FSGBasicHandModelImpl& BasicHandModelImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + SetBasicHandModelImpl(BasicHandModelImpl); +} + +USGBasicHandModel::~USGBasicHandModel() = default; + +void USGBasicHandModel::SetBasicHandModelImpl(const FSGBasicHandModelImpl& BasicHandModelImpl) +{ + FSGIC_FSGBasicHandModelImpl OutBasicHandModelContainer; + FSGIC_FSGBasicHandModelImpl RhsContainer{BasicHandModelImpl}; + SGCoreImpl_FSGBasicHandModelImpl_ctor_copy(&OutBasicHandModelContainer, &RhsContainer); + Pimpl->BasicHandModelImpl = MoveTemp(OutBasicHandModelContainer.BasicHandModelImpl); +} + +const FSGBasicHandModelImpl& USGBasicHandModel::ToBasicHandModelImpl() const +{ + return Pimpl->BasicHandModelImpl; +} + +FSGBasicHandModelImpl& USGBasicHandModel::ToBasicHandModelImpl() +{ + return Pimpl->BasicHandModelImpl; +} + +bool USGBasicHandModel::IsRight() const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + return SGCoreImpl_FSGBasicHandModelImpl_IsRight(&InstanceContainer); +} + +TArray> USGBasicHandModel::GetFingerLengths() const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_TArray_TArray_float OutLengthsContainer; + SGCoreImpl_FSGBasicHandModelImpl_GetFingerLengths(&InstanceContainer, &OutLengthsContainer); + return OutLengthsContainer.Array; +} + +TArray USGBasicHandModel::GetFingerLengths(const ESGFinger Finger) const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_TArray_float OutLengthsContainer; + FSGIC_ESGFinger FingerContainer{Finger}; + SGCoreImpl_FSGBasicHandModelImpl_GetFingerLengths_Finger(&InstanceContainer, &OutLengthsContainer, + &FingerContainer); + return OutLengthsContainer.Array; +} + +void USGBasicHandModel::SetFingerLengths(const ESGFinger Finger, const TArray& Lengths) +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_ESGFinger FingerContainer{Finger}; + FSGIC_TArray_float LengthsContainer{Lengths}; + SGCoreImpl_FSGBasicHandModelImpl_SetFingerLengths_ESGFinger(&InstanceContainer, &FingerContainer, + &LengthsContainer); +} + +void USGBasicHandModel::SetFingerLengths(const uint8 Finger, const TArray& Lengths) +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_TArray_float LengthsContainer{Lengths}; + SGCoreImpl_FSGBasicHandModelImpl_SetFingerLengths_uint8Finger(&InstanceContainer, Finger, &LengthsContainer); +} + +TArray> USGBasicHandModel::GetFingerRatios() const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_TArray_TArray_float OutRatiosContainer; + SGCoreImpl_FSGBasicHandModelImpl_GetFingerRatios(&InstanceContainer, &OutRatiosContainer); + return OutRatiosContainer.Array; +} + +TArray USGBasicHandModel::GetFingerRatios(const ESGFinger Finger) const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_ESGFinger FingerContainer{Finger}; + FSGIC_TArray_float OutRatiosContainer; + SGCoreImpl_FSGBasicHandModelImpl_GetFingerRatios_Finger(&InstanceContainer, &OutRatiosContainer, + &FingerContainer); + return OutRatiosContainer.Array; +} + +TArray USGBasicHandModel::GetStartJointPositions() const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_TArray_FVector OutPositionsContainer; + SGCoreImpl_FSGBasicHandModelImpl_GetStartJointPositions(&InstanceContainer, &OutPositionsContainer); + return OutPositionsContainer.Array; +} + +void USGBasicHandModel::SetStartJointPosition(const ESGFinger Finger, const FVector& Position) +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_ESGFinger FingerContainer{Finger}; + FSGIC_FVector PositionContainer{Position}; + SGCoreImpl_FSGBasicHandModelImpl_SetStartJointPosition_ESGFinger(&InstanceContainer, &FingerContainer, + &PositionContainer); +} + +void USGBasicHandModel::SetStartJointPosition(const uint8 Finger, const FVector& Position) +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_FVector PositionContainer{Position}; + SGCoreImpl_FSGBasicHandModelImpl_SetStartJointPosition_uin8Finger(&InstanceContainer, Finger, &PositionContainer); +} + +TArray USGBasicHandModel::GetStartJointRotationsQ() const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_TArray_FQuat OutRotationsContainer; + SGCoreImpl_FSGBasicHandModelImpl_GetStartJointRotations(&InstanceContainer, &OutRotationsContainer); + return OutRotationsContainer.Array; +} + +TArray USGBasicHandModel::GetStartJointRotations() const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_TArray_FQuat OutRotationsContainer; + SGCoreImpl_FSGBasicHandModelImpl_GetStartJointRotations(&InstanceContainer, &OutRotationsContainer); + return FSGArrayUtils::QuatsToRotators(OutRotationsContainer.Array); +} + +FVector USGBasicHandModel::GetJointPosition(const ESGFinger Finger) const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_FVector OutPositionContainer; + FSGIC_ESGFinger FingerContainer{Finger}; + SGCoreImpl_FSGBasicHandModelImpl_GetJointPosition(&InstanceContainer, &OutPositionContainer, &FingerContainer); + return OutPositionContainer.Vector; +} + +void USGBasicHandModel::SetJointPosition(const FVector& NewPosition, const ESGFinger Finger) +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_FVector NewPositionContainer{NewPosition}; + FSGIC_ESGFinger FingerContainer{Finger}; + SGCoreImpl_FSGBasicHandModelImpl_SetJointPosition(&InstanceContainer, &NewPositionContainer, &FingerContainer); +} + +FQuat USGBasicHandModel::GetJointRotationQ(const ESGFinger Finger) const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_FQuat OutRotationContainer; + FSGIC_ESGFinger FingerContainer{Finger}; + SGCoreImpl_FSGBasicHandModelImpl_GetJointRotation(&InstanceContainer, &OutRotationContainer, &FingerContainer); + return OutRotationContainer.Quat; +} + +FRotator USGBasicHandModel::GetJointRotation(const ESGFinger Finger) const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_FQuat OutRotationContainer; + FSGIC_ESGFinger FingerContainer{Finger}; + SGCoreImpl_FSGBasicHandModelImpl_GetJointRotation(&InstanceContainer, &OutRotationContainer, &FingerContainer); + return OutRotationContainer.Quat.Rotator(); +} + +void USGBasicHandModel::SetJointRotation(const FQuat& NewRotation, const ESGFinger Finger) +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_FQuat NewRotationContainer{NewRotation}; + FSGIC_ESGFinger FingerContainer{Finger}; + SGCoreImpl_FSGBasicHandModelImpl_SetJointRotation(&InstanceContainer, &NewRotationContainer, &FingerContainer); +} + +void USGBasicHandModel::SetJointRotation(const FRotator& NewRotation, const ESGFinger Finger) +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_FQuat NewRotationContainer{NewRotation.Quaternion()}; + FSGIC_ESGFinger FingerContainer{Finger}; + SGCoreImpl_FSGBasicHandModelImpl_SetJointRotation(&InstanceContainer, &NewRotationContainer, &FingerContainer); +} + +TArray USGBasicHandModel::GetTotalLengths() const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_TArray_float OutLengthsContainer; + SGCoreImpl_FSGBasicHandModelImpl_GetTotalLengths(&InstanceContainer, &OutLengthsContainer); + return OutLengthsContainer.Array; +} + +float USGBasicHandModel::GetTotalLength(const ESGFinger Finger) const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_ESGFinger FingerContainer{Finger}; + return SGCoreImpl_FSGBasicHandModelImpl_GetTotalLength(&InstanceContainer, &FingerContainer); +} + +TArray USGBasicHandModel::Get3DLengths(const ESGFinger Finger) const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_TArray_FVector OutLengthsContainer; + FSGIC_ESGFinger FingerContainer{Finger}; + SGCoreImpl_FSGBasicHandModelImpl_Get3DLengths(&InstanceContainer, &OutLengthsContainer, + &FingerContainer); + return OutLengthsContainer.Array; +} + +bool USGBasicHandModel::Equals(const USGBasicHandModel* BasicHandModel) const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_FSGBasicHandModelImpl BasicHandModelContainer{BasicHandModel->ToBasicHandModelImpl()}; + return SGCoreImpl_FSGBasicHandModelImpl_Equals(&InstanceContainer, &BasicHandModelContainer); +} + +FString USGBasicHandModel::ToString() const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGBasicHandModelImpl_ToString(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +FString USGBasicHandModel::ToString(const bool bLengthsOnly) const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGBasicHandModelImpl_ToString_bLengthsOnly(&InstanceContainer, &OutStringContainer, bLengthsOnly); + return OutStringContainer.String; +} + +FString USGBasicHandModel::SGSerialize() const +{ + FSGIC_FSGBasicHandModelImpl InstanceContainer{ToBasicHandModelImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGBasicHandModelImpl_Serialize(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +USGBasicHandModel::FImpl::FImpl(USGBasicHandModel* InOwner) + : Owner(InOwner) +{ +} + +USGBasicHandModel::FImpl::~FImpl() = default; + +void USGBasicHandModel::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGBetaDevice.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGBetaDevice.cpp new file mode 100644 index 0000000..afe362c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGBetaDevice.cpp @@ -0,0 +1,208 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGBetaDevice.h" + +#include "Engine/World.h" + +#include "SGCore/SGDeviceImplCast.h" +#include "SGCoreImpl/SGBetaDeviceImpl.h" +#include "SGCoreImpl/SGDeviceImpl.h" +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_ESGDeviceType.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_TSharedPtr_FSGBetaDeviceImpl.h" + +USGBetaDevice* USGBetaDevice::NewBetaDevice(UObject* Outer, const FSGBetaDeviceImpl& BetaDeviceImpl) +{ + USGBetaDevice* Instance = NewObject(Outer); + Instance->SetSGDeviceImpl(BetaDeviceImpl); + return Instance; +} + +USGBetaDevice* USGBetaDevice::NewBetaDevice(UObject* Outer, TSharedRef BetaDeviceImpl) +{ + USGBetaDevice* Instance = NewObject(Outer); + Instance->SetSGDeviceImpl(MoveTemp(BetaDeviceImpl)); + return Instance; +} + +USGBetaDevice* USGBetaDevice::NewBetaDevice(UObject* Outer) +{ + FSGIC_TSharedPtr_FSGBetaDeviceImpl OutSharedPtrContainer; + SGCoreImpl_FSGBetaDeviceImpl_ctor_MakeShared(&OutSharedPtrContainer); + + return NewBetaDevice(Outer, OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +USGBetaDevice* USGBetaDevice::NewBetaDevice(UObject* Outer, const FString& ConstantsString, const FString& DeviceId, + const FString& HardwareVersion, const int32 FirmwareVersion, const int32 SubFirmwareVersion) +{ + FSGIC_TSharedPtr_FSGBetaDeviceImpl OutSharedPtrContainer; + FSGIC_FString ConstantsStringContainer{ConstantsString}; + FSGIC_FString DeviceIdContainer{DeviceId}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + SGCoreImpl_FSGBetaDeviceImpl_ctor_ConstantsString_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_MakeShared( + &OutSharedPtrContainer, &ConstantsStringContainer, &DeviceIdContainer, + &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion); + + return NewBetaDevice(Outer, OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +USGBetaDevice* USGBetaDevice::Parse(UObject* Outer, const FString& String) +{ + FSGIC_FString StringContainer{String}; + FSGIC_TSharedPtr_FSGBetaDeviceImpl OutSharedPtrContainer; + SGCoreImpl_FSGBetaDeviceImpl_Parse(&OutSharedPtrContainer, &StringContainer); + + return NewBetaDevice(Outer, OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +USGBetaDevice::USGBetaDevice() + : USGDevice() +{ + FSGIC_TSharedPtr_FSGBetaDeviceImpl OutSharedPtrContainer; + SGCoreImpl_FSGBetaDeviceImpl_ctor_MakeShared(&OutSharedPtrContainer); + + SetSGDeviceImpl(OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +USGBetaDevice::USGBetaDevice(const FString& ConstantsString, const FString& DeviceId, + const FString& HardwareVersion, + const int32 FirmwareVersion, const int32 SubFirmwareVersion) + : USGDevice() +{ + FSGIC_TSharedPtr_FSGBetaDeviceImpl OutSharedPtrContainer; + FSGIC_FString ConstantsStringContainer{ConstantsString}; + FSGIC_FString DeviceIdContainer{DeviceId}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + SGCoreImpl_FSGBetaDeviceImpl_ctor_ConstantsString_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_MakeShared( + &OutSharedPtrContainer, &ConstantsStringContainer, &DeviceIdContainer, + &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion); + + SetSGDeviceImpl(OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +USGBetaDevice::USGBetaDevice(const FSGBetaDeviceImpl& BetaDeviceImpl) + : USGDevice(BetaDeviceImpl) +{ +} + +USGBetaDevice::USGBetaDevice(TSharedRef BetaDeviceImpl) + : USGDevice(MoveTemp(BetaDeviceImpl)) +{ +} + +USGBetaDevice::~USGBetaDevice() = default; + +TSharedRef USGBetaDevice::ToBetaDeviceImpl() const +{ + return FSGDeviceImplCast::ToBetaDeviceImpl(ToSGDeviceImpl()); +} + +ESGDeviceType USGBetaDevice::GetDeviceType() const +{ + FSGIC_TSharedPtr_FSGBetaDeviceImpl InstanceContainer{ToBetaDeviceImpl()}; + FSGIC_ESGDeviceType OutTypeContainer; + SGCoreImpl_FSGBetaDeviceImpl_GetDeviceType(&InstanceContainer, &OutTypeContainer); + return OutTypeContainer.Type; +} + +FString USGBetaDevice::GetDeviceId() const +{ + FSGIC_TSharedPtr_FSGBetaDeviceImpl InstanceContainer{ToBetaDeviceImpl()}; + FSGIC_FString OutIdContainer; + SGCoreImpl_FSGBetaDeviceImpl_GetDeviceId(&InstanceContainer, &OutIdContainer); + return OutIdContainer.String; +} + +FString USGBetaDevice::GetHardwareVersion() const +{ + FSGIC_TSharedPtr_FSGBetaDeviceImpl InstanceContainer{ToBetaDeviceImpl()}; + FSGIC_FString VersionContainer; + SGCoreImpl_FSGBetaDeviceImpl_GetHardwareVersion(&InstanceContainer, &VersionContainer); + return VersionContainer.String; +} + +int32 USGBetaDevice::GetFirmwareVersion() const +{ + FSGIC_TSharedPtr_FSGBetaDeviceImpl InstanceContainer{ToBetaDeviceImpl()}; + return SGCoreImpl_FSGBetaDeviceImpl_GetFirmwareVersion(&InstanceContainer); +} + +int32 USGBetaDevice::GetSubFirmwareVersion() const +{ + FSGIC_TSharedPtr_FSGBetaDeviceImpl InstanceContainer{ToBetaDeviceImpl()}; + return SGCoreImpl_FSGBetaDeviceImpl_GetSubFirmwareVersion(&InstanceContainer); +} + +FString USGBetaDevice::GetConstantsString() const +{ + FSGIC_TSharedPtr_FSGBetaDeviceImpl InstanceContainer{ToBetaDeviceImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGBetaDeviceImpl_GetConstantsString(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +FString USGBetaDevice::GetSensorData() const +{ + FSGIC_TSharedPtr_FSGBetaDeviceImpl InstanceContainer{ToBetaDeviceImpl()}; + FSGIC_FString OutDataContainer; + SGCoreImpl_FSGBetaDeviceImpl_GetSensorData(&InstanceContainer, &OutDataContainer); + return OutDataContainer.String; +} + +FString USGBetaDevice::GetLastCommand() const +{ + FSGIC_TSharedPtr_FSGBetaDeviceImpl InstanceContainer{ToBetaDeviceImpl()}; + FSGIC_FString OutCommandContainer; + SGCoreImpl_FSGBetaDeviceImpl_GetLastCommand(&InstanceContainer, &OutCommandContainer); + return OutCommandContainer.String; +} + +bool USGBetaDevice::SendHaptics(const FString& Command) const +{ + FSGIC_TSharedPtr_FSGBetaDeviceImpl InstanceContainer{ToBetaDeviceImpl()}; + FSGIC_FString CommandContainer{Command}; + return SGCoreImpl_FSGBetaDeviceImpl_SendHaptics(&InstanceContainer, &CommandContainer); +} + +FString USGBetaDevice::ToString() const +{ + FSGIC_TSharedPtr_FSGBetaDeviceImpl InstanceContainer{ToBetaDeviceImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGBetaDeviceImpl_ToString(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGCore.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGCore.cpp new file mode 100644 index 0000000..e14e126 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGCore.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGCore.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGCustomWaveform.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGCustomWaveform.cpp new file mode 100644 index 0000000..a773e32 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGCustomWaveform.cpp @@ -0,0 +1,340 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGCustomWaveform.h" + +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_ESGWaveformType.h" +#include "SGInterop/SGIC_FSGCustomWaveformImpl.h" +#include "SGInterop/SGIC_FString.h" + +struct USGCustomWaveform::FImpl +{ + /************************ + * Member variables + ************************/ + + FSGCustomWaveformImpl CustomWaveformImpl; + + /************************ + * Owner object + ************************/ + + USGCustomWaveform* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGCustomWaveform* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGCustomWaveform* USGCustomWaveform::NewCustomWaveform(UObject* Outer, const FSGCustomWaveformImpl& CustomWaveformImpl) +{ + USGCustomWaveform* Instance = NewObject(Outer); + Instance->SetCustomWaveformImpl(CustomWaveformImpl); + return Instance; +} + +USGCustomWaveform* USGCustomWaveform::NewCustomWaveform(UObject* Outer) +{ + FSGIC_FSGCustomWaveformImpl OutCustomWaveformImplContainer; + SGCoreImpl_FSGCustomWaveformImpl_ctor(&OutCustomWaveformImplContainer); + + return NewCustomWaveform(Outer, MoveTemp(OutCustomWaveformImplContainer.CustomWaveformImpl)); +} + +USGCustomWaveform* USGCustomWaveform::NewCustomWaveform(UObject* Outer, const float Amplitude, const float Duration) +{ + FSGIC_FSGCustomWaveformImpl OutCustomWaveformImplContainer; + SGCoreImpl_FSGCustomWaveformImpl_ctor_Amplitude_Duration( + &OutCustomWaveformImplContainer, Amplitude, Duration); + + return NewCustomWaveform(Outer, MoveTemp(OutCustomWaveformImplContainer.CustomWaveformImpl)); +} + +USGCustomWaveform* USGCustomWaveform::NewCustomWaveform( + UObject* Outer, const float Amplitude, const float Duration, const float Frequency) +{ + FSGIC_FSGCustomWaveformImpl OutCustomWaveformImplContainer; + SGCoreImpl_FSGCustomWaveformImpl_ctor_Amplitude_Duration_Frequency( + &OutCustomWaveformImplContainer, Amplitude, Duration, Frequency); + + return NewCustomWaveform(Outer, MoveTemp(OutCustomWaveformImplContainer.CustomWaveformImpl)); +} + +FString USGCustomWaveform::ToString(const ESGWaveformType Type) +{ + FSGIC_ESGWaveformType TypeContainer{Type}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGCustomWaveformImpl_ToString_Type(&OutStringContainer, &TypeContainer); + return OutStringContainer.String; +} + +USGCustomWaveform::USGCustomWaveform() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGCustomWaveformImpl OutCustomWaveformImplContainer; + SGCoreImpl_FSGCustomWaveformImpl_ctor(&OutCustomWaveformImplContainer); + + Pimpl->CustomWaveformImpl = MoveTemp(OutCustomWaveformImplContainer.CustomWaveformImpl); +} + +USGCustomWaveform::USGCustomWaveform(const float Amplitude, const float Duration) +{ + FSGIC_FSGCustomWaveformImpl OutCustomWaveformImplContainer; + SGCoreImpl_FSGCustomWaveformImpl_ctor_Amplitude_Duration( + &OutCustomWaveformImplContainer, Amplitude, Duration); + + Pimpl->CustomWaveformImpl = MoveTemp(OutCustomWaveformImplContainer.CustomWaveformImpl); +} + +USGCustomWaveform::USGCustomWaveform(const float Amplitude, const float Duration, const float Frequency) +{ + FSGIC_FSGCustomWaveformImpl OutCustomWaveformImplContainer; + SGCoreImpl_FSGCustomWaveformImpl_ctor_Amplitude_Duration_Frequency( + &OutCustomWaveformImplContainer, Amplitude, Duration, Frequency); + + Pimpl->CustomWaveformImpl = MoveTemp(OutCustomWaveformImplContainer.CustomWaveformImpl); +} + +USGCustomWaveform::USGCustomWaveform(const FSGCustomWaveformImpl& CustomWaveformImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + SetCustomWaveformImpl(CustomWaveformImpl); +} + +USGCustomWaveform::~USGCustomWaveform() = default; + +void USGCustomWaveform::SetCustomWaveformImpl(const FSGCustomWaveformImpl& CustomWaveformImpl) +{ + FSGIC_FSGCustomWaveformImpl OutCustomWaveformContainer; + FSGIC_FSGCustomWaveformImpl RhsContainer{CustomWaveformImpl}; + SGCoreImpl_FSGCustomWaveformImpl_ctor_copy(&OutCustomWaveformContainer, &RhsContainer); + Pimpl->CustomWaveformImpl = MoveTemp(OutCustomWaveformContainer.CustomWaveformImpl); +} + +const FSGCustomWaveformImpl& USGCustomWaveform::ToCustomWaveformImpl() const +{ + return Pimpl->CustomWaveformImpl; +} + +float USGCustomWaveform::GetAmplitude() const +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + return SGCoreImpl_FSGCustomWaveformImpl_GetAmplitude(&InstanceContainer); +} + +void USGCustomWaveform::SetAmplitude(const float Amplitude) +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + SGCoreImpl_FSGCustomWaveformImpl_SetAmplitude(&InstanceContainer, Amplitude); +} + +ESGWaveformType USGCustomWaveform::GetWaveType() const +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + FSGIC_ESGWaveformType OutTypeContainer; + SGCoreImpl_FSGCustomWaveformImpl_GetWaveType(&InstanceContainer, &OutTypeContainer); + return OutTypeContainer.Type; +} + +void USGCustomWaveform::SetWaveType(const ESGWaveformType Type) +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + FSGIC_ESGWaveformType TypeContainer{Type}; + SGCoreImpl_FSGCustomWaveformImpl_SetWaveType(&InstanceContainer, &TypeContainer); +} + +bool USGCustomWaveform::IsInfinite() const +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + return SGCoreImpl_FSGCustomWaveformImpl_IsInfinite(&InstanceContainer); +} + +void USGCustomWaveform::SetInfinite(const bool bInfinite) +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + SGCoreImpl_FSGCustomWaveformImpl_SetInfinite(&InstanceContainer, bInfinite); +} + +int32 USGCustomWaveform::GetRepeatAmount() const +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + return SGCoreImpl_FSGCustomWaveformImpl_GetRepeatAmount(&InstanceContainer); +} + +void USGCustomWaveform::SetRepeatAmount(const int32 Amount) +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + SGCoreImpl_FSGCustomWaveformImpl_SetRepeatAmount(&InstanceContainer, Amount); +} + +float USGCustomWaveform::GetAttackTime() const +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + return SGCoreImpl_FSGCustomWaveformImpl_GetAttackTime(&InstanceContainer); +} + +void USGCustomWaveform::SetAttackTime(const float Time) +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + SGCoreImpl_FSGCustomWaveformImpl_SetAttackTime(&InstanceContainer, Time); +} + +float USGCustomWaveform::GetSustainTime() const +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + return SGCoreImpl_FSGCustomWaveformImpl_GetSustainTime(&InstanceContainer); +} + +void USGCustomWaveform::SetSustainTime(const float Time) +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + SGCoreImpl_FSGCustomWaveformImpl_SetSustainTime(&InstanceContainer, Time); +} + +float USGCustomWaveform::GetDecayTime() const +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + return SGCoreImpl_FSGCustomWaveformImpl_GetDecayTime(&InstanceContainer); +} + +void USGCustomWaveform::SetDecayTime(const float Time) +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + SGCoreImpl_FSGCustomWaveformImpl_SetDecayTime(&InstanceContainer, Time); +} + +float USGCustomWaveform::GetFrequencyStart() const +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + return SGCoreImpl_FSGCustomWaveformImpl_GetFrequencyStart(&InstanceContainer); +} + +void USGCustomWaveform::SetFrequencyStart(const float Frequency) +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + SGCoreImpl_FSGCustomWaveformImpl_SetFrequencyStart(&InstanceContainer, Frequency); +} + +float USGCustomWaveform::GetFrequencyEnd() const +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + return SGCoreImpl_FSGCustomWaveformImpl_GetFrequencyEnd(&InstanceContainer); +} + +void USGCustomWaveform::SetFrequencyEnd(const float Frequency) +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + SGCoreImpl_FSGCustomWaveformImpl_SetFrequencyEnd(&InstanceContainer, Frequency); +} + +float USGCustomWaveform::GetFrequencySwitchTime() const +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + return SGCoreImpl_FSGCustomWaveformImpl_GetFrequencySwitchTime(&InstanceContainer); +} + +void USGCustomWaveform::SetFrequencySwitchTime(const float Time) +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + SGCoreImpl_FSGCustomWaveformImpl_SetFrequencySwitchTime(&InstanceContainer, Time); +} + +float USGCustomWaveform::GetFrequencySwitchFactor() const +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + return SGCoreImpl_FSGCustomWaveformImpl_GetFrequencySwitchFactor(&InstanceContainer); +} + +void USGCustomWaveform::SetFrequencySwitchFactor(const float Time) +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + SGCoreImpl_FSGCustomWaveformImpl_SetFrequencySwitchFactor(&InstanceContainer, Time); +} + +float USGCustomWaveform::GetEffectTime() const +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + return SGCoreImpl_FSGCustomWaveformImpl_GetEffectTime(&InstanceContainer); +} + +float USGCustomWaveform::GetTotalEffectTime() const +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + return SGCoreImpl_FSGCustomWaveformImpl_GetTotalEffectTime(&InstanceContainer); +} + +bool USGCustomWaveform::FrequencyJumps() const +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + return SGCoreImpl_FSGCustomWaveformImpl_FrequencyJumps(&InstanceContainer); +} + +bool USGCustomWaveform::Equals(const USGCustomWaveform* CustomWaveform) const +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + FSGIC_FSGCustomWaveformImpl CustomWaveformContainer{CustomWaveform->ToCustomWaveformImpl()}; + return SGCoreImpl_FSGCustomWaveformImpl_Equals(&InstanceContainer, &CustomWaveformContainer); +} + +FString USGCustomWaveform::ToString() const +{ + FSGIC_FSGCustomWaveformImpl InstanceContainer{ToCustomWaveformImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGCustomWaveformImpl_ToString(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +USGCustomWaveform::FImpl::FImpl(USGCustomWaveform* InOwner) + : Owner(InOwner) +{ +} + +USGCustomWaveform::FImpl::~FImpl() = default; + +void USGCustomWaveform::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGDevice.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGDevice.cpp new file mode 100644 index 0000000..5139684 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGDevice.cpp @@ -0,0 +1,556 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGDevice.h" + +#include "SGDeviceImplCast.h" +#include "Engine/Engine.h" + +#include "SGCore/SGBetaDevice.h" +#include "SGCore/SGHapticChannelInfo.h" +#include "SGCore/SGHapticGlove.h" +#include "SGCore/SGNova2Glove.h" +#include "SGCore/SGNovaGlove.h" +#include "SGCore/SGSenseGlove.h" +#include "SGCoreImpl/SGBetaDeviceImpl.h" +#include "SGCoreImpl/SGDeviceImpl.h" +#include "SGCoreImpl/SGHapticChannelInfoImpl.h" +#include "SGCoreImpl/SGHapticGloveImpl.h" +#include "SGCoreImpl/SGNova2GloveImpl.h" +#include "SGCoreImpl/SGNovaGloveImpl.h" +#include "SGCoreImpl/SGSenseGloveImpl.h" +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_ESGConnectionType.h" +#include "SGInterop/SGIC_ESGDeviceType.h" +#include "SGInterop/SGIC_ESGHapticChannelType.h" +#include "SGInterop/SGIC_FSGBetaDeviceImpl.h" +#include "SGInterop/SGIC_FSGDeviceImpl.h" +#include "SGInterop/SGIC_FSGHapticChannelInfoImpl.h" +#include "SGInterop/SGIC_FSGHapticGloveImpl.h" +#include "SGInterop/SGIC_FSGNova2GloveImpl.h" +#include "SGInterop/SGIC_FSGNovaGloveImpl.h" +#include "SGInterop/SGIC_FSGSenseGloveImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_TSharedPtr_FSGBetaDeviceImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGDeviceImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGHapticGloveImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGNova2GloveImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGNovaGloveImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGSenseGloveImpl.h" + +struct USGDevice::FImpl +{ + /************************ + * Member variables + ************************/ + + TSharedPtr SGDeviceImpl; + + /************************ + * Owner object + ************************/ + + USGDevice* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGDevice* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +void USGDevice::ParseFirmware(const FString& RawFirmware, int32& OutMainVersion, int32& OutSubVersion) +{ + FSGIC_FString RawFirmwareContainer{RawFirmware}; + SGCoreImpl_FSGDeviceImpl_ParseFirmware(&RawFirmwareContainer, &OutMainVersion, &OutSubVersion); +} + +bool USGDevice::FirmwareNewerThan( + const int32 MyFirmwareMain, const int32 MyFirmwareSub, const int32 ReferenceMain, const int32 ReferenceSub, + const bool bInclusive) +{ + return + SGCoreImpl_FSGDeviceImpl_FirmwareNewerThan_MyFirmwareMain_MyFirmwareSub_ReferenceMain_ReferenceSub_bInclusive( + MyFirmwareMain, MyFirmwareSub, ReferenceMain, ReferenceSub, bInclusive); +} + +bool USGDevice::FirmwareOlderThan( + const int32 MyFirmwareMain, const int32 MyFirmwareSub, const int32 ReferenceMain, const int32 ReferenceSub, + const bool bInclusive) +{ + return + SGCoreImpl_FSGDeviceImpl_FirmwareOlderThan_MyFirmwareMain_MyFirmwareSub_ReferenceMain_ReferenceSub_bInclusive( + MyFirmwareMain, MyFirmwareSub, ReferenceMain, ReferenceSub, bInclusive); +} + +FString USGDevice::ToString(const ESGDeviceType DeviceType) +{ + FSGIC_ESGDeviceType DeviceTypeContainer{DeviceType}; + FSGIC_FString OutString; + SGCoreImpl_FSGDeviceImpl_ToString(&DeviceTypeContainer, &OutString); + return OutString.String; +} + +USGDevice::USGDevice() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_TSharedPtr_FSGDeviceImpl OutSharedPtrContainer; + SGCoreImpl_FSGDeviceImpl_ctor_MakeShared(&OutSharedPtrContainer); + + Pimpl->SGDeviceImpl = MoveTemp(OutSharedPtrContainer.Ptr); +} + +USGDevice::USGDevice(const FSGDeviceImpl& SGDeviceImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_TSharedPtr_FSGDeviceImpl OutSharedPtrContainer; + FSGIC_FSGDeviceImpl RhsContainer{SGDeviceImpl}; + SGCoreImpl_FSGDeviceImpl_ctor_copy_MakeShared(&OutSharedPtrContainer, &RhsContainer); + + Pimpl->SGDeviceImpl = MoveTemp(OutSharedPtrContainer.Ptr); +} + +USGDevice::USGDevice(const FSGBetaDeviceImpl& BetaDeviceImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_TSharedPtr_FSGBetaDeviceImpl OutSharedPtrContainer; + FSGIC_FSGBetaDeviceImpl RhsContainer{BetaDeviceImpl}; + SGCoreImpl_FSGBetaDeviceImpl_ctor_copy_MakeShared(&OutSharedPtrContainer, &RhsContainer); + + Pimpl->SGDeviceImpl = MoveTemp(OutSharedPtrContainer.Ptr); +} + +USGDevice::USGDevice(const FSGHapticGloveImpl& HapticGloveImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl OutSharedPtrContainer; + FSGIC_FSGHapticGloveImpl RhsContainer{HapticGloveImpl}; + SGCoreImpl_FSGHapticGloveImpl_ctor_copy_MakeShared(&OutSharedPtrContainer, &RhsContainer); + + Pimpl->SGDeviceImpl = MoveTemp(OutSharedPtrContainer.Ptr); +} + +USGDevice::USGDevice(const FSGNova2GloveImpl& Nova2GloveImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl OutSharedPtrContainer; + FSGIC_FSGNova2GloveImpl RhsContainer{Nova2GloveImpl}; + SGCoreImpl_FSGNova2GloveImpl_ctor_copy_MakeShared(&OutSharedPtrContainer, &RhsContainer); + + Pimpl->SGDeviceImpl = MoveTemp(OutSharedPtrContainer.Ptr); +} + +USGDevice::USGDevice(const FSGNovaGloveImpl& NovaGloveImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl OutSharedPtrContainer; + FSGIC_FSGNovaGloveImpl RhsContainer{NovaGloveImpl}; + SGCoreImpl_FSGNovaGloveImpl_ctor_copy_MakeShared(&OutSharedPtrContainer, &RhsContainer); + + Pimpl->SGDeviceImpl = MoveTemp(OutSharedPtrContainer.Ptr); +} + +USGDevice::USGDevice(const FSGSenseGloveImpl& SenseGloveImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl OutSharedPtrContainer; + FSGIC_FSGSenseGloveImpl RhsContainer{SenseGloveImpl}; + SGCoreImpl_FSGSenseGloveImpl_ctor_copy_MakeShared(&OutSharedPtrContainer, &RhsContainer); + + Pimpl->SGDeviceImpl = MoveTemp(OutSharedPtrContainer.Ptr); +} + +USGDevice::USGDevice(TSharedRef SGDeviceImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->SGDeviceImpl = MoveTemp(SGDeviceImpl); +} + +USGDevice::USGDevice(TSharedRef BetaDeviceImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->SGDeviceImpl = MoveTemp(BetaDeviceImpl); +} + +USGDevice::USGDevice(TSharedRef HapticGloveImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->SGDeviceImpl = MoveTemp(HapticGloveImpl); +} + +USGDevice::USGDevice(TSharedRef Nova2GloveImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->SGDeviceImpl = MoveTemp(Nova2GloveImpl); +} + +USGDevice::USGDevice(TSharedRef NovaGloveImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->SGDeviceImpl = MoveTemp(NovaGloveImpl); +} + +USGDevice::USGDevice(TSharedRef SenseGloveImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->SGDeviceImpl = MoveTemp(SenseGloveImpl); +} + +USGDevice::~USGDevice() = default; + +void USGDevice::SetSGDeviceImpl(const FSGDeviceImpl& SGDeviceImpl) +{ + FSGIC_TSharedPtr_FSGDeviceImpl OutSharedPtrContainer; + FSGIC_FSGDeviceImpl RhsContainer{SGDeviceImpl}; + SGCoreImpl_FSGDeviceImpl_ctor_copy_MakeShared(&OutSharedPtrContainer, &RhsContainer); + Pimpl->SGDeviceImpl = MoveTemp(OutSharedPtrContainer.Ptr); +} + +void USGDevice::SetSGDeviceImpl(const FSGBetaDeviceImpl& BetaDeviceImpl) +{ + FSGIC_TSharedPtr_FSGBetaDeviceImpl OutSharedPtrContainer; + FSGIC_FSGBetaDeviceImpl RhsContainer{BetaDeviceImpl}; + SGCoreImpl_FSGBetaDeviceImpl_ctor_copy_MakeShared(&OutSharedPtrContainer, &RhsContainer); + Pimpl->SGDeviceImpl = MoveTemp(OutSharedPtrContainer.Ptr); +} + +void USGDevice::SetSGDeviceImpl(const FSGHapticGloveImpl& HapticGloveImpl) +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl OutSharedPtrContainer; + FSGIC_FSGHapticGloveImpl RhsContainer{HapticGloveImpl}; + SGCoreImpl_FSGHapticGloveImpl_ctor_copy_MakeShared(&OutSharedPtrContainer, &RhsContainer); + Pimpl->SGDeviceImpl = MoveTemp(OutSharedPtrContainer.Ptr); +} + +void USGDevice::SetSGDeviceImpl(const FSGNova2GloveImpl& Nova2GloveImpl) +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl OutSharedPtrContainer; + FSGIC_FSGNova2GloveImpl RhsContainer{Nova2GloveImpl}; + SGCoreImpl_FSGNovaGloveImpl_ctor_copy_MakeShared(&OutSharedPtrContainer, &RhsContainer); + Pimpl->SGDeviceImpl = MoveTemp(OutSharedPtrContainer.Ptr); +} + +void USGDevice::SetSGDeviceImpl(const FSGNovaGloveImpl& NovaGloveImpl) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl OutSharedPtrContainer; + FSGIC_FSGNovaGloveImpl RhsContainer{NovaGloveImpl}; + SGCoreImpl_FSGNovaGloveImpl_ctor_copy_MakeShared(&OutSharedPtrContainer, &RhsContainer); + Pimpl->SGDeviceImpl = MoveTemp(OutSharedPtrContainer.Ptr); +} + +void USGDevice::SetSGDeviceImpl(const FSGSenseGloveImpl& SenseGloveImpl) +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl OutSharedPtrContainer; + FSGIC_FSGSenseGloveImpl RhsContainer{SenseGloveImpl}; + SGCoreImpl_FSGSenseGloveImpl_ctor_copy_MakeShared(&OutSharedPtrContainer, &RhsContainer); + Pimpl->SGDeviceImpl = MoveTemp(OutSharedPtrContainer.Ptr); +} + +void USGDevice::SetSGDeviceImpl(TSharedRef SGDeviceImpl) +{ + Pimpl->SGDeviceImpl = MoveTemp(SGDeviceImpl); +} + +void USGDevice::SetSGDeviceImpl(TSharedRef BetaDeviceImpl) +{ + Pimpl->SGDeviceImpl = MoveTemp(BetaDeviceImpl); +} + +void USGDevice::SetSGDeviceImpl(TSharedRef HapticGloveImpl) +{ + Pimpl->SGDeviceImpl = MoveTemp(HapticGloveImpl); +} + +void USGDevice::SetSGDeviceImpl(TSharedRef Nova2GloveImpl) +{ + Pimpl->SGDeviceImpl = MoveTemp(Nova2GloveImpl); +} + +void USGDevice::SetSGDeviceImpl(TSharedRef NovaGloveImpl) +{ + Pimpl->SGDeviceImpl = MoveTemp(NovaGloveImpl); +} + +void USGDevice::SetSGDeviceImpl(TSharedRef SenseGloveImpl) +{ + Pimpl->SGDeviceImpl = MoveTemp(SenseGloveImpl); +} + +TSharedRef USGDevice::ToSGDeviceImpl() const +{ + return Pimpl->SGDeviceImpl.ToSharedRef(); +} + +bool USGDevice::IsABetaDevice() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + return SGCoreImpl_FSGDeviceImpl_IsABetaDevice(&InstanceContainer); +} + +bool USGDevice::IsAHapticGlove() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + return SGCoreImpl_FSGDeviceImpl_IsAHapticGlove(&InstanceContainer); +} + +bool USGDevice::IsANova2Glove() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + return SGCoreImpl_FSGDeviceImpl_IsANova2Glove(&InstanceContainer); +} + +bool USGDevice::IsANovaGlove() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + return SGCoreImpl_FSGDeviceImpl_IsANovaGlove(&InstanceContainer); +} + +bool USGDevice::IsASenseGlove() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + return SGCoreImpl_FSGDeviceImpl_IsASenseGlove(&InstanceContainer); +} + +USGBetaDevice* USGDevice::AsBetaDevice(UObject* Outer) const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + FSGIC_TSharedPtr_FSGBetaDeviceImpl OutSharedPtr; + SGCoreImpl_FSGDeviceImpl_AsBetaDevice(&InstanceContainer, &OutSharedPtr); + + USGBetaDevice* BetaDevice = NewObject(Outer); + BetaDevice->SetSGDeviceImpl(OutSharedPtr.Ptr.ToSharedRef()); + return BetaDevice; +} + +USGHapticGlove* USGDevice::AsHapticGlove(UObject* Outer) const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + FSGIC_TSharedPtr_FSGHapticGloveImpl OutSharedPtr; + SGCoreImpl_FSGDeviceImpl_AsHapticGlove(&InstanceContainer, &OutSharedPtr); + + USGHapticGlove* HapticGlove = NewObject(Outer); + HapticGlove->SetSGDeviceImpl(OutSharedPtr.Ptr.ToSharedRef()); + return HapticGlove; +} + +USGNova2Glove* USGDevice::AsNova2Glove(UObject* Outer) const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + FSGIC_TSharedPtr_FSGNova2GloveImpl OutSharedPtr; + SGCoreImpl_FSGDeviceImpl_AsNova2Glove(&InstanceContainer, &OutSharedPtr); + + USGNova2Glove* Nova2Glove = NewObject(Outer); + Nova2Glove->SetSGDeviceImpl(OutSharedPtr.Ptr.ToSharedRef()); + return Nova2Glove; +} + +USGNovaGlove* USGDevice::AsNovaGlove(UObject* Outer) const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + FSGIC_TSharedPtr_FSGNovaGloveImpl OutSharedPtr; + SGCoreImpl_FSGDeviceImpl_AsNovaGlove(&InstanceContainer, &OutSharedPtr); + + USGNovaGlove* NovaGlove = NewObject(Outer); + NovaGlove->SetSGDeviceImpl(OutSharedPtr.Ptr.ToSharedRef()); + return NovaGlove; +} + +USGSenseGlove* USGDevice::AsSenseGlove(UObject* Outer) const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + FSGIC_TSharedPtr_FSGSenseGloveImpl OutSharedPtr; + SGCoreImpl_FSGDeviceImpl_AsSenseGlove(&InstanceContainer, &OutSharedPtr); + + USGSenseGlove* SenseGlove = NewObject(Outer); + SenseGlove->SetSGDeviceImpl(OutSharedPtr.Ptr.ToSharedRef()); + return SenseGlove; +} + +ESGDeviceType USGDevice::GetDeviceType() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + FSGIC_ESGDeviceType OutTypeContainer; + SGCoreImpl_FSGDeviceImpl_GetDeviceType(&InstanceContainer, &OutTypeContainer); + return OutTypeContainer.Type; +} + +int32 USGDevice::GetSubFirmwareVersion() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + return SGCoreImpl_FSGDeviceImpl_GetSubFirmwareVersion(&InstanceContainer); +} + +FString USGDevice::GetFirmwareString() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGDeviceImpl_GetFirmwareString(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +bool USGDevice::FirmwareNewerThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + return SGCoreImpl_FSGDeviceImpl_FirmwareNewerThan_MyFirmwareMain_MyFirmwareSub_bInclusive( + &InstanceContainer, FirmwareMain, FirmwareSub, bInclusive); +} + +bool USGDevice::FirmwareOlderThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + return SGCoreImpl_FSGDeviceImpl_FirmwareOlderThan_MyFirmwareMain_MyFirmwareSub_bInclusive( + &InstanceContainer, FirmwareMain, FirmwareSub, bInclusive); +} + +FString USGDevice::GetAddress() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + FSGIC_FString AddressContainer; + SGCoreImpl_FSGDeviceImpl_GetAddress(&InstanceContainer, &AddressContainer); + return AddressContainer.String; +} + +bool USGDevice::IsConnected() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + return SGCoreImpl_FSGDeviceImpl_IsConnected(&InstanceContainer); +} + +ESGConnectionType USGDevice::GetConnectionType() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + FSGIC_ESGConnectionType OutTypeContainer; + SGCoreImpl_FSGDeviceImpl_GetConnectionType(&InstanceContainer, &OutTypeContainer); + return OutTypeContainer.Type; +} + +int32 USGDevice::PacketsPerSecondReceived() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + return SGCoreImpl_FSGDeviceImpl_PacketsPerSecondReceived(&InstanceContainer); +} + +int32 USGDevice::PacketsPerSecondSent() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + return SGCoreImpl_FSGDeviceImpl_PacketsPerSecondSent(&InstanceContainer); +} + +int32 USGDevice::GetDeviceIndex() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + return SGCoreImpl_FSGDeviceImpl_GetDeviceIndex(&InstanceContainer); +} + +void USGDevice::SetDeviceIndex(const int32 NewIndex) +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + SGCoreImpl_FSGDeviceImpl_SetDeviceIndex(&InstanceContainer, NewIndex); +} + +bool USGDevice::IsWireless() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + return SGCoreImpl_FSGDeviceImpl_IsWireless(&InstanceContainer); +} + +bool USGDevice::HasBattery() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + return SGCoreImpl_FSGDeviceImpl_HasBattery(&InstanceContainer); +} + +bool USGDevice::IsCharging() +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + const bool bResult = SGCoreImpl_FSGDeviceImpl_IsCharging(&InstanceContainer); + + return bResult; +} + +bool USGDevice::GetBatteryLevel(float& OutLevel) +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + const bool bResult = SGCoreImpl_FSGDeviceImpl_GetBatteryLevel(&InstanceContainer, &OutLevel); + return bResult; +} + +void USGDevice::SetHapticChannels(const USGHapticChannelInfo* Channels) +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + FSGIC_FSGHapticChannelInfoImpl ChannelsContainer{Channels->ToHapticChannelInfoImpl()}; + SGCoreImpl_FSGDeviceImpl_SetHapticChannels(&InstanceContainer, &ChannelsContainer); +} + +int32 USGDevice::GetHapticChannelCount() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + return SGCoreImpl_FSGDeviceImpl_GetHapticChannelCount(&InstanceContainer); +} + +int32 USGDevice::GetHapticChannelCount(ESGHapticChannelType ChannelType) const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + FSGIC_ESGHapticChannelType ChannelTypeContainer{ChannelType}; + return SGCoreImpl_FSGDeviceImpl_GetHapticChannelCount_ChannelType(&InstanceContainer, &ChannelTypeContainer); +} + +FString USGDevice::ToString() const +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{ToSGDeviceImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGDeviceImpl_ToString(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +USGDevice::FImpl::FImpl(USGDevice* InOwner) + : Owner(InOwner) +{ +} + +USGDevice::FImpl::~FImpl() = default; + +void USGDevice::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGDeviceImplCast.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGDeviceImplCast.cpp new file mode 100644 index 0000000..bbc9adb --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGDeviceImplCast.cpp @@ -0,0 +1,90 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGDeviceImplCast.h" + +#include "SGCoreImpl/SGBetaDeviceImpl.h" +#include "SGCoreImpl/SGDeviceImpl.h" +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGCoreImpl/SGHapticGloveImpl.h" +#include "SGCoreImpl/SGNova2GloveImpl.h" +#include "SGCoreImpl/SGNovaGloveImpl.h" +#include "SGCoreImpl/SGSenseGloveImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGBetaDeviceImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGDeviceImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGHapticGloveImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGNova2GloveImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGNovaGloveImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGSenseGloveImpl.h" + +TSharedRef FSGDeviceImplCast::ToBetaDeviceImpl(TSharedRef SGDeviceImpl) +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{MoveTemp(SGDeviceImpl)}; + FSGIC_TSharedPtr_FSGBetaDeviceImpl OutSharedPtrContainer; + SGCoreImpl_FSGDeviceImpl_ToBetaDeviceImplRef(&InstanceContainer, &OutSharedPtrContainer); + return OutSharedPtrContainer.Ptr.ToSharedRef(); +} + +TSharedRef FSGDeviceImplCast::ToHapticGloveImpl(TSharedRef SGDeviceImpl) +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{MoveTemp(SGDeviceImpl)}; + FSGIC_TSharedPtr_FSGHapticGloveImpl OutSharedPtrContainer; + SGCoreImpl_FSGDeviceImpl_ToHapticGloveImplRef(&InstanceContainer, &OutSharedPtrContainer); + return OutSharedPtrContainer.Ptr.ToSharedRef(); +} + +TSharedRef FSGDeviceImplCast::ToNova2GloveImpl(TSharedRef SGDeviceImpl) +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{MoveTemp(SGDeviceImpl)}; + FSGIC_TSharedPtr_FSGNova2GloveImpl OutSharedPtrContainer; + SGCoreImpl_FSGDeviceImpl_ToNova2GloveImplRef(&InstanceContainer, &OutSharedPtrContainer); + return OutSharedPtrContainer.Ptr.ToSharedRef(); +} + +TSharedRef FSGDeviceImplCast::ToNovaGloveImpl(TSharedRef SGDeviceImpl) +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{MoveTemp(SGDeviceImpl)}; + FSGIC_TSharedPtr_FSGNovaGloveImpl OutSharedPtrContainer; + SGCoreImpl_FSGDeviceImpl_ToNovaGloveImplRef(&InstanceContainer, &OutSharedPtrContainer); + return OutSharedPtrContainer.Ptr.ToSharedRef(); +} + +TSharedRef FSGDeviceImplCast::ToSenseGloveImpl(TSharedRef SGDeviceImpl) +{ + FSGIC_TSharedPtr_FSGDeviceImpl InstanceContainer{MoveTemp(SGDeviceImpl)}; + FSGIC_TSharedPtr_FSGSenseGloveImpl OutSharedPtrContainer; + SGCoreImpl_FSGDeviceImpl_ToSenseGloveImplRef(&InstanceContainer, &OutSharedPtrContainer); + return OutSharedPtrContainer.Ptr.ToSharedRef(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGDeviceImplCast.h b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGDeviceImplCast.h new file mode 100644 index 0000000..01c39cf --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGDeviceImplCast.h @@ -0,0 +1,59 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Templates/SharedPointer.h" + +class FSGBetaDeviceImpl; +class FSGDeviceImpl; +class FSGHapticGloveImpl; +class FSGNova2GloveImpl; +class FSGNovaGloveImpl; +class FSGSenseGloveImpl; + +class SENSEGLOVECORE_API FSGDeviceImplCast +{ +public: + static TSharedRef ToBetaDeviceImpl(TSharedRef SGDeviceImpl); + + static TSharedRef ToHapticGloveImpl(TSharedRef SGDeviceImpl); + + static TSharedRef ToNova2GloveImpl(TSharedRef SGDeviceImpl); + + static TSharedRef ToNovaGloveImpl(TSharedRef SGDeviceImpl); + + static TSharedRef ToSenseGloveImpl(TSharedRef SGDeviceImpl); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGDeviceList.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGDeviceList.cpp new file mode 100644 index 0000000..0440d4d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGDeviceList.cpp @@ -0,0 +1,225 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGDeviceList.h" + +#include "Templates/SubclassOf.h" + +#include "SGCore/SGBetaDevice.h" +#include "SGCore/SGDevice.h" +#include "SGCore/SGDeviceImplCast.h" +#include "SGCore/SGNova2Glove.h" +#include "SGCore/SGNovaGlove.h" +#include "SGCore/SGSenseGlove.h" +#include "SGCoreImpl/SGBetaDeviceImpl.h" +#include "SGCoreImpl/SGDeviceImpl.h" +#include "SGCoreImpl/SGNovaGloveImpl.h" +#include "SGCoreImpl/SGSenseGloveImpl.h" +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_ESGConnectionType.h" +#include "SGInterop/SGIC_ESGDeviceType.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_TArray_TSharedRef_FSGDeviceImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGDeviceImpl.h" + +int32 FSGDeviceList::ActiveDevices() +{ + return SGCoreImpl_FSGDeviceListImpl_ActiveDevices(); +} + +bool FSGDeviceList::SenseCommRunning() +{ + return SGCoreImpl_FSGDeviceListImpl_SenseCommRunning(); +} + +void FSGDeviceList::Dispose() +{ + SGCoreImpl_FSGDeviceListImpl_Dispose(); +} + +void FSGDeviceList::Reinitialize() +{ + SGCoreImpl_FSGDeviceListImpl_Reinitialize(); +} + +TArray FSGDeviceList::GetDevices(UObject* Outer) +{ + FSGIC_TArray_TSharedRef_FSGDeviceListImpl DeviceImplsArrayContainer; + SGCoreImpl_FSGDeviceListImpl_GetDevices(&DeviceImplsArrayContainer); + + TArray Devices; + + for (TSharedRef DeviceImpl: DeviceImplsArrayContainer.Array) + { + FSGIC_TSharedPtr_FSGDeviceImpl DeviceImplContainer{DeviceImpl}; + FSGIC_ESGDeviceType DeviceTypeContainer; + SGCoreImpl_FSGDeviceImpl_GetDeviceType(&DeviceImplContainer, &DeviceTypeContainer); + switch (DeviceTypeContainer.Type) + { + case ESGDeviceType::BetaDevice: + { + TSharedRef BetaDeviceImpl{FSGDeviceImplCast::ToBetaDeviceImpl(DeviceImpl)}; + USGBetaDevice* BetaDevice = USGBetaDevice::NewBetaDevice(Outer, MoveTemp(BetaDeviceImpl)); + Devices.Push(BetaDevice); + } + break; + case ESGDeviceType::Nova2: + { + TSharedRef Nova2GloveImpl{FSGDeviceImplCast::ToNova2GloveImpl(DeviceImpl)}; + USGNova2Glove* Nova2Glove = USGNova2Glove::NewNova2Glove(Outer, MoveTemp(Nova2GloveImpl)); + Devices.Push(Nova2Glove); + } + case ESGDeviceType::Nova: + { + TSharedRef NovaGloveImpl{FSGDeviceImplCast::ToNovaGloveImpl(DeviceImpl)}; + USGNovaGlove* NovaGlove = USGNovaGlove::NewNovaGlove(Outer, MoveTemp(NovaGloveImpl)); + Devices.Push(NovaGlove); + } + break; + case ESGDeviceType::SenseGlove: + { + TSharedRef SenseGloveImpl{FSGDeviceImplCast::ToSenseGloveImpl(DeviceImpl)}; + USGSenseGlove* SenseGlove = USGSenseGlove::NewSenseGlove(Outer, MoveTemp(SenseGloveImpl)); + Devices.Push(SenseGlove); + } + break; + default: + ensureAlwaysMsgf(false, TEXT("Unknown SenseGlove device!")); + break; + } + } + + return Devices; +} + +TArray FSGDeviceList::GetDevices(UObject* Outer, const TSubclassOf& DeviceType) +{ + ensureAlwaysMsgf(IsValid(DeviceType.GetDefaultObject()), TEXT("Invalid default object!")); + const UClass* ClassFilter = DeviceType->StaticClass(); + + const TArray CurrentDevices = GetDevices(Outer); + TArray Devices; + + for (USGDevice* Device: CurrentDevices) + { + ensureAlwaysMsgf(IsValid(Device), TEXT("Invalid device!")); + + const UClass* DeviceClass = Device->StaticClass(); + if (DeviceClass == ClassFilter) + { + Devices.Push(Device); + } + } + + return Devices; +} + +TArray FSGDeviceList::GetDevices(UObject* Outer, const ESGDeviceType DeviceType) +{ + const TArray CurrentDevices = GetDevices(Outer); + TArray Devices; + + for (USGDevice* Device: CurrentDevices) + { + ensureAlwaysMsgf(IsValid(Device), TEXT("Invalid device!")); + + if (Device->GetDeviceType() == DeviceType) + { + Devices.Push(Device); + } + } + + return Devices; +} + +bool FSGDeviceList::GetSensorDataString(const int32 IpcIndex, const FString& IpcAddress, FString& OutString) +{ + FSGIC_FString IpcAddressContainer{IpcAddress}; + FSGIC_FString OutStringContainer; + const bool bReturn = SGCoreImpl_FSGDeviceListImpl_GetSensorDataString( + IpcIndex, &IpcAddressContainer, &OutStringContainer); + OutString = OutStringContainer.String; + return bReturn; +} + +bool FSGDeviceList::SendHaptics( + const int32 IpcIndex, const FString& IpcAddress, const int32 ChannelIndex, const FString& Commands) +{ + FSGIC_FString IpcAddressContainer{IpcAddress}; + FSGIC_FString CommandsContainer{Commands}; + return SGCoreImpl_FSGDeviceListImpl_SendHaptics(IpcIndex, &IpcAddressContainer, ChannelIndex, &CommandsContainer); +} + +FString FSGDeviceList::GetDeviceStringAt(const int32 IpcIndex, const FString& IpcAddress, const int32 Index) +{ + FSGIC_FString IpcAddressContainer{IpcAddress}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGDeviceListImpl_GetDeviceStringAt(&OutStringContainer, IpcIndex, &IpcAddressContainer, Index); + return OutStringContainer.String; +} + +FString FSGDeviceList::GetAddress(const int32 IpcIndex, const FString& IpcAddress) +{ + FSGIC_FString IpcAddressContainer{IpcAddress}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGDeviceListImpl_GetAddress(&OutStringContainer, IpcIndex, &IpcAddressContainer); + return OutStringContainer.String; +} + +ESGConnectionType FSGDeviceList::GetConnectionType(const int32 IpcIndex, const FString& IpcAddress) +{ + FSGIC_FString IpcAddressContainer{IpcAddress}; + FSGIC_ESGConnectionType OutTypeContainer; + SGCoreImpl_FSGDeviceListImpl_GetConnectionType(&OutTypeContainer, IpcIndex, &IpcAddressContainer); + return OutTypeContainer.Type; +} + +bool FSGDeviceList::IsConnected(const int32 IpcIndex, const FString& IpcAddress) +{ + FSGIC_FString IpcAddressContainer{IpcAddress}; + return SGCoreImpl_FSGDeviceListImpl_IsConnected(IpcIndex, &IpcAddressContainer); +} + +int32 FSGDeviceList::PacketsPerSecondReceived(const int32 IpcIndex, const FString& IpcAddress) +{ + FSGIC_FString IpcAddressContainer{IpcAddress}; + return SGCoreImpl_FSGDeviceListImpl_PacketsPerSecondReceived(IpcIndex, &IpcAddressContainer); +} + +int32 FSGDeviceList::PacketsPerSecondSent(const int32 IpcIndex, const FString& IpcAddress) +{ + FSGIC_FString IpcAddressContainer{IpcAddress}; + return SGCoreImpl_FSGDeviceListImpl_PacketsPerSecondSent(IpcIndex, &IpcAddressContainer); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGDeviceModel.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGDeviceModel.cpp new file mode 100644 index 0000000..b0ad963 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGDeviceModel.cpp @@ -0,0 +1,215 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGDeviceModel.h" + +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_FSGDeviceModelImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_TArray_bool.h" + +struct USGDeviceModel::FImpl +{ + /************************ + * Member variables + ************************/ + + FSGDeviceModelImpl DeviceModelImpl; + + /************************ + * Owner object + ************************/ + + USGDeviceModel* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGDeviceModel* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGDeviceModel* USGDeviceModel::NewDeviceModel(UObject* Outer, const FSGDeviceModelImpl& DeviceModelImpl) +{ + USGDeviceModel* Instance = NewObject(Outer); + Instance->SetDeviceModelImpl(DeviceModelImpl); + return Instance; +} + +USGDeviceModel* USGDeviceModel::NewDeviceModel(UObject* Outer) +{ + FSGIC_FSGDeviceModelImpl OutDeviceModelImplContainer; + SGCoreImpl_FSGDeviceModelImpl_ctor(&OutDeviceModelImplContainer); + + return NewDeviceModel(Outer, MoveTemp(OutDeviceModelImplContainer.DeviceModelImpl)); +} + +USGDeviceModel* USGDeviceModel::NewDeviceModel( + UObject* Outer, + const FString& Id, const FString& HardwareVersion, const int32 FirmwareVersion, const int32 SubFirmwareVersion) +{ + FSGIC_FSGDeviceModelImpl OutDeviceModelImplContainer; + FSGIC_FString IdContainer{Id}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + SGCoreImpl_FSGDeviceModelImpl_ctor_Id_HardwareVersion_FirmwareVersion_SubFirmwareVersion( + &OutDeviceModelImplContainer, &IdContainer, &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion); + + return NewDeviceModel(Outer, MoveTemp(OutDeviceModelImplContainer.DeviceModelImpl)); +} + +TArray USGDeviceModel::ParseFunctions(const int32 Value, const int32 Size) +{ + FSGIC_TArray_bool OutParseFunctionsContainer; + SGCoreImpl_FSGDeviceModelImpl_ParseFunctions(&OutParseFunctionsContainer, Value, Size); + return OutParseFunctionsContainer.Array; +} + +void USGDeviceModel::ParseFirmware(const FString& RawFirmware, int32& OutMainVersion, int32& OutSubVersion) +{ + FSGIC_FString RawFirmwareContainer{RawFirmware}; + SGCoreImpl_FSGDeviceModelImpl_ParseFirmware(&RawFirmwareContainer, &OutMainVersion, &OutSubVersion); +} + +USGDeviceModel::USGDeviceModel() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGDeviceModelImpl OutDeviceModelImplContainer; + SGCoreImpl_FSGDeviceModelImpl_ctor(&OutDeviceModelImplContainer); + + Pimpl->DeviceModelImpl = MoveTemp(OutDeviceModelImplContainer.DeviceModelImpl); +} + +USGDeviceModel::USGDeviceModel(const FString& Id, const FString& HardwareVersion, + const int32 FirmwareVersion, const int32 SubFirmwareVersion) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGDeviceModelImpl OutDeviceModelImplContainer; + FSGIC_FString IdContainer{Id}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + SGCoreImpl_FSGDeviceModelImpl_ctor_Id_HardwareVersion_FirmwareVersion_SubFirmwareVersion( + &OutDeviceModelImplContainer, &IdContainer, &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion); + + Pimpl->DeviceModelImpl = MoveTemp(OutDeviceModelImplContainer.DeviceModelImpl); +} + +USGDeviceModel::USGDeviceModel(const FSGDeviceModelImpl& DeviceModelImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + SetDeviceModelImpl(DeviceModelImpl); +} + +USGDeviceModel::~USGDeviceModel() = default; + +void USGDeviceModel::SetDeviceModelImpl(const FSGDeviceModelImpl& DeviceModelImpl) +{ + FSGIC_FSGDeviceModelImpl OutDeviceModelContainer; + FSGIC_FSGDeviceModelImpl RhsContainer{DeviceModelImpl}; + SGCoreImpl_FSGDeviceModelImpl_ctor_copy(&OutDeviceModelContainer, &RhsContainer); + Pimpl->DeviceModelImpl = MoveTemp(OutDeviceModelContainer.DeviceModelImpl); +} + +const FSGDeviceModelImpl& USGDeviceModel::ToDeviceModelImpl() const +{ + return Pimpl->DeviceModelImpl; +} + +FSGDeviceModelImpl& USGDeviceModel::ToDeviceModelImpl() +{ + return Pimpl->DeviceModelImpl; +} + +FString USGDeviceModel::GetDeviceId() const +{ + FSGIC_FSGDeviceModelImpl InstanceContainer{ToDeviceModelImpl()}; + FSGIC_FString OutIdContainer; + SGCoreImpl_FSGDeviceModelImpl_GetDeviceId(&InstanceContainer, &OutIdContainer); + return OutIdContainer.String; +} + +FString USGDeviceModel::GetHardwareVersion() const +{ + FSGIC_FSGDeviceModelImpl InstanceContainer{ToDeviceModelImpl()}; + FSGIC_FString OutVersionContainer; + SGCoreImpl_FSGDeviceModelImpl_GetHardwareVersion(&InstanceContainer, &OutVersionContainer); + return OutVersionContainer.String; +} + +int32 USGDeviceModel::GetFirmwareVersion() const +{ + FSGIC_FSGDeviceModelImpl InstanceContainer{ToDeviceModelImpl()}; + return SGCoreImpl_FSGDeviceModelImpl_GetFirmwareVersion(&InstanceContainer); +} + +int32 USGDeviceModel::GetSubFirmwareVersion() const +{ + FSGIC_FSGDeviceModelImpl InstanceContainer{ToDeviceModelImpl()}; + return SGCoreImpl_FSGDeviceModelImpl_GetSubFirmwareVersion(&InstanceContainer); +} + +bool USGDeviceModel::FirmwareNewerThan(const int32 FirmwareMain, const int32 FirmwareSub, + const bool bInclusive) const +{ + FSGIC_FSGDeviceModelImpl InstanceContainer{ToDeviceModelImpl()}; + return SGCoreImpl_FSGDeviceModelImpl_FirmwareNewerThan( + &InstanceContainer, FirmwareMain, FirmwareSub, bInclusive); +} + +bool USGDeviceModel::FirmwareOlderThan(const int32 FirmwareMain, const int32 FirmwareSub, + const bool bInclusive) const +{ + FSGIC_FSGDeviceModelImpl InstanceContainer{ToDeviceModelImpl()}; + return SGCoreImpl_FSGDeviceModelImpl_FirmwareOlderThan( + &InstanceContainer, FirmwareMain, FirmwareSub, bInclusive); +} + +USGDeviceModel::FImpl::FImpl(USGDeviceModel* InOwner) + : Owner(InOwner) +{ +} + +USGDeviceModel::FImpl::~FImpl() = default; + +void USGDeviceModel::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGHandInterpolator.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGHandInterpolator.cpp new file mode 100644 index 0000000..5f0bbf7 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGHandInterpolator.cpp @@ -0,0 +1,220 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGHandInterpolator.h" + +#include "SGCore/SGInterpolationSet.h" +#include "SGCoreImpl/SGInterpolationSetImpl.h" +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGCoreImpl/SGHandInterpolatorImpl.h" +#include "SGInterop/SGIC_ESGFinger.h" +#include "SGInterop/SGIC_ESGFingerMovement.h" +#include "SGInterop/SGIC_ESGThumbMovement.h" +#include "SGInterop/SGIC_FQuat.h" +#include "SGInterop/SGIC_FSGHandInterpolatorImpl.h" +#include "SGInterop/SGIC_FSGInterpolationSetImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_FVector.h" +#include "SGInterop/SGIC_TArray_FVector.h" +#include "SGInterop/SGIC_TArray_float.h" +#include "SGInterop/SGIC_TArray_TArray_float.h" +#include "SGInterop/SGIC_TArray_TArray_FSGInterpolationSetImpl.h" +#include "SGInterop/SGIC_TArray_TArray_FVector.h" +#include "SGUtils/SGArrayUtils.h" + +struct USGHandInterpolator::FImpl +{ + /************************ + * Member variables + ************************/ + + FSGHandInterpolatorImpl HandInterpolatorImpl; + + /************************ + * Owner object + ************************/ + + USGHandInterpolator* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGHandInterpolator* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGHandInterpolator* USGHandInterpolator::NewHandInterpolator( + UObject* Outer, const FSGHandInterpolatorImpl& HandInterpolatorImpl) +{ + USGHandInterpolator* Instance = NewObject(Outer); + Instance->SetHandInterpolatorImpl(HandInterpolatorImpl); + return Instance; +} + +USGHandInterpolator* USGHandInterpolator::NewHandInterpolator(UObject* Outer) +{ + FSGIC_FSGHandInterpolatorImpl OutHandInterpolatorImplContainer; + SGCoreImpl_FSGHandInterpolatorImpl_ctor(&OutHandInterpolatorImplContainer); + + return NewHandInterpolator(Outer, MoveTemp(OutHandInterpolatorImplContainer.HandInterpolatorImpl)); +} + +USGHandInterpolator* USGHandInterpolator::NewHandInterpolator(UObject* Outer, const bool bRightHanded) +{ + FSGIC_FSGHandInterpolatorImpl OutHandInterpolatorImplContainer; + SGCoreImpl_FSGHandInterpolatorImpl_ctor_bRightHanded(&OutHandInterpolatorImplContainer, + bRightHanded); + + return NewHandInterpolator(Outer, MoveTemp(OutHandInterpolatorImplContainer.HandInterpolatorImpl)); +} + +USGHandInterpolator* USGHandInterpolator::Deserialize(UObject* Outer, + const FString& SerializedString, const bool bRightHanded) +{ + FSGIC_FSGHandInterpolatorImpl OutHandInterpolatorImplContainer; + FSGIC_FString SerializedStringContainer{SerializedString}; + SGCoreImpl_FSGHandInterpolatorImpl_Deserialize(&OutHandInterpolatorImplContainer, + &SerializedStringContainer, bRightHanded); + + return NewHandInterpolator(Outer, MoveTemp(OutHandInterpolatorImplContainer.HandInterpolatorImpl)); +} + +USGHandInterpolator::USGHandInterpolator() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGHandInterpolatorImpl OutHandInterpolatorImplContainer; + SGCoreImpl_FSGHandInterpolatorImpl_ctor(&OutHandInterpolatorImplContainer); + + Pimpl->HandInterpolatorImpl = MoveTemp(OutHandInterpolatorImplContainer.HandInterpolatorImpl); +} + +USGHandInterpolator::USGHandInterpolator(const bool bRightHanded) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGHandInterpolatorImpl OutHandInterpolatorImplContainer; + SGCoreImpl_FSGHandInterpolatorImpl_ctor_bRightHanded(&OutHandInterpolatorImplContainer, + bRightHanded); + + Pimpl->HandInterpolatorImpl = MoveTemp(OutHandInterpolatorImplContainer.HandInterpolatorImpl); +} + +USGHandInterpolator::USGHandInterpolator(const FSGHandInterpolatorImpl& HandInterpolatorImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + SetHandInterpolatorImpl(HandInterpolatorImpl); +} + +USGHandInterpolator::~USGHandInterpolator() = default; + +void USGHandInterpolator::SetHandInterpolatorImpl(const FSGHandInterpolatorImpl& HandInterpolatorImpl) +{ + FSGIC_FSGHandInterpolatorImpl OutHandInterpolatorContainer; + FSGIC_FSGHandInterpolatorImpl RhsContainer{HandInterpolatorImpl}; + SGCoreImpl_FSGHandInterpolatorImpl_ctor_copy(&OutHandInterpolatorContainer, &RhsContainer); + Pimpl->HandInterpolatorImpl = MoveTemp(OutHandInterpolatorContainer.HandInterpolatorImpl); +} + +const FSGHandInterpolatorImpl& USGHandInterpolator::ToHandInterpolatorImpl() const +{ + return Pimpl->HandInterpolatorImpl; +} + +float USGHandInterpolator::CalculateAngle( + const ESGFingerMovement Movement, const float Value, const bool bApplyLimits) const +{ + FSGIC_FSGHandInterpolatorImpl InstanceContainer{ToHandInterpolatorImpl()}; + FSGIC_ESGFingerMovement MovementContainer{Movement}; + const float Angle = SGCoreImpl_FSGHandInterpolatorImpl_CalculateAngle_ESGFingerMovement_Value_bApplyLimits( + &InstanceContainer, &MovementContainer, Value, bApplyLimits); + return Angle; +} + +float USGHandInterpolator::CalculateAngle( + const ESGThumbMovement Movement, const float Value, const bool bApplyLimits) const +{ + FSGIC_FSGHandInterpolatorImpl InstanceContainer{ToHandInterpolatorImpl()}; + FSGIC_ESGThumbMovement MovementContainer{Movement}; + const float Angle = SGCoreImpl_FSGHandInterpolatorImpl_CalculateAngle_ESGThumbMovement_Value_bApplyLimits( + &InstanceContainer, &MovementContainer, Value, bApplyLimits); + return Angle; +} + +TArray> USGHandInterpolator::InterpolateHandAngles( + const TArray>& Flexions, const TArray& Abductions, const float CmcTwist) const +{ + FSGIC_FSGHandInterpolatorImpl InstanceContainer{ToHandInterpolatorImpl()}; + FSGIC_TArray_TArray_FVector OutAnglesContainer; + FSGIC_TArray_TArray_float FlexionsContainer{Flexions}; + FSGIC_TArray_float AbductionsContainer{Abductions}; + SGCoreImpl_FSGHandInterpolatorImpl_InterpolateHandAngles( + &InstanceContainer, &OutAnglesContainer, &FlexionsContainer, &AbductionsContainer, CmcTwist); + return OutAnglesContainer.Array; +} + +bool USGHandInterpolator::Equals(const USGHandInterpolator* HandInterpolator) const +{ + FSGIC_FSGHandInterpolatorImpl InstanceContainer{ToHandInterpolatorImpl()}; + FSGIC_FSGHandInterpolatorImpl HandInterpolatorContainer{HandInterpolator->ToHandInterpolatorImpl()}; + const bool bEquals = SGCoreImpl_FSGHandInterpolatorImpl_Equals(&InstanceContainer, &HandInterpolatorContainer); + return bEquals; +} + +FString USGHandInterpolator::SGSerialize() const +{ + FSGIC_FSGHandInterpolatorImpl InstanceContainer{ToHandInterpolatorImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGHandInterpolatorImpl_Serialize(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +USGHandInterpolator::FImpl::FImpl(USGHandInterpolator* InOwner) + : Owner(InOwner) +{ +} + +USGHandInterpolator::FImpl::~FImpl() = default; + +void USGHandInterpolator::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGHandLayer.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGHandLayer.cpp new file mode 100644 index 0000000..7c06b49 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGHandLayer.cpp @@ -0,0 +1,222 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGHandLayer.h" + +#include "SGCore/SGCustomWaveform.h" +#include "SGCore/SGHandPose.h" +#include "SGCore/SGHapticGlove.h" +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_ESGDeviceType.h" +#include "SGInterop/SGIC_ESGHapticGloveCalibrationState.h" +#include "SGInterop/SGIC_ESGHapticLocation.h" +#include "SGInterop/SGIC_ESGPositionalTrackingHardware.h" +#include "SGInterop/SGIC_FQuat.h" +#include "SGInterop/SGIC_FSGCustomWaveformImpl.h" +#include "SGInterop/SGIC_FSGHandPoseImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_FVector.h" +#include "SGInterop/SGIC_TArray_float.h" +#include "SGInterop/SGIC_TSharedPtr_FSGHapticGloveImpl.h" + +bool FSGHandLayer::DeviceConnected(const bool bRightHanded) +{ + return SGCoreImpl_FSGHandLayerImpl_DeviceConnected(bRightHanded); +} + +ESGDeviceType FSGHandLayer::GetDeviceType(const bool bRightHanded) +{ + FSGIC_ESGDeviceType DeviceTypeContainer; + SGCoreImpl_FSGHandLayerImpl_GetDeviceType(&DeviceTypeContainer, bRightHanded); + return DeviceTypeContainer.Type; +} + +bool FSGHandLayer::GetFirstGloveHandedness() +{ + return SGCoreImpl_FSGHandLayerImpl_GetFirstGloveHandedness(); +} + +int32 FSGHandLayer::GlovesConnected() +{ + return SGCoreImpl_FSGHandLayerImpl_GlovesConnected(); +} + +bool FSGHandLayer::GetGloveInstance(UObject* Outer, const bool bRightHanded, USGHapticGlove*& OutGlove) +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl OutGloveContainer; + const bool bResult = SGCoreImpl_FSGHandLayerImpl_GetGloveInstance(bRightHanded, &OutGloveContainer); + OutGlove = USGHapticGlove::NewHapticGlove(Outer, OutGloveContainer.Ptr.ToSharedRef()); + return bResult; +} + +ESGHapticGloveCalibrationState FSGHandLayer::GetCalibrationState(const bool bRightHanded) +{ + FSGIC_ESGHapticGloveCalibrationState HapticGloveCalibrationStateContainer; + SGCoreImpl_FSGHandLayerImpl_GetDeviceType(&HapticGloveCalibrationStateContainer, bRightHanded); + return HapticGloveCalibrationStateContainer.State; +} + +FString FSGHandLayer::GetCalibrationInstructions(const bool bRightHanded) +{ + FSGIC_FString CalibrationInstructionsContainer; + SGCoreImpl_FSGHandLayerImpl_GetCalibrationInstructions(&CalibrationInstructionsContainer, bRightHanded); + return CalibrationInstructionsContainer.String; +} + +void FSGHandLayer::ResetCalibration(const bool bRightHanded) +{ + SGCoreImpl_FSGHandLayerImpl_ResetCalibration(bRightHanded); +} + +void FSGHandLayer::EndCalibration(const bool bRightHanded) +{ + SGCoreImpl_FSGHandLayerImpl_EndCalibration(bRightHanded); +} + +bool FSGHandLayer::GetHandPose(UObject* Outer, const bool bRightHanded, USGHandPose*& OutHandPose) +{ + FSGIC_FSGHandPoseImpl OutHandPoseContainer; + const bool bResult = SGCoreImpl_FSGHandLayerImpl_GetHandPose(bRightHanded, &OutHandPoseContainer); + OutHandPose = USGHandPose::NewHandPose(Outer, OutHandPose->ToHandPoseImpl()); + return bResult; +} + +void FSGHandLayer::GetWristLocation( + const bool bRightHanded, const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, FVector& OutWristPosition, FQuat& OutWristRotation) +{ + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutWristPositionContainer; + FSGIC_FQuat OutWristRotationContainer; + + SGCoreImpl_FSGHandLayerImpl_GetWristLocation( + bRightHanded, &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &OutWristPositionContainer, &OutWristRotationContainer); + + OutWristPosition = MoveTemp(OutWristPositionContainer.Vector); + OutWristRotation = MoveTemp(OutWristRotationContainer.Quat); +} + +void FSGHandLayer::StopAllHaptics(const bool bRightHanded) +{ + SGCoreImpl_FSGHandLayerImpl_StopAllHaptics(bRightHanded); +} + +bool FSGHandLayer::SendHaptics(const bool bRightHanded) +{ + return SGCoreImpl_FSGHandLayerImpl_SendHaptics(bRightHanded); +} + +bool FSGHandLayer::SupportsCustomWaveform( + const bool bRightHanded, const ESGHapticLocation AtLocation) +{ + FSGIC_ESGHapticLocation AtLocationContainer{AtLocation}; + return SGCoreImpl_FSGHandLayerImpl_SupportsCustomWaveform(bRightHanded, &AtLocationContainer); +} + +bool FSGHandLayer::SendCustomWaveform( + const bool bRightHanded, USGCustomWaveform* OutWaveform, const ESGHapticLocation Location) +{ + FSGIC_FSGCustomWaveformImpl OutWaveformContainer{OutWaveform->ToCustomWaveformImpl()}; + FSGIC_ESGHapticLocation LocationContainer{Location}; + return SGCoreImpl_FSGHandLayerImpl_SendCustomWaveform(bRightHanded, &OutWaveformContainer, &LocationContainer); +} + +bool FSGHandLayer::QueueCommand_ForceFeedbackLevel( + const bool bRightHanded, const int32 Finger, const float Level01, const bool bSendImmediate) +{ + return SGCoreImpl_FSGHandLayerImpl_QueueCommand_ForceFeedbackLevel(bRightHanded, Finger, Level01, bSendImmediate); +} + +bool FSGHandLayer::QueueCommand_ForceFeedbackLevels( + const bool bRightHanded, const TArray& Levels01, const bool bSendImmediate) +{ + FSGIC_TArray_float Levels01Container{Levels01}; + return SGCoreImpl_FSGHandLayerImpl_QueueCommand_ForceFeedbackLevels( + bRightHanded, &Levels01Container, bSendImmediate); +} + +bool FSGHandLayer::QueueCommand_VibroLevels( + const bool bRightHanded, const TArray& Levels01, const bool bSendImmediate) +{ + FSGIC_TArray_float Levels01Container{Levels01}; + return SGCoreImpl_FSGHandLayerImpl_QueueCommand_VibroLevels(bRightHanded, &Levels01Container, bSendImmediate); +} + +bool FSGHandLayer::QueueCommand_VibroLevel( + const bool bRightHanded, const int32 Finger, const float Level01, const bool bSendImmediate) +{ + return SGCoreImpl_FSGHandLayerImpl_QueueCommand_VibroLevel_bRightHanded_Finger_Level0_bSendImmediate( + bRightHanded, Finger, Level01, bSendImmediate); +} + +bool FSGHandLayer::QueueCommand_VibroLevel( + const bool bRightHanded, const ESGHapticLocation AtLocation, const float Level01, const bool bSendImmediate) +{ + FSGIC_ESGHapticLocation AtLocationContainer{AtLocation}; + return SGCoreImpl_FSGHandLayerImpl_QueueCommand_VibroLevel_bRightHanded_AtLocation_Level01_bSendImmediate( + bRightHanded, &AtLocationContainer, Level01, bSendImmediate); +} + +bool FSGHandLayer::SupportsWristSqueeze(const bool bRightHanded) +{ + return SGCoreImpl_FSGHandLayerImpl_SupportsWristSqueeze(bRightHanded); +} + +bool FSGHandLayer::QueueCommand_WristSqueeze( + const bool bRightHanded, const float SqueezeLevel01, const bool bSendImmediate) +{ + return SGCoreImpl_FSGHandLayerImpl_QueueCommand_WristSqueeze(bRightHanded, SqueezeLevel01, bSendImmediate); +} + +bool FSGHandLayer::SupportsFlexionLocks(const bool bRightHanded) +{ + return SGCoreImpl_FSGHandLayerImpl_SupportsFlexionLocks(bRightHanded); +} + +bool FSGHandLayer::QueueCommand_FlexionLock( + const bool bRightHanded, const int32 Finger, const float Flexion01, const bool bSendImmediate) +{ + return SGCoreImpl_FSGHandLayerImpl_QueueCommand_FlexionLock(bRightHanded, Finger, Flexion01, bSendImmediate); +} + +bool FSGHandLayer::QueueCommand_ClearFlexionLock( + const bool bRightHanded, const int32 Finger, const bool bSendImmediate) +{ + return SGCoreImpl_FSGHandLayerImpl_QueueCommand_ClearFlexionLock(bRightHanded, Finger, bSendImmediate); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGHandPose.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGHandPose.cpp new file mode 100644 index 0000000..3d29229 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGHandPose.cpp @@ -0,0 +1,471 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGHandPose.h" + +#include "SGCore/SGBasicHandModel.h" +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGCoreImpl/SGHandPoseImpl.h" +#include "SGInterop/SGIC_ESGFinger.h" +#include "SGInterop/SGIC_FSGBasicHandModelImpl.h" +#include "SGInterop/SGIC_FSGHandPoseImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_TArray_float.h" +#include "SGInterop/SGIC_TArray_TArray_FQuat.h" +#include "SGInterop/SGIC_TArray_TArray_FVector.h" +#include "SGTypes/SGRotatorArray.h" +#include "SGUtils/SGArrayUtils.h" + +struct USGHandPose::FImpl +{ + /************************ + * Member variables + ************************/ + + FSGHandPoseImpl HandPoseImpl; + + /************************ + * Owner object + ************************/ + + USGHandPose* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGHandPose* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGHandPose* USGHandPose::NewHandPose(UObject* Outer, const FSGHandPoseImpl& HandPoseImpl) +{ + USGHandPose* Instance = NewObject(Outer); + Instance->SetHandPoseImpl(HandPoseImpl); + return Instance; +} + +USGHandPose* USGHandPose::NewHandPose(UObject* Outer) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + SGCoreImpl_FSGHandPoseImpl_ctor(&OutHandPoseImplContainer); + + return NewHandPose(Outer, MoveTemp(OutHandPoseImplContainer.HandPoseImpl)); +} + +USGHandPose* USGHandPose::NewHandPose( + UObject* Outer, + const bool bRightHanded, const TArray>& JointPositions, const TArray>& JointRotations, + const TArray>& HandAngles) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + FSGIC_TArray_TArray_FVector JointPositionsContainer{JointPositions}; + FSGIC_TArray_TArray_FQuat JointRotationsContainer{JointRotations}; + FSGIC_TArray_TArray_FVector HandAnglesContainer{HandAngles}; + SGCoreImpl_FSGHandPoseImpl_ctor_bRightHanded_JointPositions_JointRotations_HandAngles( + &OutHandPoseImplContainer, bRightHanded, &JointPositionsContainer, + &JointRotationsContainer, &HandAnglesContainer); + + return NewHandPose(Outer, MoveTemp(OutHandPoseImplContainer.HandPoseImpl)); +} + +USGHandPose* USGHandPose::NewHandPose( + UObject* Outer, + const bool bRightHanded, + const TArray>& JointPositions, const TArray>& JointRotations, + const TArray>& HandAngles) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + FSGIC_TArray_TArray_FVector JointPositionsContainer{JointPositions}; + FSGIC_TArray_TArray_FQuat JointRotationsContainer{FSGArrayUtils::RotatorsToQuats(JointRotations)}; + FSGIC_TArray_TArray_FVector HandAnglesContainer{HandAngles}; + SGCoreImpl_FSGHandPoseImpl_ctor_bRightHanded_JointPositions_JointRotations_HandAngles( + &OutHandPoseImplContainer, bRightHanded, &JointPositionsContainer, + &JointRotationsContainer, &HandAnglesContainer); + + return NewHandPose(Outer, MoveTemp(OutHandPoseImplContainer.HandPoseImpl)); +} + +USGHandPose* USGHandPose::NewHandPose( + UObject* Outer, + const bool bRightHanded, const TArray& JointPositions, const TArray& JointRotations, + const TArray& HandAngles) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + FSGIC_TArray_TArray_FVector JointPositionsContainer{ + FSGArrayUtils::FromNestedBPArray(JointPositions) + }; + FSGIC_TArray_TArray_FQuat JointRotationsContainer{ + FSGArrayUtils::FromNestedBPArray(JointRotations) + }; + FSGIC_TArray_TArray_FVector HandAnglesContainer{ + FSGArrayUtils::FromNestedBPArray(HandAngles) + }; + SGCoreImpl_FSGHandPoseImpl_ctor_bRightHanded_JointPositions_JointRotations_HandAngles( + &OutHandPoseImplContainer, bRightHanded, &JointPositionsContainer, + &JointRotationsContainer, &HandAnglesContainer); + + return NewHandPose(Outer, MoveTemp(OutHandPoseImplContainer.HandPoseImpl)); +} + +USGHandPose* USGHandPose::NewHandPose( + UObject* Outer, + const bool bRightHanded, + const TArray& JointPositions, const TArray& JointRotations, + const TArray& HandAngles) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + FSGIC_TArray_TArray_FVector JointPositionsContainer{ + FSGArrayUtils::FromNestedBPArray(JointPositions) + }; + FSGIC_TArray_TArray_FQuat JointRotationsContainer{ + FSGArrayUtils::RotatorsToQuats(JointRotations) + }; + FSGIC_TArray_TArray_FVector HandAnglesContainer{ + FSGArrayUtils::FromNestedBPArray(HandAngles) + }; + SGCoreImpl_FSGHandPoseImpl_ctor_bRightHanded_JointPositions_JointRotations_HandAngles( + &OutHandPoseImplContainer, bRightHanded, &JointPositionsContainer, + &JointRotationsContainer, &HandAnglesContainer); + + return NewHandPose(Outer, MoveTemp(OutHandPoseImplContainer.HandPoseImpl)); +} + +USGHandPose* USGHandPose::Deserialize(UObject* Outer, const FString& SerializedString) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + FSGIC_FString SerializedStringContainer{SerializedString}; + SGCoreImpl_FSGHandPoseImpl_Deserialize(&OutHandPoseImplContainer, &SerializedStringContainer); + + return NewHandPose(Outer, MoveTemp(OutHandPoseImplContainer.HandPoseImpl)); +} + +USGHandPose* USGHandPose::FromHandAngles(UObject* Outer, + const TArray>& HandAngles, const bool bRightHanded, + const USGBasicHandModel* HandDimensions) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + FSGIC_TArray_TArray_FVector HandAnglesContainer{HandAngles}; + FSGIC_FSGBasicHandModelImpl HandDimensionsContainer{HandDimensions->ToBasicHandModelImpl()}; + SGCoreImpl_FSGHandPoseImpl_FromHandAngles_HandAngles_bRightHanded_HandDimensions( + &OutHandPoseImplContainer, &HandAnglesContainer, bRightHanded, &HandDimensionsContainer); + + return NewHandPose(Outer, MoveTemp(OutHandPoseImplContainer.HandPoseImpl)); +} + +USGHandPose* USGHandPose::FromHandAngles(UObject* Outer, + const TArray>& HandAngles, const bool bRightHanded) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + FSGIC_TArray_TArray_FVector HandAnglesContainer{HandAngles}; + SGCoreImpl_FSGHandPoseImpl_FromHandAngles_HandAngles_bRightHanded( + &OutHandPoseImplContainer, &HandAnglesContainer, bRightHanded); + + return NewHandPose(Outer, MoveTemp(OutHandPoseImplContainer.HandPoseImpl)); +} + +USGHandPose* USGHandPose::DefaultIdle(UObject* Outer, const bool bRightHanded, const USGBasicHandModel* HandDimensions) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + FSGIC_FSGBasicHandModelImpl HandDimensionsContainer{HandDimensions->ToBasicHandModelImpl()}; + SGCoreImpl_FSGHandPoseImpl_DefaultIdle_bRightHanded_HandDimensions( + &OutHandPoseImplContainer, bRightHanded, &HandDimensionsContainer); + + return NewHandPose(Outer, MoveTemp(OutHandPoseImplContainer.HandPoseImpl)); +} + +USGHandPose* USGHandPose::DefaultIdle(UObject* Outer, const bool bRightHanded) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + SGCoreImpl_FSGHandPoseImpl_DefaultIdle_bRightHanded(&OutHandPoseImplContainer, bRightHanded); + + return NewHandPose(Outer, MoveTemp(OutHandPoseImplContainer.HandPoseImpl)); +} + +USGHandPose* USGHandPose::FlatHand(UObject* Outer, const bool bRightHanded, const USGBasicHandModel* HandDimensions) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + FSGIC_FSGBasicHandModelImpl HandDimensionsContainer{HandDimensions->ToBasicHandModelImpl()}; + SGCoreImpl_FSGHandPoseImpl_FlatHand_bRightHanded_HandDimensions( + &OutHandPoseImplContainer, bRightHanded, &HandDimensionsContainer); + + return NewHandPose(Outer, MoveTemp(OutHandPoseImplContainer.HandPoseImpl)); +} + +USGHandPose* USGHandPose::FlatHand(UObject* Outer, const bool bRightHanded) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + SGCoreImpl_FSGHandPoseImpl_FlatHand_bRightHanded(&OutHandPoseImplContainer, bRightHanded); + + return NewHandPose(Outer, MoveTemp(OutHandPoseImplContainer.HandPoseImpl)); +} + +USGHandPose* USGHandPose::ThumbsUp(UObject* Outer, const bool bRightHanded, const USGBasicHandModel* HandDimensions) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + FSGIC_FSGBasicHandModelImpl HandDimensionsContainer{HandDimensions->ToBasicHandModelImpl()}; + SGCoreImpl_FSGHandPoseImpl_ThumbsUp_bRightHanded_HandDimensions( + &OutHandPoseImplContainer, bRightHanded, &HandDimensionsContainer); + + return NewHandPose(Outer, MoveTemp(OutHandPoseImplContainer.HandPoseImpl)); +} + +USGHandPose* USGHandPose::ThumbsUp(UObject* Outer, const bool bRightHanded) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + SGCoreImpl_FSGHandPoseImpl_ThumbsUp_bRightHanded(&OutHandPoseImplContainer, bRightHanded); + + return NewHandPose(Outer, MoveTemp(OutHandPoseImplContainer.HandPoseImpl)); +} + +USGHandPose* USGHandPose::Fist(UObject* Outer, const bool bRightHanded, const USGBasicHandModel* HandDimensions) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + FSGIC_FSGBasicHandModelImpl HandDimensionsContainer{HandDimensions->ToBasicHandModelImpl()}; + SGCoreImpl_FSGHandPoseImpl_Fist_bRightHanded_HandDimensions( + &OutHandPoseImplContainer, bRightHanded, &HandDimensionsContainer); + + return NewHandPose(Outer, MoveTemp(OutHandPoseImplContainer.HandPoseImpl)); +} + +USGHandPose* USGHandPose::Fist(UObject* Outer, const bool bRightHanded) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + SGCoreImpl_FSGHandPoseImpl_Fist_bRightHanded(&OutHandPoseImplContainer, bRightHanded); + + return NewHandPose(Outer, MoveTemp(OutHandPoseImplContainer.HandPoseImpl)); +} + +USGHandPose::USGHandPose() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + SGCoreImpl_FSGHandPoseImpl_ctor(&OutHandPoseImplContainer); + + Pimpl->HandPoseImpl = MoveTemp(OutHandPoseImplContainer.HandPoseImpl); +} + +USGHandPose::USGHandPose(const bool bRightHanded, + const TArray>& JointPositions, const TArray>& JointRotations, + const TArray>& HandAngles) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + FSGIC_TArray_TArray_FVector JointPositionsContainer{JointPositions}; + FSGIC_TArray_TArray_FQuat JointRotationsContainer{JointRotations}; + FSGIC_TArray_TArray_FVector HandAnglesContainer{HandAngles}; + SGCoreImpl_FSGHandPoseImpl_ctor_bRightHanded_JointPositions_JointRotations_HandAngles( + &OutHandPoseImplContainer, bRightHanded, &JointPositionsContainer, + &JointRotationsContainer, &HandAnglesContainer); + + Pimpl->HandPoseImpl = MoveTemp(OutHandPoseImplContainer.HandPoseImpl); +} + +USGHandPose::USGHandPose(const bool bRightHanded, + const TArray>& JointPositions, const TArray>& JointRotations, + const TArray>& HandAngles) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + FSGIC_TArray_TArray_FVector JointPositionsContainer{JointPositions}; + FSGIC_TArray_TArray_FQuat JointRotationsContainer{FSGArrayUtils::RotatorsToQuats(JointRotations)}; + FSGIC_TArray_TArray_FVector HandAnglesContainer{HandAngles}; + SGCoreImpl_FSGHandPoseImpl_ctor_bRightHanded_JointPositions_JointRotations_HandAngles( + &OutHandPoseImplContainer, bRightHanded, &JointPositionsContainer, + &JointRotationsContainer, &HandAnglesContainer); + + Pimpl->HandPoseImpl = MoveTemp(OutHandPoseImplContainer.HandPoseImpl); +} + +USGHandPose::USGHandPose(const bool bRightHanded, const + TArray& JointPositions, const TArray& JointRotations, + const TArray& HandAngles) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + FSGIC_TArray_TArray_FVector JointPositionsContainer{ + FSGArrayUtils::FromNestedBPArray(JointPositions) + }; + FSGIC_TArray_TArray_FQuat JointRotationsContainer{ + FSGArrayUtils::FromNestedBPArray(JointRotations) + }; + FSGIC_TArray_TArray_FVector HandAnglesContainer{ + FSGArrayUtils::FromNestedBPArray(HandAngles) + }; + SGCoreImpl_FSGHandPoseImpl_ctor_bRightHanded_JointPositions_JointRotations_HandAngles( + &OutHandPoseImplContainer, bRightHanded, &JointPositionsContainer, + &JointRotationsContainer, &HandAnglesContainer); + + Pimpl->HandPoseImpl = MoveTemp(OutHandPoseImplContainer.HandPoseImpl); +} + +USGHandPose::USGHandPose(const bool bRightHanded, + const TArray& JointPositions, const TArray& JointRotations, + const TArray& HandAngles) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGHandPoseImpl OutHandPoseImplContainer; + FSGIC_TArray_TArray_FVector JointPositionsContainer{ + FSGArrayUtils::FromNestedBPArray(JointPositions) + }; + FSGIC_TArray_TArray_FQuat JointRotationsContainer{ + FSGArrayUtils::RotatorsToQuats(JointRotations) + }; + FSGIC_TArray_TArray_FVector HandAnglesContainer{ + FSGArrayUtils::FromNestedBPArray(HandAngles) + }; + SGCoreImpl_FSGHandPoseImpl_ctor_bRightHanded_JointPositions_JointRotations_HandAngles( + &OutHandPoseImplContainer, bRightHanded, &JointPositionsContainer, + &JointRotationsContainer, &HandAnglesContainer); + + Pimpl->HandPoseImpl = MoveTemp(OutHandPoseImplContainer.HandPoseImpl); +} + +USGHandPose::USGHandPose(const FSGHandPoseImpl& HandPoseImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + SetHandPoseImpl(HandPoseImpl); +} + +USGHandPose::~USGHandPose() = default; + +void USGHandPose::SetHandPoseImpl(const FSGHandPoseImpl& HandPoseImpl) +{ + FSGIC_FSGHandPoseImpl OutHandPoseContainer; + FSGIC_FSGHandPoseImpl RhsContainer{HandPoseImpl}; + SGCoreImpl_FSGHandPoseImpl_ctor_copy(&OutHandPoseContainer, &RhsContainer); + Pimpl->HandPoseImpl = MoveTemp(OutHandPoseContainer.HandPoseImpl); +} + +const FSGHandPoseImpl& USGHandPose::ToHandPoseImpl() const +{ + return Pimpl->HandPoseImpl; +} + +bool USGHandPose::IsRight() const +{ + FSGIC_FSGHandPoseImpl InstanceContainer{ToHandPoseImpl()}; + return SGCoreImpl_FSGHandPoseImpl_IsRight(&InstanceContainer); +} + +TArray> USGHandPose::GetJointPositions() const +{ + FSGIC_FSGHandPoseImpl InstanceContainer{ToHandPoseImpl()}; + FSGIC_TArray_TArray_FVector OutPositionsContainer; + SGCoreImpl_FSGHandPoseImpl_GetJointPositions(&InstanceContainer, &OutPositionsContainer); + return OutPositionsContainer.Array; +} + +TArray> USGHandPose::GetJointRotationsQ() const +{ + FSGIC_FSGHandPoseImpl InstanceContainer{ToHandPoseImpl()}; + FSGIC_TArray_TArray_FQuat OutRotationsContainer; + SGCoreImpl_FSGHandPoseImpl_GetJointRotations(&InstanceContainer, &OutRotationsContainer); + return OutRotationsContainer.Array; +} + +TArray> USGHandPose::GetJointRotations() const +{ + FSGIC_FSGHandPoseImpl InstanceContainer{ToHandPoseImpl()}; + FSGIC_TArray_TArray_FQuat OutRotationsContainer; + SGCoreImpl_FSGHandPoseImpl_GetJointRotations(&InstanceContainer, &OutRotationsContainer); + return FSGArrayUtils::QuatsToRotators(OutRotationsContainer.Array); +} + +TArray> USGHandPose::GetHandAngles() const +{ + FSGIC_FSGHandPoseImpl InstanceContainer{ToHandPoseImpl()}; + FSGIC_TArray_TArray_FVector OutAnglesContainer; + SGCoreImpl_FSGHandPoseImpl_GetHandAngles(&InstanceContainer, &OutAnglesContainer); + return OutAnglesContainer.Array; +} + +bool USGHandPose::Equals(const USGHandPose* HandPose) const +{ + FSGIC_FSGHandPoseImpl InstanceContainer{ToHandPoseImpl()}; + FSGIC_FSGHandPoseImpl HandPoseContainer{HandPose->ToHandPoseImpl()}; + return SGCoreImpl_FSGHandPoseImpl_Equals(&InstanceContainer, &HandPoseContainer); +} + +float USGHandPose::GetNormalizedFlexion(const ESGFinger Finger, const bool bClamp01) const +{ + FSGIC_FSGHandPoseImpl InstanceContainer{ToHandPoseImpl()}; + FSGIC_ESGFinger FingerContainer{Finger}; + return SGCoreImpl_FSGHandPoseImpl_GetNormalizedFlexion_Finger_bClamp01( + &InstanceContainer, &FingerContainer, bClamp01); +} + +TArray USGHandPose::GetNormalizedFlexion(const bool bClamp01) const +{ + FSGIC_FSGHandPoseImpl InstanceContainer{ToHandPoseImpl()}; + FSGIC_TArray_float OutFlexionContainer; + SGCoreImpl_FSGHandPoseImpl_GetNormalizedFlexion_bClamp01(&InstanceContainer, &OutFlexionContainer, bClamp01); + return OutFlexionContainer.Array; +} + +FString USGHandPose::ToString(const bool bShortFormat) const +{ + FSGIC_FSGHandPoseImpl InstanceContainer{ToHandPoseImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGHandPoseImpl_ToString(&InstanceContainer, &OutStringContainer, bShortFormat); + return OutStringContainer.String; +} + +FString USGHandPose::SGSerialize() const +{ + FSGIC_FSGHandPoseImpl InstanceContainer{ToHandPoseImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGHandPoseImpl_Serialize(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +USGHandPose::FImpl::FImpl(USGHandPose* InOwner) + : Owner(InOwner) +{ +} + +USGHandPose::FImpl::~FImpl() = default; + +void USGHandPose::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGHapticChannelInfo.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGHapticChannelInfo.cpp new file mode 100644 index 0000000..3607601 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGHapticChannelInfo.cpp @@ -0,0 +1,236 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGHapticChannelInfo.h" + +#include "SGCoreImpl/SGHapticChannelInfoImpl.h" +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_ESGHapticChannelType.h" +#include "SGInterop/SGIC_ESGWaveformType.h" +#include "SGInterop/SGIC_FSGHapticChannelInfoImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_TArray_FString.h" +#include "SGInterop/SGIC_TArray_int32.h" + +struct USGHapticChannelInfo::FImpl +{ + /************************ + * Member variables + ************************/ + + FSGHapticChannelInfoImpl HapticChannelInfoImpl; + + /************************ + * Owner object + ************************/ + + USGHapticChannelInfo* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGHapticChannelInfo* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGHapticChannelInfo* USGHapticChannelInfo::NewHapticChannelInfo(UObject* Outer, + const FSGHapticChannelInfoImpl& HapticChannelInfoImpl) +{ + USGHapticChannelInfo* Instance = NewObject(Outer); + Instance->SetHapticChannelInfoImpl(HapticChannelInfoImpl); + return Instance; +} + +USGHapticChannelInfo* USGHapticChannelInfo::NewHapticChannelInfo(UObject* Outer) +{ + FSGIC_FSGHapticChannelInfoImpl OutHapticChannelInfoImplContainer; + SGCoreImpl_FSGHapticChannelInfoImpl_ctor(&OutHapticChannelInfoImplContainer); + + return NewHapticChannelInfo(Outer, MoveTemp(OutHapticChannelInfoImplContainer.HapticChannelInfoImpl)); +} + +USGHapticChannelInfo* USGHapticChannelInfo::NewHapticChannelInfo( + UObject* Outer, + const TArray& StreamIndex, const TArray& FireAndForgetIndex) +{ + FSGIC_FSGHapticChannelInfoImpl OutHapticChannelInfoImplContainer; + FSGIC_TArray_int32 StreamIndexContainer{StreamIndex}; + FSGIC_TArray_int32 FireAndForgetContainer{FireAndForgetIndex}; + SGCoreImpl_FSGHapticChannelInfoImpl_ctor_StreamIndex_FireAndForgetIndex( + &OutHapticChannelInfoImplContainer, &StreamIndexContainer, &FireAndForgetContainer); + + return NewHapticChannelInfo(Outer, MoveTemp(OutHapticChannelInfoImplContainer.HapticChannelInfoImpl)); +} + +FString USGHapticChannelInfo::GenerateAddress(const int32 DeviceIndex, const int32 ChannelIndex) +{ + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGHapticChannelInfoImpl_GenerateAddress(&OutStringContainer, DeviceIndex, ChannelIndex); + return OutStringContainer.String; +} + +USGHapticChannelInfo* USGHapticChannelInfo::Parse(UObject* Outer, const FString& IpcString) +{ + FSGIC_FSGHapticChannelInfoImpl OutHapticChannelInfoImplContainer; + FSGIC_FString IpcStringContainer{IpcString}; + SGCoreImpl_FSGHapticChannelInfoImpl_Parse(&OutHapticChannelInfoImplContainer, &IpcStringContainer); + + return NewHapticChannelInfo(Outer, MoveTemp(OutHapticChannelInfoImplContainer.HapticChannelInfoImpl)); +} + +int32 USGHapticChannelInfo::GetStreamingType() +{ + return SGCoreImpl_FSGHapticChannelInfoImpl_GetStreamingType(); +} + +int32 USGHapticChannelInfo::GetFireAndForgetType() +{ + return SGCoreImpl_FSGHapticChannelInfoImpl_GetFireAndForgetType(); +} + +USGHapticChannelInfo::USGHapticChannelInfo() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGHapticChannelInfoImpl OutHapticChannelInfoImplContainer; + SGCoreImpl_FSGHapticChannelInfoImpl_ctor(&OutHapticChannelInfoImplContainer); + + Pimpl->HapticChannelInfoImpl = MoveTemp(OutHapticChannelInfoImplContainer.HapticChannelInfoImpl); +} + +USGHapticChannelInfo::USGHapticChannelInfo(const TArray& StreamIndex, const TArray& FireAndForgetIndex) +{ + FSGIC_FSGHapticChannelInfoImpl OutHapticChannelInfoImplContainer; + FSGIC_TArray_int32 StreamIndexContainer{StreamIndex}; + FSGIC_TArray_int32 FireAndForgetContainer{FireAndForgetIndex}; + SGCoreImpl_FSGHapticChannelInfoImpl_ctor_StreamIndex_FireAndForgetIndex( + &OutHapticChannelInfoImplContainer, &StreamIndexContainer, &FireAndForgetContainer); + + Pimpl->HapticChannelInfoImpl = MoveTemp(OutHapticChannelInfoImplContainer.HapticChannelInfoImpl); +} + +USGHapticChannelInfo::USGHapticChannelInfo(const FSGHapticChannelInfoImpl& HapticChannelInfoImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + SetHapticChannelInfoImpl(HapticChannelInfoImpl); +} + +USGHapticChannelInfo::~USGHapticChannelInfo() = default; + +void USGHapticChannelInfo::SetHapticChannelInfoImpl(const FSGHapticChannelInfoImpl& HapticChannelInfoImpl) +{ + FSGIC_FSGHapticChannelInfoImpl OutHapticChannelInfoContainer; + FSGIC_FSGHapticChannelInfoImpl RhsContainer{HapticChannelInfoImpl}; + SGCoreImpl_FSGHapticChannelInfoImpl_ctor_copy(&OutHapticChannelInfoContainer, &RhsContainer); + Pimpl->HapticChannelInfoImpl = MoveTemp(OutHapticChannelInfoContainer.HapticChannelInfoImpl); +} + +const FSGHapticChannelInfoImpl& USGHapticChannelInfo::ToHapticChannelInfoImpl() const +{ + return Pimpl->HapticChannelInfoImpl; +} + +int32 USGHapticChannelInfo::GetStreamChannelCount() const +{ + FSGIC_FSGHapticChannelInfoImpl InstanceContainer{ToHapticChannelInfoImpl()}; + return SGCoreImpl_FSGHapticChannelInfoImpl_GetStreamChannelCount(&InstanceContainer); +} + +int32 USGHapticChannelInfo::GetFireAndForgetChannelCount() const +{ + FSGIC_FSGHapticChannelInfoImpl InstanceContainer{ToHapticChannelInfoImpl()}; + return SGCoreImpl_FSGHapticChannelInfoImpl_GetFireAndForgetChannelCount(&InstanceContainer); +} + +int32 USGHapticChannelInfo::GetTotalChannelCount() const +{ + FSGIC_FSGHapticChannelInfoImpl InstanceContainer{ToHapticChannelInfoImpl()}; + return SGCoreImpl_FSGHapticChannelInfoImpl_GetTotalChannelCount(&InstanceContainer); +} + +FString USGHapticChannelInfo::GetAddress_Unguarded(const ESGHapticChannelType Type, const int32 TypeIndex) const +{ + FSGIC_FSGHapticChannelInfoImpl InstanceContainer{ToHapticChannelInfoImpl()}; + FSGIC_FString OutStringContainer; + FSGIC_ESGHapticChannelType TypeContainer{Type}; + SGCoreImpl_FSGHapticChannelInfoImpl_GetAddress_Unguarded( + &InstanceContainer, &OutStringContainer, &TypeContainer, TypeIndex); + return OutStringContainer.String; +} + +void USGHapticChannelInfo::GetIpcParams_Unguarded( + const ESGHapticChannelType Type, const int32 TypeIndex, int32& OutIndex, FString& OutAddressString) const +{ + FSGIC_FSGHapticChannelInfoImpl InstanceContainer{ToHapticChannelInfoImpl()}; + FSGIC_ESGHapticChannelType TypeContainer{Type}; + FSGIC_FString OutAddressStringContainer; + SGCoreImpl_FSGHapticChannelInfoImpl_GetIpcParams_Unguarded( + &InstanceContainer, &TypeContainer, TypeIndex, &OutIndex, &OutAddressString); + + OutAddressString = MoveTemp(OutAddressStringContainer.String); +} + +void USGHapticChannelInfo::RegenerateAddresses(const int32 ForDeviceIndex) +{ + FSGIC_FSGHapticChannelInfoImpl InstanceContainer{ToHapticChannelInfoImpl()}; + SGCoreImpl_FSGHapticChannelInfoImpl_RegenerateAddresses(&InstanceContainer, ForDeviceIndex); +} + +TArray USGHapticChannelInfo::GetAllAddresses() const +{ + FSGIC_FSGHapticChannelInfoImpl InstanceContainer{ToHapticChannelInfoImpl()}; + FSGIC_TArray_FString* OutArrayContainer; + SGCoreImpl_FSGHapticChannelInfoImpl_GetAllAddresses(&InstanceContainer, &OutArrayContainer); + return OutArrayContainer->Array; +} + +USGHapticChannelInfo::FImpl::FImpl(USGHapticChannelInfo* InOwner) + : Owner(InOwner) +{ +} + +USGHapticChannelInfo::FImpl::~FImpl() = default; + +void USGHapticChannelInfo::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGHapticGlove.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGHapticGlove.cpp new file mode 100644 index 0000000..0ea57fc --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGHapticGlove.cpp @@ -0,0 +1,515 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGHapticGlove.h" + +#include "SGCore/SGBasicHandModel.h" +#include "SGCore/SGCustomWaveform.h" +#include "SGCore/SGDeviceImplCast.h" +#include "SGCore/SGSenseGlove.h" +#include "SGCoreImpl/SGBasicHandModelImpl.h" +#include "SGCoreImpl/SGCustomWaveformImpl.h" +#include "SGCoreImpl/SGDeviceImpl.h" +#include "SGCoreImpl/SGHapticGloveImpl.h" +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_ESGDeviceType.h" +#include "SGInterop/SGIC_ESGHapticGloveCalibrationState.h" +#include "SGInterop/SGIC_ESGHapticLocation.h" +#include "SGInterop/SGIC_ESGPositionalTrackingHardware.h" +#include "SGInterop/SGIC_FQuat.h" +#include "SGInterop/SGIC_FSGBasicHandModelImpl.h" +#include "SGInterop/SGIC_FSGCustomWaveformImpl.h" +#include "SGInterop/SGIC_FSGHandPoseImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_FVector.h" +#include "SGInterop/SGIC_TArray_FVector.h" +#include "SGInterop/SGIC_TArray_TArray_FVector.h" +#include "SGInterop/SGIC_TArray_TSharedRef_FSGHapticGloveImpl.h" +#include "SGInterop/SGIC_TArray_float.h" +#include "SGInterop/SGIC_TSharedPtr_FSGHapticGloveImpl.h" + +USGHapticGlove* USGHapticGlove::NewHapticGlove(UObject* Outer, const FSGHapticGloveImpl& HapticGloveImpl) +{ + USGHapticGlove* Instance = NewObject(Outer); + Instance->SetSGDeviceImpl(HapticGloveImpl); + return Instance; +} + +USGHapticGlove* USGHapticGlove::NewHapticGlove(UObject* Outer, TSharedRef HapticGloveImpl) +{ + USGHapticGlove* Instance = NewObject(Outer); + Instance->SetSGDeviceImpl(MoveTemp(HapticGloveImpl)); + return Instance; +} + +USGHapticGlove* USGHapticGlove::NewHapticGlove(UObject* Outer) +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl OutSharedPtrContainer; + SGCoreImpl_FSGBetaDeviceImpl_ctor_MakeShared(&OutSharedPtrContainer); + + return NewHapticGlove(Outer, OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +TArray USGHapticGlove::GetHapticGloves(UObject* Outer, const bool bConnectedOnly) +{ + FSGIC_TArray_TSharedRef_FSGHapticGloveImpl OutGlovesContainer; + SGCoreImpl_FSGHapticGloveImpl_GetHapticGloves(&OutGlovesContainer, bConnectedOnly); + TArray HapticGloves; + for (TSharedRef HapticGloveImpl: OutGlovesContainer.Array) + { + HapticGloves.Add(NewHapticGlove(Outer, MoveTemp(HapticGloveImpl))); + } + return HapticGloves; +} + +bool USGHapticGlove::GetGlove(UObject* Outer, USGHapticGlove*& OutGlove) +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl OutGloveContainer; + const bool bResult = SGCoreImpl_FSGHapticGloveImpl_GetGlove_OutGlove(&OutGloveContainer); + + if (bResult) + { + OutGlove = NewHapticGlove(Outer, OutGloveContainer.Ptr.ToSharedRef()); + } + + return bResult; +} + +bool USGHapticGlove::GetGlove(UObject* Outer, const bool bRightHanded, USGHapticGlove*& OutGlove) +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl OutGloveContainer; + + const bool bResult = SGCoreImpl_FSGHapticGloveImpl_GetGlove_bRightHanded_OutGlove( + bRightHanded, &OutGloveContainer); + if (bResult) + { + OutGlove = NewHapticGlove(Outer, OutGloveContainer.Ptr.ToSharedRef()); + } + + return bResult; +} + +FString USGHapticGlove::ToString(const ESGHapticGloveCalibrationState State) +{ + FSGIC_ESGHapticGloveCalibrationState StateContainer{State}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGHapticGloveImpl_ToString_State(&StateContainer, &OutStringContainer); + return OutStringContainer.String; +} + +FString USGHapticGlove::ToString(const ESGHapticLocation Location) +{ + FSGIC_ESGHapticLocation LocationContainer{Location}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGHapticGloveImpl_ToString_Location(&LocationContainer, &OutStringContainer); + return OutStringContainer.String; +} + +USGHapticGlove::USGHapticGlove() + : USGDevice() +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl OutSharedPtrContainer; + SGCoreImpl_FSGBetaDeviceImpl_ctor_MakeShared(&OutSharedPtrContainer); + + SetSGDeviceImpl(OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +USGHapticGlove::USGHapticGlove(const FSGDeviceImpl& SGDeviceImpl) + : USGDevice(SGDeviceImpl) +{ +} + +USGHapticGlove::USGHapticGlove(const FSGHapticGloveImpl& HapticGloveImpl) + : USGDevice(HapticGloveImpl) +{ +} + +USGHapticGlove::USGHapticGlove(const FSGNova2GloveImpl& Nova2GloveImpl) + : USGDevice(Nova2GloveImpl) +{ +} + +USGHapticGlove::USGHapticGlove(const FSGNovaGloveImpl& NovaGloveImpl) + : USGDevice(NovaGloveImpl) +{ +} + +USGHapticGlove::USGHapticGlove(const FSGSenseGloveImpl& SenseGloveImpl) + : USGDevice(SenseGloveImpl) +{ +} + +USGHapticGlove::USGHapticGlove(TSharedRef SGDeviceImpl) + : USGDevice(MoveTemp(SGDeviceImpl)) +{ +} + +USGHapticGlove::USGHapticGlove(TSharedRef HapticGloveImpl) + : USGDevice(MoveTemp(HapticGloveImpl)) +{ +} + +USGHapticGlove::USGHapticGlove(TSharedRef Nova2GloveImpl) + : USGDevice(MoveTemp(Nova2GloveImpl)) +{ +} + +USGHapticGlove::USGHapticGlove(TSharedRef NovaGloveImpl) + : USGDevice(MoveTemp(NovaGloveImpl)) +{ +} + +USGHapticGlove::USGHapticGlove(TSharedRef SenseGloveImpl) + : USGDevice(MoveTemp(SenseGloveImpl)) +{ +} + +USGHapticGlove::~USGHapticGlove() = default; + +TSharedRef USGHapticGlove::ToHapticGloveImpl() const +{ + return FSGDeviceImplCast::ToHapticGloveImpl(ToSGDeviceImpl()); +} + +ESGDeviceType USGHapticGlove::GetDeviceType() const +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_ESGDeviceType OutTypeContainer; + SGCoreImpl_FSGHapticGloveImpl_GetDeviceType(&InstanceContainer, &OutTypeContainer); + return OutTypeContainer.Type; +} + +FString USGHapticGlove::GetDeviceId() const +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_FString OutIdContainer; + SGCoreImpl_FSGHapticGloveImpl_GetDeviceId(&InstanceContainer, &OutIdContainer); + return OutIdContainer.String; +} + +FString USGHapticGlove::GetHardwareVersion() const +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_FString OutVersionContainer; + SGCoreImpl_FSGHapticGloveImpl_GetHardwareVersion(&InstanceContainer, &OutVersionContainer); + return OutVersionContainer.String; +} + +int32 USGHapticGlove::GetFirmwareVersion() const +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + return SGCoreImpl_FSGHapticGloveImpl_GetFirmwareVersion(&InstanceContainer); +} + +int32 USGHapticGlove::GetSubFirmwareVersion() const +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + return SGCoreImpl_FSGHapticGloveImpl_GetSubFirmwareVersion(&InstanceContainer); +} + +bool USGHapticGlove::IsRight() const +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + return SGCoreImpl_FSGHapticGloveImpl_IsRight(&InstanceContainer); +} + +bool USGHapticGlove::GetImuRotation(FQuat& OutImu) +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_FQuat OutImuContainer; + const bool bResult = SGCoreImpl_FSGHapticGloveImpl_GetImuRotation(&InstanceContainer, &OutImuContainer); + + if (bResult) + { + OutImu = MoveTemp(OutImuContainer.Quat); + } + + return bResult; +} + +bool USGHapticGlove::GetImuRotation(FRotator& OutImu) +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_FQuat OutImuContainer; + const bool bResult = SGCoreImpl_FSGHapticGloveImpl_GetImuRotation(&InstanceContainer, &OutImuContainer); + + if (bResult) + { + OutImu = OutImuContainer.Quat.Rotator(); + } + + return bResult; +} + +bool USGHapticGlove::GetHandPose( + UObject* Outer, const USGBasicHandModel* HandGeometry, USGHandPose*& OutHandPose) const +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_FSGBasicHandModelImpl HandGeometryContainer{HandGeometry->ToBasicHandModelImpl()}; + FSGIC_FSGHandPoseImpl OutHandPoseContainer; + const bool bResult = SGCoreImpl_FSGHapticGloveImpl_GetHandPose_HandGeometry_OutHandPose( + &InstanceContainer, &HandGeometryContainer, &OutHandPoseContainer); + + if (bResult) + { + OutHandPose = USGHandPose::NewHandPose(Outer, MoveTemp(OutHandPoseContainer.HandPoseImpl)); + } + + return bResult; +} + +bool USGHapticGlove::GetHandPose(UObject* Outer, USGHandPose*& OutHandPose) +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_FSGHandPoseImpl OutHandPoseContainer; + const bool bResult = SGCoreImpl_FSGHapticGloveImpl_GetHandPose_OutHandPose( + &InstanceContainer, &OutHandPoseContainer); + + if (bResult) + { + OutHandPose = USGHandPose::NewHandPose(Outer, MoveTemp(OutHandPoseContainer.HandPoseImpl)); + } + + return bResult; +} + +bool USGHapticGlove::GetHandAngles(TArray>& OutHandAngles) const +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_TArray_TArray_FVector OutHandAnglesContainer; + const bool bResult = SGCoreImpl_FSGHapticGloveImpl_GetHandAngles_OutHandAngles( + &InstanceContainer, &OutHandAnglesContainer); + + if (bResult) + { + OutHandAngles = MoveTemp(OutHandAnglesContainer.Array); + } + + return bResult; +} + +USGBasicHandModel* USGHapticGlove::GetHandGeometry(UObject* Outer) const +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_FSGBasicHandModelImpl OutBasicHandModelContainer; + SGCoreImpl_FSGHapticGloveImpl_GetHandGeometry(&InstanceContainer, &OutBasicHandModelContainer); + return USGBasicHandModel::NewBasicHandModel(Outer, MoveTemp(OutBasicHandModelContainer.BasicHandModelImpl)); +} + +void USGHapticGlove::SetHandGeometry(const USGBasicHandModel* HandGeometry) +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_FSGBasicHandModelImpl HandGeometryContainer{HandGeometry->ToBasicHandModelImpl()}; + SGCoreImpl_FSGHapticGloveImpl_SetHandGeometry(&InstanceContainer, &HandGeometryContainer); +} + +ESGHapticGloveCalibrationState USGHapticGlove::GetCalibrationState() const +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_ESGHapticGloveCalibrationState OutHapticGloveCalibrationStateContainer; + SGCoreImpl_FSGHapticGloveImpl_GetCalibrationState(&InstanceContainer, &OutHapticGloveCalibrationStateContainer); + return OutHapticGloveCalibrationStateContainer.State; +} + +void USGHapticGlove::EndCalibration() +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + SGCoreImpl_FSGHapticGloveImpl_EndCalibration(&InstanceContainer); +} + +void USGHapticGlove::ResetCalibration() +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + SGCoreImpl_FSGHapticGloveImpl_ResetCalibration(&InstanceContainer); +} + +FString USGHapticGlove::GetCalibrationInstruction() const +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGHapticGloveImpl_GetCalibrationInstruction(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +void USGHapticGlove::StopHaptics() +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + SGCoreImpl_FSGHapticGloveImpl_StopHaptics(&InstanceContainer); +} + +void USGHapticGlove::StopVibrations() +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + SGCoreImpl_FSGHapticGloveImpl_StopVibrations(&InstanceContainer); +} + +bool USGHapticGlove::SendHaptics() +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + return SGCoreImpl_FSGHapticGloveImpl_SendHaptics(&InstanceContainer); +} + +bool USGHapticGlove::QueueForceFeedbackLevels(const TArray& Levels01) +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_TArray_float Levels01Container{Levels01}; + return SGCoreImpl_FSGHapticGloveImpl_QueueForceFeedbackLevels(&InstanceContainer, &Levels01Container); +} + +bool USGHapticGlove::QueueForceFeedbackLevel(const int32 Finger, const float Level01) +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + return SGCoreImpl_FSGHapticGloveImpl_QueueForceFeedbackLevel(&InstanceContainer, Finger, Level01); +} + +bool USGHapticGlove::QueueVibroLevels(const TArray& Levels01) +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_TArray_float Levels01Container{Levels01}; + return SGCoreImpl_FSGHapticGloveImpl_QueueVibroLevels(&InstanceContainer, &Levels01Container); +} + +bool USGHapticGlove::QueueVibroLevel(const ESGHapticLocation Location, const float Level01) +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_ESGHapticLocation LocationContainer{Location}; + return SGCoreImpl_FSGHapticGloveImpl_QueueVibroLevel(&InstanceContainer, &LocationContainer, Level01); +} + +bool USGHapticGlove::SupportsCustomWaveform(const ESGHapticLocation AtLocation) const +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_ESGHapticLocation AtLocationContainer{AtLocation}; + return SGCoreImpl_FSGHapticGloveImpl_SupportsCustomWaveform(&InstanceContainer, &AtLocationContainer); +} + +bool USGHapticGlove::SendCustomWaveform(USGCustomWaveform* OutWaveform, const ESGHapticLocation Location) +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_FSGCustomWaveformImpl OutWaveformContainer{OutWaveform->ToCustomWaveformImpl()}; + FSGIC_ESGHapticLocation LocationContainer{Location}; + return SGCoreImpl_FSGHapticGloveImpl_SendCustomWaveform( + &InstanceContainer, &OutWaveformContainer, &LocationContainer); +} + +void USGHapticGlove::GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) const +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutWristPositionContainer; + FSGIC_FQuat OutWristRotationContainer; + SGCoreImpl_FSGHapticGloveImpl_GetWristLocation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &OutWristPositionContainer, &OutWristRotationContainer); + + OutWristPosition = MoveTemp(OutWristPositionContainer.Vector); + OutWristRotation = MoveTemp(OutWristRotationContainer.Quat); +} + +void USGHapticGlove::GetWristLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FRotator& OutWristRotation) const +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation.Quaternion()}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutWristPositionContainer; + FSGIC_FQuat OutWristRotationContainer; + SGCoreImpl_FSGHapticGloveImpl_GetWristLocation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &OutWristPositionContainer, &OutWristRotationContainer); + + OutWristPosition = MoveTemp(OutWristPositionContainer.Vector); + OutWristRotation = OutWristRotationContainer.Quat.Rotator(); +} + +void USGHapticGlove::GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutGlovePositionContainer; + FSGIC_FQuat OutGloveRotationContainer; + + SGCoreImpl_FSGHapticGloveImpl_GetGloveLocation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &OutGlovePositionContainer, &OutGloveRotationContainer); + + OutGlovePosition = MoveTemp(OutGlovePositionContainer.Vector); + OutGloveRotation = MoveTemp(OutGloveRotationContainer.Quat); +} + +void USGHapticGlove::GetGloveLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FRotator& OutGloveRotation) const +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation.Quaternion()}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutGlovePositionContainer; + FSGIC_FQuat OutGloveRotationContainer; + + SGCoreImpl_FSGHapticGloveImpl_GetGloveLocation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &OutGlovePositionContainer, &OutGloveRotationContainer); + + OutGlovePosition = MoveTemp(OutGlovePositionContainer.Vector); + OutGloveRotation = OutGloveRotationContainer.Quat.Rotator(); +} + +FString USGHapticGlove::ToString() const +{ + FSGIC_TSharedPtr_FSGHapticGloveImpl InstanceContainer{ToHapticGloveImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGHapticGloveImpl_ToString(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGInterpolationSet.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGInterpolationSet.cpp new file mode 100644 index 0000000..23e8528 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGInterpolationSet.cpp @@ -0,0 +1,288 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGInterpolationSet.h" + +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGCoreImpl/SGInterpolationSetImpl.h" +#include "SGInterop/SGIC_FSGInterpolationSetImpl.h" +#include "SGInterop/SGIC_FString.h" + +struct USGInterpolationSet::FImpl +{ + /************************ + * Member variables + ************************/ + + FSGInterpolationSetImpl InterpolationSetImpl; + + /************************ + * Owner object + ************************/ + + USGInterpolationSet* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGInterpolationSet* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGInterpolationSet* USGInterpolationSet::NewInterpolationSet(UObject* Outer, + const FSGInterpolationSetImpl& InterpolationSetImpl) +{ + USGInterpolationSet* Instance = NewObject(Outer); + Instance->SetInterpolationSetImpl(InterpolationSetImpl); + return Instance; +} + +USGInterpolationSet* USGInterpolationSet::NewInterpolationSet(UObject* Outer) +{ + FSGIC_FSGInterpolationSetImpl OutInterpolationSetImplContainer; + SGCoreImpl_FSGInterpolationSetImpl_ctor(&OutInterpolationSetImplContainer); + + return NewInterpolationSet(Outer, MoveTemp(OutInterpolationSetImplContainer.InterpolationSetImpl)); +} + +USGInterpolationSet* USGInterpolationSet::NewInterpolationSet( + UObject* Outer, const float From1, const float From2, const float To1, const float To2) +{ + FSGIC_FSGInterpolationSetImpl OutInterpolationSetImplContainer; + SGCoreImpl_FSGInterpolationSetImpl_ctor_From1_From2_To1_To2(&OutInterpolationSetImplContainer, + From1, From2, To1, To2); + + return NewInterpolationSet(Outer, MoveTemp(OutInterpolationSetImplContainer.InterpolationSetImpl)); +} + +USGInterpolationSet* USGInterpolationSet::NewInterpolationSet( + UObject* Outer, + const float From1, const float From2, const float To1, const float To2, const float Min, const float Max) +{ + FSGIC_FSGInterpolationSetImpl OutInterpolationSetImplContainer; + SGCoreImpl_FSGInterpolationSetImpl_ctor_From1_From2_To1_To2_Min_Max(&OutInterpolationSetImplContainer, + From1, From2, To1, To2, Min, Max); + + return NewInterpolationSet(Outer, MoveTemp(OutInterpolationSetImplContainer.InterpolationSetImpl)); +} + +USGInterpolationSet* USGInterpolationSet::Deserialize(UObject* Outer, const FString& SerializedString) +{ + FSGIC_FSGInterpolationSetImpl OutInterpolationSetImplContainer; + FSGIC_FString SerializedStringContainer{SerializedString}; + SGCoreImpl_FSGInterpolationSetImpl_Deserialize(&OutInterpolationSetImplContainer, &SerializedStringContainer); + + return NewInterpolationSet(Outer, MoveTemp(OutInterpolationSetImplContainer.InterpolationSetImpl)); +} + +USGInterpolationSet::USGInterpolationSet() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGInterpolationSetImpl OutInterpolationSetImplContainer; + SGCoreImpl_FSGInterpolationSetImpl_ctor(&OutInterpolationSetImplContainer); + + Pimpl->InterpolationSetImpl = MoveTemp(OutInterpolationSetImplContainer.InterpolationSetImpl); +} + +USGInterpolationSet::USGInterpolationSet(const float From1, const float From2, const float To1, const float To2) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGInterpolationSetImpl OutInterpolationSetImplContainer; + SGCoreImpl_FSGInterpolationSetImpl_ctor_From1_From2_To1_To2(&OutInterpolationSetImplContainer, + From1, From2, To1, To2); + + Pimpl->InterpolationSetImpl = MoveTemp(OutInterpolationSetImplContainer.InterpolationSetImpl); +} + +USGInterpolationSet::USGInterpolationSet(const float From1, const float From2, const float To1, const float To2, + const float Min, const float Max) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGInterpolationSetImpl OutInterpolationSetImplContainer; + SGCoreImpl_FSGInterpolationSetImpl_ctor_From1_From2_To1_To2_Min_Max(&OutInterpolationSetImplContainer, + From1, From2, To1, To2, Min, Max); + + Pimpl->InterpolationSetImpl = MoveTemp(OutInterpolationSetImplContainer.InterpolationSetImpl); +} + +USGInterpolationSet::USGInterpolationSet(const FSGInterpolationSetImpl& InterpolationSetImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + SetInterpolationSetImpl(InterpolationSetImpl); +} + +USGInterpolationSet::~USGInterpolationSet() = default; + +void USGInterpolationSet::SetInterpolationSetImpl(const FSGInterpolationSetImpl& InterpolationSetImpl) +{ + FSGIC_FSGInterpolationSetImpl OutInterpolationSetContainer; + FSGIC_FSGInterpolationSetImpl RhsContainer{InterpolationSetImpl}; + SGCoreImpl_FSGInterpolationSetImpl_ctor_copy(&OutInterpolationSetContainer, &RhsContainer); + Pimpl->InterpolationSetImpl = MoveTemp(OutInterpolationSetContainer.InterpolationSetImpl); +} + +const FSGInterpolationSetImpl& USGInterpolationSet::ToInterpolationSetImpl() const +{ + return Pimpl->InterpolationSetImpl; +} + +float USGInterpolationSet::GetX0() const +{ + FSGIC_FSGInterpolationSetImpl InstanceContainer{ToInterpolationSetImpl()}; + return SGCoreImpl_FSGInterpolationSetImpl_GetX0(&InstanceContainer); +} + +void USGInterpolationSet::SetX0(const float X0) +{ + FSGIC_FSGInterpolationSetImpl InstanceContainer{ToInterpolationSetImpl()}; + SGCoreImpl_FSGInterpolationSetImpl_SetX0(&InstanceContainer, X0); +} + +float USGInterpolationSet::GetX1() const +{ + FSGIC_FSGInterpolationSetImpl InstanceContainer{ToInterpolationSetImpl()}; + return SGCoreImpl_FSGInterpolationSetImpl_GetX1(&InstanceContainer); +} + +void USGInterpolationSet::SetX1(const float X1) +{ + FSGIC_FSGInterpolationSetImpl InstanceContainer{ToInterpolationSetImpl()}; + SGCoreImpl_FSGInterpolationSetImpl_SetX1(&InstanceContainer, X1); +} + +float USGInterpolationSet::GetY0() const +{ + FSGIC_FSGInterpolationSetImpl InstanceContainer{ToInterpolationSetImpl()}; + return SGCoreImpl_FSGInterpolationSetImpl_GetY0(&InstanceContainer); +} + +void USGInterpolationSet::SetY0(const float Y0) +{ + FSGIC_FSGInterpolationSetImpl InstanceContainer{ToInterpolationSetImpl()}; + SGCoreImpl_FSGInterpolationSetImpl_SetY0(&InstanceContainer, Y0); +} + +float USGInterpolationSet::GetY1() const +{ + FSGIC_FSGInterpolationSetImpl InstanceContainer{ToInterpolationSetImpl()}; + return SGCoreImpl_FSGInterpolationSetImpl_GetY1(&InstanceContainer); +} + +void USGInterpolationSet::SetY1(const float Y1) +{ + FSGIC_FSGInterpolationSetImpl InstanceContainer{ToInterpolationSetImpl()}; + SGCoreImpl_FSGInterpolationSetImpl_SetY1(&InstanceContainer, Y1); +} + +float USGInterpolationSet::GetMin() const +{ + FSGIC_FSGInterpolationSetImpl InstanceContainer{ToInterpolationSetImpl()}; + return SGCoreImpl_FSGInterpolationSetImpl_GetMin(&InstanceContainer); +} + +void USGInterpolationSet::SetMin(const float Min) +{ + FSGIC_FSGInterpolationSetImpl InstanceContainer{ToInterpolationSetImpl()}; + SGCoreImpl_FSGInterpolationSetImpl_SetMin(&InstanceContainer, Min); +} + +float USGInterpolationSet::GetMax() const +{ + FSGIC_FSGInterpolationSetImpl InstanceContainer{ToInterpolationSetImpl()}; + return SGCoreImpl_FSGInterpolationSetImpl_GetMax(&InstanceContainer); +} + +void USGInterpolationSet::SetMax(const float Max) +{ + FSGIC_FSGInterpolationSetImpl InstanceContainer{ToInterpolationSetImpl()}; + SGCoreImpl_FSGInterpolationSetImpl_SetMax(&InstanceContainer, Max); +} + +float USGInterpolationSet::Get(const float Value, const bool bLimit, const bool bNormalizeAngle) const +{ + FSGIC_FSGInterpolationSetImpl InstanceContainer{ToInterpolationSetImpl()}; + return SGCoreImpl_FSGInterpolationSetImpl_Get(&InstanceContainer, Value, bLimit, bNormalizeAngle); +} + +bool USGInterpolationSet::Equals(const USGInterpolationSet* InterpolationSet) const +{ + FSGIC_FSGInterpolationSetImpl InstanceContainer{ToInterpolationSetImpl()}; + FSGIC_FSGInterpolationSetImpl InterpolationSetContainer{InterpolationSet->ToInterpolationSetImpl()}; + return SGCoreImpl_FSGInterpolationSetImpl_Equals(&InstanceContainer, &InterpolationSetContainer); +} + +FString USGInterpolationSet::ToString() const +{ + FSGIC_FSGInterpolationSetImpl InstanceContainer{ToInterpolationSetImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGInterpolationSetImpl_ToString(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +FString USGInterpolationSet::ToString(const bool bLimits) const +{ + FSGIC_FSGInterpolationSetImpl InstanceContainer{ToInterpolationSetImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGInterpolationSetImpl_ToString_bLimits(&InstanceContainer, &OutStringContainer, bLimits); + return OutStringContainer.String; +} + +FString USGInterpolationSet::SGSerialize() const +{ + FSGIC_FSGInterpolationSetImpl InstanceContainer{ToInterpolationSetImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGInterpolationSetImpl_Serialize(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +USGInterpolationSet::FImpl::FImpl(USGInterpolationSet* InOwner) + : Owner(InOwner) +{ +} + +USGInterpolationSet::FImpl::~FImpl() = default; + +void USGInterpolationSet::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGInterpolationSetArray.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGInterpolationSetArray.cpp new file mode 100644 index 0000000..c214563 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGInterpolationSetArray.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGInterpolationSetArray.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGJointKinematics.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGJointKinematics.cpp new file mode 100644 index 0000000..83b7360 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGJointKinematics.cpp @@ -0,0 +1,132 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGJointKinematics.h" + +#include "SGCore/SGBasicHandModel.h" +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_ESGFinger.h" +#include "SGInterop/SGIC_FQuat.h" +#include "SGInterop/SGIC_FSGBasicHandModelImpl.h" +#include "SGInterop/SGIC_FVector.h" +#include "SGInterop/SGIC_TArray_FQuat.h" +#include "SGInterop/SGIC_TArray_FVector.h" +#include "SGUtils/SGArrayUtils.h" + +bool FSGJointKinematics::ForwardKinematics( + const FVector& StartPosition, const FQuat& StartRotation, const TArray& JointLengths, + const TArray& JointAngles, TArray& OutNewPositions, TArray& OutNewRotations) +{ + FSGIC_FVector StartPositionContainer{StartPosition}; + FSGIC_FQuat StartRotationContainer{StartRotation}; + FSGIC_TArray_FVector JointLengthsContainer{JointLengths}; + FSGIC_TArray_FVector JointAnglesContainer{JointAngles}; + FSGIC_TArray_FVector OutNewPositionsContainer; + FSGIC_TArray_FQuat OutNewRotationsContainer; + + const bool bResult = + SGCoreImpl_FSGJointKinematicsImpl_ForwardKinematics_StartPosition_StartRotation_JointLengths_JointAngles_OutNewPositions_OutNewRotations( + &StartPositionContainer, &StartRotationContainer, &JointLengthsContainer, &JointAnglesContainer, + &OutNewPositionsContainer, &OutNewRotationsContainer); + + OutNewPositions = MoveTemp(OutNewPositionsContainer.Array); + OutNewRotations = MoveTemp(OutNewRotationsContainer.Array); + + return bResult; +} + +bool FSGJointKinematics::ForwardKinematics( + const FVector& StartPosition, const FRotator& StartRotation, const TArray& JointLengths, + const TArray& JointAngles, TArray& OutNewPositions, TArray& OutNewRotations) +{ + FSGIC_FVector StartPositionContainer{StartPosition}; + FSGIC_FQuat StartRotationContainer{StartRotation.Quaternion()}; + FSGIC_TArray_FVector JointLengthsContainer{JointLengths}; + FSGIC_TArray_FVector JointAnglesContainer{JointAngles}; + FSGIC_TArray_FVector OutNewPositionsContainer; + FSGIC_TArray_FQuat OutNewRotationsContainer; + + const bool bResult = + SGCoreImpl_FSGJointKinematicsImpl_ForwardKinematics_StartPosition_StartRotation_JointLengths_JointAngles_OutNewPositions_OutNewRotations( + &StartPositionContainer, &StartRotationContainer, &JointLengthsContainer, &JointAnglesContainer, + &OutNewPositionsContainer, &OutNewRotationsContainer); + + OutNewPositions = MoveTemp(OutNewPositionsContainer.Array); + OutNewRotations = FSGArrayUtils::QuatsToRotators(OutNewRotationsContainer.Array); + + return bResult; +} + +bool FSGJointKinematics::ForwardKinematics( + const USGBasicHandModel* Profile, const ESGFinger Finger, const TArray& JointAngles, + TArray& OutNewPositions, TArray& OutNewRotations) +{ + FSGIC_FSGBasicHandModelImpl ProfileContainer{Profile->ToBasicHandModelImpl()}; + FSGIC_ESGFinger FingerContainer{Finger}; + FSGIC_TArray_FVector JointAnglesContainer{JointAngles}; + FSGIC_TArray_FVector OutNewPositionsContainer; + FSGIC_TArray_FQuat OutNewRotationsContainer; + + const bool bResult = + SGCoreImpl_FSGJointKinematicsImpl_ForwardKinematics_Profile_Finger_JointAngles_OutNewPositions_OutNewRotations( + &ProfileContainer, &FingerContainer, &JointAnglesContainer, + &OutNewPositionsContainer, &OutNewRotationsContainer); + + OutNewPositions = MoveTemp(OutNewPositionsContainer.Array); + OutNewRotations = MoveTemp(OutNewRotationsContainer.Array); + + return bResult; +} + +bool FSGJointKinematics::ForwardKinematics( + const USGBasicHandModel* Profile, const ESGFinger Finger, const TArray& JointAngles, + TArray& OutNewPositions, TArray& OutNewRotations) +{ + FSGIC_FSGBasicHandModelImpl ProfileContainer{Profile->ToBasicHandModelImpl()}; + FSGIC_ESGFinger FingerContainer{Finger}; + FSGIC_TArray_FVector JointAnglesContainer{JointAngles}; + FSGIC_TArray_FVector OutNewPositionsContainer; + FSGIC_TArray_FQuat OutNewRotationsContainer; + + const bool bResult = + SGCoreImpl_FSGJointKinematicsImpl_ForwardKinematics_Profile_Finger_JointAngles_OutNewPositions_OutNewRotations( + &ProfileContainer, &FingerContainer, &JointAnglesContainer, + &OutNewPositionsContainer, &OutNewRotationsContainer); + + OutNewPositions = MoveTemp(OutNewPositionsContainer.Array); + OutNewRotations = FSGArrayUtils::QuatsToRotators(OutNewRotationsContainer.Array); + + return bResult; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGLibrary.cpp new file mode 100644 index 0000000..98d4549 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGLibrary.cpp @@ -0,0 +1,68 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGLibrary.h" + +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_ESGBackendType.h" +#include "SGInterop/SGIC_FString.h" + +FString FSGLibrary::GetVersion() +{ + FSGIC_FString Container; + SGCoreImpl_FSGLibraryImpl_Version(&Container); + return Container.String; +} + +ESGBackendType FSGLibrary::GetBackendType() +{ + FSGIC_ESGBackendType Container; + SGCoreImpl_FSGLibraryImpl_GetBackendType(&Container); + return Container.Type; +} + +FString FSGLibrary::GetBackendVersion() +{ + FSGIC_FString Container; + SGCoreImpl_FSGLibraryImpl_BackendVersion(&Container); + return Container.String; +} + +FString FSGLibrary::GetSGConnectVersion() +{ + FSGIC_FString Container; + SGCoreImpl_FSGLibraryImpl_SGConnectVersion(&Container); + return Container.String; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGNova2Glove.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGNova2Glove.cpp new file mode 100644 index 0000000..74bf19f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGNova2Glove.cpp @@ -0,0 +1,742 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGNova2Glove.h" + +#include "SGCore/SGBasicHandModel.h" +#include "SGCore/SGCustomWaveform.h" +#include "SGCore/SGDeviceImplCast.h" +#include "SGCore/SGHandInterpolator.h" +#include "SGCore/SGHandPose.h" +#include "SGCore/SGNovaGloveInfo.h" +#include "SGCore/SGNova2GloveSensorData.h" +#include "SGCore/SGSensorNormalization.h" +#include "SGCore/SGThresholdCommand.h" +#include "SGCoreImpl/SGDeviceImpl.h" +#include "SGCoreImpl/SGHapticGloveImpl.h" +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGCoreImpl/SGNova2GloveImpl.h" +#include "SGInterop/SGIC_ESGDeviceType.h" +#include "SGInterop/SGIC_ESGHapticGloveCalibrationState.h" +#include "SGInterop/SGIC_ESGHapticLocation.h" +#include "SGInterop/SGIC_ESGNova2VibroMotor.h" +#include "SGInterop/SGIC_ESGPositionalTrackingHardware.h" +#include "SGInterop/SGIC_FQuat.h" +#include "SGInterop/SGIC_FSGBasicHandModelImpl.h" +#include "SGInterop/SGIC_FSGCustomWaveformImpl.h" +#include "SGInterop/SGIC_FSGHandInterpolatorImpl.h" +#include "SGInterop/SGIC_FSGHandPoseImpl.h" +#include "SGInterop/SGIC_FSGNova2GloveImpl.h" +#include "SGInterop/SGIC_FSGNovaGloveInfoImpl.h" +#include "SGInterop/SGIC_FSGNova2GloveSensorDataImpl.h" +#include "SGInterop/SGIC_FSGSensorNormalizationImpl.h" +#include "SGInterop/SGIC_FSGThresholdCommandImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_FVector.h" +#include "SGInterop/SGIC_TArray_FSGNova2GloveImpl.h" +#include "SGInterop/SGIC_TArray_FVector.h" +#include "SGInterop/SGIC_TArray_TArray_FVector.h" +#include "SGInterop/SGIC_TArray_float.h" +#include "SGInterop/SGIC_TSharedPtr_FSGNova2GloveImpl.h" + +USGNova2Glove* USGNova2Glove::NewNova2Glove(UObject* Outer, const FSGNova2GloveImpl& Nova2GloveImpl) +{ + USGNova2Glove* Instance = NewObject(Outer); + Instance->SetSGDeviceImpl(Nova2GloveImpl); + return Instance; +} + +USGNova2Glove* USGNova2Glove::NewNova2Glove(UObject* Outer, TSharedRef Nova2GloveImpl) +{ + USGNova2Glove* Instance = NewObject(Outer); + Instance->SetSGDeviceImpl(MoveTemp(Nova2GloveImpl)); + return Instance; +} + +USGNova2Glove* USGNova2Glove::NewNova2Glove(UObject* Outer) +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl OutSharedPtrContainer; + SGCoreImpl_FSGNova2GloveImpl_ctor_MakeShared(&OutSharedPtrContainer); + + return NewNova2Glove(Outer, OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +USGNova2Glove* USGNova2Glove::NewNova2Glove(UObject* Outer, const USGNovaGloveInfo& DeviceInfo) +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl OutSharedPtrContainer; + FSGIC_FSGNovaGloveInfoImpl DeviceInfoContainer{DeviceInfo.ToNovaGloveInfoImpl()}; + SGCoreImpl_FSGNova2GloveImpl_ctor_DeviceInfo_MakeShared(&OutSharedPtrContainer, &DeviceInfoContainer); + + return NewNova2Glove(Outer, OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +USGDevice* USGNova2Glove::Parse(UObject* Outer, const FString& ConstantsString) +{ + FSGIC_FSGNova2GloveImpl OutNova2GloveImplContainer; + FSGIC_FString ConstantsStringContainer{ConstantsString}; + SGCoreImpl_FSGNova2GloveImpl_Parse(&OutNova2GloveImplContainer, &ConstantsStringContainer); + + return NewNova2Glove(Outer, MoveTemp(OutNova2GloveImplContainer.Nova2GloveImpl)); +} + +TArray USGNova2Glove::GetNova2Gloves(UObject* Outer) +{ + FSGIC_TArray_FSGNova2GloveImpl OutGlovesContainer; + SGCoreImpl_FSGNova2GloveImpl_GetNova2Gloves(&OutGlovesContainer); + TArray Gloves; + for (const FSGNova2GloveImpl& Nova2GloveImpl: OutGlovesContainer.Array) + { + USGNova2Glove* Nova2Glove = USGNova2Glove::NewNova2Glove(Outer, Nova2GloveImpl); + Gloves.Add(Nova2Glove); + } + return Gloves; +} + +bool USGNova2Glove::GetNova2Glove(UObject* Outer, USGNova2Glove*& OutGlove) +{ + FSGIC_FSGNova2GloveImpl OutGloveContainer; + const bool bResult = SGCoreImpl_FSGNova2GloveImpl_GetNova2Glove_OutGlove(&OutGloveContainer); + + if (bResult) + { + OutGlove = NewNova2Glove(Outer, MoveTemp(OutGloveContainer.Nova2GloveImpl)); + } + + return bResult; +} + +bool USGNova2Glove::GetNova2Glove(UObject* Outer, const bool bRightHanded, USGNova2Glove*& OutGlove) +{ + FSGIC_FSGNova2GloveImpl OutGloveContainer; + const bool bResult = SGCoreImpl_FSGNova2GloveImpl_GetNova2Glove_bRightHanded_OutGlove( + bRightHanded, &OutGloveContainer); + + if (bResult) + { + OutGlove = NewNova2Glove(Outer, MoveTemp(OutGloveContainer.Nova2GloveImpl)); + } + + return bResult; +} + +void USGNova2Glove::CalculateGloveLocation( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, const FString& HardwareVersion, + FVector& OutGlovePosition, FQuat& OutGloveRotation) +{ + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FVector OutGlovePositionContainer; + FSGIC_FQuat OutGloveRotationContainer; + + SGCoreImpl_FSGNova2GloveImpl_CalculateGloveLocation( + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, bRightHanded, &HardwareVersionContainer, + &OutGlovePositionContainer, &OutGloveRotationContainer); + + OutGlovePosition = MoveTemp(OutGlovePositionContainer.Vector); + OutGloveRotation = MoveTemp(OutGloveRotationContainer.Quat); +} + +void USGNova2Glove::CalculateGloveLocation( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, const FString& HardwareVersion, + FVector& OutGlovePosition, FRotator& OutGloveRotation) +{ + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation.Quaternion()}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FVector OutGlovePositionContainer; + FSGIC_FQuat OutGloveRotationContainer; + + SGCoreImpl_FSGNova2GloveImpl_CalculateGloveLocation( + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, bRightHanded, &HardwareVersionContainer, + &OutGlovePositionContainer, &OutGloveRotationContainer); + + OutGlovePosition = MoveTemp(OutGlovePositionContainer.Vector); + OutGloveRotation = OutGloveRotationContainer.Quat.Rotator(); +} + +void USGNova2Glove::CalculateWristLocation( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, const FString& HardwareVersion, + FVector& OutWristPosition, FQuat& OutWristRotation) +{ + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FVector OutWristPositionContainer; + FSGIC_FQuat OutWristRotationContainer; + + SGCoreImpl_FSGNova2GloveImpl_CalculateWristLocation( + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, bRightHanded, &HardwareVersionContainer, + &OutWristPositionContainer, &OutWristRotationContainer); + + OutWristPosition = MoveTemp(OutWristPositionContainer.Vector); + OutWristRotation = MoveTemp(OutWristRotationContainer.Quat); +} + +void USGNova2Glove::CalculateWristLocation( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, const FString& HardwareVersion, + FVector& OutWristPosition, FRotator& OutWristRotation) +{ + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation.Quaternion()}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FVector OutWristPositionContainer; + FSGIC_FQuat OutWristRotationContainer; + + SGCoreImpl_FSGNova2GloveImpl_CalculateWristLocation( + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, bRightHanded, &HardwareVersionContainer, + &OutWristPositionContainer, &OutWristRotationContainer); + + OutWristPosition = MoveTemp(OutWristPositionContainer.Vector); + OutWristRotation = OutWristRotationContainer.Quat.Rotator(); +} + +ANSICHAR USGNova2Glove::GetStreamByte() +{ + return SGCoreImpl_FSGNova2GloveImpl_GetStreamByte(); +} + +TArray USGNova2Glove::GetNova2SensorRanges() +{ + FSGIC_TArray_float OutNova2SensorRangesContainer; + SGCoreImpl_FSGNova2GloveImpl_GetNova2SensorRanges(&OutNova2SensorRangesContainer); + return OutNova2SensorRangesContainer.Array; +} + +TArray USGNova2Glove::ToNormalizedValues(const USGNova2GloveSensorData* SensorData) +{ + FSGIC_TArray_float OutNormalizedValuesContainer; + FSGIC_FSGNova2GloveSensorDataImpl SensorDataContainer{SensorData->ToNova2GloveSensorDataImpl()}; + SGCoreImpl_FSGNova2GloveImpl_ToNormalizedValues_SensorData( + &OutNormalizedValuesContainer, &SensorDataContainer); + return OutNormalizedValuesContainer.Array; +} + +TArray USGNova2Glove::ToNormalizedValues( + UObject* Outer, const USGNova2GloveSensorData* SensorData, USGSensorNormalization*& OutSensorNormalizer) +{ + FSGIC_TArray_float OutNormalizedValuesContainer; + FSGIC_FSGNova2GloveSensorDataImpl SensorDataContainer{SensorData->ToNova2GloveSensorDataImpl()}; + FSGIC_FSGSensorNormalizationImpl OutSensorNormalizerContainer; + SGCoreImpl_FSGNova2GloveImpl_ToNormalizedValues_SensorData_OutSensorNormalizer( + &OutNormalizedValuesContainer, &SensorDataContainer, &OutSensorNormalizerContainer); + + OutSensorNormalizer = USGSensorNormalization::NewSensorNormalization( + Outer, MoveTemp(OutSensorNormalizerContainer.SensorNormalizationImpl)); + + return OutNormalizedValuesContainer.Array; +} + +TArray> USGNova2Glove::CalculateHandAngles( + const TArray& NormalizedValues, const USGHandInterpolator* Interpolator, const bool bInfluenceIndex) +{ + FSGIC_TArray_TArray_FVector OutHandAnglesContainer; + FSGIC_TArray_float NormalizedValuesContainer{NormalizedValues}; + FSGIC_FSGHandInterpolatorImpl InterpolatorContainer{Interpolator->ToHandInterpolatorImpl()}; + SGCoreImpl_FSGNova2GloveImpl_CalculateHandAngles( + &OutHandAnglesContainer, &NormalizedValuesContainer, &InterpolatorContainer, bInfluenceIndex); + return OutHandAnglesContainer.Array; +} + +TArray> USGNova2Glove::ToNormalizedAngles( + const TArray& NormalizedData, const USGNovaGloveInfo* GloveInfo) +{ + FSGIC_TArray_TArray_FVector OutHandAnglesContainer; + FSGIC_TArray_float NormalizedDataContainer{NormalizedData}; + FSGIC_FSGNovaGloveInfoImpl GloveInfoContainer{GloveInfo->ToNovaGloveInfoImpl()}; + SGCoreImpl_FSGNova2GloveImpl_ToNormalizedAngles( + &OutHandAnglesContainer, &NormalizedDataContainer, &GloveInfoContainer); + return OutHandAnglesContainer.Array; +} + +USGNova2Glove::USGNova2Glove() + : USGHapticGlove() +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl OutSharedPtrContainer; + SGCoreImpl_FSGNova2GloveImpl_ctor_MakeShared(&OutSharedPtrContainer); + + SetSGDeviceImpl(OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +USGNova2Glove::USGNova2Glove(const USGNovaGloveInfo& DeviceInfo) + : USGHapticGlove() +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl OutSharedPtrContainer; + FSGIC_FSGNovaGloveInfoImpl DeviceInfoContainer{DeviceInfo.ToNovaGloveInfoImpl()}; + SGCoreImpl_FSGNova2GloveImpl_ctor_DeviceInfo_MakeShared(&OutSharedPtrContainer, &DeviceInfoContainer); + + SetSGDeviceImpl(OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +USGNova2Glove::USGNova2Glove(const FSGDeviceImpl& SGDeviceImpl) + : USGHapticGlove(SGDeviceImpl) +{ +} + +USGNova2Glove::USGNova2Glove(const FSGHapticGloveImpl& HapticGloveImpl) + : USGHapticGlove(HapticGloveImpl) +{ +} + +USGNova2Glove::USGNova2Glove(const FSGNova2GloveImpl& Nova2GloveImpl) + : USGHapticGlove(Nova2GloveImpl) +{ +} + +USGNova2Glove::USGNova2Glove(const TSharedRef SGDeviceImpl) + : USGHapticGlove(SGDeviceImpl) +{ +} + +USGNova2Glove::USGNova2Glove(const TSharedRef HapticGloveImpl) + : USGHapticGlove(HapticGloveImpl) +{ +} + +USGNova2Glove::USGNova2Glove(const TSharedRef Nova2GloveImpl) + : USGHapticGlove(Nova2GloveImpl) +{ +} + +USGNova2Glove::~USGNova2Glove() = default; + +TSharedRef USGNova2Glove::ToNova2GloveImpl() const +{ + return FSGDeviceImplCast::ToNova2GloveImpl(ToSGDeviceImpl()); +} + +ESGDeviceType USGNova2Glove::GetDeviceType() const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_ESGDeviceType OutTypeContainer; + SGCoreImpl_FSGNova2GloveImpl_GetDeviceType(&InstanceContainer, &OutTypeContainer); + return OutTypeContainer.Type; +} + +FString USGNova2Glove::GetDeviceId() const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_FString OutIdContainer; + SGCoreImpl_FSGNova2GloveImpl_GetDeviceId(&InstanceContainer, &OutIdContainer); + return OutIdContainer.String; +} + +FString USGNova2Glove::GetHardwareVersion() const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_FString OutVersionContainer; + SGCoreImpl_FSGNova2GloveImpl_GetHardwareVersion(&InstanceContainer, &OutVersionContainer); + return OutVersionContainer.String; +} + +int32 USGNova2Glove::GetFirmwareVersion() const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + return SGCoreImpl_FSGNova2GloveImpl_GetFirmwareVersion(&InstanceContainer); +} + +int32 USGNova2Glove::GetSubFirmwareVersion() const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + return SGCoreImpl_FSGNova2GloveImpl_GetSubFirmwareVersion(&InstanceContainer); +} + +bool USGNova2Glove::HasBattery() const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + return SGCoreImpl_FSGNova2GloveImpl_HasBattery(&InstanceContainer); +} + +bool USGNova2Glove::IsCharging() +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + const bool bResult = SGCoreImpl_FSGNova2GloveImpl_IsCharging(&InstanceContainer); + return bResult; +} + +bool USGNova2Glove::GetBatteryLevel(float& OutBatteryLevel) +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + const bool bResult = SGCoreImpl_FSGNova2GloveImpl_GetBatteryLevel(&InstanceContainer, &OutBatteryLevel); + return bResult; +} + +bool USGNova2Glove::IsRight() const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + return SGCoreImpl_FSGNova2GloveImpl_IsRight(&InstanceContainer); +} + + +bool USGNova2Glove::GetImuRotation(FQuat& OutImu) +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_FQuat OutImuContainer; + const bool bResult = SGCoreImpl_FSGNova2GloveImpl_GetImuRotation(&InstanceContainer, &OutImuContainer); + + if (bResult) + { + OutImu = MoveTemp(OutImuContainer.Quat); + } + + return bResult; +} + +bool USGNova2Glove::GetImuRotation(FRotator& OutImu) +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_FQuat OutImuContainer; + const bool bResult = SGCoreImpl_FSGNova2GloveImpl_GetImuRotation(&InstanceContainer, &OutImuContainer); + + if (bResult) + { + OutImu = OutImuContainer.Quat.Rotator(); + } + + return bResult; +} + +bool USGNova2Glove::GetHandPose(UObject* Outer, const USGBasicHandModel* HandGeometry, USGHandPose*& OutHandPose) const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_FSGBasicHandModelImpl HandModelContainer{HandGeometry->ToBasicHandModelImpl()}; + FSGIC_FSGHandPoseImpl OutHandPoseContainer; + const bool bResult = SGCoreImpl_FSGNova2GloveImpl_GetHandPose( + &InstanceContainer, &HandModelContainer, &OutHandPoseContainer); + + if (bResult) + { + OutHandPose = USGHandPose::NewHandPose(Outer, MoveTemp(OutHandPoseContainer.HandPoseImpl)); + } + + return bResult; +} + +bool USGNova2Glove::GetHandAngles(TArray>& OutHandAngles) const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_TArray_TArray_FVector OutHandAnglesContainer; + const bool bResult = SGCoreImpl_FSGNova2GloveImpl_GetHandAngles(&InstanceContainer, &OutHandAnglesContainer); + OutHandAngles = MoveTemp(OutHandAnglesContainer.Array); + return bResult; + +} + +ESGHapticGloveCalibrationState USGNova2Glove::GetCalibrationState() const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_ESGHapticGloveCalibrationState OutHapticGloveCalibrationStateContainer; + SGCoreImpl_FSGNova2GloveImpl_GetCalibrationState(&InstanceContainer, &OutHapticGloveCalibrationStateContainer); + return OutHapticGloveCalibrationStateContainer.State; +} + +void USGNova2Glove::EndCalibration() +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + SGCoreImpl_FSGNova2GloveImpl_EndCalibration(&InstanceContainer); +} + +void USGNova2Glove::ResetCalibration() +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + SGCoreImpl_FSGNova2GloveImpl_ResetCalibration(&InstanceContainer); +} + +void USGNova2Glove::StopHaptics() +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + SGCoreImpl_FSGNova2GloveImpl_StopHaptics(&InstanceContainer); +} + +void USGNova2Glove::StopVibrations() +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + SGCoreImpl_FSGNova2GloveImpl_StopVibrations(&InstanceContainer); +} + +bool USGNova2Glove::SendHaptics() +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + return SGCoreImpl_FSGNova2GloveImpl_SendHaptics(&InstanceContainer); +} + +bool USGNova2Glove::SupportsCustomWaveform(ESGHapticLocation AtLocation) const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + return SGCoreImpl_FSGNova2GloveImpl_SendHaptics(&InstanceContainer); +} + +bool USGNova2Glove::SendCustomWaveform(USGCustomWaveform* OutWaveform, ESGHapticLocation Location) +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + return SGCoreImpl_FSGNova2GloveImpl_SendHaptics(&InstanceContainer); +} + +bool USGNova2Glove::QueueForceFeedbackLevels(const TArray& Levels01) +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_TArray_float Levels01Container{Levels01}; + return SGCoreImpl_FSGNova2GloveImpl_QueueForceFeedbackLevels(&InstanceContainer, &Levels01Container); +} + +bool USGNova2Glove::QueueForceFeedbackLevel(const int32 Finger, const float Level01) +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + return SGCoreImpl_FSGNova2GloveImpl_QueueForceFeedbackLevel(&InstanceContainer, Finger, Level01); +} + +bool USGNova2Glove::QueueVibroLevels(const TArray& Amplitudes) +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_TArray_float AmplitudesContainer{Amplitudes}; + return SGCoreImpl_FSGNova2GloveImpl_QueueVibroLevels(&InstanceContainer, &AmplitudesContainer); +} + +bool USGNova2Glove::QueueVibroLevel(const ESGHapticLocation Location, const float Level01) +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_ESGHapticLocation LocationContainer{Location}; + return SGCoreImpl_FSGNova2GloveImpl_QueueVibroLevel(&InstanceContainer, &LocationContainer, Level01); +} + +bool USGNova2Glove::QueueSqueezeLevel(const float SqueezeLevel01) +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + return SGCoreImpl_FSGNova2GloveImpl_QueueSqueezeLevel(&InstanceContainer, SqueezeLevel01); +} + +void USGNova2Glove::GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutGlovePositionContainer; + FSGIC_FQuat OutGloveRotationContainer; + + SGCoreImpl_FSGNova2GloveImpl_GetGloveLocation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &OutGlovePositionContainer, &OutGloveRotationContainer); + + OutGlovePosition = MoveTemp(OutGlovePositionContainer.Vector); + OutGloveRotation = MoveTemp(OutGloveRotationContainer.Quat); +} + +void USGNova2Glove::GetGloveLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FRotator& OutGloveRotation) const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation.Quaternion()}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutGlovePositionContainer; + FSGIC_FQuat OutGloveRotationContainer; + + SGCoreImpl_FSGNova2GloveImpl_GetGloveLocation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &OutGlovePositionContainer, &OutGloveRotationContainer); + + OutGlovePosition = MoveTemp(OutGlovePositionContainer.Vector); + OutGloveRotation = OutGloveRotationContainer.Quat.Rotator(); +} + +void USGNova2Glove::GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutWristPositionContainer; + FSGIC_FQuat OutWristRotationContainer; + SGCoreImpl_FSGNova2GloveImpl_GetWristLocation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &OutWristPositionContainer, &OutWristRotationContainer); + + OutWristPosition = MoveTemp(OutWristPositionContainer.Vector); + OutWristRotation = MoveTemp(OutWristRotationContainer.Quat); +} + +void USGNova2Glove::GetWristLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FRotator& OutWristRotation) const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation.Quaternion()}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutWristPositionContainer; + FSGIC_FQuat OutWristRotationContainer; + SGCoreImpl_FSGNova2GloveImpl_GetWristLocation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &OutWristPositionContainer, &OutWristRotationContainer); + + OutWristPosition = MoveTemp(OutWristPositionContainer.Vector); + OutWristRotation = OutWristRotationContainer.Quat.Rotator(); +} + +USGNovaGloveInfo* USGNova2Glove::GetGloveInfo(UObject* Outer) const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_FSGNovaGloveInfoImpl OutGloveInfoContainer; + SGCoreImpl_FSGNova2GloveImpl_GetGloveInfo(&InstanceContainer, &OutGloveInfoContainer); + return USGNovaGloveInfo::NewNovaGloveInfo(Outer, MoveTemp(OutGloveInfoContainer.NovaGloveInfoImpl)); +} + +bool USGNova2Glove::DoesIndexInfluenceOthers() const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + return SGCoreImpl_FSGNova2GloveImpl_DoesIndexInfluenceOthers(&InstanceContainer); +} + +void USGNova2Glove::SetIndexInfluencesOthers(const bool bInfluenceOthers) +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + SGCoreImpl_FSGNova2GloveImpl_SetIndexInfluencesOthers(&InstanceContainer, bInfluenceOthers); +} + +bool USGNova2Glove::SupportsOnBoardNormalization() const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + return SGCoreImpl_FSGNova2GloveImpl_SupportsOnBoardNormalization(&InstanceContainer); +} + +bool USGNova2Glove::GetSensorData(UObject* Outer, USGNova2GloveSensorData*& OutSensorData) +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_FSGNova2GloveSensorDataImpl OutSensorDataContainer; + const bool bResult = SGCoreImpl_FSGNova2GloveImpl_GetSensorData(&InstanceContainer, &OutSensorDataContainer); + + if (bResult) + { + OutSensorData = USGNova2GloveSensorData::NewNova2GloveSensorData( + Outer, MoveTemp(OutSensorDataContainer.Nova2GloveSensorDataImpl)); + } + + return bResult; +} + +bool USGNova2Glove::GetNormalizedInput(TArray& OutNormalizedValues) const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_TArray_float OutNormalizedValuesContainer; + const bool bResult = SGCoreImpl_FSGNova2GloveImpl_GetNormalizedInput( + &InstanceContainer, &OutNormalizedValuesContainer); + + if (bResult) + { + OutNormalizedValues = MoveTemp(OutNormalizedValuesContainer.Array); + } + + return bResult; +} + +bool USGNova2Glove::SendRawData() +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + return SGCoreImpl_FSGNova2GloveImpl_SendRawData(&InstanceContainer); +} + +bool USGNova2Glove::SendNormalizedData() +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + return SGCoreImpl_FSGNova2GloveImpl_SendNormalizedData(&InstanceContainer); +} + +ESGNova2VibroMotor USGNova2Glove::ToNovaMotor(const ESGHapticLocation Location) const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_ESGNova2VibroMotor OutVibroMotorContainer; + FSGIC_ESGHapticLocation LocationContainer{Location}; + SGCoreImpl_FSGNova2GloveImpl_ToNovaMotor(&InstanceContainer, &OutVibroMotorContainer, &LocationContainer); + return OutVibroMotorContainer.Motor; +} + +int32 USGNova2Glove::ChannelIndex(const ESGNova2VibroMotor Motor) const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_ESGNova2VibroMotor MotorContainer{Motor}; + return SGCoreImpl_FSGNova2GloveImpl_ChannelIndex(&InstanceContainer, &MotorContainer); +} + +void USGNova2Glove::ValidateWaveform(USGCustomWaveform* OutWaveform, const ESGNova2VibroMotor Motor) const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_FSGCustomWaveformImpl OutWaveformContainer{OutWaveform->ToCustomWaveformImpl()}; + FSGIC_ESGNova2VibroMotor MotorContainer{Motor}; + SGCoreImpl_FSGNova2GloveImpl_ValidateWaveform(&InstanceContainer, &OutWaveformContainer, &MotorContainer); +} + +bool USGNova2Glove::SendCustomWaveform_Nova2( + USGCustomWaveform* OutWaveform, const ESGNova2VibroMotor Motor, const bool bValidateWaveform) +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_FSGCustomWaveformImpl OutWaveformContainer{OutWaveform->ToCustomWaveformImpl()}; + FSGIC_ESGNova2VibroMotor MotorContainer{Motor}; + return SGCoreImpl_FSGNova2GloveImpl_SendCustomWaveform_Nova2( + &InstanceContainer, &OutWaveformContainer, &MotorContainer, bValidateWaveform); +} + +FString USGNova2Glove::ToString() const +{ + FSGIC_TSharedPtr_FSGNova2GloveImpl InstanceContainer{ToNova2GloveImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGNova2GloveImpl_ToString(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String;; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGNova2GloveSensorData.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGNova2GloveSensorData.cpp new file mode 100644 index 0000000..5679459 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGNova2GloveSensorData.cpp @@ -0,0 +1,377 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGNova2GloveSensorData.h" + +#include "SGCore/SGNovaGloveInfo.h" +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGCoreImpl/SGNova2GloveSensorDataImpl.h" +#include "SGInterop/SGIC_ESGFinger.h" +#include "SGInterop/SGIC_ESGNormalizationState.h" +#include "SGInterop/SGIC_ESGNova2SensorLocation.h" +#include "SGInterop/SGIC_FQuat.h" +#include "SGInterop/SGIC_FSGNova2GloveSensorDataImpl.h" +#include "SGInterop/SGIC_FSGNovaGloveInfoImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_TArray_TArray_FVector.h" +#include "SGUtils/SGArrayUtils.h" + +struct USGNova2GloveSensorData::FImpl +{ + /************************ + * Member variables + ************************/ + + FSGNova2GloveSensorDataImpl Nova2GloveSensorDataImpl; + + /************************ + * Owner object + ************************/ + + USGNova2GloveSensorData* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGNova2GloveSensorData* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGNova2GloveSensorData* USGNova2GloveSensorData::NewNova2GloveSensorData( + UObject* Outer, const FSGNova2GloveSensorDataImpl& Nova2GloveSensorDataImpl) +{ + USGNova2GloveSensorData* Instance = NewObject(Outer); + Instance->SetNova2GloveSensorDataImpl(Nova2GloveSensorDataImpl); + return Instance; +} + +USGNova2GloveSensorData* USGNova2GloveSensorData::NewNova2GloveSensorData(UObject* Outer) +{ + FSGIC_FSGNova2GloveSensorDataImpl OutNova2GloveSensorDataImplContainer; + SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor(&OutNova2GloveSensorDataImplContainer); + + return NewNova2GloveSensorData(Outer, MoveTemp(OutNova2GloveSensorDataImplContainer.Nova2GloveSensorDataImpl)); +} + +USGNova2GloveSensorData* USGNova2GloveSensorData::NewNova2GloveSensorData( + UObject* Outer, const ESGNormalizationState NormalizationState, + const TArray>& Values, const int32 ParsedValues, + const FQuat& ImuRotation, const bool bImuParsed, + const float BatteryLevel, const bool bCharging) +{ + FSGIC_FSGNova2GloveSensorDataImpl OutNova2GloveSensorDataImplContainer; + FSGIC_ESGNormalizationState NormalizationStateContainer{NormalizationState}; + FSGIC_TArray_TArray_FVector ValuesContainer{Values}; + FSGIC_FQuat ImuRotationContainer{ImuRotation}; + SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor_NormalizationState_Values_ParsedValues_ImuRotation_bImuParsed_BatteryLevel_bCharging( + &OutNova2GloveSensorDataImplContainer, &NormalizationStateContainer, + &ValuesContainer, ParsedValues, + &ImuRotationContainer, bImuParsed, BatteryLevel, bCharging); + + return NewNova2GloveSensorData(Outer, MoveTemp(OutNova2GloveSensorDataImplContainer.Nova2GloveSensorDataImpl)); +} + +USGNova2GloveSensorData* USGNova2GloveSensorData::NewNova2GloveSensorData( + UObject* Outer, const ESGNormalizationState NormalizationState, + const TArray& Values, const int32 ParsedValues, + const FQuat& ImuRotation, const bool bImuParsed, const float BatteryLevel, const bool bCharging) +{ + FSGIC_FSGNova2GloveSensorDataImpl OutNova2GloveSensorDataImplContainer; + FSGIC_ESGNormalizationState NormalizationStateContainer{NormalizationState}; + FSGIC_TArray_TArray_FVector ValuesContainer{ + FSGArrayUtils::FromNestedBPArray(Values) + }; + FSGIC_FQuat ImuRotationContainer{ImuRotation}; + SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor_NormalizationState_Values_ParsedValues_ImuRotation_bImuParsed_BatteryLevel_bCharging( + &OutNova2GloveSensorDataImplContainer, &NormalizationStateContainer, + &ValuesContainer, ParsedValues, + &ImuRotationContainer, bImuParsed, BatteryLevel, bCharging); + + return NewNova2GloveSensorData(Outer, MoveTemp(OutNova2GloveSensorDataImplContainer.Nova2GloveSensorDataImpl)); +} + +USGNova2GloveSensorData* USGNova2GloveSensorData::NewNova2GloveSensorData( + UObject* Outer, const ESGNormalizationState NormalizationState, + const TArray>& Values, const int32 ParsedValues, + const FRotator& ImuRotation, const bool bImuParsed, const float BatteryLevel, const bool bCharging) +{ + FSGIC_FSGNova2GloveSensorDataImpl OutNova2GloveSensorDataImplContainer; + FSGIC_ESGNormalizationState NormalizationStateContainer{NormalizationState}; + FSGIC_TArray_TArray_FVector ValuesContainer{Values}; + FSGIC_FQuat ImuRotationContainer{ImuRotation.Quaternion()}; + SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor_NormalizationState_Values_ParsedValues_ImuRotation_bImuParsed_BatteryLevel_bCharging( + &OutNova2GloveSensorDataImplContainer, &NormalizationStateContainer, + &ValuesContainer, ParsedValues, + &ImuRotationContainer, bImuParsed, BatteryLevel, bCharging); + + return NewNova2GloveSensorData(Outer, MoveTemp(OutNova2GloveSensorDataImplContainer.Nova2GloveSensorDataImpl)); +} + +USGNova2GloveSensorData* USGNova2GloveSensorData::NewNova2GloveSensorData( + UObject* Outer, const ESGNormalizationState NormalizationState, + const TArray& Values, const int32 ParsedValues, + const FRotator& ImuRotation, const bool bImuParsed, const float BatteryLevel, const bool bCharging) +{ + FSGIC_FSGNova2GloveSensorDataImpl OutNova2GloveSensorDataImplContainer; + FSGIC_ESGNormalizationState NormalizationStateContainer{NormalizationState}; + FSGIC_TArray_TArray_FVector ValuesContainer{ + FSGArrayUtils::FromNestedBPArray(Values) + }; + FSGIC_FQuat ImuRotationContainer{ImuRotation.Quaternion()}; + SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor_NormalizationState_Values_ParsedValues_ImuRotation_bImuParsed_BatteryLevel_bCharging( + &OutNova2GloveSensorDataImplContainer, &NormalizationStateContainer, + &ValuesContainer, ParsedValues, + &ImuRotationContainer, bImuParsed, BatteryLevel, bCharging); + + return NewNova2GloveSensorData(Outer, MoveTemp(OutNova2GloveSensorDataImplContainer.Nova2GloveSensorDataImpl)); +} + +USGNova2GloveSensorData* USGNova2GloveSensorData::Parse(UObject* Outer, + const FString& RawData, const USGNovaGloveInfo* GloveInfo) +{ + FSGIC_FSGNova2GloveSensorDataImpl OutNova2GloveSensorDataImplContainer; + FSGIC_FString RawDataString{RawData}; + FSGIC_FSGNovaGloveInfoImpl GloveInfoContainer{GloveInfo->ToNovaGloveInfoImpl()}; + SGCoreImpl_FSGNova2GloveSensorDataImpl_Parse(&OutNova2GloveSensorDataImplContainer, + &RawDataString, &GloveInfoContainer); + + return NewNova2GloveSensorData(Outer, MoveTemp(OutNova2GloveSensorDataImplContainer.Nova2GloveSensorDataImpl)); +} + +USGNova2GloveSensorData::USGNova2GloveSensorData() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGNova2GloveSensorDataImpl OutNova2GloveSensorDataImplContainer; + SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor(&OutNova2GloveSensorDataImplContainer); + + Pimpl->Nova2GloveSensorDataImpl = MoveTemp(OutNova2GloveSensorDataImplContainer.Nova2GloveSensorDataImpl); +} + +USGNova2GloveSensorData::USGNova2GloveSensorData(const ESGNormalizationState NormalizationState, + const TArray>& Values, const int32 ParsedValues, + const FQuat& ImuRotation, const bool bImuParsed, + const float BatteryLevel, const bool bCharging) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGNova2GloveSensorDataImpl OutNova2GloveSensorDataImplContainer; + FSGIC_ESGNormalizationState NormalizationStateContainer{NormalizationState}; + FSGIC_TArray_TArray_FVector ValuesContainer{Values}; + FSGIC_FQuat ImuRotationContainer{ImuRotation}; + SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor_NormalizationState_Values_ParsedValues_ImuRotation_bImuParsed_BatteryLevel_bCharging( + &OutNova2GloveSensorDataImplContainer, &NormalizationStateContainer, + &ValuesContainer, ParsedValues, + &ImuRotationContainer, bImuParsed, BatteryLevel, bCharging); + + Pimpl->Nova2GloveSensorDataImpl = MoveTemp(OutNova2GloveSensorDataImplContainer.Nova2GloveSensorDataImpl); +} + +USGNova2GloveSensorData::USGNova2GloveSensorData(const ESGNormalizationState NormalizationState, + const TArray& Values, const int32 ParsedValues, + const FQuat& ImuRotation, const bool bImuParsed, + const float BatteryLevel, const bool bCharging) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGNova2GloveSensorDataImpl OutNova2GloveSensorDataImplContainer; + FSGIC_ESGNormalizationState NormalizationStateContainer{NormalizationState}; + FSGIC_TArray_TArray_FVector ValuesContainer{ + FSGArrayUtils::FromNestedBPArray(Values) + }; + FSGIC_FQuat ImuRotationContainer{ImuRotation}; + SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor_NormalizationState_Values_ParsedValues_ImuRotation_bImuParsed_BatteryLevel_bCharging( + &OutNova2GloveSensorDataImplContainer, &NormalizationStateContainer, + &ValuesContainer, ParsedValues, + &ImuRotationContainer, bImuParsed, BatteryLevel, bCharging); + + Pimpl->Nova2GloveSensorDataImpl = MoveTemp(OutNova2GloveSensorDataImplContainer.Nova2GloveSensorDataImpl); +} + +USGNova2GloveSensorData::USGNova2GloveSensorData(const ESGNormalizationState NormalizationState, + const TArray>& Values, const int32 ParsedValues, + const FRotator& ImuRotation, const bool bImuParsed, + const float BatteryLevel, const bool bCharging) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGNova2GloveSensorDataImpl OutNova2GloveSensorDataImplContainer; + FSGIC_ESGNormalizationState NormalizationStateContainer{NormalizationState}; + FSGIC_TArray_TArray_FVector ValuesContainer{Values}; + FSGIC_FQuat ImuRotationContainer{ImuRotation.Quaternion()}; + SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor_NormalizationState_Values_ParsedValues_ImuRotation_bImuParsed_BatteryLevel_bCharging( + &OutNova2GloveSensorDataImplContainer, &NormalizationStateContainer, + &ValuesContainer, ParsedValues, + &ImuRotationContainer, bImuParsed, BatteryLevel, bCharging); + + Pimpl->Nova2GloveSensorDataImpl = MoveTemp(OutNova2GloveSensorDataImplContainer.Nova2GloveSensorDataImpl); +} + +USGNova2GloveSensorData::USGNova2GloveSensorData(const ESGNormalizationState NormalizationState, + const TArray& Values, const int32 ParsedValues, + const FRotator& ImuRotation, const bool bImuParsed, + const float BatteryLevel, const bool bCharging) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGNova2GloveSensorDataImpl OutNova2GloveSensorDataImplContainer; + FSGIC_ESGNormalizationState NormalizationStateContainer{NormalizationState}; + FSGIC_TArray_TArray_FVector ValuesContainer{ + FSGArrayUtils::FromNestedBPArray(Values) + }; + FSGIC_FQuat ImuRotationContainer{ImuRotation.Quaternion()}; + SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor_NormalizationState_Values_ParsedValues_ImuRotation_bImuParsed_BatteryLevel_bCharging( + &OutNova2GloveSensorDataImplContainer, &NormalizationStateContainer, + &ValuesContainer, ParsedValues, + &ImuRotationContainer, bImuParsed, BatteryLevel, bCharging); + + Pimpl->Nova2GloveSensorDataImpl = MoveTemp(OutNova2GloveSensorDataImplContainer.Nova2GloveSensorDataImpl); +} + +USGNova2GloveSensorData::USGNova2GloveSensorData(const FSGNova2GloveSensorDataImpl& Nova2GloveSensorDataImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + SetNova2GloveSensorDataImpl(Nova2GloveSensorDataImpl); +} + +USGNova2GloveSensorData::~USGNova2GloveSensorData() = default; + +void USGNova2GloveSensorData::SetNova2GloveSensorDataImpl(const FSGNova2GloveSensorDataImpl& Nova2GloveSensorDataImpl) +{ + FSGIC_FSGNova2GloveSensorDataImpl OutNova2GloveSensorDataContainer; + FSGIC_FSGNova2GloveSensorDataImpl RhsContainer{Nova2GloveSensorDataImpl}; + SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor_copy(&OutNova2GloveSensorDataContainer, &RhsContainer); + Pimpl->Nova2GloveSensorDataImpl = MoveTemp(OutNova2GloveSensorDataContainer.Nova2GloveSensorDataImpl); +} + +const FSGNova2GloveSensorDataImpl& USGNova2GloveSensorData::ToNova2GloveSensorDataImpl() const +{ + return Pimpl->Nova2GloveSensorDataImpl; +} + +ESGNormalizationState USGNova2GloveSensorData::GetSensorState() const +{ + FSGIC_FSGNova2GloveSensorDataImpl InstanceContainer{ToNova2GloveSensorDataImpl()}; + FSGIC_ESGNormalizationState OutNormalizationState; + SGCoreImpl_FSGNova2GloveSensorDataImpl_GetSensorState(&InstanceContainer, &OutNormalizationState); + return OutNormalizationState.State; +} + +TArray> USGNova2GloveSensorData::GetSensorValues() const +{ + FSGIC_FSGNova2GloveSensorDataImpl InstanceContainer{ToNova2GloveSensorDataImpl()}; + FSGIC_TArray_TArray_FVector OutValuesContainer; + SGCoreImpl_FSGNova2GloveSensorDataImpl_GetSensorValues(&InstanceContainer, &OutValuesContainer); + return OutValuesContainer.Array; +} + +float USGNova2GloveSensorData::GetSensorValue(const ESGFinger Finger, const ESGNova2SensorLocation Location) const +{ + FSGIC_FSGNova2GloveSensorDataImpl InstanceContainer{ToNova2GloveSensorDataImpl()}; + FSGIC_ESGFinger FingerContainer{Finger}; + FSGIC_ESGNova2SensorLocation LocationContainer{Location}; + return SGCoreImpl_FSGNova2GloveSensorDataImpl_GetSensorValue( + &InstanceContainer, &FingerContainer, &LocationContainer); +} + +int32 USGNova2GloveSensorData::GetParsedValues() const +{ + FSGIC_FSGNova2GloveSensorDataImpl InstanceContainer{ToNova2GloveSensorDataImpl()}; + return SGCoreImpl_FSGNova2GloveSensorDataImpl_GetParsedValues(&InstanceContainer); +} + +FQuat USGNova2GloveSensorData::GetImuRotationQ() const +{ + FSGIC_FSGNova2GloveSensorDataImpl InstanceContainer{ToNova2GloveSensorDataImpl()}; + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGNova2GloveSensorDataImpl_GetImuRotation(&InstanceContainer, &OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator USGNova2GloveSensorData::GetImuRotation() const +{ + FSGIC_FSGNova2GloveSensorDataImpl InstanceContainer{ToNova2GloveSensorDataImpl()}; + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGNova2GloveSensorDataImpl_GetImuRotation(&InstanceContainer, &OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +bool USGNova2GloveSensorData::IsImuParsed() const +{ + FSGIC_FSGNova2GloveSensorDataImpl InstanceContainer{ToNova2GloveSensorDataImpl()}; + return SGCoreImpl_FSGNova2GloveSensorDataImpl_IsImuParsed(&InstanceContainer); +} + +float USGNova2GloveSensorData::GetBatteryLevel() const +{ + FSGIC_FSGNova2GloveSensorDataImpl InstanceContainer{ToNova2GloveSensorDataImpl()}; + return SGCoreImpl_FSGNova2GloveSensorDataImpl_GetBatteryLevel(&InstanceContainer); +} + +bool USGNova2GloveSensorData::IsCharging() const +{ + FSGIC_FSGNova2GloveSensorDataImpl InstanceContainer{ToNova2GloveSensorDataImpl()}; + return SGCoreImpl_FSGNova2GloveSensorDataImpl_IsCharging(&InstanceContainer); +} + +bool USGNova2GloveSensorData::Equals(const USGNova2GloveSensorData* Nova2GloveSensorData) const +{ + FSGIC_FSGNova2GloveSensorDataImpl InstanceContainer{ToNova2GloveSensorDataImpl()}; + FSGIC_FSGNova2GloveSensorDataImpl Nova2GloveSensorDataContainer{Nova2GloveSensorData->ToNova2GloveSensorDataImpl()}; + return SGCoreImpl_FSGNova2GloveSensorDataImpl_Equals(&InstanceContainer, &Nova2GloveSensorDataContainer); +} + +FString USGNova2GloveSensorData::ToString() const +{ + FSGIC_FSGNova2GloveSensorDataImpl InstanceContainer{ToNova2GloveSensorDataImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGNova2GloveSensorDataImpl_ToString(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +USGNova2GloveSensorData::FImpl::FImpl(USGNova2GloveSensorData* InOwner) + : Owner(InOwner) +{ +} + +USGNova2GloveSensorData::FImpl::~FImpl() = default; + +void USGNova2GloveSensorData::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGNovaGlove.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGNovaGlove.cpp new file mode 100644 index 0000000..7d44102 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGNovaGlove.cpp @@ -0,0 +1,781 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGNovaGlove.h" + +#include "SGCore/SGBasicHandModel.h" +#include "SGCore/SGCustomWaveform.h" +#include "SGCore/SGDeviceImplCast.h" +#include "SGCore/SGHandInterpolator.h" +#include "SGCore/SGHandPose.h" +#include "SGCore/SGNovaGloveInfo.h" +#include "SGCore/SGNovaGloveSensorData.h" +#include "SGCore/SGSensorNormalization.h" +#include "SGCore/SGThresholdCommand.h" +#include "SGCoreImpl/SGDeviceImpl.h" +#include "SGCoreImpl/SGHapticGloveImpl.h" +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGCoreImpl/SGNovaGloveImpl.h" +#include "SGInterop/SGIC_ESGDeviceType.h" +#include "SGInterop/SGIC_ESGHapticGloveCalibrationState.h" +#include "SGInterop/SGIC_ESGHapticLocation.h" +#include "SGInterop/SGIC_ESGNovaVibroMotor.h" +#include "SGInterop/SGIC_ESGPositionalTrackingHardware.h" +#include "SGInterop/SGIC_FQuat.h" +#include "SGInterop/SGIC_FSGBasicHandModelImpl.h" +#include "SGInterop/SGIC_FSGCustomWaveformImpl.h" +#include "SGInterop/SGIC_FSGHandInterpolatorImpl.h" +#include "SGInterop/SGIC_FSGHandPoseImpl.h" +#include "SGInterop/SGIC_FSGNovaGloveImpl.h" +#include "SGInterop/SGIC_FSGNovaGloveInfoImpl.h" +#include "SGInterop/SGIC_FSGNovaGloveSensorDataImpl.h" +#include "SGInterop/SGIC_FSGSensorNormalizationImpl.h" +#include "SGInterop/SGIC_FSGThresholdCommandImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_FVector.h" +#include "SGInterop/SGIC_TArray_FSGNovaGloveImpl.h" +#include "SGInterop/SGIC_TArray_FVector.h" +#include "SGInterop/SGIC_TArray_TArray_FVector.h" +#include "SGInterop/SGIC_TArray_float.h" +#include "SGInterop/SGIC_TSharedPtr_FSGNovaGloveImpl.h" + +USGNovaGlove* USGNovaGlove::NewNovaGlove(UObject* Outer, const FSGNovaGloveImpl& NovaGloveImpl) +{ + USGNovaGlove* Instance = NewObject(Outer); + Instance->SetSGDeviceImpl(NovaGloveImpl); + return Instance; +} + +USGNovaGlove* USGNovaGlove::NewNovaGlove(UObject* Outer, TSharedRef NovaGloveImpl) +{ + USGNovaGlove* Instance = NewObject(Outer); + Instance->SetSGDeviceImpl(MoveTemp(NovaGloveImpl)); + return Instance; +} + +USGNovaGlove* USGNovaGlove::NewNovaGlove(UObject* Outer) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl OutSharedPtrContainer; + SGCoreImpl_FSGNovaGloveImpl_ctor_MakeShared(&OutSharedPtrContainer); + + return NewNovaGlove(Outer, OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +USGNovaGlove* USGNovaGlove::NewNovaGlove(UObject* Outer, const USGNovaGloveInfo& DeviceInfo) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl OutSharedPtrContainer; + FSGIC_FSGNovaGloveInfoImpl DeviceInfoContainer{DeviceInfo.ToNovaGloveInfoImpl()}; + SGCoreImpl_FSGNovaGloveImpl_ctor_DeviceInfo_MakeShared(&OutSharedPtrContainer, &DeviceInfoContainer); + + return NewNovaGlove(Outer, OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +USGDevice* USGNovaGlove::Parse(UObject* Outer, const FString& ConstantsString) +{ + FSGIC_FSGNovaGloveImpl OutNovaGloveImplContainer; + FSGIC_FString ConstantsStringContainer{ConstantsString}; + SGCoreImpl_FSGNovaGloveImpl_Parse(&OutNovaGloveImplContainer, &ConstantsStringContainer); + + return NewNovaGlove(Outer, MoveTemp(OutNovaGloveImplContainer.NovaGloveImpl)); +} + +TArray USGNovaGlove::GetNovaGloves(UObject* Outer) +{ + FSGIC_TArray_FSGNovaGloveImpl OutGlovesContainer; + SGCoreImpl_FSGNovaGloveImpl_GetNovaGloves(&OutGlovesContainer); + TArray Gloves; + for (const FSGNovaGloveImpl& NovaGloveImpl: OutGlovesContainer.Array) + { + USGNovaGlove* NovaGlove = USGNovaGlove::NewNovaGlove(Outer, NovaGloveImpl); + Gloves.Add(NovaGlove); + } + return Gloves; +} + +bool USGNovaGlove::GetNovaGlove(UObject* Outer, USGNovaGlove*& OutGlove) +{ + FSGIC_FSGNovaGloveImpl OutGloveContainer; + const bool bResult = SGCoreImpl_FSGNovaGloveImpl_GetNovaGlove_OutGlove(&OutGloveContainer); + + if (bResult) + { + OutGlove = NewNovaGlove(Outer, MoveTemp(OutGloveContainer.NovaGloveImpl)); + } + + return bResult; +} + +bool USGNovaGlove::GetNovaGlove(UObject* Outer, const bool bRightHanded, USGNovaGlove*& OutGlove) +{ + FSGIC_FSGNovaGloveImpl OutGloveContainer; + const bool bResult = SGCoreImpl_FSGNovaGloveImpl_GetNovaGlove_bRightHanded_OutGlove( + bRightHanded, &OutGloveContainer); + + if (bResult) + { + OutGlove = NewNovaGlove(Outer, MoveTemp(OutGloveContainer.NovaGloveImpl)); + } + + return bResult; +} + +void USGNovaGlove::CalculateGloveLocation( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, + FVector& OutGlovePosition, FQuat& OutGloveRotation) +{ + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutGlovePositionContainer; + FSGIC_FQuat OutGloveRotationContainer; + + SGCoreImpl_FSGNovaGloveImpl_CalculateGloveLocation( + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, bRightHanded, + &OutGlovePositionContainer, &OutGloveRotationContainer); + + OutGlovePosition = MoveTemp(OutGlovePositionContainer.Vector); + OutGloveRotation = MoveTemp(OutGloveRotationContainer.Quat); +} + +void USGNovaGlove::CalculateGloveLocation( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, + FVector& OutGlovePosition, FRotator& OutGloveRotation) +{ + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation.Quaternion()}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutGlovePositionContainer; + FSGIC_FQuat OutGloveRotationContainer; + + SGCoreImpl_FSGNovaGloveImpl_CalculateGloveLocation( + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, bRightHanded, + &OutGlovePositionContainer, &OutGloveRotationContainer); + + OutGlovePosition = MoveTemp(OutGlovePositionContainer.Vector); + OutGloveRotation = OutGloveRotationContainer.Quat.Rotator(); +} + +void USGNovaGlove::CalculateWristLocation( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, + FVector& OutWristPosition, FQuat& OutWristRotation) +{ + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutWristPositionContainer; + FSGIC_FQuat OutWristRotationContainer; + + SGCoreImpl_FSGNovaGloveImpl_CalculateWristLocation( + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, bRightHanded, + &OutWristPositionContainer, &OutWristRotationContainer); + + OutWristPosition = MoveTemp(OutWristPositionContainer.Vector); + OutWristRotation = MoveTemp(OutWristRotationContainer.Quat); +} + +void USGNovaGlove::CalculateWristLocation( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, + FVector& OutWristPosition, FRotator& OutWristRotation) +{ + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation.Quaternion()}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutWristPositionContainer; + FSGIC_FQuat OutWristRotationContainer; + + SGCoreImpl_FSGNovaGloveImpl_CalculateWristLocation( + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, bRightHanded, + &OutWristPositionContainer, &OutWristRotationContainer); + + OutWristPosition = MoveTemp(OutWristPositionContainer.Vector); + OutWristRotation = OutWristRotationContainer.Quat.Rotator(); +} + +ANSICHAR USGNovaGlove::GetHapticsByte() +{ + return SGCoreImpl_FSGNovaGloveImpl_GetHapticsByte(); +} + +ANSICHAR USGNovaGlove::GetThresholdsByte() +{ + return SGCoreImpl_FSGNovaGloveImpl_GetThresholdsByte(); +} + +ANSICHAR USGNovaGlove::GetIgnoreThresholdsByte() +{ + return SGCoreImpl_FSGNovaGloveImpl_GetIgnoreThresholdsByte(); +} + +TArray USGNovaGlove::GetNovaSensorRanges() +{ + FSGIC_TArray_float OutNovaSensorRangesContainer; + SGCoreImpl_FSGNovaGloveImpl_GetNovaSensorRanges(&OutNovaSensorRangesContainer); + return OutNovaSensorRangesContainer.Array; +} + +TArray USGNovaGlove::ToNormalizedValues(const USGNovaGloveSensorData* SensorData) +{ + FSGIC_TArray_float OutNormalizedValuesContainer; + FSGIC_FSGNovaGloveSensorDataImpl SensorDataContainer{SensorData->ToNovaGloveSensorDataImpl()}; + SGCoreImpl_FSGNovaGloveImpl_ToNormalizedValues_SensorData( + &OutNormalizedValuesContainer, &SensorDataContainer); + return OutNormalizedValuesContainer.Array; +} + +TArray USGNovaGlove::ToNormalizedValues( + UObject* Outer, const USGNovaGloveSensorData* SensorData, USGSensorNormalization*& OutSensorNormalizer) +{ + FSGIC_TArray_float OutNormalizedValuesContainer; + FSGIC_FSGNovaGloveSensorDataImpl SensorDataContainer{SensorData->ToNovaGloveSensorDataImpl()}; + FSGIC_FSGSensorNormalizationImpl OutSensorNormalizerContainer; + SGCoreImpl_FSGNovaGloveImpl_ToNormalizedValues_SensorData_OutSensorNormalizer( + &OutNormalizedValuesContainer, &SensorDataContainer, &OutSensorNormalizerContainer); + + OutSensorNormalizer = USGSensorNormalization::NewSensorNormalization( + Outer, MoveTemp(OutSensorNormalizerContainer.SensorNormalizationImpl)); + + return OutNormalizedValuesContainer.Array; +} + +TArray> USGNovaGlove::CalculateHandAngles( + const TArray& NormalizedValues, const USGHandInterpolator* Interpolator) +{ + FSGIC_TArray_TArray_FVector OutHandAnglesContainer; + FSGIC_TArray_float NormalizedValuesContainer{NormalizedValues}; + FSGIC_FSGHandInterpolatorImpl InterpolatorContainer{Interpolator->ToHandInterpolatorImpl()}; + SGCoreImpl_FSGNovaGloveImpl_CalculateHandAngles( + &OutHandAnglesContainer, &NormalizedValuesContainer, &InterpolatorContainer); + return OutHandAnglesContainer.Array; +} + +FString USGNovaGlove::ToNovaCommandAsFlexion(const USGThresholdCommand* Thresholds) +{ + FSGIC_FString OutStringContainer; + FSGIC_FSGThresholdCommandImpl ThresholdsContainer{Thresholds->ToThresholdCommandImpl()}; + SGCoreImpl_FSGNovaGloveImpl_ToNovaCommandAsFlexion(&OutStringContainer, &ThresholdsContainer); + return OutStringContainer.String; +} + +FString USGNovaGlove::ToNovaCommandAsRaw( + const USGThresholdCommand* Thresholds, const USGSensorNormalization* Interpolator) +{ + FSGIC_FString OutStringContainer; + FSGIC_FSGThresholdCommandImpl ThresholdsContainer{Thresholds->ToThresholdCommandImpl()}; + FSGIC_FSGSensorNormalizationImpl InterpolatorContainer{Interpolator->ToSensorNormalizationImpl()}; + SGCoreImpl_FSGNovaGloveImpl_ToNovaCommandAsRaw( + &OutStringContainer, &ThresholdsContainer, &InterpolatorContainer); + return OutStringContainer.String; +} + +USGNovaGlove::USGNovaGlove() + : USGHapticGlove() +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl OutSharedPtrContainer; + SGCoreImpl_FSGNovaGloveImpl_ctor_MakeShared(&OutSharedPtrContainer); + + SetSGDeviceImpl(OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +USGNovaGlove::USGNovaGlove(const USGNovaGloveInfo& DeviceInfo) + : USGHapticGlove() +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl OutSharedPtrContainer; + FSGIC_FSGNovaGloveInfoImpl DeviceInfoContainer{DeviceInfo.ToNovaGloveInfoImpl()}; + SGCoreImpl_FSGNovaGloveImpl_ctor_DeviceInfo_MakeShared(&OutSharedPtrContainer, &DeviceInfoContainer); + + SetSGDeviceImpl(OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +USGNovaGlove::USGNovaGlove(const FSGDeviceImpl& SGDeviceImpl) + : USGHapticGlove(SGDeviceImpl) +{ +} + +USGNovaGlove::USGNovaGlove(const FSGHapticGloveImpl& HapticGloveImpl) + : USGHapticGlove(HapticGloveImpl) +{ +} + +USGNovaGlove::USGNovaGlove(const FSGNovaGloveImpl& NovaGloveImpl) + : USGHapticGlove(NovaGloveImpl) +{ +} + +USGNovaGlove::USGNovaGlove(const TSharedRef SGDeviceImpl) + : USGHapticGlove(SGDeviceImpl) +{ +} + +USGNovaGlove::USGNovaGlove(const TSharedRef HapticGloveImpl) + : USGHapticGlove(HapticGloveImpl) +{ +} + +USGNovaGlove::USGNovaGlove(const TSharedRef NovaGloveImpl) + : USGHapticGlove(NovaGloveImpl) +{ +} + +USGNovaGlove::~USGNovaGlove() = default; + +TSharedRef USGNovaGlove::ToNovaGloveImpl() const +{ + return FSGDeviceImplCast::ToNovaGloveImpl(ToSGDeviceImpl()); +} + +ESGDeviceType USGNovaGlove::GetDeviceType() const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_ESGDeviceType OutTypeContainer; + SGCoreImpl_FSGNovaGloveImpl_GetDeviceType(&InstanceContainer, &OutTypeContainer); + return OutTypeContainer.Type; +} + +FString USGNovaGlove::GetDeviceId() const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_FString OutIdContainer; + SGCoreImpl_FSGNovaGloveImpl_GetDeviceId(&InstanceContainer, &OutIdContainer); + return OutIdContainer.String; +} + +FString USGNovaGlove::GetHardwareVersion() const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_FString OutVersionContainer; + SGCoreImpl_FSGNovaGloveImpl_GetHardwareVersion(&InstanceContainer, &OutVersionContainer); + return OutVersionContainer.String; +} + +int32 USGNovaGlove::GetFirmwareVersion() const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + return SGCoreImpl_FSGNovaGloveImpl_GetFirmwareVersion(&InstanceContainer); +} + +int32 USGNovaGlove::GetSubFirmwareVersion() const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + return SGCoreImpl_FSGNovaGloveImpl_GetSubFirmwareVersion(&InstanceContainer); +} + +void USGNovaGlove::SetDeviceIndex(int32 NewIndex) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + return SGCoreImpl_FSGNovaGloveImpl_SetDeviceIndex(&InstanceContainer, NewIndex); +} + +bool USGNovaGlove::HasBattery() const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + return SGCoreImpl_FSGNovaGloveImpl_HasBattery(&InstanceContainer); +} + +bool USGNovaGlove::IsCharging() +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + const bool bResult = SGCoreImpl_FSGNovaGloveImpl_IsCharging(&InstanceContainer); + return bResult; +} + +bool USGNovaGlove::GetBatteryLevel(float& OutBatteryLevel) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + const bool bResult = SGCoreImpl_FSGNovaGloveImpl_GetBatteryLevel(&InstanceContainer, &OutBatteryLevel); + return bResult; +} + +bool USGNovaGlove::IsRight() const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + return SGCoreImpl_FSGNovaGloveImpl_IsRight(&InstanceContainer); +} + + +bool USGNovaGlove::GetImuRotation(FQuat& OutImu) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_FQuat OutImuContainer; + const bool bResult = SGCoreImpl_FSGNovaGloveImpl_GetImuRotation(&InstanceContainer, &OutImuContainer); + + if (bResult) + { + OutImu = MoveTemp(OutImuContainer.Quat); + } + + return bResult; +} + +bool USGNovaGlove::GetImuRotation(FRotator& OutImu) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_FQuat OutImuContainer; + const bool bResult = SGCoreImpl_FSGNovaGloveImpl_GetImuRotation(&InstanceContainer, &OutImuContainer); + + if (bResult) + { + OutImu = OutImuContainer.Quat.Rotator(); + } + + return bResult; +} + +bool USGNovaGlove::GetHandPose(UObject* Outer, const USGBasicHandModel* HandGeometry, USGHandPose*& OutHandPose) const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_FSGBasicHandModelImpl HandModelContainer{HandGeometry->ToBasicHandModelImpl()}; + FSGIC_FSGHandPoseImpl OutHandPoseContainer; + const bool bResult = SGCoreImpl_FSGNovaGloveImpl_GetHandPose( + &InstanceContainer, &HandModelContainer, &OutHandPoseContainer); + + if (bResult) + { + OutHandPose = USGHandPose::NewHandPose(Outer, MoveTemp(OutHandPoseContainer.HandPoseImpl)); + } + + return bResult; +} + +bool USGNovaGlove::GetHandAngles(TArray>& OutHandAngles) const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_TArray_TArray_FVector OutHandAnglesContainer; + const bool bResult = SGCoreImpl_FSGNovaGloveImpl_GetHandAngles(&InstanceContainer, &OutHandAnglesContainer); + OutHandAngles = MoveTemp(OutHandAnglesContainer.Array); + return bResult; + +} + +ESGHapticGloveCalibrationState USGNovaGlove::GetCalibrationState() const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_ESGHapticGloveCalibrationState OutHapticGloveCalibrationStateContainer; + SGCoreImpl_FSGNovaGloveImpl_GetCalibrationState(&InstanceContainer, &OutHapticGloveCalibrationStateContainer); + return OutHapticGloveCalibrationStateContainer.State; +} + +void USGNovaGlove::EndCalibration() +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + SGCoreImpl_FSGNovaGloveImpl_EndCalibration(&InstanceContainer); +} + +void USGNovaGlove::ResetCalibration() +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + SGCoreImpl_FSGNovaGloveImpl_ResetCalibration(&InstanceContainer); +} + +void USGNovaGlove::StopHaptics() +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + SGCoreImpl_FSGNovaGloveImpl_StopHaptics(&InstanceContainer); +} + +void USGNovaGlove::StopVibrations() +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + SGCoreImpl_FSGNovaGloveImpl_StopVibrations(&InstanceContainer); +} + +bool USGNovaGlove::SendHaptics() +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + return SGCoreImpl_FSGNovaGloveImpl_SendHaptics(&InstanceContainer); +} + +bool USGNovaGlove::SupportsCustomWaveform(ESGHapticLocation AtLocation) const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + return SGCoreImpl_FSGNovaGloveImpl_SendHaptics(&InstanceContainer); +} + +bool USGNovaGlove::SendCustomWaveform(USGCustomWaveform* OutWaveform, ESGHapticLocation Location) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + return SGCoreImpl_FSGNovaGloveImpl_SendHaptics(&InstanceContainer); +} + +bool USGNovaGlove::QueueForceFeedbackLevels(const TArray& Levels01) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_TArray_float Levels01Container{Levels01}; + return SGCoreImpl_FSGNovaGloveImpl_QueueForceFeedbackLevels(&InstanceContainer, &Levels01Container); +} + +bool USGNovaGlove::QueueForceFeedbackLevel(const int32 Finger, const float Level01) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + return SGCoreImpl_FSGNovaGloveImpl_QueueForceFeedbackLevel(&InstanceContainer, Finger, Level01); +} + +bool USGNovaGlove::QueueVibroLevels(const TArray& Amplitudes) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_TArray_float AmplitudesContainer{Amplitudes}; + return SGCoreImpl_FSGNovaGloveImpl_QueueVibroLevels(&InstanceContainer, &AmplitudesContainer); +} + +bool USGNovaGlove::QueueVibroLevel(ESGHapticLocation Location, float Level01) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_ESGHapticLocation LocationContainer{Location}; + return SGCoreImpl_FSGNovaGloveImpl_QueueVibroLevel_Localtion_Level01( + &InstanceContainer, &LocationContainer, Level01); +} + +void USGNovaGlove::GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutGlovePositionContainer; + FSGIC_FQuat OutGloveRotationContainer; + + SGCoreImpl_FSGNovaGloveImpl_GetGloveLocation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &OutGlovePositionContainer, &OutGloveRotationContainer); + + OutGlovePosition = MoveTemp(OutGlovePositionContainer.Vector); + OutGloveRotation = MoveTemp(OutGloveRotationContainer.Quat); +} + +void USGNovaGlove::GetGloveLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FRotator& OutGloveRotation) const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation.Quaternion()}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutGlovePositionContainer; + FSGIC_FQuat OutGloveRotationContainer; + + SGCoreImpl_FSGNovaGloveImpl_GetGloveLocation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &OutGlovePositionContainer, &OutGloveRotationContainer); + + OutGlovePosition = MoveTemp(OutGlovePositionContainer.Vector); + OutGloveRotation = OutGloveRotationContainer.Quat.Rotator(); +} + +void USGNovaGlove::GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutWristPositionContainer; + FSGIC_FQuat OutWristRotationContainer; + SGCoreImpl_FSGNovaGloveImpl_GetWristLocation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &OutWristPositionContainer, &OutWristRotationContainer); + + OutWristPosition = MoveTemp(OutWristPositionContainer.Vector); + OutWristRotation = MoveTemp(OutWristRotationContainer.Quat); +} + +void USGNovaGlove::GetWristLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FRotator& OutWristRotation) const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation.Quaternion()}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutWristPositionContainer; + FSGIC_FQuat OutWristRotationContainer; + SGCoreImpl_FSGNovaGloveImpl_GetWristLocation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &OutWristPositionContainer, &OutWristRotationContainer); + + OutWristPosition = MoveTemp(OutWristPositionContainer.Vector); + OutWristRotation = OutWristRotationContainer.Quat.Rotator(); +} + +USGNovaGloveInfo* USGNovaGlove::GetGloveInfo(UObject* Outer) const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_FSGNovaGloveInfoImpl OutGloveInfoContainer; + SGCoreImpl_FSGNovaGloveImpl_GetGloveInfo(&InstanceContainer, &OutGloveInfoContainer); + return USGNovaGloveInfo::NewNovaGloveInfo(Outer, MoveTemp(OutGloveInfoContainer.NovaGloveInfoImpl)); +} + +bool USGNovaGlove::SupportsThresholds() const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + return SGCoreImpl_FSGNovaGloveImpl_SupportsThresholds(&InstanceContainer); +} + +bool USGNovaGlove::SupportsCustomWaveforms() const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + return SGCoreImpl_FSGNovaGloveImpl_SupportsCustomWaveforms(&InstanceContainer); +} + +bool USGNovaGlove::SupportsOnBoardNormalization() const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + return SGCoreImpl_FSGNovaGloveImpl_SupportsOnBoardNormalization(&InstanceContainer); +} + +bool USGNovaGlove::GetSensorData(UObject* Outer, USGNovaGloveSensorData*& OutSensorData) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_FSGNovaGloveSensorDataImpl OutSensorDataContainer; + const bool bResult = SGCoreImpl_FSGNovaGloveImpl_GetSensorData(&InstanceContainer, &OutSensorDataContainer); + + if (bResult) + { + OutSensorData = USGNovaGloveSensorData::NewNovaGloveSensorData( + Outer, MoveTemp(OutSensorDataContainer.NovaGloveSensorDataImpl)); + } + + return bResult; +} + +bool USGNovaGlove::GetNormalizedInput(TArray& OutNormalizedValues) const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_TArray_float OutNormalizedValuesContainer; + const bool bResult = SGCoreImpl_FSGNovaGloveImpl_GetNormalizedInput( + &InstanceContainer, &OutNormalizedValuesContainer); + + if (bResult) + { + OutNormalizedValues = MoveTemp(OutNormalizedValuesContainer.Array); + } + + return bResult; +} + +FString USGNovaGlove::ToNovaCommand( + const TArray& ForceFeedbackLevels, const TArray& BuzzLevels, float WristLevel) const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_FString OutStringContainer; + FSGIC_TArray_float ForceFeedbackLevelsContainer{ForceFeedbackLevels}; + FSGIC_TArray_float BuzzLevelsContainer{BuzzLevels}; + SGCoreImpl_FSGNovaGloveImpl_ToNovaCommand(&InstanceContainer, &OutStringContainer, + &ForceFeedbackLevelsContainer, &BuzzLevelsContainer, WristLevel); + return OutStringContainer.String; +} + +bool USGNovaGlove::QueueVibroLevel(const int32 Finger, const float Amplitude) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + return SGCoreImpl_FSGNovaGloveImpl_QueueVibroLevel_Finger_Amplitude(&InstanceContainer, Finger, Amplitude); +} + +bool USGNovaGlove::QueueWristLevel(const float Amplitude) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + return SGCoreImpl_FSGNovaGloveImpl_QueueWristLevel(&InstanceContainer, Amplitude); +} + +ESGNovaVibroMotor USGNovaGlove::ToNovaMotor(const ESGHapticLocation Location) const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_ESGNovaVibroMotor OutVibroMotorContainer; + FSGIC_ESGHapticLocation LocationContainer{Location}; + SGCoreImpl_FSGNovaGloveImpl_ToNovaMotor(&InstanceContainer, &OutVibroMotorContainer, &LocationContainer); + return OutVibroMotorContainer.Motor; +} + +int32 USGNovaGlove::ChannelIndex(const ESGNovaVibroMotor Motor) const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_ESGNovaVibroMotor MotorContainer{Motor}; + return SGCoreImpl_FSGNovaGloveImpl_ChannelIndex(&InstanceContainer, &MotorContainer); +} + +void USGNovaGlove::ValidateWaveform(USGCustomWaveform* OutWaveform, const ESGNovaVibroMotor Motor) const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_FSGCustomWaveformImpl OutWaveformContainer{OutWaveform->ToCustomWaveformImpl()}; + FSGIC_ESGNovaVibroMotor MotorContainer{Motor}; + SGCoreImpl_FSGNovaGloveImpl_ValidateWaveform(&InstanceContainer, &OutWaveformContainer, &MotorContainer); +} + +bool USGNovaGlove::SendCustomWaveform_Nova( + USGCustomWaveform* OutWaveform, const ESGNovaVibroMotor Motor, const bool bValidateWaveform) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_FSGCustomWaveformImpl OutWaveformContainer{OutWaveform->ToCustomWaveformImpl()}; + FSGIC_ESGNovaVibroMotor MotorContainer{Motor}; + return SGCoreImpl_FSGNovaGloveImpl_SendCustomWaveform_Nova( + &InstanceContainer, &OutWaveformContainer, &MotorContainer, bValidateWaveform); +} + +bool USGNovaGlove::QueueThresholdCommand_Flexion(const int32 Finger, const float FlexionThreshold) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + return SGCoreImpl_FSGNovaGloveImpl_QueueThresholdCommand_Flexion(&InstanceContainer, Finger, FlexionThreshold); +} + +bool USGNovaGlove::QueueClearThreshold(const int32 Finger) +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + return SGCoreImpl_FSGNovaGloveImpl_QueueClearThreshold(&InstanceContainer, Finger); +} + +FString USGNovaGlove::ToString() const +{ + FSGIC_TSharedPtr_FSGNovaGloveImpl InstanceContainer{ToNovaGloveImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGNovaGloveImpl_ToString(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String;; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGNovaGloveInfo.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGNovaGloveInfo.cpp new file mode 100644 index 0000000..1b93b42 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGNovaGloveInfo.cpp @@ -0,0 +1,285 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGNovaGloveInfo.h" + +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_FQuat.h" +#include "SGInterop/SGIC_FSGNovaGloveInfoImpl.h" +#include "SGInterop/SGIC_FString.h" + +struct USGNovaGloveInfo::FImpl +{ + /************************ + * Member variables + ************************/ + + FSGNovaGloveInfoImpl NovaGloveInfoImpl; + + /************************ + * Owner object + ************************/ + + USGNovaGloveInfo* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGNovaGloveInfo* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGNovaGloveInfo* USGNovaGloveInfo::NewNovaGloveInfo(UObject* Outer, const FSGNovaGloveInfoImpl& NovaGloveInfoImpl) +{ + USGNovaGloveInfo* Instance = NewObject(Outer); + Instance->SetNovaGloveInfoImpl(NovaGloveInfoImpl); + return Instance; +} + +USGNovaGloveInfo* USGNovaGloveInfo::NewNovaGloveInfo(UObject* Outer) +{ + FSGIC_FSGNovaGloveInfoImpl OutNovaGloveInfoImplContainer; + SGCoreImpl_FSGNovaGloveInfoImpl_ctor(&OutNovaGloveInfoImplContainer); + + return NewNovaGloveInfo(Outer, MoveTemp(OutNovaGloveInfoImplContainer.NovaGloveInfoImpl)); +} + +USGNovaGloveInfo* USGNovaGloveInfo::NewNovaGloveInfo(UObject* Outer, const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, + int32 SubFirmwareVersion, bool bRightHanded, + const FQuat& ImuCorrection, int32 NumberOfSensors) +{ + FSGIC_FSGNovaGloveInfoImpl OutNovaGloveInfoImplContainer; + FSGIC_FString DeviceIdContainer{DeviceId}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FQuat ImuCorrectionContainer{ImuCorrection}; + SGCoreImpl_FSGNovaGloveInfoImpl_ctor_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded_ImuCorrection_NumberOfSensors( + &OutNovaGloveInfoImplContainer, + &DeviceIdContainer, &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion, + bRightHanded, &ImuCorrectionContainer, NumberOfSensors); + + return NewNovaGloveInfo(Outer, MoveTemp(OutNovaGloveInfoImplContainer.NovaGloveInfoImpl)); +} + +bool USGNovaGloveInfo::Parse(UObject* Outer, const FString& ConstantsString, USGNovaGloveInfo*& OutGloveInfo) +{ + FSGIC_FString ConstantsStringContainer{ConstantsString}; + FSGIC_FSGNovaGloveInfoImpl OutGloveInfoImplContainer; + const bool bResult = SGCoreImpl_FSGNovaGloveInfoImpl_Parse(&ConstantsStringContainer, &OutGloveInfoImplContainer); + + if (bResult) + { + OutGloveInfo = NewNovaGloveInfo(Outer, MoveTemp(OutGloveInfoImplContainer.NovaGloveInfoImpl)); + } + + return bResult; +} + +USGNovaGloveInfo* USGNovaGloveInfo::Deserialize(UObject* Outer, const FString& SerializedString) +{ + FSGIC_FString SerializedStringContainer{SerializedString}; + FSGIC_FSGNovaGloveInfoImpl OutNovaGloveInfoImplContainer; + SGCoreImpl_FSGNovaGloveInfoImpl_Deserialize(&OutNovaGloveInfoImplContainer, &SerializedStringContainer); + + return NewNovaGloveInfo(Outer, MoveTemp(OutNovaGloveInfoImplContainer.NovaGloveInfoImpl)); +} + +USGNovaGloveInfo::USGNovaGloveInfo() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGNovaGloveInfoImpl OutNovaGloveInfoImplContainer; + SGCoreImpl_FSGNovaGloveInfoImpl_ctor(&OutNovaGloveInfoImplContainer); + + Pimpl->NovaGloveInfoImpl = MoveTemp(OutNovaGloveInfoImplContainer.NovaGloveInfoImpl); +} + +USGNovaGloveInfo::USGNovaGloveInfo( + const FString& DeviceId, + const FString& HardwareVersion, const int32 FirmwareVersion, const int32 SubFirmwareVersion, + const bool bRightHanded, const FQuat& ImuCorrection, const int32 NumberOfSensors) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGNovaGloveInfoImpl OutNovaGloveInfoImplContainer; + FSGIC_FString DeviceIdContainer{DeviceId}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FQuat ImuCorrectionContainer{ImuCorrection}; + SGCoreImpl_FSGNovaGloveInfoImpl_ctor_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded_ImuCorrection_NumberOfSensors( + &OutNovaGloveInfoImplContainer, + &DeviceIdContainer, &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion, + bRightHanded, &ImuCorrectionContainer, NumberOfSensors); + + Pimpl->NovaGloveInfoImpl = MoveTemp(OutNovaGloveInfoImplContainer.NovaGloveInfoImpl); +} + +USGNovaGloveInfo::USGNovaGloveInfo(const FSGNovaGloveInfoImpl& NovaGloveInfoImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + SetNovaGloveInfoImpl(NovaGloveInfoImpl); +} + +USGNovaGloveInfo::~USGNovaGloveInfo() = default; + +void USGNovaGloveInfo::SetNovaGloveInfoImpl(const FSGNovaGloveInfoImpl& NovaGloveInfoImpl) +{ + FSGIC_FSGNovaGloveInfoImpl OutNovaGloveInfoContainer; + FSGIC_FSGNovaGloveInfoImpl RhsContainer{NovaGloveInfoImpl}; + SGCoreImpl_FSGNovaGloveInfoImpl_ctor_copy(&OutNovaGloveInfoContainer, &RhsContainer); + Pimpl->NovaGloveInfoImpl = MoveTemp(OutNovaGloveInfoContainer.NovaGloveInfoImpl); +} + +const FSGNovaGloveInfoImpl& USGNovaGloveInfo::ToNovaGloveInfoImpl() const +{ + return Pimpl->NovaGloveInfoImpl; +} + +FSGNovaGloveInfoImpl& USGNovaGloveInfo::ToNovaGloveInfoImpl() +{ + return Pimpl->NovaGloveInfoImpl; +} + +FString USGNovaGloveInfo::GetDeviceId() const +{ + FSGIC_FSGNovaGloveInfoImpl InstanceContainer{ToNovaGloveInfoImpl()}; + FSGIC_FString OutIdContainer; + SGCoreImpl_FSGNovaGloveInfoImpl_GetDeviceId(&InstanceContainer, &OutIdContainer); + return OutIdContainer.String; +} + +FString USGNovaGloveInfo::GetHardwareVersion() const +{ + FSGIC_FSGNovaGloveInfoImpl InstanceContainer{ToNovaGloveInfoImpl()}; + FSGIC_FString OutVersionContainer; + SGCoreImpl_FSGNovaGloveInfoImpl_GetHardwareVersion(&InstanceContainer, &OutVersionContainer); + return OutVersionContainer.String; +} + +int32 USGNovaGloveInfo::GetFirmwareVersion() const +{ + FSGIC_FSGNovaGloveInfoImpl InstanceContainer{ToNovaGloveInfoImpl()}; + return SGCoreImpl_FSGNovaGloveInfoImpl_GetFirmwareVersion(&InstanceContainer); +} + +int32 USGNovaGloveInfo::GetSubFirmwareVersion() const +{ + FSGIC_FSGNovaGloveInfoImpl InstanceContainer{ToNovaGloveInfoImpl()}; + return SGCoreImpl_FSGNovaGloveInfoImpl_GetSubFirmwareVersion(&InstanceContainer); +} + +bool USGNovaGloveInfo::IsRight() const +{ + FSGIC_FSGNovaGloveInfoImpl InstanceContainer{ToNovaGloveInfoImpl()}; + return SGCoreImpl_FSGNovaGloveInfoImpl_IsRight(&InstanceContainer); +} + +FQuat USGNovaGloveInfo::GetImuCorrectionQ() const +{ + FSGIC_FSGNovaGloveInfoImpl InstanceContainer{ToNovaGloveInfoImpl()}; + FSGIC_FQuat OutCorrectionContainer; + SGCoreImpl_FSGNovaGloveInfoImpl_GetImuCorrection(&InstanceContainer, &OutCorrectionContainer); + return OutCorrectionContainer.Quat; +} + +FRotator USGNovaGloveInfo::GetImuCorrection() const +{ + FSGIC_FSGNovaGloveInfoImpl InstanceContainer{ToNovaGloveInfoImpl()}; + FSGIC_FQuat OutCorrectionContainer; + SGCoreImpl_FSGNovaGloveInfoImpl_GetImuCorrection(&InstanceContainer, &OutCorrectionContainer); + return OutCorrectionContainer.Quat.Rotator(); +} + +int32 USGNovaGloveInfo::GetNumberOfSensors() const +{ + FSGIC_FSGNovaGloveInfoImpl InstanceContainer{ToNovaGloveInfoImpl()}; + return SGCoreImpl_FSGNovaGloveInfoImpl_GetNumberOfSensors(&InstanceContainer); +} + +bool USGNovaGloveInfo::FirmwareNewerThan( + const int32 FirmwareMain, const int32 FirmwareSub, const bool bInclusive) const +{ + FSGIC_FSGNovaGloveInfoImpl InstanceContainer{ToNovaGloveInfoImpl()}; + return SGCoreImpl_FSGNovaGloveInfoImpl_FirmwareNewerThan(&InstanceContainer, + FirmwareMain, FirmwareSub, bInclusive); +} + +bool USGNovaGloveInfo::FirmwareOlderThan( + const int32 FirmwareMain, const int32 FirmwareSub, const bool bInclusive) const +{ + FSGIC_FSGNovaGloveInfoImpl InstanceContainer{ToNovaGloveInfoImpl()}; + return SGCoreImpl_FSGNovaGloveInfoImpl_FirmwareOlderThan(&InstanceContainer, + FirmwareMain, FirmwareSub, bInclusive); +} + +bool USGNovaGloveInfo::Equals(const USGNovaGloveInfo* NovaGloveInfo) const +{ + FSGIC_FSGNovaGloveInfoImpl InstanceContainer{ToNovaGloveInfoImpl()}; + FSGIC_FSGNovaGloveInfoImpl NovaGloveInfoImplContainer{NovaGloveInfo->ToNovaGloveInfoImpl()}; + return SGCoreImpl_FSGNovaGloveInfoImpl_Equals(&InstanceContainer, &NovaGloveInfoImplContainer); +} + +FString USGNovaGloveInfo::ToString() const +{ + FSGIC_FSGNovaGloveInfoImpl InstanceContainer{ToNovaGloveInfoImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGNovaGloveInfoImpl_ToString(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +FString USGNovaGloveInfo::SGSerialize() const +{ + FSGIC_FSGNovaGloveInfoImpl InstanceContainer{ToNovaGloveInfoImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGNovaGloveInfoImpl_Serialize(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +USGNovaGloveInfo::FImpl::FImpl(USGNovaGloveInfo* InOwner) + : Owner(InOwner) +{ +} + +USGNovaGloveInfo::FImpl::~FImpl() = default; + +void USGNovaGloveInfo::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGNovaGloveSensorData.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGNovaGloveSensorData.cpp new file mode 100644 index 0000000..f52483f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGNovaGloveSensorData.cpp @@ -0,0 +1,301 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 NovaGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGNovaGloveSensorData.h" + +#include "SGCore/SGNovaGloveInfo.h" +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGCoreImpl/SGNovaGloveSensorDataImpl.h" +#include "SGInterop/SGIC_ESGFinger.h" +#include "SGInterop/SGIC_ESGNovaSensorLocation.h" +#include "SGInterop/SGIC_FQuat.h" +#include "SGInterop/SGIC_FSGNovaGloveInfoImpl.h" +#include "SGInterop/SGIC_FSGNovaGloveSensorDataImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_TArray_FVector.h" + +struct USGNovaGloveSensorData::FImpl +{ + /************************ + * Member variables + ************************/ + + FSGNovaGloveSensorDataImpl NovaGloveSensorDataImpl; + + /************************ + * Owner object + ************************/ + + USGNovaGloveSensorData* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGNovaGloveSensorData* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGNovaGloveSensorData* USGNovaGloveSensorData::NewNovaGloveSensorData( + UObject* Outer, const FSGNovaGloveSensorDataImpl& NovaGloveSensorDataImpl) +{ + USGNovaGloveSensorData* Instance = NewObject(Outer); + Instance->SetNovaGloveSensorDataImpl(NovaGloveSensorDataImpl); + return Instance; +} + +USGNovaGloveSensorData* USGNovaGloveSensorData::NewNovaGloveSensorData(UObject* Outer) +{ + FSGIC_FSGNovaGloveSensorDataImpl OutNovaGloveSensorDataImplContainer; + SGCoreImpl_FSGNovaGloveSensorDataImpl_ctor(&OutNovaGloveSensorDataImplContainer); + + return NewNovaGloveSensorData(Outer, MoveTemp(OutNovaGloveSensorDataImplContainer.NovaGloveSensorDataImpl)); +} + +USGNovaGloveSensorData* USGNovaGloveSensorData::NewNovaGloveSensorData( + UObject* Outer, const TArray& Values, const int32 ParsedValues, + const FQuat& ImuRotation, const bool bImuParsed, const float BatteryLevel, const bool bCharging) +{ + FSGIC_FSGNovaGloveSensorDataImpl OutNovaGloveSensorDataImplContainer; + FSGIC_TArray_FVector ValuesContainer{Values}; + FSGIC_FQuat ImuRotationContainer{ImuRotation}; + SGCoreImpl_FSGNovaGloveSensorDataImpl_ctor_Values_ParsedValues_ImuRotation_bImuParsed_BatteryLevel_bCharging( + &OutNovaGloveSensorDataImplContainer, &ValuesContainer, ParsedValues, + &ImuRotationContainer, bImuParsed, BatteryLevel, bCharging); + + return NewNovaGloveSensorData(Outer, MoveTemp(OutNovaGloveSensorDataImplContainer.NovaGloveSensorDataImpl)); +} + +USGNovaGloveSensorData* USGNovaGloveSensorData::NewNovaGloveSensorData( + UObject* Outer, const TArray& Values, const int32 ParsedValues, + const FRotator& ImuRotation, const bool bImuParsed, const float BatteryLevel, const bool bCharging) +{ + FSGIC_FSGNovaGloveSensorDataImpl OutNovaGloveSensorDataImplContainer; + FSGIC_TArray_FVector ValuesContainer{Values}; + FSGIC_FQuat ImuRotationContainer{ImuRotation.Quaternion()}; + SGCoreImpl_FSGNovaGloveSensorDataImpl_ctor_Values_ParsedValues_ImuRotation_bImuParsed_BatteryLevel_bCharging( + &OutNovaGloveSensorDataImplContainer, &ValuesContainer, ParsedValues, + &ImuRotationContainer, bImuParsed, BatteryLevel, bCharging); + + return NewNovaGloveSensorData(Outer, MoveTemp(OutNovaGloveSensorDataImplContainer.NovaGloveSensorDataImpl)); +} + +USGNovaGloveSensorData* USGNovaGloveSensorData::Empty(UObject* Outer) +{ + FSGIC_FSGNovaGloveSensorDataImpl OutNovaGloveSensorDataImplContainer; + SGCoreImpl_FSGNovaGloveSensorDataImpl_Empty(&OutNovaGloveSensorDataImplContainer); + + return NewNovaGloveSensorData(Outer, MoveTemp(OutNovaGloveSensorDataImplContainer.NovaGloveSensorDataImpl)); +} + +USGNovaGloveSensorData* USGNovaGloveSensorData::Parse(UObject* Outer, + const FString& RawData, const USGNovaGloveInfo* GloveInfo) +{ + FSGIC_FSGNovaGloveSensorDataImpl OutNovaGloveSensorDataImplContainer; + FSGIC_FString RawDataString{RawData}; + FSGIC_FSGNovaGloveInfoImpl GloveInfoContainer{GloveInfo->ToNovaGloveInfoImpl()}; + SGCoreImpl_FSGNovaGloveSensorDataImpl_Parse(&OutNovaGloveSensorDataImplContainer, + &RawDataString, &GloveInfoContainer); + + return NewNovaGloveSensorData(Outer, MoveTemp(OutNovaGloveSensorDataImplContainer.NovaGloveSensorDataImpl)); +} + +USGNovaGloveSensorData* USGNovaGloveSensorData::Deserialize(UObject* Outer, const FString& SerializedString) +{ + FSGIC_FSGNovaGloveSensorDataImpl OutNovaGloveSensorDataImplContainer; + FSGIC_FString SerializedStringContainer{SerializedString}; + SGCoreImpl_FSGNovaGloveSensorDataImpl_Deserialize(&OutNovaGloveSensorDataImplContainer, &SerializedStringContainer); + + return NewNovaGloveSensorData(Outer, MoveTemp(OutNovaGloveSensorDataImplContainer.NovaGloveSensorDataImpl)); +} + +USGNovaGloveSensorData::USGNovaGloveSensorData() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGNovaGloveSensorDataImpl OutNovaGloveSensorDataImplContainer; + SGCoreImpl_FSGNovaGloveSensorDataImpl_ctor(&OutNovaGloveSensorDataImplContainer); + + Pimpl->NovaGloveSensorDataImpl = MoveTemp(OutNovaGloveSensorDataImplContainer.NovaGloveSensorDataImpl); +} + +USGNovaGloveSensorData::USGNovaGloveSensorData(const TArray& Values, const int32 ParsedValues, + const FQuat& ImuRotation, const bool bImuParsed, + const float BatteryLevel, const bool bCharging) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGNovaGloveSensorDataImpl OutNovaGloveSensorDataImplContainer; + FSGIC_TArray_FVector ValuesContainer{Values}; + FSGIC_FQuat ImuRotationContainer{ImuRotation}; + SGCoreImpl_FSGNovaGloveSensorDataImpl_ctor_Values_ParsedValues_ImuRotation_bImuParsed_BatteryLevel_bCharging( + &OutNovaGloveSensorDataImplContainer, &ValuesContainer, ParsedValues, + &ImuRotationContainer, bImuParsed, BatteryLevel, bCharging); + + Pimpl->NovaGloveSensorDataImpl = MoveTemp(OutNovaGloveSensorDataImplContainer.NovaGloveSensorDataImpl); +} + +USGNovaGloveSensorData::USGNovaGloveSensorData(const TArray& Values, const int32 ParsedValues, + const FRotator& ImuRotation, const bool bImuParsed, + const float BatteryLevel, const bool bCharging) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGNovaGloveSensorDataImpl OutNovaGloveSensorDataImplContainer; + FSGIC_TArray_FVector ValuesContainer{Values}; + FSGIC_FQuat ImuRotationContainer{ImuRotation.Quaternion()}; + SGCoreImpl_FSGNovaGloveSensorDataImpl_ctor_Values_ParsedValues_ImuRotation_bImuParsed_BatteryLevel_bCharging( + &OutNovaGloveSensorDataImplContainer, &ValuesContainer, ParsedValues, + &ImuRotationContainer, bImuParsed, BatteryLevel, bCharging); + + Pimpl->NovaGloveSensorDataImpl = MoveTemp(OutNovaGloveSensorDataImplContainer.NovaGloveSensorDataImpl); +} + +USGNovaGloveSensorData::USGNovaGloveSensorData(const FSGNovaGloveSensorDataImpl& NovaGloveSensorDataImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + SetNovaGloveSensorDataImpl(NovaGloveSensorDataImpl); +} + +USGNovaGloveSensorData::~USGNovaGloveSensorData() = default; + +void USGNovaGloveSensorData::SetNovaGloveSensorDataImpl(const FSGNovaGloveSensorDataImpl& NovaGloveSensorDataImpl) +{ + FSGIC_FSGNovaGloveSensorDataImpl OutNovaGloveSensorDataContainer; + FSGIC_FSGNovaGloveSensorDataImpl RhsContainer{NovaGloveSensorDataImpl}; + SGCoreImpl_FSGNovaGloveSensorDataImpl_ctor_copy(&OutNovaGloveSensorDataContainer, &RhsContainer); + Pimpl->NovaGloveSensorDataImpl = MoveTemp(OutNovaGloveSensorDataContainer.NovaGloveSensorDataImpl); +} + +const FSGNovaGloveSensorDataImpl& USGNovaGloveSensorData::ToNovaGloveSensorDataImpl() const +{ + return Pimpl->NovaGloveSensorDataImpl; +} + +TArray USGNovaGloveSensorData::GetSensorValues() const +{ + FSGIC_FSGNovaGloveSensorDataImpl InstanceContainer{ToNovaGloveSensorDataImpl()}; + FSGIC_TArray_FVector OutValuesContainer; + SGCoreImpl_FSGNovaGloveSensorDataImpl_GetSensorValues(&InstanceContainer, &OutValuesContainer); + return OutValuesContainer.Array; +} + +float USGNovaGloveSensorData::GetSensorValue(const ESGFinger Finger, const ESGNovaSensorLocation Location) const +{ + FSGIC_FSGNovaGloveSensorDataImpl InstanceContainer{ToNovaGloveSensorDataImpl()}; + FSGIC_ESGFinger FingerContainer{Finger}; + FSGIC_ESGNovaSensorLocation LocationContainer{Location}; + return SGCoreImpl_FSGNovaGloveSensorDataImpl_GetSensorValue( + &InstanceContainer, &FingerContainer, &LocationContainer); +} + +int32 USGNovaGloveSensorData::GetParsedValues() const +{ + FSGIC_FSGNovaGloveSensorDataImpl InstanceContainer{ToNovaGloveSensorDataImpl()}; + return SGCoreImpl_FSGNovaGloveSensorDataImpl_GetParsedValues(&InstanceContainer); +} + +FQuat USGNovaGloveSensorData::GetImuRotationQ() const +{ + FSGIC_FSGNovaGloveSensorDataImpl InstanceContainer{ToNovaGloveSensorDataImpl()}; + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGNovaGloveSensorDataImpl_GetImuRotation(&InstanceContainer, &OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator USGNovaGloveSensorData::GetImuRotation() const +{ + FSGIC_FSGNovaGloveSensorDataImpl InstanceContainer{ToNovaGloveSensorDataImpl()}; + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGNovaGloveSensorDataImpl_GetImuRotation(&InstanceContainer, &OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +bool USGNovaGloveSensorData::IsImuParsed() const +{ + FSGIC_FSGNovaGloveSensorDataImpl InstanceContainer{ToNovaGloveSensorDataImpl()}; + return SGCoreImpl_FSGNovaGloveSensorDataImpl_IsImuParsed(&InstanceContainer); +} + +float USGNovaGloveSensorData::GetBatteryLevel() const +{ + FSGIC_FSGNovaGloveSensorDataImpl InstanceContainer{ToNovaGloveSensorDataImpl()}; + return SGCoreImpl_FSGNovaGloveSensorDataImpl_GetBatteryLevel(&InstanceContainer); +} + +bool USGNovaGloveSensorData::IsCharging() const +{ + FSGIC_FSGNovaGloveSensorDataImpl InstanceContainer{ToNovaGloveSensorDataImpl()}; + return SGCoreImpl_FSGNovaGloveSensorDataImpl_IsCharging(&InstanceContainer); +} + +bool USGNovaGloveSensorData::Equals(const USGNovaGloveSensorData* NovaGloveSensorData) const +{ + FSGIC_FSGNovaGloveSensorDataImpl InstanceContainer{ToNovaGloveSensorDataImpl()}; + FSGIC_FSGNovaGloveSensorDataImpl NovaGloveSensorDataContainer{NovaGloveSensorData->ToNovaGloveSensorDataImpl()}; + return SGCoreImpl_FSGNovaGloveSensorDataImpl_Equals(&InstanceContainer, &NovaGloveSensorDataContainer); +} + +FString USGNovaGloveSensorData::ToString() const +{ + FSGIC_FSGNovaGloveSensorDataImpl InstanceContainer{ToNovaGloveSensorDataImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGNovaGloveSensorDataImpl_ToString(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +FString USGNovaGloveSensorData::SGSerialize() const +{ + FSGIC_FSGNovaGloveSensorDataImpl InstanceContainer{ToNovaGloveSensorDataImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGNovaGloveSensorDataImpl_Serialize(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +USGNovaGloveSensorData::FImpl::FImpl(USGNovaGloveSensorData* InOwner) + : Owner(InOwner) +{ +} + +USGNovaGloveSensorData::FImpl::~FImpl() = default; + +void USGNovaGloveSensorData::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseCom.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseCom.cpp new file mode 100644 index 0000000..6e8cac6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseCom.cpp @@ -0,0 +1,86 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGSenseCom.h" + +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_FString.h" + +bool FSGSenseCom::RegisterExe() +{ + return SGCoreImpl_FSGSenseComImpl_RegisterExe(); +} + +bool FSGSenseCom::RegisterExe(const FString& ExePath) +{ + FSGIC_FString ExePathContainer{ExePath}; + return SGCoreImpl_FSGSenseComImpl_RegisterExe_ExePath(&ExePathContainer); +} + +bool FSGSenseCom::GetExePath(FString& OutExePath) +{ + FSGIC_FString OutExePathContainer; + const bool bResult = SGCoreImpl_FSGSenseComImpl_GetExePath(&OutExePathContainer); + + if (bResult) + { + OutExePath = MoveTemp(OutExePathContainer.String); + } + + return bResult; +} + +bool FSGSenseCom::ScanningActive() +{ + return SGCoreImpl_FSGSenseComImpl_ScanningActive(); +} + +bool FSGSenseCom::GetCurrentExeDirectory(FString& OutDirectory) +{ + FSGIC_FString OutDirectoryContainer; + const bool bResult = SGCoreImpl_FSGSenseComImpl_GetCurrentExeDirectory(&OutDirectoryContainer); + + if (bResult) + { + OutDirectory = MoveTemp(OutDirectoryContainer.String); + } + + return bResult; +} + +bool FSGSenseCom::StartupSenseCom() +{ + return SGCoreImpl_FSGSenseComImpl_StartupSenseCom(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGlove.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGlove.cpp new file mode 100644 index 0000000..8f3f7ac --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGlove.cpp @@ -0,0 +1,826 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGSenseGlove.h" + +#include "SGCore/SGDeviceImplCast.h" +#include "SGCore/SGHandInterpolator.h" +#include "SGCore/SGHandPose.h" +#include "SGCore/SGSenseGloveSensorNormalizer.h" +#include "SGCoreImpl/SGDeviceImpl.h" +#include "SGCoreImpl/SGHandInterpolatorImpl.h" +#include "SGCoreImpl/SGHandPoseImpl.h" +#include "SGCoreImpl/SGHapticGloveImpl.h" +#include "SGCoreImpl/SGHapticGloveImpl.h" +#include "SGCoreImpl/SGSenseGloveSensorNormalizerImpl.h" +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGCoreImpl/SGSenseGloveImpl.h" +#include "SGInterop/SGIC_ESGDeviceType.h" +#include "SGInterop/SGIC_ESGFinger.h" +#include "SGInterop/SGIC_ESGHapticGloveCalibrationState.h" +#include "SGInterop/SGIC_ESGHapticLocation.h" +#include "SGInterop/SGIC_ESGPositionalTrackingHardware.h" +#include "SGInterop/SGIC_ESGSenseGloveThumperCommand.h" +#include "SGInterop/SGIC_FQuat.h" +#include "SGInterop/SGIC_FSGBasicHandModelImpl.h" +#include "SGInterop/SGIC_FSGHandInterpolatorImpl.h" +#include "SGInterop/SGIC_FSGHandPoseImpl.h" +#include "SGInterop/SGIC_FSGSenseGloveImpl.h" +#include "SGInterop/SGIC_FSGSenseGloveInfoImpl.h" +#include "SGInterop/SGIC_FSGSenseGlovePoseImpl.h" +#include "SGInterop/SGIC_FSGSenseGloveSensorDataImpl.h" +#include "SGInterop/SGIC_FSGSenseGloveSensorNormalizerImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_FVector.h" +#include "SGInterop/SGIC_TArray_float.h" +#include "SGInterop/SGIC_TArray_FVector.h" +#include "SGInterop/SGIC_TArray_FSGSenseGloveImpl.h" +#include "SGInterop/SGIC_TArray_TArray_FVector.h" +#include "SGInterop/SGIC_TSharedPtr_FSGSenseGloveImpl.h" + +USGSenseGlove* USGSenseGlove::NewSenseGlove(UObject* Outer, const FSGSenseGloveImpl& SenseGloveImpl) +{ + USGSenseGlove* Instance = NewObject(Outer); + Instance->SetSGDeviceImpl(SenseGloveImpl); + return Instance; +} + +USGSenseGlove* USGSenseGlove::NewSenseGlove(UObject* Outer, TSharedRef SenseGloveImpl) +{ + USGSenseGlove* Instance = NewObject(Outer); + Instance->SetSGDeviceImpl(MoveTemp(SenseGloveImpl)); + return Instance; +} + +USGSenseGlove* USGSenseGlove::NewSenseGlove(UObject* Outer) +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl OutSharedPtrContainer; + SGCoreImpl_FSGSenseGloveImpl_ctor_MakeShared(&OutSharedPtrContainer); + + return NewSenseGlove(Outer, OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +USGSenseGlove* USGSenseGlove::NewSenseGlove(UObject* Outer, const USGSenseGloveInfo& Model) +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl OutSharedPtrContainer; + FSGIC_FSGSenseGloveInfoImpl ModelContainer{Model.ToSenseGloveInfoImpl()}; + SGCoreImpl_FSGSenseGloveImpl_ctor_Model_MakeShared(&OutSharedPtrContainer, &ModelContainer); + + return NewSenseGlove(Outer, OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +USGDevice* USGSenseGlove::Parse(UObject* Outer, const FString& ConstantsString) +{ + FSGIC_FSGSenseGloveImpl OutSenseGloveImplContainer; + FSGIC_FString ConstantsStringContainer{ConstantsString}; + SGCoreImpl_FSGSenseGloveImpl_Parse(&OutSenseGloveImplContainer, &ConstantsStringContainer); + + return NewSenseGlove(Outer, MoveTemp(OutSenseGloveImplContainer.SenseGloveImpl)); +} + +TArray USGSenseGlove::GetSenseGloves(UObject* Outer) +{ + FSGIC_TArray_FSGSenseGloveImpl OutGlovesContainer; + SGCoreImpl_FSGSenseGloveImpl_GetSenseGloves(&OutGlovesContainer); + TArray Gloves; + for (const FSGSenseGloveImpl& SenseGloveImpl: OutGlovesContainer.Array) + { + USGSenseGlove* SenseGlove = USGSenseGlove::NewSenseGlove(Outer, SenseGloveImpl); + Gloves.Add(SenseGlove); + } + return Gloves; +} + +bool USGSenseGlove::GetSenseGlove(UObject* Outer, USGSenseGlove*& OutGlove) +{ + FSGIC_FSGSenseGloveImpl OutGloveContainer; + const bool bResult = SGCoreImpl_FSGSenseGloveImpl_GetSenseGlove_OutGlove(&OutGloveContainer); + + if (bResult) + { + OutGlove = NewSenseGlove(Outer, MoveTemp(OutGloveContainer.SenseGloveImpl)); + } + + return bResult; +} + +bool USGSenseGlove::GetSenseGlove(UObject* Outer, const bool bRightHanded, USGSenseGlove*& OutGlove) +{ + FSGIC_FSGSenseGloveImpl OutGloveContainer; + const bool bResult = SGCoreImpl_FSGSenseGloveImpl_GetSenseGlove_bRightHanded_OutGlove( + bRightHanded, &OutGloveContainer); + + if (bResult) + { + OutGlove = NewSenseGlove(Outer, MoveTemp(OutGloveContainer.SenseGloveImpl)); + } + + return bResult; +} + +void USGSenseGlove::CalculateGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + const bool bRightHanded, const ESGFinger MountedOn, + FVector& OutGlovePosition, FQuat& OutGloveRotation) +{ + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_ESGFinger MountedOnContainer{MountedOn}; + FSGIC_FVector OutGlovePositionContainer; + FSGIC_FQuat OutGloveRotationContainer; + + SGCoreImpl_FSGSenseGloveImpl_CalculateGloveLocation( + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + bRightHanded, &MountedOnContainer, + &OutGlovePositionContainer, &OutGloveRotationContainer); + + OutGlovePosition = MoveTemp(OutGlovePositionContainer.Vector); + OutGloveRotation = MoveTemp(OutGloveRotationContainer.Quat); +} + +void USGSenseGlove::CalculateGloveLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + const bool bRightHanded, const ESGFinger MountedOn, + FVector& OutGlovePosition, FRotator& OutGloveRotation) +{ + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation.Quaternion()}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_ESGFinger MountedOnContainer{MountedOn}; + FSGIC_FVector OutGlovePositionContainer; + FSGIC_FQuat OutGloveRotationContainer; + + SGCoreImpl_FSGSenseGloveImpl_CalculateGloveLocation( + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + bRightHanded, &MountedOnContainer, + &OutGlovePositionContainer, &OutGloveRotationContainer); + + OutGlovePosition = MoveTemp(OutGlovePositionContainer.Vector); + OutGloveRotation = OutGloveRotationContainer.Quat.Rotator(); +} + +void USGSenseGlove::CalculateWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + const bool bRightHanded, const ESGFinger MountedOn, + const FVector& GloveWristPositionOffset, + const FQuat& GloveWristRotationOffset, + FVector& OutWristPosition, FQuat& OutWristRotation) +{ + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_ESGFinger MountedOnContainer{MountedOn}; + FSGIC_FVector GloveWristPositionOffsetContainer{GloveWristPositionOffset}; + FSGIC_FQuat GloveWristRotationOffsetContainer{GloveWristRotationOffset}; + FSGIC_FVector OutWristPositionContainer; + FSGIC_FQuat OutWristRotationContainer; + + SGCoreImpl_FSGSenseGloveImpl_CalculateWristLocation( + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + bRightHanded, &MountedOnContainer, + &GloveWristPositionOffsetContainer, &GloveWristRotationOffsetContainer, + &OutWristPositionContainer, &OutWristRotationContainer); + + OutWristPosition = MoveTemp(OutWristPositionContainer.Vector); + OutWristRotation = MoveTemp(OutWristRotationContainer.Quat); +} + +void USGSenseGlove::CalculateWristLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + const bool bRightHanded, const ESGFinger MountedOn, + const FVector& GloveWristPositionOffset, + const FRotator& GloveWristRotationOffset, + FVector& OutWristPosition, FRotator& OutWristRotation) +{ + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation.Quaternion()}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_ESGFinger MountedOnContainer{MountedOn}; + FSGIC_FVector GloveWristPositionOffsetContainer{GloveWristPositionOffset}; + FSGIC_FQuat GloveWristRotationOffsetContainer{GloveWristRotationOffset.Quaternion()}; + FSGIC_FVector OutWristPositionContainer; + FSGIC_FQuat OutWristRotationContainer; + + SGCoreImpl_FSGSenseGloveImpl_CalculateWristLocation( + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + bRightHanded, &MountedOnContainer, + &GloveWristPositionOffsetContainer, &GloveWristRotationOffsetContainer, + &OutWristPositionContainer, &OutWristRotationContainer); + + OutWristPosition = MoveTemp(OutWristPositionContainer.Vector); + OutWristRotation = OutWristRotationContainer.Quat.Rotator(); +} + +ANSICHAR USGSenseGlove::GetHapticsByte() +{ + return SGCoreImpl_FSGSenseGloveImpl_GetHapticsByte(); +} + +ANSICHAR USGSenseGlove::GetThumperByte() +{ + return SGCoreImpl_FSGSenseGloveImpl_GetThumperByte(); +} + +FVector USGSenseGlove::GetDefaultThimbleOffset() +{ + FSGIC_FVector OutOffsetContainer; + SGCoreImpl_FSGSenseGloveImpl_GetDefaultThimbleOffset(&OutOffsetContainer); + return OutOffsetContainer.Vector; +} + +USGSenseGlovePose* USGSenseGlove::CalculateGlovePose(UObject* Outer, + const USGSenseGloveSensorData* SensorData, + const USGSenseGloveInfo* GloveModel) +{ + FSGIC_FSGSenseGlovePoseImpl OutPoseContainer; + FSGIC_FSGSenseGloveSensorDataImpl SensorDataContainer{SensorData->ToSenseGloveSensorDataImpl()}; + FSGIC_FSGSenseGloveInfoImpl GloveModelContainer{GloveModel->ToSenseGloveInfoImpl()}; + SGCoreImpl_FSGSenseGloveImpl_CalculateGlovePose_SensorData_GloveModel( + &OutPoseContainer, &SensorDataContainer, &GloveModelContainer); + + return USGSenseGlovePose::NewSenseGlovePose(Outer, MoveTemp(OutPoseContainer.SenseGlovePoseImpl)); +} + +USGSenseGlovePose* USGSenseGlove::CalculateGlovePose(UObject* Outer, + const TArray>& GloveAngles, + const USGSenseGloveInfo* GloveModel) +{ + FSGIC_FSGSenseGlovePoseImpl OutPoseContainer; + FSGIC_TArray_TArray_FVector GloveAnglesContainer{GloveAngles}; + FSGIC_FSGSenseGloveInfoImpl GloveModelContainer{GloveModel->ToSenseGloveInfoImpl()}; + SGCoreImpl_FSGSenseGloveImpl_CalculateGlovePose_GloveAngles_GloveModel( + &OutPoseContainer, &GloveAnglesContainer, &GloveModelContainer); + + return USGSenseGlovePose::NewSenseGlovePose(Outer, MoveTemp(OutPoseContainer.SenseGlovePoseImpl)); +} + +void USGSenseGlove::NormalizeValues( + const TArray& SumAngles, const USGSenseGloveSensorNormalizer* Normalizer, + TArray& OutFlexions, TArray& OutAbductions) +{ + FSGIC_TArray_FVector SumAnglesContainer{SumAngles}; + FSGIC_FSGSenseGloveSensorNormalizerImpl NormalizerContainer{Normalizer->ToSenseGloveSensorNormalizerImpl()}; + FSGIC_TArray_float OutFlexionsContainer; + FSGIC_TArray_float OutAbductionsContainer; + SGCoreImpl_FSGSenseGloveImpl_NormalizeValues( + &SumAnglesContainer, &NormalizerContainer, &OutFlexionsContainer, &OutAbductionsContainer); + + OutFlexions = MoveTemp(OutFlexionsContainer.Array); + OutAbductions = MoveTemp(OutAbductionsContainer.Array); +} + +void USGSenseGlove::CalculateHandAngles( + const USGSenseGlovePose* GlovePose, + const USGSenseGloveSensorNormalizer* Normalizer, const USGHandInterpolator* NormalizedToAngles, + TArray>& OutHandAngles) +{ + FSGIC_FSGSenseGlovePoseImpl GlovePoseContainer{GlovePose->ToSenseGlovePoseImpl()}; + FSGIC_FSGSenseGloveSensorNormalizerImpl NormalizerContainer{Normalizer->ToSenseGloveSensorNormalizerImpl()}; + FSGIC_FSGHandInterpolatorImpl NormalizedToAnglesContainer{NormalizedToAngles->ToHandInterpolatorImpl()}; + FSGIC_TArray_TArray_FVector OutHandAnglesContainer; + SGCoreImpl_FSGSenseGloveImpl_CalculateHandAngles( + &GlovePoseContainer, &NormalizerContainer, &NormalizedToAnglesContainer, &OutHandAnglesContainer); + + OutHandAngles = MoveTemp(OutHandAnglesContainer.Array); +} + +void USGSenseGlove::CalculateHandPose( + UObject* Outer, + const USGSenseGlovePose* GlovePose, const USGBasicHandModel* HandModel, + const USGSenseGloveSensorNormalizer* Normalizer, const USGHandInterpolator* NormalizedToAngles, + USGHandPose*& OutHandPose) +{ + FSGIC_FSGSenseGlovePoseImpl GlovePoseContainer{GlovePose->ToSenseGlovePoseImpl()}; + FSGIC_FSGSenseGloveSensorNormalizerImpl NormalizerContainer{Normalizer->ToSenseGloveSensorNormalizerImpl()}; + FSGIC_FSGHandInterpolatorImpl NormalizedToAnglesContainer{NormalizedToAngles->ToHandInterpolatorImpl()}; + FSGIC_FSGHandPoseImpl OutHandPoseContainer; + SGCoreImpl_FSGSenseGloveImpl_CalculateHandAngles( + &GlovePoseContainer, &NormalizerContainer, &NormalizedToAnglesContainer, &OutHandPoseContainer); + + OutHandPose = USGHandPose::NewHandPose(Outer, MoveTemp(OutHandPoseContainer.HandPoseImpl)); +} + +USGSenseGlove::USGSenseGlove() + : USGHapticGlove() +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl OutSharedPtrContainer; + SGCoreImpl_FSGSenseGloveImpl_ctor_MakeShared(&OutSharedPtrContainer); + + SetSGDeviceImpl(OutSharedPtrContainer.Ptr.ToSharedRef()); +} + +USGSenseGlove::USGSenseGlove(const USGSenseGloveInfo& Model) + : USGHapticGlove() +{ +} + +USGSenseGlove::USGSenseGlove(const FSGDeviceImpl& SGDeviceImpl) + : USGHapticGlove(SGDeviceImpl) +{ +} + +USGSenseGlove::USGSenseGlove(const FSGHapticGloveImpl& HapticGloveImpl) + : USGHapticGlove(HapticGloveImpl) +{ +} + +USGSenseGlove::USGSenseGlove(const FSGSenseGloveImpl& SenseGloveImpl) + : USGHapticGlove(SenseGloveImpl) +{ +} + +USGSenseGlove::USGSenseGlove(TSharedRef SGDeviceImpl) + : USGHapticGlove(MoveTemp(SGDeviceImpl)) +{ +} + +USGSenseGlove::USGSenseGlove(TSharedRef HapticGloveImpl) + : USGHapticGlove(MoveTemp(HapticGloveImpl)) +{ +} + +USGSenseGlove::USGSenseGlove(TSharedRef SenseGloveImpl) + : USGHapticGlove(MoveTemp(SenseGloveImpl)) +{ +} + +USGSenseGlove::~USGSenseGlove() = default; + +TSharedRef USGSenseGlove::ToSenseGloveImpl() const +{ + return FSGDeviceImplCast::ToSenseGloveImpl(ToSGDeviceImpl()); +} + +ESGDeviceType USGSenseGlove::GetDeviceType() const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_ESGDeviceType OutTypeContainer; + SGCoreImpl_FSGSenseGloveImpl_GetDeviceType(&InstanceContainer, &OutTypeContainer); + return OutTypeContainer.Type; +} + +FString USGSenseGlove::GetDeviceId() const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FString OutIdContainer; + SGCoreImpl_FSGSenseGloveImpl_GetDeviceId(&InstanceContainer, &OutIdContainer); + return OutIdContainer.String; +} + +FString USGSenseGlove::GetHardwareVersion() const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FString OutVersionContainer; + SGCoreImpl_FSGSenseGloveImpl_GetHardwareVersion(&InstanceContainer, &OutVersionContainer); + return OutVersionContainer.String; +} + +int32 USGSenseGlove::GetFirmwareVersion() const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + return SGCoreImpl_FSGSenseGloveImpl_GetFirmwareVersion(&InstanceContainer); +} + +int32 USGSenseGlove::GetSubFirmwareVersion() const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + return SGCoreImpl_FSGSenseGloveImpl_GetSubFirmwareVersion(&InstanceContainer); +} + +bool USGSenseGlove::IsRight() const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + return SGCoreImpl_FSGSenseGloveImpl_IsRight(&InstanceContainer); +} + +bool USGSenseGlove::GetImuRotation(FQuat& OutImu) +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FQuat OutImuContainer; + const bool bResult = SGCoreImpl_FSGSenseGloveImpl_GetImuRotation(&InstanceContainer, &OutImuContainer); + + if (bResult) + { + OutImu = MoveTemp(OutImuContainer.Quat); + } + + return bResult; +} + +bool USGSenseGlove::GetImuRotation(FRotator& OutImu) +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FQuat OutImuContainer; + const bool bResult = SGCoreImpl_FSGSenseGloveImpl_GetImuRotation(&InstanceContainer, &OutImuContainer); + + if (bResult) + { + OutImu = OutImuContainer.Quat.Rotator(); + } + + return bResult; +} + +bool USGSenseGlove::GetHandPose(UObject* Outer, const USGBasicHandModel* HandGeometry, USGHandPose*& OutHandPose) const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FSGBasicHandModelImpl HandModelContainer{HandGeometry->ToBasicHandModelImpl()}; + FSGIC_FSGHandPoseImpl OutHandPoseContainer; + const bool bResult = SGCoreImpl_FSGSenseGloveImpl_GetHandPose( + &InstanceContainer, &HandModelContainer, &OutHandPoseContainer); + + if (bResult) + { + OutHandPose = USGHandPose::NewHandPose(Outer, MoveTemp(OutHandPoseContainer.HandPoseImpl)); + } + + return bResult; +} + +bool USGSenseGlove::GetHandAngles(TArray>& OutHandAngles) const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_TArray_TArray_FVector OutHandAnglesContainer; + const bool bResult = SGCoreImpl_FSGSenseGloveImpl_GetHandAngles(&InstanceContainer, &OutHandAnglesContainer); + OutHandAngles = MoveTemp(OutHandAnglesContainer.Array); + return bResult; +} + +ESGHapticGloveCalibrationState USGSenseGlove::GetCalibrationState() const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_ESGHapticGloveCalibrationState OutHapticGloveCalibrationStateContainer; + SGCoreImpl_FSGSenseGloveImpl_GetCalibrationState(&InstanceContainer, &OutHapticGloveCalibrationStateContainer); + return OutHapticGloveCalibrationStateContainer.State; +} + +void USGSenseGlove::EndCalibration() +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + SGCoreImpl_FSGSenseGloveImpl_EndCalibration(&InstanceContainer); +} + +void USGSenseGlove::ResetCalibration() +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + SGCoreImpl_FSGSenseGloveImpl_ResetCalibration(&InstanceContainer); +} + +void USGSenseGlove::StopHaptics() +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + SGCoreImpl_FSGSenseGloveImpl_StopHaptics(&InstanceContainer); +} + +void USGSenseGlove::StopVibrations() +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + SGCoreImpl_FSGSenseGloveImpl_StopVibrations(&InstanceContainer); +} + +bool USGSenseGlove::SendHaptics() +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + return SGCoreImpl_FSGSenseGloveImpl_SendHaptics(&InstanceContainer); +} + +bool USGSenseGlove::QueueForceFeedbackLevels(const TArray& Levels01) +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_TArray_float Levels01Container{Levels01}; + return SGCoreImpl_FSGSenseGloveImpl_QueueForceFeedbackLevels(&InstanceContainer, &Levels01Container); +} + +bool USGSenseGlove::QueueForceFeedbackLevel(const int32 Finger, const float Level01) +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + return SGCoreImpl_FSGSenseGloveImpl_QueueForceFeedbackLevel(&InstanceContainer, Finger, Level01); +} + +bool USGSenseGlove::QueueVibroLevels(const TArray& Amplitudes) +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_TArray_float AmplitudesContainer{Amplitudes}; + return SGCoreImpl_FSGSenseGloveImpl_QueueVibroLevels(&InstanceContainer, &AmplitudesContainer); +} + +bool USGSenseGlove::QueueVibroLevel(const ESGHapticLocation Location, const float Level01) +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_ESGHapticLocation LocationContainer{Location}; + return SGCoreImpl_FSGSenseGloveImpl_QueueVibroLevel_Location_Level01( + &InstanceContainer, &LocationContainer, Level01); +} + +void USGSenseGlove::GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutGlovePositionContainer; + FSGIC_FQuat OutGloveRotationContainer; + + SGCoreImpl_FSGSenseGloveImpl_GetGloveLocation_ReferencePosition_ReferenceRotation_TrackingHardware_OutGlovePosition_OutGloveRotation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &OutGlovePositionContainer, &OutGloveRotationContainer); + + OutGlovePosition = MoveTemp(OutGlovePositionContainer.Vector); + OutGloveRotation = MoveTemp(OutGloveRotationContainer.Quat); +} + +void USGSenseGlove::GetGloveLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FRotator& OutGloveRotation) const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation.Quaternion()}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutGlovePositionContainer; + FSGIC_FQuat OutGloveRotationContainer; + + SGCoreImpl_FSGSenseGloveImpl_GetGloveLocation_ReferencePosition_ReferenceRotation_TrackingHardware_OutGlovePosition_OutGloveRotation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &OutGlovePositionContainer, &OutGloveRotationContainer); + + OutGlovePosition = MoveTemp(OutGlovePositionContainer.Vector); + OutGloveRotation = OutGloveRotationContainer.Quat.Rotator(); +} + +void USGSenseGlove::GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const ESGFinger MountedOn, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_ESGFinger MountedOnContainer{MountedOn}; + FSGIC_FVector OutGlovePositionContainer; + FSGIC_FQuat OutGloveRotationContainer; + + SGCoreImpl_FSGSenseGloveImpl_GetGloveLocation_ReferencePosition_ReferenceRotation_TrackingHardware_MountedOn_OutGlovePosition_OutGloveRotation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, &MountedOnContainer, + &OutGlovePositionContainer, &OutGloveRotationContainer); + + OutGlovePosition = MoveTemp(OutGlovePositionContainer.Vector); + OutGloveRotation = MoveTemp(OutGloveRotationContainer.Quat); +} + +void USGSenseGlove::GetGloveLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const ESGFinger MountedOn, + FVector& OutGlovePosition, FRotator& OutGloveRotation) const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation.Quaternion()}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_ESGFinger MountedOnContainer{MountedOn}; + FSGIC_FVector OutGlovePositionContainer; + FSGIC_FQuat OutGloveRotationContainer; + + SGCoreImpl_FSGSenseGloveImpl_GetGloveLocation_ReferencePosition_ReferenceRotation_TrackingHardware_MountedOn_OutGlovePosition_OutGloveRotation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, &MountedOnContainer, + &OutGlovePositionContainer, &OutGloveRotationContainer); + + OutGlovePosition = MoveTemp(OutGlovePositionContainer.Vector); + OutGloveRotation = OutGloveRotationContainer.Quat.Rotator(); +} + +void USGSenseGlove::GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutWristPositionContainer; + FSGIC_FQuat OutWristRotationContainer; + SGCoreImpl_FSGSenseGloveImpl_GetWristLocation_ReferencePosition_ReferenceRotation_TrackingHardware_OutWristPosition_OutWristRotation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &OutWristPositionContainer, &OutWristRotationContainer); + + OutWristPosition = MoveTemp(OutWristPositionContainer.Vector); + OutWristRotation = MoveTemp(OutWristRotationContainer.Quat); +} + +void USGSenseGlove::GetWristLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FRotator& OutWristRotation) const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation.Quaternion()}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector OutWristPositionContainer; + FSGIC_FQuat OutWristRotationContainer; + SGCoreImpl_FSGSenseGloveImpl_GetWristLocation_ReferencePosition_ReferenceRotation_TrackingHardware_OutWristPosition_OutWristRotation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &OutWristPositionContainer, &OutWristRotationContainer); + + OutWristPosition = MoveTemp(OutWristPositionContainer.Vector); + OutWristRotation = OutWristRotationContainer.Quat.Rotator(); +} + +void USGSenseGlove::GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + const FVector& GloveWristPositionOffset, + const FQuat& GloveWristRotationOffset, + FVector& OutWristPosition, FQuat& OutWristRotation) const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector GloveWristPositionOffsetContainer{GloveWristPositionOffset}; + FSGIC_FQuat GloveWristRotationOffsetContainer{GloveWristRotationOffset}; + FSGIC_FVector OutWristPositionContainer; + FSGIC_FQuat OutWristRotationContainer; + SGCoreImpl_FSGSenseGloveImpl_GetWristLocation_ReferencePosition_ReferenceRotation_TrackingHardware_GloveWristPositionOffset_GloveWristRotationOffset_OutWristPosition_OutWristRotation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &GloveWristPositionOffsetContainer, &GloveWristRotationOffsetContainer, + &OutWristPositionContainer, &OutWristRotationContainer); + + OutWristPosition = MoveTemp(OutWristPositionContainer.Vector); + OutWristRotation = MoveTemp(OutWristRotationContainer.Quat); +} + +void USGSenseGlove::GetWristLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + const FVector& GloveWristPositionOffset, + const FRotator& GloveWristRotationOffset, + FVector& OutWristPosition, FRotator& OutWristRotation) const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FVector ReferencePositionContainer{ReferencePosition}; + FSGIC_FQuat ReferenceRotationContainer{ReferenceRotation.Quaternion()}; + FSGIC_ESGPositionalTrackingHardware TrackingHardwareContainer{TrackingHardware}; + FSGIC_FVector GloveWristPositionOffsetContainer{GloveWristPositionOffset}; + FSGIC_FQuat GloveWristRotationOffsetContainer{GloveWristRotationOffset.Quaternion()}; + FSGIC_FVector OutWristPositionContainer; + FSGIC_FQuat OutWristRotationContainer; + SGCoreImpl_FSGSenseGloveImpl_GetWristLocation_ReferencePosition_ReferenceRotation_TrackingHardware_GloveWristPositionOffset_GloveWristRotationOffset_OutWristPosition_OutWristRotation( + &InstanceContainer, + &ReferencePositionContainer, &ReferenceRotationContainer, + &TrackingHardwareContainer, + &GloveWristPositionOffsetContainer, &GloveWristRotationOffsetContainer, + &OutWristPositionContainer, &OutWristRotationContainer); + + OutWristPosition = MoveTemp(OutWristPositionContainer.Vector); + OutWristRotation = OutWristRotationContainer.Quat.Rotator(); +} + +USGSenseGloveInfo* USGSenseGlove::GetGloveInfo(UObject* Outer) const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FSGSenseGloveInfoImpl OutGloveInfoContainer; + SGCoreImpl_FSGSenseGloveImpl_GetGloveInfo(&InstanceContainer, &OutGloveInfoContainer); + + return USGSenseGloveInfo::NewSenseGloveInfo(Outer, MoveTemp(OutGloveInfoContainer.SenseGloveInfoImpl)); +} + +TArray USGSenseGlove::GetFingerThimbleOffsets() const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_TArray_FVector OutFingerThimbleOffsetsContainer; + SGCoreImpl_FSGSenseGloveImpl_GetFingerThimbleOffsets(&InstanceContainer, &OutFingerThimbleOffsetsContainer); + return OutFingerThimbleOffsetsContainer.Array; +} + +void USGSenseGlove::SetFingerThimbleOffset(const int32 Finger, const FVector& Offset) +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FVector OffsetContainer{Offset}; + SGCoreImpl_FSGSenseGloveImpl_SetFingerThimbleOffset(&InstanceContainer, Finger, &OffsetContainer); +} + +bool USGSenseGlove::SupportsWristActuator() const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + return SGCoreImpl_FSGSenseGloveImpl_SupportsWristActuator(&InstanceContainer); +} + +bool USGSenseGlove::GetSensorData(UObject* Outer, USGSenseGloveSensorData*& OutSensorData) const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FSGSenseGloveSensorDataImpl OutSensorDataContainer; + const bool bResult = SGCoreImpl_FSGSenseGloveImpl_GetSensorData(&InstanceContainer, &OutSensorDataContainer); + + if (bResult) + { + OutSensorData = USGSenseGloveSensorData::NewSenseGloveSensorData( + Outer, MoveTemp(OutSensorDataContainer.SenseGloveSensorDataImpl)); + } + + return bResult; +} + +bool USGSenseGlove::GetGlovePose(UObject* Outer, USGSenseGlovePose*& OutGlovePose) +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FSGSenseGlovePoseImpl OutGlovePoseContainer; + const bool bResult = SGCoreImpl_FSGSenseGloveImpl_GetGlovePose_OutGlovePose( + &InstanceContainer, &OutGlovePoseContainer); + + if (bResult) + { + OutGlovePose = USGSenseGlovePose::NewSenseGlovePose( + Outer, MoveTemp(OutGlovePoseContainer.SenseGlovePoseImpl)); + } + + return bResult; +} + +bool USGSenseGlove::GetGlovePose( + UObject* Outer, const USGSenseGloveSensorData* SensorData, USGSenseGlovePose*& OutGlovePose) +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FSGSenseGloveSensorDataImpl SensorDataContainer{SensorData->ToSenseGloveSensorDataImpl()}; + FSGIC_FSGSenseGlovePoseImpl OutGlovePoseContainer; + const bool bResult = SGCoreImpl_FSGSenseGloveImpl_GetGlovePose_SensorData_OutGlovePose( + &InstanceContainer, &SensorDataContainer, &OutGlovePoseContainer); + + if (bResult) + { + OutGlovePose = USGSenseGlovePose::NewSenseGlovePose( + Outer, MoveTemp(OutGlovePoseContainer.SenseGlovePoseImpl)); + } + + return bResult; +} + +bool USGSenseGlove::QueueVibroLevel(const int32 Finger, const float Amplitude) +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + return SGCoreImpl_FSGSenseGloveImpl_QueueVibroLevel_Finger_Amplitude(&InstanceContainer, Finger, Amplitude); +} + +bool USGSenseGlove::QueueThumperCommand(ESGSenseGloveThumperCommand Command) +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_ESGSenseGloveThumperCommand CommandContainer{Command}; + return SGCoreImpl_FSGSenseGloveImpl_QueueThumperCommand(&InstanceContainer, &CommandContainer); +} + +FString USGSenseGlove::ToString() const +{ + FSGIC_TSharedPtr_FSGSenseGloveImpl InstanceContainer{ToSenseGloveImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGSenseGloveImpl_ToString(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String;; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGloveInfo.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGloveInfo.cpp new file mode 100644 index 0000000..6896994 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGloveInfo.cpp @@ -0,0 +1,555 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGSenseGloveInfo.h" + +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_ESGFinger.h" +#include "SGInterop/SGIC_FQuat.h" +#include "SGInterop/SGIC_FSGSenseGloveInfoImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_FVector.h" +#include "SGInterop/SGIC_TArray_bool.h" +#include "SGInterop/SGIC_TArray_FQuat.h" +#include "SGInterop/SGIC_TArray_FVector.h" +#include "SGInterop/SGIC_TArray_TArray_float.h" +#include "SGInterop/SGIC_TArray_TArray_FVector.h" +#include "SGUtils/SGArrayUtils.h" + +struct USGSenseGloveInfo::FImpl +{ + /************************ + * Member variables + ************************/ + + FSGSenseGloveInfoImpl SenseGloveInfoImpl; + + /************************ + * Owner object + ************************/ + + USGSenseGloveInfo* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGSenseGloveInfo* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGSenseGloveInfo* USGSenseGloveInfo::NewSenseGloveInfo(UObject* Outer, const FSGSenseGloveInfoImpl& SenseGloveInfoImpl) +{ + USGSenseGloveInfo* Instance = NewObject(Outer); + Instance->SetSenseGloveInfoImpl(SenseGloveInfoImpl); + return Instance; +} + +USGSenseGloveInfo* USGSenseGloveInfo::NewSenseGloveInfo(UObject* Outer) +{ + FSGIC_FSGSenseGloveInfoImpl OutSenseGloveInfoImplContainer; + SGCoreImpl_FSGSenseGloveInfoImpl_ctor(&OutSenseGloveInfoImplContainer); + + return NewSenseGloveInfo(Outer, MoveTemp(OutSenseGloveInfoImplContainer.SenseGloveInfoImpl)); +} + +USGSenseGloveInfo* USGSenseGloveInfo::NewSenseGloveInfo(UObject* Outer, const FString& DeviceId, + const FString& HardwareVersion, const int32 FirmwareVersion, + const int32 SubFirmwareVersion, const bool bRightHanded, + const int32 NumberOfSensors, const FQuat& ImuCorrection, + const TArray& StartPositions, + const TArray& StartRotations, + const TArray>& GloveLengths, + const TArray& Functions) +{ + FSGIC_FSGSenseGloveInfoImpl OutSenseGloveInfoImplContainer; + FSGIC_FString DeviceIdContainer{DeviceId}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FQuat ImuCorrectionContainer{ImuCorrection}; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + FSGIC_TArray_FQuat StartRotationsContainer{StartRotations}; + FSGIC_TArray_TArray_FVector GloveLengthsContainer{GloveLengths}; + FSGIC_TArray_bool FunctionsContainer{Functions}; + SGCoreImpl_FSGSenseGloveInfoImpl_ctor_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded_NumberOfSensors_ImuCorrection_StartPositions_StartRotations_GloveLengths_Functions( + &OutSenseGloveInfoImplContainer, + &DeviceIdContainer, &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion, + bRightHanded, NumberOfSensors, &ImuCorrectionContainer, + &StartPositionsContainer, &StartRotationsContainer, + &GloveLengthsContainer, &FunctionsContainer); + + return NewSenseGloveInfo(Outer, MoveTemp(OutSenseGloveInfoImplContainer.SenseGloveInfoImpl)); +} + +USGSenseGloveInfo* USGSenseGloveInfo::NewSenseGloveInfo(UObject* Outer, const FString& DeviceId, + const FString& HardwareVersion, const int32 FirmwareVersion, + const int32 SubFirmwareVersion, const bool bRightHanded, + const int32 NumberOfSensors, const FRotator& ImuCorrection, + const TArray& StartPositions, + const TArray& StartRotations, + const TArray>& GloveLengths, + const TArray& Functions) +{ + FSGIC_FSGSenseGloveInfoImpl OutSenseGloveInfoImplContainer; + FSGIC_FString DeviceIdContainer{DeviceId}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FQuat ImuCorrectionContainer{ImuCorrection.Quaternion()}; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + FSGIC_TArray_FQuat StartRotationsContainer{FSGArrayUtils::RotatorsToQuats(StartRotations)}; + FSGIC_TArray_TArray_FVector GloveLengthsContainer{GloveLengths}; + FSGIC_TArray_bool FunctionsContainer{Functions}; + SGCoreImpl_FSGSenseGloveInfoImpl_ctor_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded_NumberOfSensors_ImuCorrection_StartPositions_StartRotations_GloveLengths_Functions( + &OutSenseGloveInfoImplContainer, + &DeviceIdContainer, &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion, + bRightHanded, NumberOfSensors, &ImuCorrectionContainer, + &StartPositionsContainer, &StartRotationsContainer, + &GloveLengthsContainer, &FunctionsContainer); + + return NewSenseGloveInfo(Outer, MoveTemp(OutSenseGloveInfoImplContainer.SenseGloveInfoImpl)); +} + +USGSenseGloveInfo* USGSenseGloveInfo::NewSenseGloveInfo(UObject* Outer, const FString& DeviceId, + const FString& HardwareVersion, const int32 FirmwareVersion, + const int32 SubFirmwareVersion, const bool bRightHanded, + const int32 NumberOfSensors, const FQuat& ImuCorrection, + const TArray& StartPositions, + const TArray& StartRotations, + const TArray& GloveLengths, + const TArray& Functions) +{ + FSGIC_FSGSenseGloveInfoImpl OutSenseGloveInfoImplContainer; + FSGIC_FString DeviceIdContainer{DeviceId}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FQuat ImuCorrectionContainer{ImuCorrection}; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + FSGIC_TArray_FQuat StartRotationsContainer{StartRotations}; + FSGIC_TArray_TArray_FVector GloveLengthsContainer{ + FSGArrayUtils::FromNestedBPArray(GloveLengths) + }; + FSGIC_TArray_bool FunctionsContainer{Functions}; + SGCoreImpl_FSGSenseGloveInfoImpl_ctor_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded_NumberOfSensors_ImuCorrection_StartPositions_StartRotations_GloveLengths_Functions( + &OutSenseGloveInfoImplContainer, + &DeviceIdContainer, &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion, + bRightHanded, NumberOfSensors, &ImuCorrectionContainer, + &StartPositionsContainer, &StartRotationsContainer, + &GloveLengthsContainer, &FunctionsContainer); + + return NewSenseGloveInfo(Outer, MoveTemp(OutSenseGloveInfoImplContainer.SenseGloveInfoImpl)); +} + +USGSenseGloveInfo* USGSenseGloveInfo::NewSenseGloveInfo(UObject* Outer, const FString& DeviceId, + const FString& HardwareVersion, const int32 FirmwareVersion, + const int32 SubFirmwareVersion, const bool bRightHanded, + const int32 NumberOfSensors, const FRotator& ImuCorrection, + const TArray& StartPositions, + const TArray& StartRotations, + const TArray& GloveLengths, + const TArray& Functions) +{ + FSGIC_FSGSenseGloveInfoImpl OutSenseGloveInfoImplContainer; + FSGIC_FString DeviceIdContainer{DeviceId}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FQuat ImuCorrectionContainer{ImuCorrection.Quaternion()}; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + FSGIC_TArray_FQuat StartRotationsContainer{FSGArrayUtils::RotatorsToQuats(StartRotations)}; + FSGIC_TArray_TArray_FVector GloveLengthsContainer{ + FSGArrayUtils::FromNestedBPArray(GloveLengths) + }; + FSGIC_TArray_bool FunctionsContainer{Functions}; + SGCoreImpl_FSGSenseGloveInfoImpl_ctor_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded_NumberOfSensors_ImuCorrection_StartPositions_StartRotations_GloveLengths_Functions( + &OutSenseGloveInfoImplContainer, + &DeviceIdContainer, &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion, + bRightHanded, NumberOfSensors, &ImuCorrectionContainer, + &StartPositionsContainer, &StartRotationsContainer, + &GloveLengthsContainer, &FunctionsContainer); + + return NewSenseGloveInfo(Outer, MoveTemp(OutSenseGloveInfoImplContainer.SenseGloveInfoImpl)); +} + +bool USGSenseGloveInfo::Parse(UObject* Outer, const FString& ConstantsString, USGSenseGloveInfo*& OutGloveInfo, + const bool bUpdateOldModels) +{ + FSGIC_FString ConstantsStringContainer{ConstantsString}; + FSGIC_FSGSenseGloveInfoImpl OutGloveInfoImplContainer; + const bool bResult = SGCoreImpl_FSGSenseGloveInfoImpl_Parse(&ConstantsStringContainer, &OutGloveInfoImplContainer, + bUpdateOldModels); + + if (bResult) + { + OutGloveInfo = NewSenseGloveInfo(Outer, MoveTemp(OutGloveInfoImplContainer.SenseGloveInfoImpl)); + } + + return bResult; +} + +USGSenseGloveInfo* USGSenseGloveInfo::Deserialize(UObject* Outer, const FString& SerializedString) +{ + FSGIC_FString SerializedStringContainer{SerializedString}; + FSGIC_FSGSenseGloveInfoImpl OutSenseGloveInfoImplContainer; + SGCoreImpl_FSGSenseGloveInfoImpl_Deserialize(&OutSenseGloveInfoImplContainer, &SerializedStringContainer); + + return NewSenseGloveInfo(Outer, MoveTemp(OutSenseGloveInfoImplContainer.SenseGloveInfoImpl)); +} + +USGSenseGloveInfo::USGSenseGloveInfo() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGSenseGloveInfoImpl OutSenseGloveInfoImplContainer; + SGCoreImpl_FSGSenseGloveInfoImpl_ctor(&OutSenseGloveInfoImplContainer); + + Pimpl->SenseGloveInfoImpl = MoveTemp(OutSenseGloveInfoImplContainer.SenseGloveInfoImpl); +} + +USGSenseGloveInfo::USGSenseGloveInfo( + const FString& DeviceId, + const FString& HardwareVersion, const int32 FirmwareVersion, const int32 SubFirmwareVersion, + const bool bRightHanded, const int32 NumberOfSensors, const FQuat& ImuCorrection, + const TArray& StartPositions, const TArray& StartRotations, + const TArray>& GloveLengths, const TArray& Functions) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGSenseGloveInfoImpl OutSenseGloveInfoImplContainer; + FSGIC_FString DeviceIdContainer{DeviceId}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FQuat ImuCorrectionContainer{ImuCorrection}; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + FSGIC_TArray_FQuat StartRotationsContainer{StartRotations}; + FSGIC_TArray_TArray_FVector GloveLengthsContainer{GloveLengths}; + FSGIC_TArray_bool FunctionsContainer{Functions}; + SGCoreImpl_FSGSenseGloveInfoImpl_ctor_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded_NumberOfSensors_ImuCorrection_StartPositions_StartRotations_GloveLengths_Functions( + &OutSenseGloveInfoImplContainer, + &DeviceIdContainer, &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion, + bRightHanded, NumberOfSensors, &ImuCorrectionContainer, + &StartPositionsContainer, &StartRotationsContainer, + &GloveLengthsContainer, &FunctionsContainer); + + Pimpl->SenseGloveInfoImpl = MoveTemp(OutSenseGloveInfoImplContainer.SenseGloveInfoImpl); +} + +USGSenseGloveInfo::USGSenseGloveInfo( + const FString& DeviceId, + const FString& HardwareVersion, const int32 FirmwareVersion, const int32 SubFirmwareVersion, + const bool bRightHanded, const int32 NumberOfSensors, const FRotator& ImuCorrection, + const TArray& StartPositions, const TArray& StartRotations, + const TArray>& GloveLengths, const TArray& Functions) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGSenseGloveInfoImpl OutSenseGloveInfoImplContainer; + FSGIC_FString DeviceIdContainer{DeviceId}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FQuat ImuCorrectionContainer{ImuCorrection.Quaternion()}; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + FSGIC_TArray_FQuat StartRotationsContainer{FSGArrayUtils::RotatorsToQuats(StartRotations)}; + FSGIC_TArray_TArray_FVector GloveLengthsContainer{GloveLengths}; + FSGIC_TArray_bool FunctionsContainer{Functions}; + SGCoreImpl_FSGSenseGloveInfoImpl_ctor_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded_NumberOfSensors_ImuCorrection_StartPositions_StartRotations_GloveLengths_Functions( + &OutSenseGloveInfoImplContainer, + &DeviceIdContainer, &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion, + bRightHanded, NumberOfSensors, &ImuCorrectionContainer, + &StartPositionsContainer, &StartRotationsContainer, + &GloveLengthsContainer, &FunctionsContainer); + + Pimpl->SenseGloveInfoImpl = MoveTemp(OutSenseGloveInfoImplContainer.SenseGloveInfoImpl); +} + +USGSenseGloveInfo::USGSenseGloveInfo( + const FString& DeviceId, + const FString& HardwareVersion, const int32 FirmwareVersion, const int32 SubFirmwareVersion, + const bool bRightHanded, const int32 NumberOfSensors, const FQuat& ImuCorrection, + const TArray& StartPositions, const TArray& StartRotations, + const TArray& GloveLengths, const TArray& Functions) +{ + FSGIC_FSGSenseGloveInfoImpl OutSenseGloveInfoImplContainer; + FSGIC_FString DeviceIdContainer{DeviceId}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FQuat ImuCorrectionContainer{ImuCorrection}; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + FSGIC_TArray_FQuat StartRotationsContainer{StartRotations}; + FSGIC_TArray_TArray_FVector GloveLengthsContainer{ + FSGArrayUtils::FromNestedBPArray(GloveLengths) + }; + FSGIC_TArray_bool FunctionsContainer{Functions}; + SGCoreImpl_FSGSenseGloveInfoImpl_ctor_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded_NumberOfSensors_ImuCorrection_StartPositions_StartRotations_GloveLengths_Functions( + &OutSenseGloveInfoImplContainer, + &DeviceIdContainer, &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion, + bRightHanded, NumberOfSensors, &ImuCorrectionContainer, + &StartPositionsContainer, &StartRotationsContainer, + &GloveLengthsContainer, &FunctionsContainer); + + Pimpl->SenseGloveInfoImpl = MoveTemp(OutSenseGloveInfoImplContainer.SenseGloveInfoImpl); +} + +USGSenseGloveInfo::USGSenseGloveInfo( + const FString& DeviceId, + const FString& HardwareVersion, const int32 FirmwareVersion, const int32 SubFirmwareVersion, + const bool bRightHanded, const int32 NumberOfSensors, const FRotator& ImuCorrection, + const TArray& StartPositions, const TArray& StartRotations, + const TArray& GloveLengths, const TArray& Functions) +{ + FSGIC_FSGSenseGloveInfoImpl OutSenseGloveInfoImplContainer; + FSGIC_FString DeviceIdContainer{DeviceId}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FQuat ImuCorrectionContainer{ImuCorrection.Quaternion()}; + FSGIC_TArray_FVector StartPositionsContainer{StartPositions}; + FSGIC_TArray_FQuat StartRotationsContainer{FSGArrayUtils::RotatorsToQuats(StartRotations)}; + FSGIC_TArray_TArray_FVector GloveLengthsContainer{ + FSGArrayUtils::FromNestedBPArray(GloveLengths) + }; + FSGIC_TArray_bool FunctionsContainer{Functions}; + SGCoreImpl_FSGSenseGloveInfoImpl_ctor_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded_NumberOfSensors_ImuCorrection_StartPositions_StartRotations_GloveLengths_Functions( + &OutSenseGloveInfoImplContainer, + &DeviceIdContainer, &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion, + bRightHanded, NumberOfSensors, &ImuCorrectionContainer, + &StartPositionsContainer, &StartRotationsContainer, + &GloveLengthsContainer, &FunctionsContainer); + + Pimpl->SenseGloveInfoImpl = MoveTemp(OutSenseGloveInfoImplContainer.SenseGloveInfoImpl); +} + +USGSenseGloveInfo::USGSenseGloveInfo(const FSGSenseGloveInfoImpl& SenseGloveInfoImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + SetSenseGloveInfoImpl(SenseGloveInfoImpl); +} + +USGSenseGloveInfo::~USGSenseGloveInfo() = default; + +void USGSenseGloveInfo::SetSenseGloveInfoImpl(const FSGSenseGloveInfoImpl& SenseGloveInfoImpl) +{ + FSGIC_FSGSenseGloveInfoImpl OutSenseGloveInfoContainer; + FSGIC_FSGSenseGloveInfoImpl RhsContainer{SenseGloveInfoImpl}; + SGCoreImpl_FSGSenseGloveInfoImpl_ctor_copy(&OutSenseGloveInfoContainer, &RhsContainer); + Pimpl->SenseGloveInfoImpl = MoveTemp(OutSenseGloveInfoContainer.SenseGloveInfoImpl); +} + +const FSGSenseGloveInfoImpl& USGSenseGloveInfo::ToSenseGloveInfoImpl() const +{ + return Pimpl->SenseGloveInfoImpl; +} + +FSGSenseGloveInfoImpl& USGSenseGloveInfo::ToSenseGloveInfoImpl() +{ + return Pimpl->SenseGloveInfoImpl; +} + +FString USGSenseGloveInfo::GetDeviceId() const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_FString OutIdContainer; + SGCoreImpl_FSGSenseGloveInfoImpl_GetDeviceId(&InstanceContainer, &OutIdContainer); + return OutIdContainer.String; +} + +FString USGSenseGloveInfo::GetHardwareVersion() const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_FString OutVersionContainer; + SGCoreImpl_FSGSenseGloveInfoImpl_GetHardwareVersion(&InstanceContainer, &OutVersionContainer); + return OutVersionContainer.String; +} + +int32 USGSenseGloveInfo::GetFirmwareVersion() const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + return SGCoreImpl_FSGSenseGloveInfoImpl_GetFirmwareVersion(&InstanceContainer); +} + +int32 USGSenseGloveInfo::GetSubFirmwareVersion() const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + return SGCoreImpl_FSGSenseGloveInfoImpl_GetSubFirmwareVersion(&InstanceContainer); +} + +bool USGSenseGloveInfo::IsRight() const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + return SGCoreImpl_FSGSenseGloveInfoImpl_IsRight(&InstanceContainer); +} + +int32 USGSenseGloveInfo::GetNumberOfSensors() const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + return SGCoreImpl_FSGSenseGloveInfoImpl_GetNumberOfSensors(&InstanceContainer); +} + +FQuat USGSenseGloveInfo::GetImuCorrectionQ() const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_FQuat OutCorrectionContainer; + SGCoreImpl_FSGSenseGloveInfoImpl_GetImuCorrection(&InstanceContainer, &OutCorrectionContainer); + return OutCorrectionContainer.Quat; +} + +FRotator USGSenseGloveInfo::GetImuCorrection() const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_FQuat OutCorrectionContainer; + SGCoreImpl_FSGSenseGloveInfoImpl_GetImuCorrection(&InstanceContainer, &OutCorrectionContainer); + return OutCorrectionContainer.Quat.Rotator(); +} + +TArray USGSenseGloveInfo::GetStartPositions() const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_TArray_FVector OutPositionsContainer; + SGCoreImpl_FSGSenseGloveInfoImpl_GetStartPositions(&InstanceContainer, &OutPositionsContainer); + return OutPositionsContainer.Array; +} + +TArray USGSenseGloveInfo::GetStartRotationsQ() const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_TArray_FQuat OutRotationsContainer; + SGCoreImpl_FSGSenseGloveInfoImpl_GetStartRotations(&InstanceContainer, &OutRotationsContainer); + return OutRotationsContainer.Array; +} + +TArray USGSenseGloveInfo::GetStartRotations() const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_TArray_FQuat OutRotationsContainer; + SGCoreImpl_FSGSenseGloveInfoImpl_GetStartRotations(&InstanceContainer, &OutRotationsContainer); + return FSGArrayUtils::QuatsToRotators(OutRotationsContainer.Array); +} + +TArray> USGSenseGloveInfo::GetGloveLengths() const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_TArray_TArray_FVector OutLengthsContainer; + SGCoreImpl_FSGSenseGloveInfoImpl_GetGloveLengths(&InstanceContainer, &OutLengthsContainer); + return OutLengthsContainer.Array; +} + +TArray USGSenseGloveInfo::GetFunctions() const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_TArray_bool OutFunctionsContainer; + SGCoreImpl_FSGSenseGloveInfoImpl_GetFunctions(&InstanceContainer, &OutFunctionsContainer); + return OutFunctionsContainer.Array; +} + +FVector USGSenseGloveInfo::GetStartPosition(const ESGFinger Finger) const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_FVector OutPositionContainer; + FSGIC_ESGFinger FingerContainer{Finger}; + SGCoreImpl_FSGSenseGloveInfoImpl_GetStartPosition(&InstanceContainer, &OutPositionContainer, &FingerContainer); + return OutPositionContainer.Vector; +} + +FQuat USGSenseGloveInfo::GetStartRotationQ(const ESGFinger Finger) const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_FQuat OutRotationContainer; + FSGIC_ESGFinger FingerContainer{Finger}; + SGCoreImpl_FSGSenseGloveInfoImpl_GetStartRotation(&InstanceContainer, &OutRotationContainer, &FingerContainer); + return OutRotationContainer.Quat; +} + +FRotator USGSenseGloveInfo::GetStartRotation(const ESGFinger Finger) const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_FQuat OutRotationContainer; + FSGIC_ESGFinger FingerContainer{Finger}; + SGCoreImpl_FSGSenseGloveInfoImpl_GetStartRotation(&InstanceContainer, &OutRotationContainer, &FingerContainer); + return OutRotationContainer.Quat.Rotator(); +} + +TArray USGSenseGloveInfo::GetGloveLengths(const ESGFinger Finger) const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_TArray_FVector OutLengths; + FSGIC_ESGFinger FingerContainer{Finger}; + SGCoreImpl_FSGSenseGloveInfoImpl_GetGloveLengths_Finger(&InstanceContainer, &OutLengths, &FingerContainer); + return OutLengths.Array; +} + +TArray> USGSenseGloveInfo::ToGloveAngles(const TArray>& SensorAngles) const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_TArray_TArray_FVector OutAnglesContainer; + FSGIC_TArray_TArray_float SensorAnglesContainer{SensorAngles}; + SGCoreImpl_FSGSenseGloveInfoImpl_ToGloveAngles(&InstanceContainer, &OutAnglesContainer, &SensorAnglesContainer); + return OutAnglesContainer.Array; +} + +bool USGSenseGloveInfo::Equals(const USGSenseGloveInfo* SenseGloveInfo) const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_FSGSenseGloveInfoImpl SenseGloveInfoImplContainer{SenseGloveInfo->ToSenseGloveInfoImpl()}; + return SGCoreImpl_FSGSenseGloveInfoImpl_Equals(&InstanceContainer, &SenseGloveInfoImplContainer); +} + +FString USGSenseGloveInfo::ToString(const bool bShortNotation) const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGSenseGloveInfoImpl_ToString_bShortNotation(&InstanceContainer, &OutStringContainer, bShortNotation); + return OutStringContainer.String; +} + +FString USGSenseGloveInfo::ToString() const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGSenseGloveInfoImpl_ToString(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +FString USGSenseGloveInfo::SGSerialize() const +{ + FSGIC_FSGSenseGloveInfoImpl InstanceContainer{ToSenseGloveInfoImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGSenseGloveInfoImpl_Serialize(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +USGSenseGloveInfo::FImpl::FImpl(USGSenseGloveInfo* InOwner) + : Owner(InOwner) +{ +} + +USGSenseGloveInfo::FImpl::~FImpl() = default; + +void USGSenseGloveInfo::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGlovePose.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGlovePose.cpp new file mode 100644 index 0000000..1538431 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGlovePose.cpp @@ -0,0 +1,409 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGSenseGlovePose.h" + +#include "SGCore/SGSenseGloveInfo.h" +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGCoreImpl/SGSenseGlovePoseImpl.h" +#include "SGInterop/SGIC_FSGSenseGloveInfoImpl.h" +#include "SGInterop/SGIC_FSGSenseGlovePoseImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_TArray_FQuat.h" +#include "SGInterop/SGIC_TArray_FVector.h" +#include "SGInterop/SGIC_TArray_TArray_FQuat.h" +#include "SGInterop/SGIC_TArray_TArray_FVector.h" +#include "SGUtils/SGArrayUtils.h" + +struct USGSenseGlovePose::FImpl +{ + /************************ + * Member variables + ************************/ + + FSGSenseGlovePoseImpl SenseGlovePoseImpl; + + /************************ + * Owner object + ************************/ + + USGSenseGlovePose* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGSenseGlovePose* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGSenseGlovePose* USGSenseGlovePose::NewSenseGlovePose(UObject* Outer, const FSGSenseGlovePoseImpl& SenseGlovePoseImpl) +{ + USGSenseGlovePose* Instance = NewObject(Outer); + Instance->SetSenseGlovePoseImpl(SenseGlovePoseImpl); + return Instance; +} + +USGSenseGlovePose* USGSenseGlovePose::NewSenseGlovePose(UObject* Outer) +{ + FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; + SGCoreImpl_FSGSenseGlovePoseImpl_ctor(&OutSenseGlovePoseImplContainer); + + return NewSenseGlovePose(Outer, MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl)); +} + +USGSenseGlovePose* USGSenseGlovePose::NewSenseGlovePose(UObject* Outer, const bool bRightHanded, + const TArray>& JointPositions, + const TArray>& JointRotations, + const TArray>& GloveAngles) +{ + FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; + FSGIC_TArray_TArray_FVector JointPositionsContainer{JointPositions}; + FSGIC_TArray_TArray_FQuat JointRotationsContainer{JointRotations}; + FSGIC_TArray_TArray_FVector GloveAnglesContainer{GloveAngles}; + SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( + &OutSenseGlovePoseImplContainer, bRightHanded, &JointPositionsContainer, + &JointRotationsContainer, &GloveAnglesContainer); + + return NewSenseGlovePose(Outer, MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl)); +} + +USGSenseGlovePose* USGSenseGlovePose::NewSenseGlovePose(UObject* Outer, const bool bRightHanded, + const TArray>& JointPositions, + const TArray>& JointRotations, + const TArray>& GloveAngles) +{ + FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; + FSGIC_TArray_TArray_FVector JointPositionsContainer{JointPositions}; + FSGIC_TArray_TArray_FQuat JointRotationsContainer{FSGArrayUtils::RotatorsToQuats(JointRotations)}; + FSGIC_TArray_TArray_FVector GloveAnglesContainer{GloveAngles}; + SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( + &OutSenseGlovePoseImplContainer, bRightHanded, &JointPositionsContainer, + &JointRotationsContainer, &GloveAnglesContainer); + + return NewSenseGlovePose(Outer, MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl)); +} + +USGSenseGlovePose* USGSenseGlovePose::NewSenseGlovePose(UObject* Outer, const bool bRightHanded, + const TArray& JointPositions, + const TArray& JointRotations, + const TArray& GloveAngles) +{ + FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; + FSGIC_TArray_TArray_FVector JointPositionsContainer{ + FSGArrayUtils::FromNestedBPArray(JointPositions) + }; + FSGIC_TArray_TArray_FQuat JointRotationsContainer{ + FSGArrayUtils::FromNestedBPArray(JointRotations) + }; + FSGIC_TArray_TArray_FVector GloveAnglesContainer{ + FSGArrayUtils::FromNestedBPArray(GloveAngles) + }; + SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( + &OutSenseGlovePoseImplContainer, bRightHanded, &JointPositionsContainer, + &JointRotationsContainer, &GloveAnglesContainer); + + return NewSenseGlovePose(Outer, MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl)); +} + +USGSenseGlovePose* USGSenseGlovePose::NewSenseGlovePose(UObject* Outer, const bool bRightHanded, + const TArray& JointPositions, + const TArray& JointRotations, + const TArray& GloveAngles) +{ + FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; + FSGIC_TArray_TArray_FVector JointPositionsContainer{ + FSGArrayUtils::FromNestedBPArray(JointPositions) + }; + FSGIC_TArray_TArray_FQuat JointRotationsContainer{ + FSGArrayUtils::RotatorsToQuats(JointRotations) + }; + FSGIC_TArray_TArray_FVector GloveAnglesContainer{ + FSGArrayUtils::FromNestedBPArray(GloveAngles) + }; + SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( + &OutSenseGlovePoseImplContainer, bRightHanded, &JointPositionsContainer, + &JointRotationsContainer, &GloveAnglesContainer); + + return NewSenseGlovePose(Outer, MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl)); +} + +USGSenseGlovePose* USGSenseGlovePose::IdlePose(UObject* Outer, const USGSenseGloveInfo* GloveInfo) +{ + FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; + FSGIC_FSGSenseGloveInfoImpl SenseGloveInfoContainer{GloveInfo->ToSenseGloveInfoImpl()}; + SGCoreImpl_FSGSenseGlovePoseImpl_IdlePose(&OutSenseGlovePoseImplContainer, &SenseGloveInfoContainer); + + return NewSenseGlovePose(Outer, MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl)); +} + +USGSenseGlovePose* USGSenseGlovePose::Deserialize(UObject* Outer, const FString& SerializedString) +{ + FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; + FSGIC_FString SerializedStringContainer{SerializedString}; + SGCoreImpl_FSGSenseGlovePoseImpl_Deserialize(&OutSenseGlovePoseImplContainer, &SerializedStringContainer); + + return NewSenseGlovePose(Outer, MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl)); +} + +USGSenseGlovePose::USGSenseGlovePose() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; + SGCoreImpl_FSGSenseGlovePoseImpl_ctor(&OutSenseGlovePoseImplContainer); + + Pimpl->SenseGlovePoseImpl = MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl); +} + +USGSenseGlovePose::USGSenseGlovePose(const bool bRightHanded, + const TArray>& JointPositions, + const TArray>& JointRotations, + const TArray>& GloveAngles) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; + FSGIC_TArray_TArray_FVector JointPositionsContainer{JointPositions}; + FSGIC_TArray_TArray_FQuat JointRotationsContainer{JointRotations}; + FSGIC_TArray_TArray_FVector GloveAnglesContainer{GloveAngles}; + SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( + &OutSenseGlovePoseImplContainer, bRightHanded, &JointPositionsContainer, + &JointRotationsContainer, &GloveAnglesContainer); + + Pimpl->SenseGlovePoseImpl = MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl); +} + +USGSenseGlovePose::USGSenseGlovePose(const bool bRightHanded, + const TArray>& JointPositions, + const TArray>& JointRotations, + const TArray>& GloveAngles) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; + FSGIC_TArray_TArray_FVector JointPositionsContainer{JointPositions}; + FSGIC_TArray_TArray_FQuat JointRotationsContainer{FSGArrayUtils::RotatorsToQuats(JointRotations)}; + FSGIC_TArray_TArray_FVector GloveAnglesContainer{GloveAngles}; + SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( + &OutSenseGlovePoseImplContainer, bRightHanded, &JointPositionsContainer, + &JointRotationsContainer, &GloveAnglesContainer); + + Pimpl->SenseGlovePoseImpl = MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl); +} + +USGSenseGlovePose::USGSenseGlovePose(const bool bRightHanded, + const TArray& JointPositions, + const TArray& JointRotations, + const TArray& GloveAngles) +{ + FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; + FSGIC_TArray_TArray_FVector JointPositionsContainer{ + FSGArrayUtils::FromNestedBPArray(JointPositions) + }; + FSGIC_TArray_TArray_FQuat JointRotationsContainer{ + FSGArrayUtils::FromNestedBPArray(JointRotations) + }; + FSGIC_TArray_TArray_FVector GloveAnglesContainer{ + FSGArrayUtils::FromNestedBPArray(GloveAngles) + }; + SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( + &OutSenseGlovePoseImplContainer, bRightHanded, &JointPositionsContainer, + &JointRotationsContainer, &GloveAnglesContainer); + + Pimpl->SenseGlovePoseImpl = MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl); +} + +USGSenseGlovePose::USGSenseGlovePose(const bool bRightHanded, + const TArray& JointPositions, + const TArray& JointRotations, + const TArray& GloveAngles) +{ + FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; + FSGIC_TArray_TArray_FVector JointPositionsContainer{ + FSGArrayUtils::FromNestedBPArray(JointPositions) + }; + FSGIC_TArray_TArray_FQuat JointRotationsContainer{ + FSGArrayUtils::RotatorsToQuats(JointRotations) + }; + FSGIC_TArray_TArray_FVector GloveAnglesContainer{ + FSGArrayUtils::FromNestedBPArray(GloveAngles) + }; + SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( + &OutSenseGlovePoseImplContainer, bRightHanded, &JointPositionsContainer, + &JointRotationsContainer, &GloveAnglesContainer); + + Pimpl->SenseGlovePoseImpl = MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl); +} + +USGSenseGlovePose::USGSenseGlovePose(const FSGSenseGlovePoseImpl& SenseGlovePoseImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + SetSenseGlovePoseImpl(SenseGlovePoseImpl); +} + +USGSenseGlovePose::~USGSenseGlovePose() = default; + +void USGSenseGlovePose::SetSenseGlovePoseImpl(const FSGSenseGlovePoseImpl& SenseGlovePoseImpl) +{ + FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseContainer; + FSGIC_FSGSenseGlovePoseImpl RhsContainer{SenseGlovePoseImpl}; + SGCoreImpl_FSGSenseGlovePoseImpl_ctor_copy(&OutSenseGlovePoseContainer, &RhsContainer); + Pimpl->SenseGlovePoseImpl = MoveTemp(OutSenseGlovePoseContainer.SenseGlovePoseImpl); +} + +const FSGSenseGlovePoseImpl& USGSenseGlovePose::ToSenseGlovePoseImpl() const +{ + return Pimpl->SenseGlovePoseImpl; +} + +bool USGSenseGlovePose::IsRight() const +{ + FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; + return SGCoreImpl_FSGSenseGlovePoseImpl_IsRight(&InstanceContainer); +} + +TArray> USGSenseGlovePose::GetJointPositions() const +{ + FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; + FSGIC_TArray_TArray_FVector OutPositionsContainer; + SGCoreImpl_FSGSenseGlovePoseImpl_GetJointPositions(&InstanceContainer, &OutPositionsContainer); + return OutPositionsContainer.Array; +} + +TArray> USGSenseGlovePose::GetJointRotationsQ() const +{ + FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; + FSGIC_TArray_TArray_FQuat OutRotationsContainer; + SGCoreImpl_FSGSenseGlovePoseImpl_GetJointRotations(&InstanceContainer, &OutRotationsContainer); + return OutRotationsContainer.Array; +} + +TArray> USGSenseGlovePose::GetJointRotations() const +{ + FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; + FSGIC_TArray_TArray_FQuat OutRotationsContainer; + SGCoreImpl_FSGSenseGlovePoseImpl_GetJointRotations(&InstanceContainer, &OutRotationsContainer); + return FSGArrayUtils::QuatsToRotators(OutRotationsContainer.Array); +} + +TArray> USGSenseGlovePose::GetGloveAngles() const +{ + FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; + FSGIC_TArray_TArray_FVector OutAnglesContainer; + SGCoreImpl_FSGSenseGlovePoseImpl_GetGloveAngles(&InstanceContainer, &OutAnglesContainer); + return OutAnglesContainer.Array; +} + +TArray USGSenseGlovePose::GetThimblePositions() const +{ + FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; + FSGIC_TArray_FVector OutPositionsContainer; + SGCoreImpl_FSGSenseGlovePoseImpl_GetThimblePositions(&InstanceContainer, &OutPositionsContainer); + return OutPositionsContainer.Array; +} + +TArray USGSenseGlovePose::GetThimbleRotationsQ() const +{ + FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; + FSGIC_TArray_FQuat OutRotationsContainer; + SGCoreImpl_FSGSenseGlovePoseImpl_GetThimbleRotations(&InstanceContainer, &OutRotationsContainer); + return OutRotationsContainer.Array; +} + +TArray USGSenseGlovePose::GetThimbleRotations() const +{ + FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; + FSGIC_TArray_FQuat OutRotationsContainer; + SGCoreImpl_FSGSenseGlovePoseImpl_GetThimbleRotations(&InstanceContainer, &OutRotationsContainer); + return FSGArrayUtils::QuatsToRotators(OutRotationsContainer.Array); +} + +TArray USGSenseGlovePose::GetTotalGloveAngles() const +{ + FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; + FSGIC_TArray_FVector OutAnglesContainer; + SGCoreImpl_FSGSenseGlovePoseImpl_GetTotalGloveAngles(&InstanceContainer, &OutAnglesContainer); + return OutAnglesContainer.Array; +} + +TArray USGSenseGlovePose::CalculateFingertips(const TArray& FingerOffsets) const +{ + FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; + FSGIC_TArray_FVector OutFingertipsContainer; + FSGIC_TArray_FVector FingerOffsetsContainer{FingerOffsets}; + SGCoreImpl_FSGSenseGlovePoseImpl_CalculateFingertips(&InstanceContainer, &OutFingertipsContainer, + &FingerOffsetsContainer); + return OutFingertipsContainer.Array; +} + +bool USGSenseGlovePose::Equals(const USGSenseGlovePose* SenseGlovePose) const +{ + FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; + FSGIC_FSGSenseGlovePoseImpl SenseGlovePoseContainer{SenseGlovePose->ToSenseGlovePoseImpl()}; + return SGCoreImpl_FSGSenseGlovePoseImpl_Equals(&InstanceContainer, &SenseGlovePoseContainer); +} + +FString USGSenseGlovePose::ToString(const bool bShortFormat) const +{ + FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGSenseGlovePoseImpl_ToString(&InstanceContainer, &OutStringContainer, bShortFormat); + return OutStringContainer.String; +} + +FString USGSenseGlovePose::SGSerialize() const +{ + FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGSenseGlovePoseImpl_Serialize(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +USGSenseGlovePose::FImpl::FImpl(USGSenseGlovePose* InOwner) + : Owner(InOwner) +{ +} + +USGSenseGlovePose::FImpl::~FImpl() = default; + +void USGSenseGlovePose::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGloveSensorData.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGloveSensorData.cpp new file mode 100644 index 0000000..0afb95f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGloveSensorData.cpp @@ -0,0 +1,351 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGSenseGloveSensorData.h" + +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGCoreImpl/SGSenseGloveSensorDataImpl.h" +#include "SGInterop/SGIC_ESGFinger.h" +#include "SGInterop/SGIC_FQuat.h" +#include "SGInterop/SGIC_FSGSenseGloveInfoImpl.h" +#include "SGInterop/SGIC_FSGSenseGloveSensorDataImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_TArray_float.h" +#include "SGInterop/SGIC_TArray_TArray_float.h" +#include "SGUtils/SGArrayUtils.h" + +struct USGSenseGloveSensorData::FImpl +{ + /************************ + * Member variables + ************************/ + + FSGSenseGloveSensorDataImpl SenseGloveSensorDataImpl; + + /************************ + * Owner object + ************************/ + + USGSenseGloveSensorData* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGSenseGloveSensorData* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGSenseGloveSensorData* USGSenseGloveSensorData::NewSenseGloveSensorData( + UObject* Outer, const FSGSenseGloveSensorDataImpl& SenseGloveSensorDataImpl) +{ + USGSenseGloveSensorData* Instance = NewObject(Outer); + Instance->SetSenseGloveSensorDataImpl(SenseGloveSensorDataImpl); + return Instance; +} + +USGSenseGloveSensorData* USGSenseGloveSensorData::NewSenseGloveSensorData(UObject* Outer) +{ + FSGIC_FSGSenseGloveSensorDataImpl OutSenseGloveSensorDataImplContainer; + SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor(&OutSenseGloveSensorDataImplContainer); + + return NewSenseGloveSensorData(Outer, MoveTemp(OutSenseGloveSensorDataImplContainer.SenseGloveSensorDataImpl)); +} + +USGSenseGloveSensorData* USGSenseGloveSensorData::NewSenseGloveSensorData( + UObject* Outer, const TArray>& SensorAngles, + const FQuat& ImuRotation, const int32 ParsedValues, const bool bImuParsed) +{ + FSGIC_FSGSenseGloveSensorDataImpl OutSenseGloveSensorDataImplContainer; + FSGIC_TArray_TArray_float SensorAnglesContainer{SensorAngles}; + FSGIC_FQuat ImuRotationContainer{ImuRotation}; + SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor_SensorAngles_ImuRotation_ParsedValues_bImuParsed( + &OutSenseGloveSensorDataImplContainer, &SensorAnglesContainer, &ImuRotationContainer, ParsedValues, bImuParsed); + + return NewSenseGloveSensorData(Outer, MoveTemp(OutSenseGloveSensorDataImplContainer.SenseGloveSensorDataImpl)); +} + +USGSenseGloveSensorData* USGSenseGloveSensorData::NewSenseGloveSensorData( + UObject* Outer, const TArray>& SensorAngles, + const FRotator& ImuRotation, const int32 ParsedValues, const bool bImuParsed) +{ + FSGIC_FSGSenseGloveSensorDataImpl OutSenseGloveSensorDataImplContainer; + FSGIC_TArray_TArray_float SensorAnglesContainer{SensorAngles}; + FSGIC_FQuat ImuRotationContainer{ImuRotation.Quaternion()}; + SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor_SensorAngles_ImuRotation_ParsedValues_bImuParsed( + &OutSenseGloveSensorDataImplContainer, &SensorAnglesContainer, &ImuRotationContainer, ParsedValues, bImuParsed); + + return NewSenseGloveSensorData(Outer, MoveTemp(OutSenseGloveSensorDataImplContainer.SenseGloveSensorDataImpl)); +} + +USGSenseGloveSensorData* USGSenseGloveSensorData::NewSenseGloveSensorData( + UObject* Outer, const TArray& SensorAngles, + const FQuat& ImuRotation, const int32 ParsedValues, const bool bImuParsed) +{ + FSGIC_FSGSenseGloveSensorDataImpl OutSenseGloveSensorDataImplContainer; + FSGIC_TArray_TArray_float SensorAnglesContainer{ + FSGArrayUtils::FromNestedBPArray(SensorAngles) + }; + FSGIC_FQuat ImuRotationContainer{ImuRotation}; + SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor_SensorAngles_ImuRotation_ParsedValues_bImuParsed( + &OutSenseGloveSensorDataImplContainer, &SensorAnglesContainer, &ImuRotationContainer, ParsedValues, bImuParsed); + + return NewSenseGloveSensorData(Outer, MoveTemp(OutSenseGloveSensorDataImplContainer.SenseGloveSensorDataImpl)); +} + +USGSenseGloveSensorData* USGSenseGloveSensorData::NewSenseGloveSensorData( + UObject* Outer, const TArray& SensorAngles, + const FRotator& ImuRotation, const int32 ParsedValues, const bool bImuParsed) +{ + FSGIC_FSGSenseGloveSensorDataImpl OutSenseGloveSensorDataImplContainer; + FSGIC_TArray_TArray_float SensorAnglesContainer{ + FSGArrayUtils::FromNestedBPArray(SensorAngles) + }; + FSGIC_FQuat ImuRotationContainer{ImuRotation.Quaternion()}; + SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor_SensorAngles_ImuRotation_ParsedValues_bImuParsed( + &OutSenseGloveSensorDataImplContainer, &SensorAnglesContainer, &ImuRotationContainer, ParsedValues, bImuParsed); + + return NewSenseGloveSensorData(Outer, MoveTemp(OutSenseGloveSensorDataImplContainer.SenseGloveSensorDataImpl)); +} + +USGSenseGloveSensorData* USGSenseGloveSensorData::Empty(UObject* Outer) +{ + FSGIC_FSGSenseGloveSensorDataImpl OutSenseGloveSensorDataImplContainer; + SGCoreImpl_FSGSenseGloveSensorDataImpl_Empty(&OutSenseGloveSensorDataImplContainer); + + return NewSenseGloveSensorData(Outer, MoveTemp(OutSenseGloveSensorDataImplContainer.SenseGloveSensorDataImpl)); +} + +USGSenseGloveSensorData* USGSenseGloveSensorData::Parse(UObject* Outer, + const FString& RawData, const USGSenseGloveInfo* GloveInfo) +{ + FSGIC_FSGSenseGloveSensorDataImpl OutSenseGloveSensorDataImplContainer; + FSGIC_FString RawDataString{RawData}; + FSGIC_FSGSenseGloveInfoImpl GloveInfoContainer{GloveInfo->ToSenseGloveInfoImpl()}; + SGCoreImpl_FSGSenseGloveSensorDataImpl_Parse(&OutSenseGloveSensorDataImplContainer, + &RawDataString, &GloveInfoContainer); + + return NewSenseGloveSensorData(Outer, MoveTemp(OutSenseGloveSensorDataImplContainer.SenseGloveSensorDataImpl)); +} + +USGSenseGloveSensorData* USGSenseGloveSensorData::Deserialize(UObject* Outer, const FString& SerializedString) +{ + FSGIC_FSGSenseGloveSensorDataImpl OutSenseGloveSensorDataImplContainer; + FSGIC_FString SerializedStringContainer{SerializedString}; + SGCoreImpl_FSGSenseGloveSensorDataImpl_Deserialize(&OutSenseGloveSensorDataImplContainer, + &SerializedStringContainer); + + return NewSenseGloveSensorData(Outer, MoveTemp(OutSenseGloveSensorDataImplContainer.SenseGloveSensorDataImpl)); +} + +USGSenseGloveSensorData::USGSenseGloveSensorData() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGSenseGloveSensorDataImpl OutSenseGloveSensorDataImplContainer; + SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor(&OutSenseGloveSensorDataImplContainer); + + Pimpl->SenseGloveSensorDataImpl = MoveTemp(OutSenseGloveSensorDataImplContainer.SenseGloveSensorDataImpl); +} + +USGSenseGloveSensorData::USGSenseGloveSensorData(const TArray>& SensorAngles, const FQuat& ImuRotation, + const int32 ParsedValues, const bool bImuParsed) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGSenseGloveSensorDataImpl OutSenseGloveSensorDataImplContainer; + FSGIC_TArray_TArray_float SensorAnglesContainer{SensorAngles}; + FSGIC_FQuat ImuRotationContainer{ImuRotation}; + SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor_SensorAngles_ImuRotation_ParsedValues_bImuParsed( + &OutSenseGloveSensorDataImplContainer, &SensorAnglesContainer, &ImuRotationContainer, ParsedValues, bImuParsed); + + Pimpl->SenseGloveSensorDataImpl = MoveTemp(OutSenseGloveSensorDataImplContainer.SenseGloveSensorDataImpl); +} + +USGSenseGloveSensorData::USGSenseGloveSensorData(const TArray>& SensorAngles, const FRotator& ImuRotation, + const int32 ParsedValues, const bool bImuParsed) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGSenseGloveSensorDataImpl OutSenseGloveSensorDataImplContainer; + FSGIC_TArray_TArray_float SensorAnglesContainer{SensorAngles}; + FSGIC_FQuat ImuRotationContainer{ImuRotation.Quaternion()}; + SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor_SensorAngles_ImuRotation_ParsedValues_bImuParsed( + &OutSenseGloveSensorDataImplContainer, &SensorAnglesContainer, &ImuRotationContainer, ParsedValues, bImuParsed); + + Pimpl->SenseGloveSensorDataImpl = MoveTemp(OutSenseGloveSensorDataImplContainer.SenseGloveSensorDataImpl); +} + +USGSenseGloveSensorData::USGSenseGloveSensorData(const TArray& SensorAngles, const FQuat& ImuRotation, + const int32 ParsedValues, const bool bImuParsed) +{ + FSGIC_FSGSenseGloveSensorDataImpl OutSenseGloveSensorDataImplContainer; + FSGIC_TArray_TArray_float SensorAnglesContainer{ + FSGArrayUtils::FromNestedBPArray(SensorAngles) + }; + FSGIC_FQuat ImuRotationContainer{ImuRotation}; + SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor_SensorAngles_ImuRotation_ParsedValues_bImuParsed( + &OutSenseGloveSensorDataImplContainer, &SensorAnglesContainer, &ImuRotationContainer, ParsedValues, bImuParsed); + + Pimpl->SenseGloveSensorDataImpl = MoveTemp(OutSenseGloveSensorDataImplContainer.SenseGloveSensorDataImpl); +} + +USGSenseGloveSensorData::USGSenseGloveSensorData(const TArray& SensorAngles, const FRotator& ImuRotation, + const int32 ParsedValues, const bool bImuParsed) +{ + FSGIC_FSGSenseGloveSensorDataImpl OutSenseGloveSensorDataImplContainer; + FSGIC_TArray_TArray_float SensorAnglesContainer{ + FSGArrayUtils::FromNestedBPArray(SensorAngles) + }; + FSGIC_FQuat ImuRotationContainer{ImuRotation.Quaternion()}; + SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor_SensorAngles_ImuRotation_ParsedValues_bImuParsed( + &OutSenseGloveSensorDataImplContainer, &SensorAnglesContainer, &ImuRotationContainer, ParsedValues, bImuParsed); + + Pimpl->SenseGloveSensorDataImpl = MoveTemp(OutSenseGloveSensorDataImplContainer.SenseGloveSensorDataImpl); +} + +USGSenseGloveSensorData::USGSenseGloveSensorData(const FSGSenseGloveSensorDataImpl& SenseGloveSensorDataImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + SetSenseGloveSensorDataImpl(SenseGloveSensorDataImpl); +} + +USGSenseGloveSensorData::~USGSenseGloveSensorData() = default; + +void USGSenseGloveSensorData::SetSenseGloveSensorDataImpl(const FSGSenseGloveSensorDataImpl& SenseGloveSensorDataImpl) +{ + FSGIC_FSGSenseGloveSensorDataImpl OutSenseGloveSensorDataContainer; + FSGIC_FSGSenseGloveSensorDataImpl RhsContainer{SenseGloveSensorDataImpl}; + SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor_copy(&OutSenseGloveSensorDataContainer, &RhsContainer); + Pimpl->SenseGloveSensorDataImpl = MoveTemp(OutSenseGloveSensorDataContainer.SenseGloveSensorDataImpl); +} + +const FSGSenseGloveSensorDataImpl& USGSenseGloveSensorData::ToSenseGloveSensorDataImpl() const +{ + return Pimpl->SenseGloveSensorDataImpl; +} + +TArray> USGSenseGloveSensorData::GetSensorAngles() const +{ + FSGIC_FSGSenseGloveSensorDataImpl InstanceContainer{ToSenseGloveSensorDataImpl()}; + FSGIC_TArray_TArray_float OutAnglesContainer; + SGCoreImpl_FSGSenseGloveSensorDataImpl_GetSensorAngles(&InstanceContainer, &OutAnglesContainer); + return OutAnglesContainer.Array; +} + +TArray USGSenseGloveSensorData::GetSensorAngles(const ESGFinger Finger) const +{ + FSGIC_FSGSenseGloveSensorDataImpl InstanceContainer{ToSenseGloveSensorDataImpl()}; + FSGIC_TArray_float OutAnglesContainer; + FSGIC_ESGFinger FingerContainer{Finger}; + SGCoreImpl_FSGSenseGloveSensorDataImpl_GetSensorAngles_Finger(&InstanceContainer, &OutAnglesContainer, + &FingerContainer); + return OutAnglesContainer.Array; +} + +TArray USGSenseGloveSensorData::GetAngleSequence() const +{ + FSGIC_FSGSenseGloveSensorDataImpl InstanceContainer{ToSenseGloveSensorDataImpl()}; + FSGIC_TArray_float OutSequenceContainer; + SGCoreImpl_FSGSenseGloveSensorDataImpl_GetAngleSequence(&InstanceContainer, &OutSequenceContainer); + return OutSequenceContainer.Array; +} + +FQuat USGSenseGloveSensorData::GetImuRotationQ() const +{ + FSGIC_FSGSenseGloveSensorDataImpl InstanceContainer{ToSenseGloveSensorDataImpl()}; + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGSenseGloveSensorDataImpl_GetImuRotation(&InstanceContainer, &OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator USGSenseGloveSensorData::GetImuRotation() const +{ + FSGIC_FSGSenseGloveSensorDataImpl InstanceContainer{ToSenseGloveSensorDataImpl()}; + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGSenseGloveSensorDataImpl_GetImuRotation(&InstanceContainer, &OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +int32 USGSenseGloveSensorData::GetParsedValues() const +{ + FSGIC_FSGSenseGloveSensorDataImpl InstanceContainer{ToSenseGloveSensorDataImpl()}; + return SGCoreImpl_FSGSenseGloveSensorDataImpl_GetParsedValues(&InstanceContainer); +} + +bool USGSenseGloveSensorData::IsImuParsed() const +{ + FSGIC_FSGSenseGloveSensorDataImpl InstanceContainer{ToSenseGloveSensorDataImpl()}; + return SGCoreImpl_FSGSenseGloveSensorDataImpl_IsImuParsed(&InstanceContainer); +} + +bool USGSenseGloveSensorData::Equals(const USGSenseGloveSensorData* SenseGloveSensorData) const +{ + FSGIC_FSGSenseGloveSensorDataImpl InstanceContainer{ToSenseGloveSensorDataImpl()}; + FSGIC_FSGSenseGloveSensorDataImpl SenseGloveSensorDataContainer{SenseGloveSensorData->ToSenseGloveSensorDataImpl()}; + return SGCoreImpl_FSGSenseGloveSensorDataImpl_Equals(&InstanceContainer, &SenseGloveSensorDataContainer); +} + +FString USGSenseGloveSensorData::ToString() const +{ + FSGIC_FSGSenseGloveSensorDataImpl InstanceContainer{ToSenseGloveSensorDataImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGSenseGloveSensorDataImpl_ToString(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +FString USGSenseGloveSensorData::SGSerialize() const +{ + FSGIC_FSGSenseGloveSensorDataImpl InstanceContainer{ToSenseGloveSensorDataImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGSenseGloveSensorDataImpl_Serialize(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +USGSenseGloveSensorData::FImpl::FImpl(USGSenseGloveSensorData* InOwner) + : Owner(InOwner) +{ +} + +USGSenseGloveSensorData::FImpl::~FImpl() = default; + +void USGSenseGloveSensorData::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGloveSensorNormalizer.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGloveSensorNormalizer.cpp new file mode 100644 index 0000000..eeac88c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGloveSensorNormalizer.cpp @@ -0,0 +1,172 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGSenseGloveSensorNormalizer.h" + +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGCoreImpl/SGSenseGloveSensorNormalizerImpl.h" +#include "SGInterop/SGIC_FSGSenseGloveSensorNormalizerImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_TArray_bool.h" +#include "SGInterop/SGIC_TArray_float.h" +#include "SGUtils/SGArrayUtils.h" + +struct USGSenseGloveSensorNormalizer::FImpl +{ + /************************ + * Member variables + ************************/ + + FSGSenseGloveSensorNormalizerImpl SenseGloveSensorNormalizerImpl; + + /************************ + * Owner object + ************************/ + + USGSenseGloveSensorNormalizer* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGSenseGloveSensorNormalizer* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGSenseGloveSensorNormalizer* USGSenseGloveSensorNormalizer::NewSenseGloveSensorNormalizer( + UObject* Outer, const FSGSenseGloveSensorNormalizerImpl& SenseGloveSensorNormalizerImpl) +{ + USGSenseGloveSensorNormalizer* Instance = NewObject(Outer); + Instance->SetSenseGloveSensorNormalizerImpl(SenseGloveSensorNormalizerImpl); + return Instance; +} + +USGSenseGloveSensorNormalizer* USGSenseGloveSensorNormalizer::NewSenseGloveSensorNormalizer(UObject* Outer) +{ + FSGIC_FSGSenseGloveSensorNormalizerImpl OutSenseGloveSensorNormalizerImplContainer; + SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_ctor(&OutSenseGloveSensorNormalizerImplContainer); + + return NewSenseGloveSensorNormalizer( + Outer, MoveTemp(OutSenseGloveSensorNormalizerImplContainer.SenseGloveSensorNormalizerImpl)); +} + +USGSenseGloveSensorNormalizer* USGSenseGloveSensorNormalizer::NewSenseGloveSensorNormalizer( + UObject* Outer, const bool bRightHanded) +{ + FSGIC_FSGSenseGloveSensorNormalizerImpl OutSenseGloveSensorNormalizerImplContainer; + SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_ctor_bRightHanded( + &OutSenseGloveSensorNormalizerImplContainer, bRightHanded); + + return NewSenseGloveSensorNormalizer( + Outer, MoveTemp(OutSenseGloveSensorNormalizerImplContainer.SenseGloveSensorNormalizerImpl)); +} + +USGSenseGloveSensorNormalizer::USGSenseGloveSensorNormalizer() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGSenseGloveSensorNormalizerImpl OutSenseGloveSensorNormalizerImplContainer; + SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_ctor(&OutSenseGloveSensorNormalizerImplContainer); + + Pimpl->SenseGloveSensorNormalizerImpl = MoveTemp( + OutSenseGloveSensorNormalizerImplContainer.SenseGloveSensorNormalizerImpl); +} + +USGSenseGloveSensorNormalizer::USGSenseGloveSensorNormalizer(bool bRightHanded) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGSenseGloveSensorNormalizerImpl OutSenseGloveSensorNormalizerImplContainer; + SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_ctor_bRightHanded( + &OutSenseGloveSensorNormalizerImplContainer, bRightHanded); + + Pimpl->SenseGloveSensorNormalizerImpl = + MoveTemp(OutSenseGloveSensorNormalizerImplContainer.SenseGloveSensorNormalizerImpl); +} + +USGSenseGloveSensorNormalizer::USGSenseGloveSensorNormalizer( + const FSGSenseGloveSensorNormalizerImpl& SenseGloveSensorNormalizerImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + SetSenseGloveSensorNormalizerImpl(SenseGloveSensorNormalizerImpl); +} + +USGSenseGloveSensorNormalizer::~USGSenseGloveSensorNormalizer() = default; + +void USGSenseGloveSensorNormalizer::SetSenseGloveSensorNormalizerImpl( + const FSGSenseGloveSensorNormalizerImpl& SenseGloveSensorNormalizerImpl) +{ + FSGIC_FSGSenseGloveSensorNormalizerImpl OutSenseGloveSensorNormalizerContainer; + FSGIC_FSGSenseGloveSensorNormalizerImpl RhsContainer{SenseGloveSensorNormalizerImpl}; + SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_ctor_copy(&OutSenseGloveSensorNormalizerContainer, &RhsContainer); + Pimpl->SenseGloveSensorNormalizerImpl = MoveTemp( + OutSenseGloveSensorNormalizerContainer.SenseGloveSensorNormalizerImpl); +} + +const FSGSenseGloveSensorNormalizerImpl& USGSenseGloveSensorNormalizer::ToSenseGloveSensorNormalizerImpl() const +{ + return Pimpl->SenseGloveSensorNormalizerImpl; +} + +float USGSenseGloveSensorNormalizer::NormalizeFlexion(const int32 Finger, const float SumFlexionAngles) const +{ + FSGIC_FSGSenseGloveSensorNormalizerImpl InstanceContainer{ToSenseGloveSensorNormalizerImpl()}; + return SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_NormalizeFlexion( + &InstanceContainer, Finger, SumFlexionAngles); +} + +float USGSenseGloveSensorNormalizer::NormalizeAbduction(const int32 Finger, const float SumAbductionAngles) const +{ + FSGIC_FSGSenseGloveSensorNormalizerImpl InstanceContainer{ToSenseGloveSensorNormalizerImpl()}; + return SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_NormalizeAbduction( + &InstanceContainer, Finger, SumAbductionAngles); +} + +USGSenseGloveSensorNormalizer::FImpl::FImpl(USGSenseGloveSensorNormalizer* InOwner) + : Owner(InOwner) +{ +} + +USGSenseGloveSensorNormalizer::FImpl::~FImpl() = default; + +void USGSenseGloveSensorNormalizer::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGloveVars.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGloveVars.cpp new file mode 100644 index 0000000..25bbd30 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSenseGloveVars.cpp @@ -0,0 +1,166 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGSenseGloveVars.h" + +#include "SGCore/SGSenseGloveInfo.h" +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_FQuat.h" +#include "SGInterop/SGIC_FSGSenseGloveInfoImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_TArray_bool.h" +#include "SGInterop/SGIC_TArray_FQuat.h" +#include "SGInterop/SGIC_TArray_FVector.h" +#include "SGInterop/SGIC_TArray_TArray_FVector.h" +#include "SGUtils/SGArrayUtils.h" + +FString FSGSenseGloveVars::GetStandardConstantsString(const FString& HardwareVersion, const float FirmwareVersion, + const bool bRightHanded) +{ + FSGIC_FString OutStringContainer; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + SGCoreImpl_FSGSenseGloveVarsImpl_GetStandardConstantsString(&OutStringContainer, + &HardwareVersionContainer, FirmwareVersion, + bRightHanded); + return OutStringContainer.String; +} + +FString FSGSenseGloveVars::GetSensorString(const FString& HardwareVersion, const float FirmwareVersion) +{ + FSGIC_FString OutStringContainer; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + SGCoreImpl_FSGSenseGloveVarsImpl_GetSensorString(&OutStringContainer, &HardwareVersionContainer, FirmwareVersion); + return OutStringContainer.String; +} + +TArray FSGSenseGloveVars::GetStartPositions(const FString& HardwareVersion, const bool bRightHanded) +{ + FSGIC_TArray_FVector OutPositionsContainer; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + SGCoreImpl_FSGSenseGloveVarsImpl_GetStartPositions(&OutPositionsContainer, &HardwareVersionContainer, bRightHanded); + return OutPositionsContainer.Array; +} + +TArray FSGSenseGloveVars::GetStartRotationsQ(const FString& HardwareVersion, const bool bRightHanded) +{ + FSGIC_TArray_FQuat OutRotationsContainer; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + SGCoreImpl_FSGSenseGloveVarsImpl_GetStartRotations(&OutRotationsContainer, &HardwareVersionContainer, bRightHanded); + return OutRotationsContainer.Array; +} + +TArray FSGSenseGloveVars::GetStartRotations(const FString& HardwareVersion, const bool bRightHanded) +{ + FSGIC_TArray_FQuat OutRotationsContainer; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + SGCoreImpl_FSGSenseGloveVarsImpl_GetStartRotations(&OutRotationsContainer, &HardwareVersionContainer, bRightHanded); + return FSGArrayUtils::QuatsToRotators(OutRotationsContainer.Array); +} + +TArray> FSGSenseGloveVars::GetGloveLengths(const FString& HardwareVersion) +{ + FSGIC_TArray_TArray_FVector OutLengthsContainer; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + SGCoreImpl_FSGSenseGloveVarsImpl_GetGloveLengths(&OutLengthsContainer, &HardwareVersionContainer); + return OutLengthsContainer.Array; +} + +/* +TArray FSGSenseGloveVars::GetGloveLengths_BP(const FString& HardwareVersion) +{ + return FSGArrayUtils::ToNestedBPArray(GetGloveLengths(HardwareVersion)); +} +*/ +int32 FSGSenseGloveVars::GetSensors(const FString& HardwareVersion) +{ + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + return SGCoreImpl_FSGSenseGloveVarsImpl_GetSensors(&HardwareVersionContainer); +} + +FQuat FSGSenseGloveVars::GetImuCorrectionQ(const FString& HardwareVersion, + const int32 FirmwareVersion, const int32 SubFirmwareVersion) +{ + FSGIC_FQuat OutCorrectionContainer; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + SGCoreImpl_FSGSenseGloveVarsImpl_GetImuCorrection(&OutCorrectionContainer, + &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion); + return OutCorrectionContainer.Quat; +} + +FRotator FSGSenseGloveVars::GetImuCorrection(const FString& HardwareVersion, + const int32 FirmwareVersion, const int32 SubFirmwareVersion) +{ + FSGIC_FQuat OutCorrectionContainer; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + SGCoreImpl_FSGSenseGloveVarsImpl_GetImuCorrection(&OutCorrectionContainer, + &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion); + return OutCorrectionContainer.Quat.Rotator(); +} + +TArray FSGSenseGloveVars::GetFunctions(const FString& HardwareVersion, + const int32 FirmwareVersion, const int32 SubFirmwareVersion) +{ + FSGIC_TArray_bool OutFunctionsContainer; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + SGCoreImpl_FSGSenseGloveVarsImpl_GetFunctions(&OutFunctionsContainer, + &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion); + return OutFunctionsContainer.Array; +} + +USGSenseGloveInfo* FSGSenseGloveVars::GenerateGloveModel(UObject* Outer, const FString& HardwareVersion, + const int32 FirmwareVersion, const int32 SubFirmwareVersion, + const bool bRightHanded) +{ + FSGIC_FSGSenseGloveInfoImpl OutModelContainer; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + SGCoreImpl_FSGSenseGloveVarsImpl_GenerateGloveModel_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded( + &OutModelContainer, &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion, bRightHanded); + + return USGSenseGloveInfo::NewSenseGloveInfo(Outer, MoveTemp(OutModelContainer.SenseGloveInfoImpl)); +} + +USGSenseGloveInfo* FSGSenseGloveVars::GenerateGloveModel(UObject* Outer, const FString& HardwareVersion, + const int32 FirmwareVersion, const int32 SubFirmwareVersion, + const bool bRightHanded, const FString& CustomId) +{ + FSGIC_FSGSenseGloveInfoImpl OutModelContainer; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FString CustomIdContainer{CustomId}; + SGCoreImpl_FSGSenseGloveVarsImpl_GenerateGloveModel_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded_CustomId( + &OutModelContainer, &HardwareVersionContainer, FirmwareVersion, SubFirmwareVersion, bRightHanded, + &CustomIdContainer); + + return USGSenseGloveInfo::NewSenseGloveInfo(Outer, MoveTemp(OutModelContainer.SenseGloveInfoImpl)); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSensorNormalization.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSensorNormalization.cpp new file mode 100644 index 0000000..709b3a4 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGSensorNormalization.cpp @@ -0,0 +1,228 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGSensorNormalization.h" + +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGCoreImpl/SGSensorNormalizationImpl.h" +#include "SGInterop/SGIC_FSGSensorNormalizationImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_TArray_bool.h" +#include "SGInterop/SGIC_TArray_float.h" +#include "SGUtils/SGArrayUtils.h" + +struct USGSensorNormalization::FImpl +{ + /************************ + * Member variables + ************************/ + + FSGSensorNormalizationImpl SensorNormalizationImpl; + + /************************ + * Owner object + ************************/ + + USGSensorNormalization* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGSensorNormalization* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGSensorNormalization* USGSensorNormalization::NewSensorNormalization( + UObject* Outer, const FSGSensorNormalizationImpl& SensorNormalizationImpl) +{ + USGSensorNormalization* Instance = NewObject(Outer); + Instance->SetSensorNormalizationImpl(SensorNormalizationImpl); + return Instance; +} + +USGSensorNormalization* USGSensorNormalization::NewSensorNormalization(UObject* Outer) +{ + FSGIC_FSGSensorNormalizationImpl OutSensorNormalizationImplContainer; + SGCoreImpl_FSGSensorNormalizationImpl_ctor(&OutSensorNormalizationImplContainer); + + return NewSensorNormalization(Outer, MoveTemp(OutSensorNormalizationImplContainer.SensorNormalizationImpl)); +} + +USGSensorNormalization* USGSensorNormalization::NewSensorNormalization( + UObject* Outer, const TArray& MovementRanges) +{ + FSGIC_FSGSensorNormalizationImpl OutSensorNormalizationImplContainer; + FSGIC_TArray_float MovementRangesContainer{MovementRanges}; + SGCoreImpl_FSGSensorNormalizationImpl_ctor_MovementRanges( + &OutSensorNormalizationImplContainer, &MovementRangesContainer); + + return NewSensorNormalization(Outer, MoveTemp(OutSensorNormalizationImplContainer.SensorNormalizationImpl)); +} + +USGSensorNormalization::USGSensorNormalization() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGSensorNormalizationImpl OutSensorNormalizationImplContainer; + SGCoreImpl_FSGSensorNormalizationImpl_ctor(&OutSensorNormalizationImplContainer); + + Pimpl->SensorNormalizationImpl = MoveTemp(OutSensorNormalizationImplContainer.SensorNormalizationImpl); +} + +USGSensorNormalization::USGSensorNormalization(const TArray& MovementRanges) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGSensorNormalizationImpl OutSensorNormalizationImplContainer; + FSGIC_TArray_float MovementRangesContainer{MovementRanges}; + SGCoreImpl_FSGSensorNormalizationImpl_ctor_MovementRanges( + &OutSensorNormalizationImplContainer, &MovementRangesContainer); + + Pimpl->SensorNormalizationImpl = MoveTemp(OutSensorNormalizationImplContainer.SensorNormalizationImpl); +} + +USGSensorNormalization::USGSensorNormalization(const FSGSensorNormalizationImpl& SensorNormalizationImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + SetSensorNormalizationImpl(SensorNormalizationImpl); +} + +USGSensorNormalization::~USGSensorNormalization() = default; + +void USGSensorNormalization::SetSensorNormalizationImpl(const FSGSensorNormalizationImpl& SensorNormalizationImpl) +{ + FSGIC_FSGSensorNormalizationImpl OutSensorNormalizationContainer; + FSGIC_FSGSensorNormalizationImpl RhsContainer{SensorNormalizationImpl}; + SGCoreImpl_FSGSensorNormalizationImpl_ctor_copy(&OutSensorNormalizationContainer, &RhsContainer); + Pimpl->SensorNormalizationImpl = MoveTemp(OutSensorNormalizationContainer.SensorNormalizationImpl); +} + +const FSGSensorNormalizationImpl& USGSensorNormalization::ToSensorNormalizationImpl() const +{ + return Pimpl->SensorNormalizationImpl; +} + +bool USGSensorNormalization::CollectsNormalization() const +{ + FSGIC_FSGSensorNormalizationImpl InstanceContainer{ToSensorNormalizationImpl()}; + return SGCoreImpl_FSGSensorNormalizationImpl_CollectsNormalization(&InstanceContainer); +} + +void USGSensorNormalization::SetCollectNormalization(const bool bCollectNormalization) +{ + FSGIC_FSGSensorNormalizationImpl InstanceContainer{ToSensorNormalizationImpl()}; + SGCoreImpl_FSGSensorNormalizationImpl_SetCollectNormalization( + &InstanceContainer, bCollectNormalization); +} + +int32 USGSensorNormalization::GetLength() const +{ + FSGIC_FSGSensorNormalizationImpl InstanceContainer{ToSensorNormalizationImpl()}; + return SGCoreImpl_FSGSensorNormalizationImpl_GetLength(&InstanceContainer); +} + +int32 USGSensorNormalization::GetMoveCount() const +{ + FSGIC_FSGSensorNormalizationImpl InstanceContainer{ToSensorNormalizationImpl()}; + return SGCoreImpl_FSGSensorNormalizationImpl_GetMoveCount(&InstanceContainer); +} + +bool USGSensorNormalization::AllSensorsMoving() const +{ + FSGIC_FSGSensorNormalizationImpl InstanceContainer{ToSensorNormalizationImpl()}; + return SGCoreImpl_FSGSensorNormalizationImpl_AllSensorsMoving(&InstanceContainer); +} + +void USGSensorNormalization::ResetNormalization() +{ + FSGIC_FSGSensorNormalizationImpl InstanceContainer{ToSensorNormalizationImpl()}; + return SGCoreImpl_FSGSensorNormalizationImpl_ResetNormalization(&InstanceContainer); +} + +void USGSensorNormalization::UpdateNormalization(const float Value, const int32 Index) +{ + FSGIC_FSGSensorNormalizationImpl InstanceContainer{ToSensorNormalizationImpl()}; + return SGCoreImpl_FSGSensorNormalizationImpl_UpdateNormalization( + &InstanceContainer, Value, Index); +} + +float USGSensorNormalization::NormalizeValue(const float Value, const int32 Index) +{ + FSGIC_FSGSensorNormalizationImpl InstanceContainer{ToSensorNormalizationImpl()}; + return SGCoreImpl_FSGSensorNormalizationImpl_NormalizeValue( + &InstanceContainer, Value, Index); +} + +TArray USGSensorNormalization::NormalizeValues(const TArray& Values) +{ + FSGIC_FSGSensorNormalizationImpl InstanceContainer{ToSensorNormalizationImpl()}; + FSGIC_TArray_float ValuesContainer{Values}; + FSGIC_TArray_float OutNormalizedValuesContainer; + SGCoreImpl_FSGSensorNormalizationImpl_NormalizeValues( + &InstanceContainer, &ValuesContainer, &OutNormalizedValuesContainer); + + return OutNormalizedValuesContainer.Array; +} + +bool USGSensorNormalization::MovedEnough(const int32 Index) const +{ + FSGIC_FSGSensorNormalizationImpl InstanceContainer{ToSensorNormalizationImpl()}; + return SGCoreImpl_FSGSensorNormalizationImpl_MovedEnough(&InstanceContainer, Index); +} + +float USGSensorNormalization::Denormalize(const float Value01, const int32 Index, const float FallbackValue) const +{ + FSGIC_FSGSensorNormalizationImpl InstanceContainer{ToSensorNormalizationImpl()}; + return SGCoreImpl_FSGSensorNormalizationImpl_Denormalize( + &InstanceContainer, Value01, Index, FallbackValue); +} + +USGSensorNormalization::FImpl::FImpl(USGSensorNormalization* InOwner) + : Owner(InOwner) +{ +} + +USGSensorNormalization::FImpl::~FImpl() = default; + +void USGSensorNormalization::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGThresholdCommand.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGThresholdCommand.cpp new file mode 100644 index 0000000..d830531 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGThresholdCommand.cpp @@ -0,0 +1,225 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGThresholdCommand.h" + +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGCoreImpl/SGThresholdCommandImpl.h" +#include "SGInterop/SGIC_FSGThresholdCommandImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_TArray_bool.h" +#include "SGInterop/SGIC_TArray_float.h" +#include "SGUtils/SGArrayUtils.h" + +struct USGThresholdCommand::FImpl +{ + /************************ + * Member variables + ************************/ + + FSGThresholdCommandImpl ThresholdCommandImpl; + + /************************ + * Owner object + ************************/ + + USGThresholdCommand* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGThresholdCommand* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +USGThresholdCommand* USGThresholdCommand::NewThresholdCommand( + UObject* Outer, const FSGThresholdCommandImpl& ThresholdCommandImpl) +{ + USGThresholdCommand* Instance = NewObject(Outer); + Instance->SetThresholdCommandImpl(ThresholdCommandImpl); + return Instance; +} + +USGThresholdCommand* USGThresholdCommand::NewThresholdCommand(UObject* Outer) +{ + FSGIC_FSGThresholdCommandImpl OutThresholdCommandImplContainer; + SGCoreImpl_FSGThresholdCommandImpl_ctor(&OutThresholdCommandImplContainer); + + return NewThresholdCommand(Outer, MoveTemp(OutThresholdCommandImplContainer.ThresholdCommandImpl)); +} + +USGThresholdCommand* USGThresholdCommand::NewThresholdCommand( + UObject* Outer, const TArray& AffectedFingers, const TArray& ThresholdValues) +{ + FSGIC_FSGThresholdCommandImpl OutThresholdCommandImplContainer; + FSGIC_TArray_bool AffectedFingersContainer{AffectedFingers}; + FSGIC_TArray_float ThresholdValuesContainer{ThresholdValues}; + SGCoreImpl_FSGThresholdCommandImpl_ctor_AffectedFingers_ThresholdValues( + &OutThresholdCommandImplContainer, &AffectedFingersContainer, &ThresholdValuesContainer); + + return NewThresholdCommand(Outer, MoveTemp(OutThresholdCommandImplContainer.ThresholdCommandImpl)); +} + +USGThresholdCommand::USGThresholdCommand() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGThresholdCommandImpl OutThresholdCommandImplContainer; + SGCoreImpl_FSGThresholdCommandImpl_ctor(&OutThresholdCommandImplContainer); + + Pimpl->ThresholdCommandImpl = MoveTemp(OutThresholdCommandImplContainer.ThresholdCommandImpl); +} + +USGThresholdCommand::USGThresholdCommand(const TArray& AffectedFingers, const TArray& ThresholdValues) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + FSGIC_FSGThresholdCommandImpl OutThresholdCommandImplContainer; + FSGIC_TArray_bool AffectedFingersContainer{AffectedFingers}; + FSGIC_TArray_float ThresholdValuesContainer{ThresholdValues}; + SGCoreImpl_FSGThresholdCommandImpl_ctor_AffectedFingers_ThresholdValues( + &OutThresholdCommandImplContainer, &AffectedFingersContainer, &ThresholdValuesContainer); + + Pimpl->ThresholdCommandImpl = MoveTemp(OutThresholdCommandImplContainer.ThresholdCommandImpl); +} + +USGThresholdCommand::USGThresholdCommand(const FSGThresholdCommandImpl& ThresholdCommandImpl) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + SetThresholdCommandImpl(ThresholdCommandImpl); +} + +USGThresholdCommand::~USGThresholdCommand() = default; + +void USGThresholdCommand::SetThresholdCommandImpl(const FSGThresholdCommandImpl& ThresholdCommandImpl) +{ + FSGIC_FSGThresholdCommandImpl OutThresholdCommandContainer; + FSGIC_FSGThresholdCommandImpl RhsContainer{ThresholdCommandImpl}; + SGCoreImpl_FSGThresholdCommandImpl_ctor_copy(&OutThresholdCommandContainer, &RhsContainer); + Pimpl->ThresholdCommandImpl = MoveTemp(OutThresholdCommandContainer.ThresholdCommandImpl); +} + +const FSGThresholdCommandImpl& USGThresholdCommand::ToThresholdCommandImpl() const +{ + return Pimpl->ThresholdCommandImpl; +} + +float USGThresholdCommand::GetThreshold(const int32 Finger) const +{ + FSGIC_FSGThresholdCommandImpl InstanceContainer{ToThresholdCommandImpl()}; + return SGCoreImpl_FSGThresholdCommandImpl_GetThreshold(&InstanceContainer, Finger); +} + +void USGThresholdCommand::SetThreshold(const int32 Finger, const float ThresholdValue) +{ + FSGIC_FSGThresholdCommandImpl InstanceContainer{ToThresholdCommandImpl()}; + return SGCoreImpl_FSGThresholdCommandImpl_SetThreshold(&InstanceContainer, Finger, ThresholdValue); +} + +TArray USGThresholdCommand::GetThresholds() const +{ + FSGIC_FSGThresholdCommandImpl InstanceContainer{ToThresholdCommandImpl()}; + FSGIC_TArray_float ThresholdsContainer; + SGCoreImpl_FSGThresholdCommandImpl_GetThresholds(&InstanceContainer, &ThresholdsContainer); + return ThresholdsContainer.Array; +} + +void USGThresholdCommand::SetThresholds(const TArray& AffectedFingers, const TArray& ThresholdValues) +{ + FSGIC_FSGThresholdCommandImpl InstanceContainer{ToThresholdCommandImpl()}; + FSGIC_TArray_bool AffectedFingersContainer{AffectedFingers}; + FSGIC_TArray_float ThresholdValuesContainer{ThresholdValues}; + SGCoreImpl_FSGThresholdCommandImpl_SetThresholds( + &InstanceContainer, &AffectedFingersContainer, &ThresholdValuesContainer); +} + +bool USGThresholdCommand::GetFingerActive(const int32 Finger) const +{ + FSGIC_FSGThresholdCommandImpl InstanceContainer{ToThresholdCommandImpl()}; + return SGCoreImpl_FSGThresholdCommandImpl_GetFingerActive(&InstanceContainer, Finger); +} + +TArray USGThresholdCommand::GetActiveFingers() const +{ + FSGIC_FSGThresholdCommandImpl InstanceContainer{ToThresholdCommandImpl()}; + FSGIC_TArray_bool OutActiveFingersContainer; + SGCoreImpl_FSGThresholdCommandImpl_GetActiveFingers(&InstanceContainer, &OutActiveFingersContainer); + return OutActiveFingersContainer.Array; +} + +void USGThresholdCommand::ClearThreshold(const int32 Finger) +{ + FSGIC_FSGThresholdCommandImpl InstanceContainer{ToThresholdCommandImpl()}; + SGCoreImpl_FSGThresholdCommandImpl_ClearThreshold(&InstanceContainer, Finger); +} + +void USGThresholdCommand::ClearThresholds() +{ + FSGIC_FSGThresholdCommandImpl InstanceContainer{ToThresholdCommandImpl()}; + SGCoreImpl_FSGThresholdCommandImpl_ClearThresholds(&InstanceContainer); +} + +bool USGThresholdCommand::Equals(const USGThresholdCommand* ThresholdCommand) const +{ + FSGIC_FSGThresholdCommandImpl InstanceContainer{ToThresholdCommandImpl()}; + FSGIC_FSGThresholdCommandImpl ThresholdCommandContainer{ThresholdCommand->ToThresholdCommandImpl()}; + return SGCoreImpl_FSGThresholdCommandImpl_Equals(&InstanceContainer, &ThresholdCommandContainer); +} + +FString USGThresholdCommand::ToString() const +{ + FSGIC_FSGThresholdCommandImpl InstanceContainer{ToThresholdCommandImpl()}; + FSGIC_FString OutStringContainer; + SGCoreImpl_FSGThresholdCommandImpl_ToString(&InstanceContainer, &OutStringContainer); + return OutStringContainer.String; +} + +USGThresholdCommand::FImpl::FImpl(USGThresholdCommand* InOwner) + : Owner(InOwner) +{ +} + +USGThresholdCommand::FImpl::~FImpl() = default; + +void USGThresholdCommand::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGTracking.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGTracking.cpp new file mode 100644 index 0000000..0cb8cfe --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SGCore/SGTracking.cpp @@ -0,0 +1,867 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCore/SGTracking.h" + +#include "SGCoreImpl/SGExportedFunctions.h" +#include "SGInterop/SGIC_ESGFinger.h" +#include "SGInterop/SGIC_ESGPositionalTrackingHardware.h" +#include "SGInterop/SGIC_FQuat.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_FVector.h" +#include "SGInterop/SGIC_TArray_FQuat.h" +#include "SGInterop/SGIC_TArray_FVector.h" +#include "SGUtils/SGArrayUtils.h" + +void FSGTracking::CalculateLocation(const FVector& TrackedPosition, const FQuat& TrackedRotation, + const FVector& PositionOffset, const FQuat& RotationOffset, + FVector& OutNewPosition, FQuat& OutNewRotation) +{ + FSGIC_FVector TrackedPositionContainer{TrackedPosition}; + FSGIC_FQuat TrackedRotationContainer{TrackedRotation}; + FSGIC_FVector PositionOffsetContainer{PositionOffset}; + FSGIC_FQuat RotationOffsetContainer{RotationOffset}; + FSGIC_FVector OutNewPositionContainer; + FSGIC_FQuat OutNewRotationContainer; + + SGCoreImpl_FSGTrackingImpl_CalculateLocation( + &TrackedPositionContainer, &TrackedRotationContainer, + &PositionOffsetContainer, &RotationOffsetContainer, + &OutNewPositionContainer, &OutNewRotationContainer); + + OutNewPosition = MoveTemp(OutNewPositionContainer.Vector); + OutNewRotation = MoveTemp(OutNewRotationContainer.Quat); +} + +void FSGTracking::CalculateLocation(const FVector& TrackedPosition, const FRotator& TrackedRotation, + const FVector& PositionOffset, const FRotator& RotationOffset, + FVector& OutNewPosition, FRotator& OutNewRotation) +{ + FSGIC_FVector TrackedPositionContainer{TrackedPosition}; + FSGIC_FQuat TrackedRotationContainer{TrackedRotation.Quaternion()}; + FSGIC_FVector PositionOffsetContainer{PositionOffset}; + FSGIC_FQuat RotationOffsetContainer{RotationOffset.Quaternion()}; + FSGIC_FVector OutNewPositionContainer; + FSGIC_FQuat OutNewRotationContainer; + + SGCoreImpl_FSGTrackingImpl_CalculateLocation( + &TrackedPositionContainer, &TrackedRotationContainer, + &PositionOffsetContainer, &RotationOffsetContainer, + &OutNewPositionContainer, &OutNewRotationContainer); + + OutNewPosition = MoveTemp(OutNewPositionContainer.Vector); + OutNewRotation = OutNewRotationContainer.Quat.Rotator(); +} + +TArray FSGTracking::GetSenseGloveFingerToGlovePositionOrigin() +{ + FSGIC_TArray_FVector OutOriginContainer; + SGCoreImpl_FSGTrackingImpl_GetSenseGloveFingerToGlovePositionOrigin(&OutOriginContainer); + return OutOriginContainer.Array; +} + +TArray FSGTracking::GetSenseGloveFingerToGloveRotationOriginQ() +{ + FSGIC_TArray_FQuat OutOriginContainer; + SGCoreImpl_FSGTrackingImpl_GetSenseGloveFingerToGloveRotationOrigin(&OutOriginContainer); + return OutOriginContainer.Array; +} + +TArray FSGTracking::GetSenseGloveFingerToGloveRotationOrigin() +{ + FSGIC_TArray_FQuat OutOriginContainer; + SGCoreImpl_FSGTrackingImpl_GetSenseGloveFingerToGloveRotationOrigin(&OutOriginContainer); + return FSGArrayUtils::QuatsToRotators(OutOriginContainer.Array); +} + +FVector FSGTracking::GetSenseGloveWristPositionOffset() +{ + FSGIC_FVector OutOffsetContainer; + SGCoreImpl_FSGTrackingImpl_GetSenseGloveWristPositionOffset(&OutOffsetContainer); + return OutOffsetContainer.Vector; +} + +FQuat FSGTracking::GetSenseGloveWristRotationOffsetQ() +{ + FSGIC_FQuat OutOffsetContainer; + SGCoreImpl_FSGTrackingImpl_GetSenseGloveWristRotationOffset(&OutOffsetContainer); + return OutOffsetContainer.Quat; +} + +FRotator FSGTracking::GetSenseGloveWristRotationOffset() +{ + FSGIC_FQuat OutOffsetContainer; + SGCoreImpl_FSGTrackingImpl_GetSenseGloveWristRotationOffset(&OutOffsetContainer); + return OutOffsetContainer.Quat.Rotator(); +} + +void FSGTracking::GetSenseGloveMountOffset(const bool bRightHanded, const ESGFinger ToFinger, + FVector& OutIPosition, FQuat& OutIRotation) +{ + FSGIC_ESGFinger ToFingerContainer{ToFinger}; + FSGIC_FVector OutIPositionContainer; + FSGIC_FQuat OutIRotationContainer; + + SGCoreImpl_FSGTrackingImpl_GetSenseGloveMountOffset(bRightHanded, &ToFingerContainer, + &OutIPositionContainer, &OutIRotationContainer); + + OutIPosition = MoveTemp(OutIPositionContainer.Vector); + OutIRotation = MoveTemp(OutIRotationContainer.Quat); +} + +void FSGTracking::GetSenseGloveMountOffset(const bool bRightHanded, const ESGFinger ToFinger, + FVector& OutIPosition, FRotator& OutIRotation) +{ + FSGIC_ESGFinger ToFingerContainer{ToFinger}; + FSGIC_FVector OutIPositionContainer; + FSGIC_FQuat OutIRotationContainer; + + SGCoreImpl_FSGTrackingImpl_GetSenseGloveMountOffset(bRightHanded, &ToFingerContainer, + &OutIPositionContainer, &OutIRotationContainer); + + OutIPosition = MoveTemp(OutIPositionContainer.Vector); + OutIRotation = OutIRotationContainer.Quat.Rotator(); +} + +void FSGTracking::GetSenseGloveTrackerMountOffset(const ESGPositionalTrackingHardware Hardware, const bool bRightHanded, + FVector& OutPositionOffset, FQuat& OutRotationOffset) +{ + FSGIC_ESGPositionalTrackingHardware HardwareContainer; + FSGIC_FVector OutPositionOffsetContainer; + FSGIC_FQuat OutRotationOffsetContainer; + + SGCoreImpl_FSGTrackingImpl_GetSenseGloveTrackerMountOffset(&HardwareContainer, bRightHanded, + &OutPositionOffsetContainer, + &OutRotationOffsetContainer); + + OutPositionOffset = MoveTemp(OutPositionOffsetContainer.Vector); + OutRotationOffset = MoveTemp(OutRotationOffsetContainer.Quat); +} + +void FSGTracking::GetSenseGloveTrackerMountOffset(const ESGPositionalTrackingHardware Hardware, const bool bRightHanded, + FVector& OutPositionOffset, FRotator& OutRotationOffset) +{ + FSGIC_ESGPositionalTrackingHardware HardwareContainer; + FSGIC_FVector OutPositionOffsetContainer; + FSGIC_FQuat OutRotationOffsetContainer; + + SGCoreImpl_FSGTrackingImpl_GetSenseGloveTrackerMountOffset(&HardwareContainer, bRightHanded, + &OutPositionOffsetContainer, + &OutRotationOffsetContainer); + + OutPositionOffset = MoveTemp(OutPositionOffsetContainer.Vector); + OutRotationOffset = OutRotationOffsetContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetSenseGloveViveToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetSenseGloveViveToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetSenseGloveViveToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetSenseGloveViveToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetSenseGloveViveToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetSenseGloveViveToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetSenseGloveOculusTouchToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetSenseGloveOculusTouchToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetSenseGloveOculusTouchToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetSenseGloveOculusTouchToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetSenseGloveOculusTouchToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetSenseGloveOculusTouchToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetNovaToWristPositionOffset() +{ + FSGIC_FVector OutOffsetContainer; + SGCoreImpl_FSGTrackingImpl_GetNovaToWristPositionOffset(&OutOffsetContainer); + return OutOffsetContainer.Vector; +} + +FQuat FSGTracking::GetNovaToWristRotationOffsetQ() +{ + FSGIC_FQuat OutOffsetContainer; + SGCoreImpl_FSGTrackingImpl_GetNovaToWristRotationOffset(&OutOffsetContainer); + return OutOffsetContainer.Quat; +} + +FRotator FSGTracking::GetNovaToWristRotationOffset() +{ + FSGIC_FQuat OutOffsetContainer; + SGCoreImpl_FSGTrackingImpl_GetNovaToWristRotationOffset(&OutOffsetContainer); + return OutOffsetContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetRightNovaViveToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaViveToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetRightNovaViveToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaViveToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetRightNovaViveToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaViveToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetLeftNovaViveToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaViveToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetLeftNovaViveToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaViveToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetLeftNovaViveToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaViveToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetRightNovaQuest2ToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaQuest2ToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetRightNovaQuest2ToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaQuest2ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetRightNovaQuest2ToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaQuest2ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetLeftNovaQuest2ToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuest2ToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetLeftNovaQuest2ToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuest2ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetLeftNovaQuest2ToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuest2ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetRightNovaPico2ToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaPico2ToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetRightNovaPico2ToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaPico2ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetRightNovaPico2ToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaPico2ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FQuat FSGTracking::GetLeftNovaPico2ToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaPico2ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetLeftNovaPico2ToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaPico2ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetRightNovaQuestProToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaQuestProToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetRightNovaQuestProToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaQuestProToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetRightNovaQuestProToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaQuestProToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetLeftNovaQuestProToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuestProToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetLeftNovaQuestProToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuestProToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetLeftNovaQuestProToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuestProToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetRightNovaViveFocus3ToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaViveFocus3ToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetRightNovaViveFocus3ToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaViveFocus3ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetRightNovaViveFocus3ToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaViveFocus3ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetLeftNovaViveFocus3ToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaViveFocus3ToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetLeftNovaViveFocus3ToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaViveFocus3ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetLeftNovaViveFocus3ToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaViveFocus3ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetRightNovaQuest3ToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaQuest3ToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetRightNovaQuest3ToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaQuest3ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetRightNovaQuest3ToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaQuest3ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetLeftNovaQuest3ToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuest3ToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetLeftNovaQuest3ToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuest3ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetLeftNovaQuest3ToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuest3ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +void FSGTracking::GetNovaGloveWristOffset(const bool bRightHanded, FVector& OutPositionOffset, FQuat& OutRotationOffset) +{ + FSGIC_FVector OutPositionOffsetContainer; + FSGIC_FQuat OutRotationOffsetContainer; + + SGCoreImpl_FSGTrackingImpl_GetNovaGloveWristOffset(bRightHanded, + &OutPositionOffsetContainer, &OutRotationOffsetContainer); + + OutPositionOffset = MoveTemp(OutPositionOffsetContainer.Vector); + OutRotationOffset = MoveTemp(OutRotationOffsetContainer.Quat); +} + +void FSGTracking::GetNovaGloveWristOffset(const bool bRightHanded, + FVector& OutPositionOffset, FRotator& OutRotationOffset) +{ + FSGIC_FVector OutPositionOffsetContainer; + FSGIC_FQuat OutRotationOffsetContainer; + + SGCoreImpl_FSGTrackingImpl_GetNovaGloveWristOffset(bRightHanded, + &OutPositionOffsetContainer, &OutRotationOffsetContainer); + + OutPositionOffset = MoveTemp(OutPositionOffsetContainer.Vector); + OutRotationOffset = OutRotationOffsetContainer.Quat.Rotator(); +} + +void FSGTracking::GetNovaGloveTrackerOffset(const ESGPositionalTrackingHardware Hardware, const bool bRightHanded, + FVector& OutPositionOffset, FQuat& OutRotationOffset) +{ + FSGIC_ESGPositionalTrackingHardware HardwareContainer{Hardware}; + FSGIC_FVector OutPositionOffsetContainer; + FSGIC_FQuat OutRotationOffsetContainer; + + SGCoreImpl_FSGTrackingImpl_GetNovaGloveTrackerOffset(&HardwareContainer, bRightHanded, + &OutPositionOffsetContainer, &OutRotationOffsetContainer); + + OutPositionOffset = MoveTemp(OutPositionOffsetContainer.Vector); + OutRotationOffset = MoveTemp(OutRotationOffsetContainer.Quat); +} + +void FSGTracking::GetNovaGloveTrackerOffset(const ESGPositionalTrackingHardware Hardware, const bool bRightHanded, + FVector& OutPositionOffset, FRotator& OutRotationOffset) +{ + FSGIC_ESGPositionalTrackingHardware HardwareContainer{Hardware}; + FSGIC_FVector OutPositionOffsetContainer; + FSGIC_FQuat OutRotationOffsetContainer; + + SGCoreImpl_FSGTrackingImpl_GetNovaGloveTrackerOffset(&HardwareContainer, bRightHanded, + &OutPositionOffsetContainer, &OutRotationOffsetContainer); + + OutPositionOffset = MoveTemp(OutPositionOffsetContainer.Vector); + OutRotationOffset = OutRotationOffsetContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetRightNova2ToWristPositionOffset() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNova2ToWristPositionOffset(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetRightNova2ToWristRotationOffsetQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNova2ToWristRotationOffset(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetRightNova2ToWristRotationOffset() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNova2ToWristRotationOffset(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetLeftNova2ToWristPositionOffset() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNova2ToWristPositionOffset(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetLeftNova2ToWristRotationOffsetQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNova2ToWristRotationOffset(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetLeftNova2ToWristRotationOffset() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNova2ToWristRotationOffset(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetRightNova2Quest2ToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNova2Quest2ToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetRightNova2Quest2ToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNova2Quest2ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetRightNova2Quest2ToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNova2Quest2ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetLeftNova2Quest2ToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNova2Quest2ToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetLeftNova2Quest2ToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNova2Quest2ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetLeftNova2Quest2ToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNova2Quest2ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetRightNova2QuestProToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNovaQuest2ToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetRightNova2QuestProToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNova2QuestProToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetRightNova2QuestProToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNova2QuestProToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetLeftNova2QuestProToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuest2ToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetLeftNova2QuestProToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNova2QuestProToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetLeftNova2QuestProToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNova2QuestProToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetRightNova2ViveTrackerToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNova2ViveTrackerToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetRightNova2ViveTrackerToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNova2ViveTrackerToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetRightNova2ViveTrackerToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNova2ViveTrackerToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetLeftNova2ViveTrackerToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNova2ViveTrackerToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetLeftNova2ViveTrackerToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNova2ViveTrackerToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetLeftNova2ViveTrackerToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNova2ViveTrackerToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetRightNova2ViveWristTrackerToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNova2ViveWristTrackerToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetRightNova2ViveWristTrackerToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNova2ViveWristTrackerToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FVector FSGTracking::GetRightNova2Quest3ToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNova2Quest3ToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetRightNova2Quest3ToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNova2Quest3ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetRightNova2Quest3ToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNova2Quest3ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetLeftNova2Quest3ToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNova2Quest3ToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetLeftNova2Quest3ToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNova2Quest3ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetLeftNova2Quest3ToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNova2Quest3ToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FRotator FSGTracking::GetRightNova2ViveWristTrackerToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetRightNova2ViveWristTrackerToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +FVector FSGTracking::GetLeftNova2ViveWristTrackerToAttachPosition() +{ + FSGIC_FVector OutPositionContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNova2ViveWristTrackerToAttachPosition(&OutPositionContainer); + return OutPositionContainer.Vector; +} + +FQuat FSGTracking::GetLeftNova2ViveWristTrackerToAttachRotationQ() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNova2ViveWristTrackerToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat; +} + +FRotator FSGTracking::GetLeftNova2ViveWristTrackerToAttachRotation() +{ + FSGIC_FQuat OutRotationContainer; + SGCoreImpl_FSGTrackingImpl_GetLeftNova2ViveWristTrackerToAttachRotation(&OutRotationContainer); + return OutRotationContainer.Quat.Rotator(); +} + +void FSGTracking::GetNova2GloveWristOffset(const bool bRightHanded, const FString& HardwareVersion, + FVector& OutPositionOffset, FQuat& OutRotationOffset) +{ + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FVector OutPositionOffsetContainer; + FSGIC_FQuat OutRotationOffsetContainer; + SGCoreImpl_FSGTrackingImpl_GetNova2GloveWristOffset( + bRightHanded, &HardwareVersionContainer, + &OutPositionOffsetContainer, &OutRotationOffsetContainer); + + OutPositionOffset = MoveTemp(OutPositionOffsetContainer.Vector); + OutRotationOffset = MoveTemp(OutRotationOffsetContainer.Quat); +} + +void FSGTracking::GetNova2GloveWristOffset(const bool bRightHanded, const FString& HardwareVersion, + FVector& OutPositionOffset, FRotator& OutRotationOffset) +{ + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FVector OutPositionOffsetContainer; + FSGIC_FQuat OutRotationOffsetContainer; + SGCoreImpl_FSGTrackingImpl_GetNova2GloveWristOffset( + bRightHanded, &HardwareVersionContainer, + &OutPositionOffsetContainer, &OutRotationOffsetContainer); + + OutPositionOffset = MoveTemp(OutPositionOffsetContainer.Vector); + OutRotationOffset = OutRotationOffsetContainer.Quat.Rotator(); +} + +void FSGTracking::GetNova2GloveTrackerOffset(const ESGPositionalTrackingHardware Hardware, const bool bRightHanded, + const FString& HardwareVersion, + FVector& OutPositionOffset, FQuat& OutRotationOffset) +{ + FSGIC_ESGPositionalTrackingHardware HardwareContainer{Hardware}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FVector OutPositionOffsetContainer; + FSGIC_FQuat OutRotationOffsetContainer; + SGCoreImpl_FSGTrackingImpl_GetNova2GloveTrackerOffset( + &HardwareContainer, bRightHanded, &HardwareVersionContainer, + &OutPositionOffsetContainer, &OutRotationOffsetContainer); + + OutPositionOffset = MoveTemp(OutPositionOffsetContainer.Vector); + OutRotationOffset = MoveTemp(OutRotationOffsetContainer.Quat); +} + +void FSGTracking::GetNova2GloveTrackerOffset(const ESGPositionalTrackingHardware Hardware, const bool bRightHanded, + const FString& HardwareVersion, + FVector& OutPositionOffset, FRotator& OutRotationOffset) +{ + FSGIC_ESGPositionalTrackingHardware HardwareContainer{Hardware}; + FSGIC_FString HardwareVersionContainer{HardwareVersion}; + FSGIC_FVector OutPositionOffsetContainer; + FSGIC_FQuat OutRotationOffsetContainer; + SGCoreImpl_FSGTrackingImpl_GetNova2GloveTrackerOffset( + &HardwareContainer, bRightHanded, &HardwareVersionContainer, + &OutPositionOffsetContainer, &OutRotationOffsetContainer); + + OutPositionOffset = MoveTemp(OutPositionOffsetContainer.Vector); + OutRotationOffset = OutRotationOffsetContainer.Quat.Rotator(); +} + +FString FSGTracking::ToString(const ESGPositionalTrackingHardware Hardware) +{ + FSGIC_FString OutStringContainer; + FSGIC_ESGPositionalTrackingHardware HardwareContainer{Hardware}; + SGCoreImpl_FSGTrackingImpl_ToString(&OutStringContainer, &HardwareContainer); + return OutStringContainer.String; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SenseGloveCore.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SenseGloveCore.cpp new file mode 100644 index 0000000..ef04dd8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SenseGloveCore.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveCore.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveCoreModule.h" + +IMPLEMENT_MODULE(FSenseGloveCoreModule, SenseGloveCore) diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SenseGloveCore.h b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SenseGloveCore.h new file mode 100644 index 0000000..ab121d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SenseGloveCore.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SenseGloveCoreModule.cpp b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SenseGloveCoreModule.cpp new file mode 100644 index 0000000..4b8c876 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SenseGloveCoreModule.cpp @@ -0,0 +1,65 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveCoreModule.h" +#include "Containers/UnrealString.h" +#include "SGCore/SGLibrary.h" +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveCoreModule" + +void FSenseGloveCoreModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveCore module..."); + SGLOG(FString::Printf(TEXT("The Unreal Engine implementation of '%s' has been loaded successfully!"), + *FSGLibrary::GetVersion())); +} + +void FSenseGloveCoreModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveCore module..."); +} + +void FSenseGloveCoreModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveCore module has succeeded!"); +} + +void FSenseGloveCoreModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveCore module..."); +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Private/SenseGloveCoreModule.h b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SenseGloveCoreModule.h new file mode 100644 index 0000000..40b5dbc --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Private/SenseGloveCoreModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveCore" + +class FSenseGloveCoreModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGAnatomy.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGAnatomy.h new file mode 100644 index 0000000..0a870b1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGAnatomy.h @@ -0,0 +1,118 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Hard-Coded Database that is used in calibration and in solving. + * Values herein are used to limit outputs within 'natural' ranges. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "HAL/Platform.h" +#include "Math/Vector.h" + +#include "SGAnatomy.generated.h" + +/** + * "Database" of anatomical values, such as joint limits. + */ +USTRUCT() +struct SENSEGLOVECORE_API FSGAnatomy +{ + GENERATED_BODY() + +public: + /** + * Total sum of all finger flexion that would be considered "total flexion". + */ + static float GetTotalFingerFlexion(); + + /** + * Total sum of all finger flexion that would be considered "total extension". + */ + static float GetTotalFingerExtension(); + + /** + * Total sum of all thumb flexion that would be considered "total flexion". + */ + static float GetTotalThumbFlexion(); + + /** + * Total sum of all thumb flexion that would be considered "total extension". + */ + static float GetTotalThumbExtension(); + + /** + * Retrieve one of the limits of a finger joint's movement. + */ + static float GetFingerJointLimit(bool bRightHanded, int32 Joint, int32 Movement, bool bMax); + + /** + * Retrieve one of the limits of a thumb joint's movement. + */ + static float GetThumbJointLimit(bool bRightHanded, int32 Joint, int32 Movement, bool bMax); + + /* + * Limit a value between specific joint angles. + */ + static float ClampJointAngle(float Value, int32 Finger, bool bRightHand, int32 Joint, int32 Movement); + + /** + * Convert a total finger flexion in degrees into a 0..1 representation. + */ + static float NormalizeFingerFlexion(float FlexionInDegrees); + + /** + * Convert a total thumb flexion in degrees into a 0..1 representation. + */ + static float NormalizeThumbFlexion(float FlexionInDegrees); + + /** + * Get Hand Angles that would make a Default (Idle) Pose. + */ + static TArray> GetDefaultHandAngles(bool bRightHanded); + + /** + * Get Hand Angles that would make a flat hand. + */ + static TArray> GetFlatHandAngles(bool bRightHanded); + + /** + * Get hand angles that would make a thumbs up. + */ + static TArray> GetThumbsUpHandAngles(bool bRightHanded); + + /** + * Get Hand Angles that would make a fist. + */ + static TArray> GetFistHandAngles(bool bRightHanded); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGBasicHandModel.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGBasicHandModel.h new file mode 100644 index 0000000..12f3ad1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGBasicHandModel.h @@ -0,0 +1,366 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * A data class containing the minimum required data for a hand's forward + * kinematics. + * Used in both kinematics and calibration. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGTypes/SGCoreTypes.h" +#include "SGTypes/SGFloatArray.h" + +#include "SGBasicHandModel.generated.h" + +class FSGBasicHandModelImpl; + +/** + * Represents data of a user's hand required for forward kinematics. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGBasicHandModel final : public UObject +{ + GENERATED_BODY() + +public: + static USGBasicHandModel* NewBasicHandModel( + UObject* Outer, const FSGBasicHandModelImpl& BasicHandModelImpl); + +public: + /** + * The basic class constructor. + */ + static USGBasicHandModel* NewBasicHandModel(UObject* Outer); + + /** + * Create a new BasicHandModel with no starting rotations. + */ + static USGBasicHandModel* NewBasicHandModel( + UObject* Outer, + bool bRightHanded, const TArray>& Lengths, const TArray& StartPositions); + + /** + * Create a new BasicHandModel with no starting rotations. + */ + static USGBasicHandModel* NewBasicHandModel( + UObject* Outer, + bool bRightHanded, const TArray& Lengths, const TArray& StartPositions); + + /** + * Create a new BasicHandModel. + */ + static USGBasicHandModel* NewBasicHandModel( + UObject* Outer, + bool bRightHanded, const TArray>& Lengths, + const TArray& StartPositions, const TArray& StartRotations); + + /** + * Create a new BasicHandModel. + */ + static USGBasicHandModel* NewBasicHandModel( + UObject* Outer, + bool bRightHanded, const TArray>& Lengths, + const TArray& StartPositions, const TArray& StartRotations); + + /** + * Create a new BasicHandModel. + */ + static USGBasicHandModel* NewBasicHandModel( + UObject* Outer, + bool bRightHanded, const TArray& Lengths, + const TArray& StartPositions, const TArray& StartRotations); + + /** + * Create a new BasicHandModel. + */ + static USGBasicHandModel* NewBasicHandModel( + UObject* Outer, + bool bRightHanded, const TArray& Lengths, + const TArray& StartPositions, const TArray& StartRotations); + +public: + /** + * Retrieve a default left or right hand model. + */ + static USGBasicHandModel* Default(UObject* Outer, bool bRightHanded); + + /** + * Convert a serialized HandModel back into its class representation. + */ + static USGBasicHandModel* Deserialize(UObject* Outer, const FString& SerializedString); + +public: + /** + * Default finger lengths (based on right hand). + * + * @remarks Any missing fingers are replaced with their respective value. + */ + static TArray> GetBaseFingerLengths(); + + /** + * Default joint positions (based on right hand). + * + * @remarks Any missing positions are replaced with their respective value. + */ + static TArray GetBaseJointPositions(); + + /** + * Default joint angles (based on right hand). + * + * @remarks Any missing angles are replaced with their respective value. + */ + static TArray GetBaseJointAngles(); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * The basic class constructor. + */ + USGBasicHandModel(); + + /** + * Create a new BasicHandModel with no starting rotations. + */ + USGBasicHandModel(bool bRightHanded, const TArray>& Lengths, + const TArray& StartPositions); + + /** + * Create a new BasicHandModel with no starting rotations. + */ + USGBasicHandModel(bool bRightHanded, const TArray& Lengths, + const TArray& StartPositions); + + /** + * Create a new BasicHandModel. + */ + USGBasicHandModel(bool bRightHanded, const TArray>& Lengths, + const TArray& StartPositions, const TArray& StartRotations); + + /** + * Create a new BasicHandModel. + */ + USGBasicHandModel(bool bRightHanded, const TArray>& Lengths, + const TArray& StartPositions, const TArray& StartRotations); + + /** + * Create a new BasicHandModel. + */ + USGBasicHandModel(bool bRightHanded, const TArray& Lengths, + const TArray& StartPositions, const TArray& StartRotations); + + /** + * Create a new BasicHandModel. + */ + USGBasicHandModel(bool bRightHanded, const TArray& Lengths, + const TArray& StartPositions, const TArray& StartRotations); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGBasicHandModel(const FSGBasicHandModelImpl& BasicHandModelImpl); + +public: + /** + * The destructor. + */ + virtual ~USGBasicHandModel() override; + +protected: + /** + * Allows to set the underlying object after construction. + */ + void SetBasicHandModelImpl(const FSGBasicHandModelImpl& BasicHandModelImpl); + +public: + /** + * The cast to underlying type method. + */ + const FSGBasicHandModelImpl& ToBasicHandModelImpl() const; + +protected: + /** + * The non-const cast to underlying type method. + */ + FSGBasicHandModelImpl& ToBasicHandModelImpl(); + +public: + /** + * Whether or not this BasicHandModel was created for a left- or right hand. Used for validation. + */ + bool IsRight() const; + + /** + * The length of individual finger phalangers in mm, sorted per finger. Generally 5x3. + */ + TArray> GetFingerLengths() const; + + /** + * Retrieve the finger lengths of a specific finger in cm. + */ + TArray GetFingerLengths(ESGFinger Finger) const; + + /** + * Set the finger lengths of a specific finger in cm. + */ + void SetFingerLengths(ESGFinger Finger, const TArray& Lengths); + + /** + * Set the finger lengths of a specific finger in cm. + */ + void SetFingerLengths(uint8 Finger, const TArray& Lengths); + + /** + * Get the finger ratios of all fingers. + */ + TArray> GetFingerRatios() const; + + /** + * Get the finger ratios of a specific finger. + */ + TArray GetFingerRatios(ESGFinger Finger) const; + + /** + * Starting joint positions relative to the device Origin. + */ + TArray GetStartJointPositions() const; + + /** + * + */ + void SetStartJointPosition(ESGFinger Finger, const FVector& Position); + + /** + * + */ + void SetStartJointPosition(uint8 Finger, const FVector& Position); + + /** + * Starting joint rotations relative to the device Origin. + */ + TArray GetStartJointRotationsQ() const; + + /** + * Starting joint rotations relative to the device Origin. + */ + TArray GetStartJointRotations() const; + + /** + * Retrieve the start position of a specific finger. + */ + FVector GetJointPosition(ESGFinger Finger) const; + + /** + * Set the start position of a specific finger. + */ + void SetJointPosition(const FVector& NewPosition, ESGFinger Finger); + + /** + * Retrieve the start rotation of a specific finger. + */ + FQuat GetJointRotationQ(ESGFinger Finger) const; + + /** + * Retrieve the start rotation of a specific finger. + */ + FRotator GetJointRotation(ESGFinger Finger) const; + + /** + * Set the start rotation of a specific finger. + */ + void SetJointRotation(const FQuat& NewRotation, ESGFinger Finger); + + /** + * Set the start rotation of a specific finger. + */ + void SetJointRotation(const FRotator& NewRotation, ESGFinger Finger); + + /** + * Get the total lengths of fingers, in cm. + */ + TArray GetTotalLengths() const; + + /** + * Get the total length of a specific finger, in mm. + */ + float GetTotalLength(ESGFinger Finger) const; + +public: + /** + * Retrieve the lengths of a specific finger, as BasicHandModel representation (L, 0, 0). + * + * @remarks Used for forwards kinematics. + */ + TArray Get3DLengths(ESGFinger Finger) const; + +public: + /** + * Check if this BasicHandModel has the same values as another BasicHandModel. + */ + bool Equals(const USGBasicHandModel* BasicHandModel) const; + +public: + /** + * Convert this handModel into a string notation, readable for humans. Does not include starting positions / rotations. + */ + FString ToString() const; + + /** + * Convert this handModel into a string notation, readable for humans. Optionally includes starting positions / rotations. + */ + FString ToString(bool bLengthsOnly) const; + + /** + * Serialize this HandModel into a string representation. + */ + FString SGSerialize() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGBetaDevice.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGBetaDevice.h new file mode 100644 index 0000000..5e9ce71 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGBetaDevice.h @@ -0,0 +1,177 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Represents a Sense Glove Device that has no specific class within the API. + * Used to test different iterations of the same product before integrating it + * into the Core API. + * Allows access to raw sensor values and commands of such a device. + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGCore/SGDevice.h" +#include "SGTypes/SGCoreTypes.h" + +#include "SGBetaDevice.generated.h" + +class FSGDeviceImpl; +class FSGBetaDeviceImpl; + +/** + * A Device that adheres to the SenseGlove communications protocol, but which has no implementation in this API. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGBetaDevice final : public USGDevice +{ + GENERATED_BODY() + +public: + static USGBetaDevice* NewBetaDevice(UObject* Outer, const FSGBetaDeviceImpl& BetaDeviceImpl); + + static USGBetaDevice* NewBetaDevice(UObject* Outer, TSharedRef BetaDeviceImpl); + +public: + /** + * The basic class constructor. + */ + static USGBetaDevice* NewBetaDevice(UObject* Outer); + + /** + * Creates a new instance of a Beta Device. + */ + static USGBetaDevice* NewBetaDevice( + UObject* Outer, + const FString& ConstantsString, const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion); + +public: + /** + * Deserialize a beta device from its basic constants string. Returns nullptr is unsuccessful. + */ + static USGBetaDevice* Parse(UObject* Outer, const FString& String); + +public: + /** + * The basic class constructor. + */ + USGBetaDevice(); + + /** + * Creates a new instance of a Beta Device. + */ + USGBetaDevice(const FString& ConstantsString, const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGBetaDevice(const FSGBetaDeviceImpl& BetaDeviceImpl); + +protected: + /** + * The cast from underlying pointer type constructor. + */ + explicit USGBetaDevice(TSharedRef BetaDeviceImpl); + +public: + /** + * The destructor. + */ + virtual ~USGBetaDevice() override; + +protected: + /** + * The cast to underlying type method. + */ + TSharedRef ToBetaDeviceImpl() const; + +public: + /** + * Get the DeviceType enumerator of this SenseGlove, used in DeviceList enumeration. + */ + virtual ESGDeviceType GetDeviceType() const override; + + /** + * Get the unique identifier of this device. + */ + virtual FString GetDeviceId() const override; + + /** + * Retrieve this device's hardware version. + */ + virtual FString GetHardwareVersion() const override; + + /** + * Retrieve this device's firmware version. + */ + virtual int32 GetFirmwareVersion() const override; + + /** + * Retrieve this device's sub-firmware version. + */ + virtual int32 GetSubFirmwareVersion() const override; + +public: + /** + * Retrieve the constants string for additional processing. + */ + FString GetConstantsString() const; + + /** + * Retrieve a raw sensor string from this Beta Device. + */ + FString GetSensorData() const; + + /** + * Retrieve the last command retrieved from this Beta Device. + */ + FString GetLastCommand() const; + +public: + /** + * Send a raw string command to this device. + */ + bool SendHaptics(const FString& Command) const; + +public: + /** + * Create a string representation of this device for reporting purposes. + */ + virtual FString ToString() const override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGCore.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGCore.h new file mode 100644 index 0000000..2e7fad6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGCore.h @@ -0,0 +1,59 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCore/SGAnatomy.h" +#include "SGCore/SGBasicHandModel.h" +#include "SGCore/SGBetaDevice.h" +#include "SGCore/SGDevice.h" +#include "SGCore/SGDeviceList.h" +#include "SGCore/SGDeviceModel.h" +#include "SGCore/SGHandInterpolator.h" +#include "SGCore/SGHandPose.h" +#include "SGCore/SGHapticGlove.h" +#include "SGCore/SGInterpolationSet.h" +#include "SGCore/SGJointKinematics.h" +#include "SGCore/SGLibrary.h" +#include "SGCore/SGNovaGlove.h" +#include "SGCore/SGNovaGloveInfo.h" +#include "SGCore/SGNovaGloveSensorData.h" +#include "SGCore/SGSenseCom.h" +#include "SGCore/SGSenseGlove.h" +#include "SGCore/SGSenseGloveInfo.h" +#include "SGCore/SGSenseGlovePose.h" +#include "SGCore/SGSenseGloveSensorData.h" +#include "SGCore/SGSenseGloveVars.h" +#include "SGCore/SGTracking.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGCustomWaveform.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGCustomWaveform.h new file mode 100644 index 0000000..882f9a7 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGCustomWaveform.h @@ -0,0 +1,305 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Describes a vibration based on a number of parameters. Is sent to Nova Gloves + * to be generated on the hardware and played. + */ + + +#pragma once + +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGTypes/SGCoreTypes.h" + +#include "SGCustomWaveform.generated.h" + +class FSGCustomWaveformImpl; + +/* + * A single vibration pulse for Nova Gloves. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGCustomWaveform final : public UObject +{ + GENERATED_BODY() + +public: + static USGCustomWaveform* NewCustomWaveform( + UObject* Outer, const FSGCustomWaveformImpl& CustomWaveformImpl); + +public: + /** + * The default constructor. + */ + static USGCustomWaveform* NewCustomWaveform(UObject* Outer); + + /** + * Create a new instance of CustomWaveform. + */ + static USGCustomWaveform* NewCustomWaveform( + UObject* Outer, + float Amplitude, float Duration); + + /** + * Create a new instance of CustomWaveform. + */ + static USGCustomWaveform* NewCustomWaveform( + UObject* Outer, + float Amplitude, float Duration, float Frequency); + +public: + /** + * Creates a string representation of the ESGWaveformType. + * + * @param Type + */ + static FString ToString(ESGWaveformType Type); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * The default constructor. + */ + USGCustomWaveform(); + + /** + * Create a new instance of CustomWaveform. + */ + USGCustomWaveform(float Amplitude, float Duration); + + /** + * Create a new instance of CustomWaveform. + */ + USGCustomWaveform(float Amplitude, float Duration, float Frequency); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGCustomWaveform(const FSGCustomWaveformImpl& CustomWaveformImpl); + +public: + /** + * The destructor. + */ + virtual ~USGCustomWaveform() override; + +protected: + /** + * Allows to set the underlying object after construction. + */ + void SetCustomWaveformImpl(const FSGCustomWaveformImpl& CustomWaveformImpl); + +public: + /** + * The cast to underlying type method. + */ + const FSGCustomWaveformImpl& ToCustomWaveformImpl() const; + +public: + /** + * Get the total amplitude of the wave-from, represented by 0 (off) or 1 (maximum value). + */ + float GetAmplitude() const; + + /** + * Set the total amplitude of the wave-from, represented by 0 (off) or 1 (maximum value). + * + * @param Amplitude + */ + void SetAmplitude(float Amplitude); + + /** + * Get the Type of waveform pattern that is used. + */ + ESGWaveformType GetWaveType() const; + + /** + * Set the Type of waveform pattern that is used. + * + * @param Type + */ + void SetWaveType(ESGWaveformType Type); + + /** + * Get whether or not this Waveform is infinitely repeating. + */ + bool IsInfinite() const; + + /** + * Set whether or not this Waveform is infinitely repeating. + * + * @param bInfinite + */ + void SetInfinite(bool bInfinite); + + /** + * Get the amount of times to repeat this waveform. 1 is the default. If set to 0, repeats indefinitely. + */ + int32 GetRepeatAmount() const; + + /** + * Set the amount of times to repeat this waveform. 1 is the default. If set to 0, repeats indefinitely. + * + * @param Amount + */ + void SetRepeatAmount(int32 Amount); + + /** + * Get time, in seconds, before the signal reaches its maximum amplitude. Limited to 0.01 - 1s. Set to 0 for an + * instant start. Linear only. + */ + float GetAttackTime() const; + + /** + * Set time, in seconds, before the signal reaches its maximum amplitude. Limited to 0.01 - 1s. Set to 0 for an + * instant start. Linear only. + * + * @param Time + */ + void SetAttackTime(float Time); + + /** + * Get time, in seconds, to keep the signal at one Amplitude. Limited to 0.01 - 1s. + */ + float GetSustainTime() const; + + /** + * Set time, in seconds, to keep the signal at one Amplitude. Limited to 0.01 - 1s. + * + * @param Time + */ + void SetSustainTime(float Time); + + /** + * Get time it takes for the effect to fade out after AttackTime+SustainTime has passed. Limited to 0.01 - 1s. Set + * to 0 for instant stop. Linear only. + */ + float GetDecayTime() const; + + /** + * Set time it takes for the effect to fade out after AttackTime+SustainTime has passed. Limited to 0.01 - 1s. Set + * to 0 for instant stop. Linear only. + * + * @param Time + */ + void SetDecayTime(float Time); + + /** + * Get the Wave-from Frequency at the start of the wave-from. Limited between [10 - 500Hz] for Nova Gloves. + */ + float GetFrequencyStart() const; + + /** + * Set the Wave-from Frequency at the start of the wave-from. Limited between [10 - 500Hz] for Nova Gloves. + * + * @param Frequency + */ + void SetFrequencyStart(float Frequency); + + /** + * Get the Wave-from Frequency at the end of the wave-from. Limited between [10 - 500Hz] for Nova Gloves. + */ + float GetFrequencyEnd() const; + + /** + * Set the Wave-from Frequency at the end of the wave-from. Limited between [10 - 500Hz] for Nova Gloves. + * + * @param Frequency + */ + void SetFrequencyEnd(float Frequency); + + /** + * Get value of [0..1], representing a percentage of total time (attack+sustain+decay). After that moment passes, + * we increase the frequency by FrequencySwitch factor. + */ + float GetFrequencySwitchTime() const; + + /** + * Set value of [0..1], representing a percentage of total time (attack+sustain+decay). After that moment passes, + * we increase the frequency by FrequencySwitch factor. + * + * @param Time + */ + void SetFrequencySwitchTime(float Time); + + /** + * After a certain % of the waveform (FrequencySwitchTime) plays, multiply the frequency by this factor [1x .. 3x]. + */ + float GetFrequencySwitchFactor() const; + + /** + * After a certain % of the waveform (FrequencySwitchTime) plays, multiply the frequency by this factor [1x .. 3x]. + * param Time + */ + void SetFrequencySwitchFactor(float Time); + +public: + /** + * The total command time of a single play of this pattern (not taking into account the RepeatAmount). + */ + float GetEffectTime() const; + + /** + * Total time for the entire effect (effect time multiplied by the repeat amount). + */ + float GetTotalEffectTime() const; + + /** + * If true, the frequency of this waveform jumps at any time during its playtime by FrequencySwitchFactor. + */ + bool FrequencyJumps() const; + +public: + /** + * Check if this CustomWaveform is roughly equal to another. + */ + bool Equals(const USGCustomWaveform* CustomWaveform) const; + +public: + /** + * Create a string representation of this CustomWaveform. + */ + FString ToString() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGDevice.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGDevice.h new file mode 100644 index 0000000..2c1a32f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGDevice.h @@ -0,0 +1,407 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Represents a Device built by the Sense Glove company that is compatible with + * our Communications Protocol. All such devices derive from this abstract + * class. + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGTypes/SGCoreTypes.h" + +#include "SGDevice.generated.h" + +class FSGBetaDeviceImpl; +class FSGDeviceImpl; +class FSGHapticGloveImpl; +class FSGNovaGloveImpl; +class FSGNova2GloveImpl; +class FSGSenseGloveImpl; +class USGHapticChannelInfo; +class USGBetaDevice; +class USGHapticGlove; +class USGNova2Glove; +class USGNovaGlove; +class USGSenseGlove; + +/** + * + */ +UCLASS(Abstract, BlueprintType) +class SENSEGLOVECORE_API USGDevice : public UObject +{ + GENERATED_BODY() + +public: + /** + * Parse a main and sub firmware version from its raw (v4.12) notation + */ + static void ParseFirmware(const FString& RawFirmware, int32& OutMainVersion, int32& OutSubVersion); + + /** + * If true, my firmware is newer than the reference firmware. + * + * @param MyFirmwareMain + * @param MyFirmwareSub + * @param ReferenceMain + * @param ReferenceSub + * @param bInclusive + */ + static bool FirmwareNewerThan(int32 MyFirmwareMain, int32 MyFirmwareSub, + int32 ReferenceMain, int32 ReferenceSub, + bool bInclusive); + + /** + * If true, my firmware is older than the reference firmware. + * + * @param MyFirmwareMain + * @param MyFirmwareSub + * @param ReferenceMain + * @param ReferenceSub + * @param bInclusive + */ + static bool FirmwareOlderThan(int32 MyFirmwareMain, int32 MyFirmwareSub, + int32 ReferenceMain, int32 ReferenceSub, + bool bInclusive); + + /** + * + */ + static FString ToString(ESGDeviceType DeviceType); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +protected: + /** + * The basic constructor. + */ + USGDevice(); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGDevice(const FSGDeviceImpl& SGDeviceImpl); + + /** + * The cast from underlying child type constructor. + */ + explicit USGDevice(const FSGBetaDeviceImpl& BetaDeviceImpl); + + /** + * The cast from underlying child type constructor. + */ + explicit USGDevice(const FSGHapticGloveImpl& HapticGloveImpl); + + /** + * The cast from underlying child type constructor. + */ + explicit USGDevice(const FSGNova2GloveImpl& Nova2GloveImpl); + + /** + * The cast from underlying child type constructor. + */ + explicit USGDevice(const FSGNovaGloveImpl& NovaGloveImpl); + + /** + * The cast from underlying child type constructor. + */ + explicit USGDevice(const FSGSenseGloveImpl& SenseGloveImpl); + +protected: + /** + * The cast from underlying pointer type constructor. + */ + explicit USGDevice(TSharedRef SGDeviceImpl); + + /** + * The cast from underlying child pointer type constructor. + */ + explicit USGDevice(TSharedRef BetaDeviceImpl); + + /** + * The cast from underlying child pointer type constructor. + */ + explicit USGDevice(TSharedRef HapticGloveImpl); + + /** + * The cast from underlying child pointer type constructor. + */ + explicit USGDevice(TSharedRef Nova2GloveImpl); + + /** + * The cast from underlying child pointer type constructor. + */ + explicit USGDevice(TSharedRef NovaGloveImpl); + + /** + * The cast from underlying child pointer type constructor. + */ + explicit USGDevice(TSharedRef SenseGloveImpl); + +public: + /** + * The destructor. + */ + virtual ~USGDevice() override; + +protected: + /** + * Allows the child classes to set the underlying object after construction. + */ + void SetSGDeviceImpl(const FSGDeviceImpl& SGDeviceImpl); + + /** + * Allows the child classes to set the underlying object after construction. + */ + void SetSGDeviceImpl(const FSGBetaDeviceImpl& BetaDeviceImpl); + + /** + * Allows the child classes to set the underlying object after construction. + */ + void SetSGDeviceImpl(const FSGHapticGloveImpl& HapticGloveImpl); + + /** + * Allows the child classes to set the underlying object after construction. + */ + void SetSGDeviceImpl(const FSGNova2GloveImpl& Nova2GloveImpl); + + /** + * Allows the child classes to set the underlying object after construction. + */ + void SetSGDeviceImpl(const FSGNovaGloveImpl& NovaGloveImpl); + + /** + * Allows the child classes to set the underlying object after construction. + */ + void SetSGDeviceImpl(const FSGSenseGloveImpl& SenseGloveImpl); + + /** + * Allows the child classes to set the underlying object after construction. + */ + void SetSGDeviceImpl(TSharedRef SGDeviceImpl); + + /** + * Allows the child classes to set the underlying object after construction. + */ + void SetSGDeviceImpl(TSharedRef BetaDeviceImpl); + + /** + * Allows the child classes to set the underlying object after construction. + */ + void SetSGDeviceImpl(TSharedRef HapticGloveImpl); + + /** + * Allows the child classes to set the underlying object after construction. + */ + void SetSGDeviceImpl(TSharedRef Nova2GloveImpl); + + /** + * Allows the child classes to set the underlying object after construction. + */ + void SetSGDeviceImpl(TSharedRef NovaGloveImpl); + + /** + * Allows the child classes to set the underlying object after construction. + */ + void SetSGDeviceImpl(TSharedRef SenseGloveImpl); + +public: + /** + * The cast to underlying type method. + */ + TSharedRef ToSGDeviceImpl() const; + +public: + bool IsABetaDevice() const; + bool IsAHapticGlove() const; + bool IsANova2Glove() const; + bool IsANovaGlove() const; + bool IsASenseGlove() const; + +public: + USGBetaDevice* AsBetaDevice(UObject* Outer) const; + + USGHapticGlove* AsHapticGlove(UObject* Outer) const; + + USGNova2Glove* AsNova2Glove(UObject* Outer) const; + + USGNovaGlove* AsNovaGlove(UObject* Outer) const; + + USGSenseGlove* AsSenseGlove(UObject* Outer) const; + +public: + /** + * Check which DeviceType this class belongs to. + */ + virtual ESGDeviceType GetDeviceType() const; + + /** + * Retrieve this device's unique identifier. + */ + virtual FString GetDeviceId() const PURE_VIRTUAL(FSGDevice::GetDeviceId, return FString();); + + /** + * Retrieve this device's hardware version. + */ + virtual FString GetHardwareVersion() const PURE_VIRTUAL(FSGDevice::GetHardwareVersion, return FString();); + + /** + * Retrieve this device's main firmware version. v4.12 returns 4. + */ + virtual int32 GetFirmwareVersion() const PURE_VIRTUAL(FSGDevice::FirmwareVersion, return -1;); + + /** + * Retrieve this device's sub firmware version. v4.12 returns 12. + */ + virtual int32 GetSubFirmwareVersion() const; + + /** + * + */ + virtual FString GetFirmwareString() const; + + /** + * Returns true if this glove's firmware is newer than certain version. + * + * @param FirmwareMain + * @param FirmwareSub + * @param bInclusive + */ + bool FirmwareNewerThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const; + + /** + * Returns true if this glove's firmware is older than certain version. + * + * @param FirmwareMain + * @param FirmwareSub + * @param bInclusive + */ + bool FirmwareOlderThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const; + + /** + * Retrieve this Device's Serial/Bluetooth address. + */ + FString GetAddress() const; + + /** + * Check if this device is currently connected to the system. + */ + bool IsConnected() const; + + /** + * Retrieve the connection type of this Sense Glove. + */ + ESGConnectionType GetConnectionType() const; + + /** + * Retrieve the device's Packets per Second Variable. + */ + int32 PacketsPerSecondReceived() const; + + /** + * Retrieve the device's Packets per Second Variable. + */ + int32 PacketsPerSecondSent() const; + + /** + * Retrieve the index of this device within SenseCom. + */ + int32 GetDeviceIndex() const; + + /** + * Change this device's index within the SenseCom. Warning: Can cause errors. + */ + virtual void SetDeviceIndex(int32 NewIndex); + + /** + * Returns true if this device is connected over a connection other than usb cable. + */ + virtual bool IsWireless() const; + + /** + * Returns true if this device operates on a battery. + */ + virtual bool HasBattery() const; + + /** + * Returns true if this device is currently charging. + */ + virtual bool IsCharging(); + + /** + * Returns the device's battery level, as a value between 0 (empty) and 1 (full). + */ + virtual bool GetBatteryLevel(float& OutLevel); + +public: + /** + * Assign this Device's Haptic Channels. Should not be done outside the API unless you know what you're doing. + * + * @param Channels + */ + virtual void SetHapticChannels(const USGHapticChannelInfo* Channels); + + /** + * The number of haptic channels this device can support. + */ + int32 GetHapticChannelCount() const; + + /** + * How many channels of a specific type this SGDevice possesses. + * + * @param ChannelType + */ + int32 GetHapticChannelCount(ESGHapticChannelType ChannelType) const; + +public: + /** + * Get a string representation of this SGDevice, used for debugging. + */ + virtual FString ToString() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGDeviceList.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGDeviceList.h new file mode 100644 index 0000000..47d984e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGDeviceList.h @@ -0,0 +1,137 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Interface for SenseCom, allows the retrieval of Devices and Data, but only + * as. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" +#include "UObject/ObjectMacros.h" + +#include "SGTypes/SGCoreTypes.h" + +#include "SGDeviceList.generated.h" + +class USGDevice; + +/** + * Interface for SenseCom, allows the retrieval of Devices and Data. + */ +USTRUCT() +struct SENSEGLOVECORE_API FSGDeviceList +{ + GENERATED_BODY() + +public: + /** + * Retrieve the number of devices that have been detected by the SenseCom executable. + */ + static int32 ActiveDevices(); + + /** + * Returns true if the SenseCom program is running. + */ + static bool SenseCommRunning(); + + /** + * Clear the device list, and block any further attempt to add to it until ReInitialize is called. + * + * @remarks Useful if your IDE has troubles unloading dlls (cough, Unity, Cough). + */ + static void Dispose(); + + /** + * When you've accidentally disposed of the list before you meant to. + */ + static void Reinitialize(); + + /** + * Retrieve all Sense Glove Devices connected to this system. + */ + static TArray GetDevices(UObject* Outer); + + /// TODO + // THIS PROBABLY SHOULD BE REMOVED! + /** + * Retrieve a list of SGDevices of a specific class. + */ + static TArray GetDevices(UObject* Outer, const TSubclassOf& DeviceType); + + /** + * Retrieve a list of SGDevices of a specific type. + */ + static TArray GetDevices(UObject* Outer, ESGDeviceType DeviceType); + + /** + * Retrieve the latest (raw) sensor data from a specific device in our list. + */ + static bool GetSensorDataString(int32 IpcIndex, const FString& IpcAddress, FString& OutString); + + /** + * Send a (raw) command to a specific device in the list. + */ + static bool SendHaptics(int32 IpcIndex, const FString& IpcAddress, int32 ChannelIndex, const FString& Commands); + + /** + * + */ + static FString GetDeviceStringAt(int32 IpcIndex, const FString& IpcAddress, int32 Index); + + /** + * Retrieve Device Address. + */ + static FString GetAddress(int32 IpcIndex, const FString& IpcAddress); + + /** + * Retieve this device's connectionType. + */ + static ESGConnectionType GetConnectionType(int32 IpcIndex, const FString& IpcAddress); + + /** + * Returns true if the device at this connection side is properly connected. + */ + static bool IsConnected(int32 IpcIndex, const FString& IpcAddress); + + /** + * Retrieve the device's Packets per Second Variable. + */ + static int32 PacketsPerSecondReceived(int32 IpcIndex, const FString& IpcAddress); + + /** + * Retrieve the device's Packets per Second sent Variable. + */ + static int32 PacketsPerSecondSent(int32 IpcIndex, const FString& IpcAddress); +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGDeviceModel.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGDeviceModel.h new file mode 100644 index 0000000..950ad1d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGDeviceModel.h @@ -0,0 +1,177 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Base class for Device Models containing the minimum amount of data gathered + * through Communications Protocol. Used for shared functionality. + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGDeviceModel.generated.h" + +class FSGDeviceModelImpl; + +/** + * Base class containing the minimum amount of data for device models. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGDeviceModel final : public UObject +{ + GENERATED_BODY() + +public: + static USGDeviceModel* NewDeviceModel( + UObject* Outer, const FSGDeviceModelImpl& DeviceModelImpl); + +public: + /** + * + */ + static USGDeviceModel* NewDeviceModel(UObject* Outer); + + /** + * + */ + static USGDeviceModel* NewDeviceModel( + UObject* Outer, + const FString& Id, const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion); + +public: + /** + * Parse a 32-bit integer value into a set of booleans (010010011) that indicate which (optional) functions this + * device has. + */ + static TArray ParseFunctions(int32 Value, int32 Size); + + /** + * + */ + static void ParseFirmware(const FString& RawFirmware, int32& OutMainVersion, int32& OutSubVersion); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * Empty constructor to be used by child classes. + */ + USGDeviceModel(); + + /** + * + */ + USGDeviceModel(const FString& Id, const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGDeviceModel(const FSGDeviceModelImpl& DeviceModelImpl); + +public: + /** + * The destructor. + */ + virtual ~USGDeviceModel() override; + +protected: + /** + * Allows to set the underlying object after construction. + */ + void SetDeviceModelImpl(const FSGDeviceModelImpl& DeviceModelImpl); + +public: + /** + * The cast to underlying type method. + */ + const FSGDeviceModelImpl& ToDeviceModelImpl() const; + +protected: + /** + * The non-const cast to underlying type method. + */ + FSGDeviceModelImpl& ToDeviceModelImpl(); + +public: + /** + * Retrieve the Unique identifier of this device. + */ + FString GetDeviceId() const; + + /** + * Retrieve the Hardware (sub) version of this Sense Glove Device. + */ + FString GetHardwareVersion() const; + + /** + * Firmware version running on the device's MicroController. (as of v4.12, this is the 4). + */ + int32 GetFirmwareVersion() const; + + /** + * Sub firmware version running on the device's microcontroller (as of v4.12, this is the 12). + */ + int32 GetSubFirmwareVersion() const; + +public: + /** + * Returns true if this glove's firmware is newer than certain version. + * + * @param FirmwareMain + * @param FirmwareSub + * @param bInclusive + */ + bool FirmwareNewerThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const; + + /** + * Returns true if this glove's firmware is older than certain version. + * + * @param FirmwareMain + * @param FirmwareSub + * @param bInclusive + */ + bool FirmwareOlderThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGHandInterpolator.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGHandInterpolator.h new file mode 100644 index 0000000..6c24101 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGHandInterpolator.h @@ -0,0 +1,164 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Contains interpolation sets for all hand joint movements that can be + * calculated using the Sense Glove. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" +#include "Math/Quat.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGCore/SGInterpolationSetArray.h" +#include "SGTypes/SGCoreTypes.h" + +#include "SGHandInterpolator.generated.h" + +class FSGHandInterpolatorImpl; +class USGHandInterpolator; + +/** + * Contains interpolation sets of all joint movements that can be calculated into a HandPose. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGHandInterpolator final : public UObject +{ + GENERATED_BODY() + +public: + static USGHandInterpolator* NewHandInterpolator( + UObject* Outer, const FSGHandInterpolatorImpl& HandInterpolatorImpl); + +public: + /** + * The basic constructor. + */ + static USGHandInterpolator* NewHandInterpolator(UObject* Outer); + + /** + * Create a new basic HandInterpolator. + */ + static USGHandInterpolator* NewHandInterpolator(UObject* Outer, bool bRightHanded); + +public: + /** + * Convert a serialized HandInterpolator back into a class representation. + * + * @param SerializedString + * @param bRightHanded + */ + static USGHandInterpolator* Deserialize(UObject* Outer, const FString& SerializedString, bool bRightHanded = true); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * The basic constructor. + */ + USGHandInterpolator(); + + /** + * Create a new basic HandInterpolator. + */ + explicit USGHandInterpolator(bool bRightHanded); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGHandInterpolator(const FSGHandInterpolatorImpl& HandInterpolatorImpl); + +public: + /** + * The destructor. + */ + virtual ~USGHandInterpolator() override; + +protected: + /** + * Allows to set the underlying object after construction. + */ + void SetHandInterpolatorImpl(const FSGHandInterpolatorImpl& HandInterpolatorImpl); + +public: + /** + * The cast to underlying type method. + */ + const FSGHandInterpolatorImpl& ToHandInterpolatorImpl() const; + +public: + /** + * Calculate a finger movement's rotation, using an input value. + */ + float CalculateAngle(ESGFingerMovement Movement, float Value, bool bApplyLimits = true) const; + + /** + * Calculate a thumb movement's rotation, using an input value. + */ + float CalculateAngle(ESGThumbMovement Movement, float Value, bool bApplyLimits = true) const; + +public: + /** + * Calculate all hand angles based on an interpolator and normalized input. + */ + TArray> InterpolateHandAngles( + const TArray>& Flexions, const TArray& Abductions, float CmcTwist) const; + +public: + /** + * Check if this handInterpolator matches another. + * + * @param HandInterpolator + */ + bool Equals(const USGHandInterpolator* HandInterpolator) const; + +public: + /** + * Serialize this HandInterpolator into a string representation. + */ + FString SGSerialize() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGHandLayer.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGHandLayer.h new file mode 100644 index 0000000..4c571ff --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGHandLayer.h @@ -0,0 +1,267 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * A way to access all sorts of Hand Tracking and -Haptics without needing to + * cache any device instances. + * Use this layer if you don't care where a HandPose is coming from, and are + * fine with calling generic haptic functions. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "UObject/ObjectMacros.h" + +#include "SGTypes/SGCoreTypes.h" + +#include "SGHandLayer.generated.h" + +class USGCustomWaveform; +class USGHandPose; +class USGHapticGlove; + +/** + * A way to access all sorts of Hand Tracking and -Haptics without needing to cache any device instances. + */ +USTRUCT() +struct SENSEGLOVECORE_API FSGHandLayer +{ + GENERATED_BODY() + +public: + /** + * Returns true if there is a HapticGlove Device connected that corresponds to the chosen hand. + * + * @param bRightHanded + */ + static bool DeviceConnected(bool bRightHanded); + + /** + * Returns the Device Type of the right / left hand. + * + * @param bRightHanded + */ + static ESGDeviceType GetDeviceType(bool bRightHanded); + + /** + * Returns the handedness of the first device you can find; true for right, false for left. Use this for testing a + * single glove. + */ + static bool GetFirstGloveHandedness(); + + /** + * Returns the number of Haptic Gloves connected to the system. + */ + static int32 GlovesConnected(); + + /** + * Retrieve a Glove Instance for the right- or left hand to do more complicated, device-specific stuff. + * + * @param bRightHanded + * @param OutGlove + */ + static bool GetGloveInstance(UObject* Outer, bool bRightHanded, USGHapticGlove*& OutGlove); + + /** + * Returns the calibration state of the chosen hand. + * + * @param bRightHanded + */ + static ESGHapticGloveCalibrationState GetCalibrationState(bool bRightHanded); + + /** + * Returns the Calibration Instructions for the chosen hand. + * + * @param bRightHanded + */ + static FString GetCalibrationInstructions(bool bRightHanded); + + /** + * Reset the calibration of the left/right hand. + * + * @param bRightHanded + */ + static void ResetCalibration(bool bRightHanded); + + /** + * Reset the calibration of the left/right hand. + * + * @param bRightHanded + */ + static void EndCalibration(bool bRightHanded); + + /** + * Attempt to get the HandPose through any of our gloves. You don't care which one is on the other side, as long as + * you get one. + * + * @param bRightHanded + * @param OutHandPose + */ + static bool GetHandPose(UObject* Outer, bool bRightHanded, USGHandPose*& OutHandPose); + + /** + * Calculate the Wrist Location of the chosen hand, based on a reference location and tracking hardware. + * + * @param bRightHanded + * @param ReferencePosition + * @param ReferenceRotation + * @param TrackingHardware + * @param OutWristPosition + * @param OutWristRotation + */ + static void GetWristLocation( + bool bRightHanded, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation); + + /** + * Stop all haptics on the chosen hand. + * + * @param bRightHanded + */ + static void StopAllHaptics(bool bRightHanded); + + /** + * Sends all haptics in the queue for the Left / Right hand. + * @param bRightHanded + */ + static bool SendHaptics(bool bRightHanded); + + /** + * Returns true if the glove for this hand supports a custom waveform vibration on said location. + * + * @param bRightHanded + * @param AtLocation + */ + static bool SupportsCustomWaveform(bool bRightHanded, ESGHapticLocation AtLocation); + + /** + * Send a Custom Waveform to a glove at a specific location. + * + * @param bRightHanded + * @param OutWaveform + * @param Location + */ + static bool SendCustomWaveform(bool bRightHanded, USGCustomWaveform* OutWaveform, ESGHapticLocation Location); + + /** + * Tell a specific hand to hold the force-feedback at a certain level. + * + * @param bRightHanded + * @param Finger + * @param Level01 + * @param bSendImmediate + */ + static bool QueueCommand_ForceFeedbackLevel(bool bRightHanded, int32 Finger, float Level01, bool bSendImmediate); + + /** + * Queue Force Feedback for multiple fingers. Up to 5. Make sure the value is not NULL. + * + * @param bRightHanded + * @param Levels01 + * @param bSendImmediate + */ + static bool QueueCommand_ForceFeedbackLevels( + bool bRightHanded, const TArray& Levels01, bool bSendImmediate); + + /** + * Queue a command to set the vibration level(s) of a Haptic Glove's finger. Note: This is only for Nova 1.0 and + * DK1.0. + * + * @param bRightHanded + * @param Levels01 + * @param bSendImmediate + */ + static bool QueueCommand_VibroLevels(bool bRightHanded, const TArray& Levels01, bool bSendImmediate); + + /** + * Queue a command to set the vibration level(s) of a Haptic Glove's finger. Note: This is only for Nova 1.0 and + * DK1.0. + * + * @param bRightHanded + * @param Finger + * @param Level01 + * @param bSendImmediate + */ + static bool QueueCommand_VibroLevel(bool bRightHanded, int32 Finger, float Level01, bool bSendImmediate); + + /** + * Queue a vibration level command for a specific HapticLocation. If the gloves has this vibration motor installed. + * Cross-compatible with Nova 2.0. + * + * @param bRightHanded + * @param AtLocation + * @param Level01 + * @param bSendImmediate + */ + static bool QueueCommand_VibroLevel( + bool bRightHanded, ESGHapticLocation AtLocation, float Level01, bool bSendImmediate); + + /** + * Returns true if the chosen glove supports active contact feedback on the Wrist. + * + * @param bRightHanded + */ + static bool SupportsWristSqueeze(bool bRightHanded); + + /** + * Queue a command to set a squeeze level on the wrist, and optionally send it right away. + * + * @param bRightHanded + * @param SqueezeLevel01 + * @param bSendImmediate + */ + static bool QueueCommand_WristSqueeze(bool bRightHanded, float SqueezeLevel01, bool bSendImmediate); + + /** + * Returns true is the chosen hand supports flexion locking; automatic locking of FFB when flexed beyond a specific + * point. + * + * @param bRightHanded + */ + static bool SupportsFlexionLocks(bool bRightHanded); + + /** + * If the flexion exceeds a particular value, turn on the Force-Feedback. + */ + static bool QueueCommand_FlexionLock(bool bRightHanded, int32 Finger, float Flexion01, bool bSendImmediate); + + /** + * Stop any Flexion Threshold active on the chosen finger. + */ + static bool QueueCommand_ClearFlexionLock(bool bRightHanded, int32 Finger, bool bSendImmediate); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGHandPose.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGHandPose.h new file mode 100644 index 0000000..6a1d215 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGHandPose.h @@ -0,0 +1,291 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Data class containing all variables to draw or analyze a virtual hand + * in different formats. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGTypes/SGCoreTypes.h" +#include "SGTypes/SGQuatArray.h" +#include "SGTypes/SGRotatorArray.h" +#include "SGTypes/SGVectorArray.h" + +#include "SGHandPose.generated.h" + +class FSGHandPoseImpl; +class USGBasicHandModel; +class USGHandPose; + +/** + * Contains all variables required to draw or analyze a virtual hand. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGHandPose final : public UObject +{ + GENERATED_BODY() + +public: + static USGHandPose* NewHandPose( + UObject* Outer, const FSGHandPoseImpl& HandPoseImpl); + +public: + /** + * The default constructor. + */ + static USGHandPose* NewHandPose(UObject* Outer); + + static USGHandPose* NewHandPose( + UObject* Outer, + bool bRightHanded, const TArray>& JointPositions, const TArray>& JointRotations, + const TArray>& HandAngles); + + /** + * Create a new instance of HandPose. + */ + static USGHandPose* NewHandPose( + UObject* Outer, + bool bRightHanded, + const TArray>& JointPositions, const TArray>& JointRotations, + const TArray>& HandAngles); + + /** + * Create a new instance of HandPose. + */ + static USGHandPose* NewHandPose( + UObject* Outer, + bool bRightHanded, const TArray& JointPositions, const TArray& JointRotations, + const TArray& HandAngles); + + /** + * Create a new instance of HandPose. + */ + static USGHandPose* NewHandPose( + UObject* Outer, + bool bRightHanded, const TArray& JointPositions, const TArray& JointRotations, + const TArray& HandAngles); + +public: + /** + * Deserialize a HandPose back into usable values. + */ + static USGHandPose* Deserialize(UObject* Outer, const FString& SerializedString); + + /** + * Generate a HandPose based on articulation angles (handAngles). + */ + static USGHandPose* FromHandAngles(UObject* Outer, + const TArray>& HandAngles, bool bRightHanded, + const USGBasicHandModel* HandDimensions); + + /** + * Generate a HandPose based on articulation angles (handAngles), with a default HandModel. + */ + static USGHandPose* FromHandAngles(UObject* Outer, const TArray>& HandAngles, bool bRightHanded); + + /** + * Create a new instance of a left or right handed Pose that is "idle"; in a neutral position. + */ + static USGHandPose* DefaultIdle(UObject* Outer, bool bRightHanded, const USGBasicHandModel* HandDimensions); + + /** + * Create a new instance of a left or right handed Pose that is "idle"; in a neutral position. + */ + static USGHandPose* DefaultIdle(UObject* Outer, bool bRightHanded); + + /** + * Generates a HandPose representing an 'open hand', used in calibration to determine finger extension. + */ + static USGHandPose* FlatHand(UObject* Outer, bool bRightHanded, const USGBasicHandModel* HandDimensions); + + /** + * Generates a HandPose representing an 'open hand', used in calibration to determine finger extension. + */ + static USGHandPose* FlatHand(UObject* Outer, bool bRightHanded); + + /** + * Generates a HandPose representing a 'thumbs up', used in calibration to determine finger flexion, thumb + * extension and adduction. + */ + static USGHandPose* ThumbsUp(UObject* Outer, bool bRightHanded, const USGBasicHandModel* HandDimensions); + + /** + * Generates a HandPose representing a 'thumbs up', used in calibration to determine finger flexion, thumb + * extension and adduction. + */ + static USGHandPose* ThumbsUp(UObject* Outer, bool bRightHanded); + + /** + * Generates a HandPose representing a 'fist', used in calibration to determine, thumb flexion and abduction. + */ + static USGHandPose* Fist(UObject* Outer, bool bRightHanded, const USGBasicHandModel* HandDimensions); + + /** + * Generates a HandPose representing a 'fist', used in calibration to determine, thumb flexion and abduction. + */ + static USGHandPose* Fist(UObject* Outer, bool bRightHanded); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * The default constructor. + */ + USGHandPose(); + + /** + * Create a new instance of HandPose. + */ + USGHandPose(bool bRightHanded, + const TArray>& JointPositions, const TArray>& JointRotations, + const TArray>& HandAngles); + + /** + * Create a new instance of HandPose. + */ + USGHandPose(bool bRightHanded, + const TArray>& JointPositions, const TArray>& JointRotations, + const TArray>& HandAngles); + + /** + * Create a new instance of HandPose. + */ + USGHandPose(bool bRightHanded, + const TArray& JointPositions, const TArray& JointRotations, + const TArray& HandAngles); + + /** + * Create a new instance of HandPose. + */ + USGHandPose(bool bRightHanded, + const TArray& JointPositions, const TArray& JointRotations, + const TArray& HandAngles); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGHandPose(const FSGHandPoseImpl& HandPoseImpl); + +public: + /** + * The destructor. + */ + virtual ~USGHandPose() override; + +protected: + /** + * Allows to set the underlying object after construction. + */ + void SetHandPoseImpl(const FSGHandPoseImpl& HandPoseImpl); + +public: + /** + * The cast to underlying type method. + */ + const FSGHandPoseImpl& ToHandPoseImpl() const; + +public: + /** + * Whether this HandPose was created to be a right- or left hand. + */ + bool IsRight() const; + + /** + * Positions of all hand joints relative to the Sense Glove origin. From thumb to pinky, proximal to distal. + */ + TArray> GetJointPositions() const; + + /** + * Quaternion rotations of all hand joints. From thumb to pinky, proximal to distal. + */ + TArray> GetJointRotationsQ() const; + + /** + * Rotations of all hand joints. From thumb to pinky, proximal to distal. + */ + TArray> GetJointRotations() const; + + /** + * Euler representations of all possible hand angles. From thumb to pinky, proximal to distal. + */ + TArray> GetHandAngles() const; + +public: + /** + * Returns true of these two hand poses are roughly equal. + */ + bool Equals(const USGHandPose* HandPose) const; + + /** + * Returns the total flexion of a specific finger as a value between 0 (fully extended) and 1 (fully flexed). + * + * @remarks Useful for animation or for detecting gestures. + */ + float GetNormalizedFlexion(ESGFinger Finger, bool bClamp01 = true) const; + + /** + * Returns the total flexion of a specific finger as a value between 0 (fully extended) and 1 (fully flexed). + * + * @remarks Useful for animation or for detecting gestures. + */ + TArray GetNormalizedFlexion(bool bClamp01 = true) const; + +public: + /** + * + */ + FString ToString(bool bShortFormat = false) const; + + /** + * Serialize this HandPose into a string representation. + */ + FString SGSerialize() const; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGHapticChannelInfo.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGHapticChannelInfo.h new file mode 100644 index 0000000..15e9d9d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGHapticChannelInfo.h @@ -0,0 +1,199 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Contains information on Haptic channels available to this device for IPC. + * Some devices have different "Haptic Channels". This info is exposed via IPC + * to SGCore. + */ + + +#pragma once + +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGTypes/SGCoreTypes.h" + +#include "SGHapticChannelInfo.generated.h" + +class FSGHapticChannelInfoImpl; + +/* + * Contains information on Haptic channels available to this device for IPC. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGHapticChannelInfo final : public UObject +{ + GENERATED_BODY() + +public: + static USGHapticChannelInfo* NewHapticChannelInfo( + UObject* Outer, const FSGHapticChannelInfoImpl& HapticChannelInfoImpl); + +public: + /** + * The default constructor. + */ + static USGHapticChannelInfo* NewHapticChannelInfo(UObject* Outer); + + /** + * Create a new instance of HapticChannelInfo. + */ + static USGHapticChannelInfo* NewHapticChannelInfo( + UObject* Outer, + const TArray& StreamIndex, const TArray& FireAndForgetIndex); + +public: + /** + * Generate a single IPCAddress for an address. + * + * @param DeviceIndex + * @param ChannelIndex + */ + static FString GenerateAddress(int32 DeviceIndex, int32 ChannelIndex); + + /** + * Parse HapticChannelInfo received through IPC into usable data. + * + * @param IpcString + */ + static USGHapticChannelInfo* Parse(UObject* Outer, const FString& IpcString); + +public: + /** + * Byte used to identify streaming channels. + */ + static int32 GetStreamingType(); + + /** + * Byte used to indicate fire-and-forget channels. + */ + static int32 GetFireAndForgetType(); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * Creates a default HapticChannelInfo, with solely a single streaming haptic Channel. + */ + USGHapticChannelInfo(); + + /** + * Create a new instance of HapticChannelInfo. + */ + USGHapticChannelInfo(const TArray& StreamIndex, const TArray& FireAndForgetIndex); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGHapticChannelInfo(const FSGHapticChannelInfoImpl& HapticChannelInfoImpl); + +public: + /** + * The destructor. + */ + virtual ~USGHapticChannelInfo() override; + +protected: + /** + * Allows to set the underlying object after construction. + */ + void SetHapticChannelInfoImpl(const FSGHapticChannelInfoImpl& HapticChannelInfoImpl); + +public: + /** + * The cast to underlying type method. + */ + const FSGHapticChannelInfoImpl& ToHapticChannelInfoImpl() const; + +public: + /** + * Returns the amount of streaming channels available for haptics. Will indicate if a device can support the + * haptics you're trying to send through it. + */ + int32 GetStreamChannelCount() const; + + /** + * Returns the amount of fire-and-forget channels available for haptics. Will indicate if a device can support the + * haptics you're trying to send through it. + */ + int32 GetFireAndForgetChannelCount() const; + + /** + * Retrieve the total amount of channels for this device. + */ + int32 GetTotalChannelCount() const; + + /** + * Returns the address that corresponds to the nth channel of a specific type. It's unguarded, which means I don't + * check the validity of index - could result in an exception. Optimized piece of code for for loops. + * + * @param Type + * @param TypeIndex + */ + FString GetAddress_Unguarded(ESGHapticChannelType Type, int32 TypeIndex) const; + + /** + * Returns the address that corresponds to the nth channel of a specific type. It's unguarded, which means I don't + * check the validity of index - could result in an exception. Optimized piece of code for for loops. + * Used for Internals. + * + * @param Type + * @param TypeIndex + * @param OutIndex + * @param OutAddressString + */ + void GetIpcParams_Unguarded(ESGHapticChannelType Type, int32 TypeIndex, + int32& OutIndex, FString& OutAddressString) const; + + /** + * Regenerate the channel names for a specific device Index in shared memory. + * + * @param ForDeviceIndex + */ + void RegenerateAddresses(int32 ForDeviceIndex); + + /** + * Returns an array of all the haptic addresses stored for this info channel. + */ + TArray GetAllAddresses() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGHapticGlove.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGHapticGlove.h new file mode 100644 index 0000000..73b7430 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGHapticGlove.h @@ -0,0 +1,390 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * An interface for any of our gloves that can track hand motion and/or send + * force / vibrotactile feedback. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGCore/SGBasicHandModel.h" +#include "SGCore/SGDevice.h" +#include "SGCore/SGHandPose.h" +#include "SGTypes/SGCoreTypes.h" + +#include "SGHapticGlove.generated.h" + +class FSGHapticGloveImpl; +class FSGNovaGloveImpl; +class FSGNova2GloveImpl; +class FSGSenseGloveImpl; +class USGBasicHandModel; +class USGCustomWaveform; + +/** + * A glove developed by SenseGlove, that has hand tracking and/or haptic feedback functionality. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGHapticGlove : public USGDevice +{ + GENERATED_BODY() + +private: + friend class USGHapticGloveCalibrationSequence; + friend struct FSGHandLayer; + +protected: + static USGHapticGlove* NewHapticGlove(UObject* Outer, const FSGHapticGloveImpl& HapticGloveImpl); + + static USGHapticGlove* NewHapticGlove(UObject* Outer, TSharedRef HapticGloveImpl); + +protected: + /** + * + */ + static USGHapticGlove* NewHapticGlove(UObject* Outer); + +public: + /** + * Get all Haptic Gloves detected on this system. + * + * @param bConnectedOnly + */ + static TArray GetHapticGloves(UObject* Outer, bool bConnectedOnly = true); + + /** + * Get the first Haptic Glove detected on this system. + * + * @param OutGlove + */ + static bool GetGlove(UObject* Outer, USGHapticGlove*& OutGlove); + + /** + * Get the first left/right Haptic Glove detected on this system. + * + * @param bRightHanded + * @param OutGlove + */ + static bool GetGlove(UObject* Outer, bool bRightHanded, USGHapticGlove*& OutGlove); + +public: + /** + * + */ + static FString ToString(ESGHapticGloveCalibrationState State); + + /** + * + */ + static FString ToString(ESGHapticLocation Location); + +protected: + /** + * The basic constructor. + */ + USGHapticGlove(); + +public: + /** + * The cast from underlying parent type constructor. + */ + explicit USGHapticGlove(const FSGDeviceImpl& SGDeviceImpl); + + /** + * The cast from underlying type constructor. + */ + explicit USGHapticGlove(const FSGHapticGloveImpl& HapticGloveImpl); + + /** + * The cast from underlying child type constructor. + */ + explicit USGHapticGlove(const FSGNova2GloveImpl& NovaGloveImpl); + + /** + * The cast from underlying child type constructor. + */ + explicit USGHapticGlove(const FSGNovaGloveImpl& NovaGloveImpl); + + /** + * The cast from underlying child type constructor. + */ + explicit USGHapticGlove(const FSGSenseGloveImpl& SenseGloveImpl); + +protected: + /** + * The cast from underlying parent pointer type constructor. + */ + explicit USGHapticGlove(TSharedRef SGDeviceImpl); + + /** + * The cast from underlying pointer type constructor. + */ + explicit USGHapticGlove(TSharedRef HapticGloveImpl); + + /** + * The cast from underlying child pointer type constructor. + */ + explicit USGHapticGlove(TSharedRef NovaGloveImpl); + + /** + * The cast from underlying child pointer type constructor. + */ + explicit USGHapticGlove(TSharedRef NovaGloveImpl); + + /** + * The cast from underlying child pointer type constructor. + */ + explicit USGHapticGlove(TSharedRef SenseGloveImpl); + +public: + /** + * The destructor. + */ + virtual ~USGHapticGlove() override; + +public: + /** + * The cast to underlying type method. + */ + TSharedRef ToHapticGloveImpl() const; + +public: + /** + * Get the DeviceType enumerator of this device; used to check if its a SenseGlove/Nova/etc. + */ + virtual ESGDeviceType GetDeviceType() const override; + + /** + * Retrieve this glove's unique identifier. + */ + virtual FString GetDeviceId() const override; + + /** + * Retrieve this glove's hardware (sub) version. "DK1", "DK2", etc. + */ + virtual FString GetHardwareVersion() const override; + + /** + * Retrieve this device's main firmware version. v4.12 returns 4. + */ + virtual int32 GetFirmwareVersion() const override; + + /** + * Retrieve this device's sub firmware version. v4.12 returns 12. + */ + virtual int32 GetSubFirmwareVersion() const override; + + /** + * Returns true if this glove is made for a right hand. If false, it's a left hand. + */ + virtual bool IsRight() const; + + /** + * Retrieve this glove's IMU rotation, if if has any. + */ + virtual bool GetImuRotation(FQuat& OutImu); + + /** + * Retrieve this glove's IMU rotation, if if has any. + */ + virtual bool GetImuRotation(FRotator& OutImu); + + /** + * Retrieve a HandPose based on the latest profile, but with a specific hand geometry. + */ + virtual bool GetHandPose(UObject* Outer, const USGBasicHandModel* HandGeometry, USGHandPose*& OutHandPose) const; + + /** + * Retrieve a HandPose based on the latest profile and default hand Geometry. + */ + virtual bool GetHandPose(UObject* Outer, USGHandPose*& OutHandPose); + + /** + * Returns the Hand Angles calculated by this Nova 2 Glove. Used for input for HandPoses, but can be used in and of + * itself. + * + * @param OutHandAngles + */ + virtual bool GetHandAngles(TArray>& OutHandAngles) const; + + /** + * + */ + USGBasicHandModel* GetHandGeometry(UObject* Outer) const; + + /** + * + */ + void SetHandGeometry(const USGBasicHandModel* HandGeometry); + +public: + /** + * Returns the HapticGlove's state of calibration for its on-board sensors. + */ + virtual ESGHapticGloveCalibrationState GetCalibrationState() const; + + /** + * Resets internal calibration of the Haptic Glove. + */ + virtual void EndCalibration(); + + /** + * Force-End any form of calibration manually, if any is still running. + */ + virtual void ResetCalibration(); + + /** + * Retrieve the current calibration instruction. + */ + virtual FString GetCalibrationInstruction() const; + +public: + /** + * Stops all Haptic effects if any are currently playing. Useful at the end of simulations or when resetting. + */ + virtual void StopHaptics(); + + /** + * Stops only vibrations. + */ + virtual void StopVibrations(); + + /** + * Take all active commands in the device queue, compile them into one and send them to the device. + * + * @return Returns true if the message was successfully sent to SenseCom. + */ + virtual bool SendHaptics(); + +public: + /** + * Returns true if the HapticGlove supports vibration feedback on the specified location. + * + * @param AtLocation + */ + virtual bool SupportsCustomWaveform(ESGHapticLocation AtLocation) const; + + /** + * Sends a custom waveform to the location specified, provided that the glove has a motor there, and can support + * custom waveforms. + * + * @param OutWaveform + * @param Location + */ + virtual bool SendCustomWaveform(USGCustomWaveform* OutWaveform, ESGHapticLocation Location); + + /** + * Queue a list of force-feedback levels, between 0.0f and 1.0f. Your list should be sorted from thumb to pinky. + * + * @param Levels01 Array containing the Force-Feedback levels, from 0.0f (no FFB) to 1.0f. A value < 0.0f will be + * ignored. + * + * @remarks Devices that 'only' have on/off FFB will treat any value > 0.0 as 1.0. + */ + virtual bool QueueForceFeedbackLevels(const TArray& Levels01); + + /** + * Set the Force-Feedback value of a particular finger to a specific level + * + * @param Level01 Value will be clamped between [0...1], where 0.0f means no Force-Feedback, and 1.0 means full + * force-feedback. + * @param Finger The finger to which to send the command. + */ + virtual bool QueueForceFeedbackLevel(int32 Finger, float Level01); + + /** + * Queue a list of vibration levels, between 0.0 and 1.0. Your list should be sorted from thumb to pinky. + * + * @param Levels01 Array containing the vibration levels, from 0.0 (no vibration) to 1.0. A value < 0.0f will be + * ignored. + * + * @remarks Devices that 'only' have on/off FFB will treat any value > 0.0 as 1.0. + */ + virtual bool QueueVibroLevels(const TArray& Levels01); + + /** + * Queue a command to set the (continuous) vibration level at a specific location to a set amplitude. + * + * @param Location + * @param Level01 Value will be clamped between [0...1], where 0.0f means no vibration, and 1.0 means full + * vibration. + */ + virtual bool QueueVibroLevel(ESGHapticLocation Location, float Level01); + +public: + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + * + * @remarks The simplest interface, using default offsets. + */ + virtual void GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) const; + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + * + * @remarks The simplest interface, using default offsets. + */ + virtual void GetWristLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FRotator& OutWristRotation) const; + + /** + * Retrieve the location of the glove origin, based on a reference location. + */ + virtual void GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const; + + /** + * Retrieve the location of the glove origin, based on a reference location. + */ + virtual void GetGloveLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FRotator& OutGloveRotation) const; + +public: + /** + * Create a String Representation of this Haptic Glove. + */ + virtual FString ToString() const override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGInterpolationSet.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGInterpolationSet.h new file mode 100644 index 0000000..690bdcc --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGInterpolationSet.h @@ -0,0 +1,225 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Data class containing all variables to map an input value from one range to + * another. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGInterpolationSet.generated.h" + +class FSGInterpolationSetImpl; + +/** + * Set of variables to map a value from one range to the next. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGInterpolationSet final : public UObject +{ + GENERATED_BODY() + +public: + static USGInterpolationSet* NewInterpolationSet( + UObject* Outer, const FSGInterpolationSetImpl& InterpolationSetImpl); + +public: + /** + * Creates a basic interpolation set, without limits. + */ + static USGInterpolationSet* NewInterpolationSet(UObject* Outer); + + /** + * Create a new interpolation set without limits. + */ + static USGInterpolationSet* NewInterpolationSet(UObject* Outer, float From1, float From2, float To1, float To2); + + /** + * Create a new interpolation set with limits. + */ + static USGInterpolationSet* NewInterpolationSet( + UObject* Outer, float From1, float From2, float To1, float To2, float Min, float Max); + +public: + /** + * Convert a string notation of an InterpolationSet into a new class instance. + */ + static USGInterpolationSet* Deserialize(UObject* Outer, const FString& SerializedString); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * Creates a basic interpolation set, without limits. + */ + USGInterpolationSet(); + + /** + * Create a new interpolation set without limits. + */ + USGInterpolationSet(float From1, float From2, float To1, float To2); + + /** + * Create a new interpolation set with limits. + */ + USGInterpolationSet(float From1, float From2, float To1, float To2, float Min, float Max); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGInterpolationSet(const FSGInterpolationSetImpl& InterpolationSetImpl); + +public: + /** + * The destructor. + */ + virtual ~USGInterpolationSet() override; + +protected: + /** + * Allows to set the underlying object after construction. + */ + void SetInterpolationSetImpl(const FSGInterpolationSetImpl& InterpolationSetImpl); + +public: + /** + * The cast to underlying type method. + */ + const FSGInterpolationSetImpl& ToInterpolationSetImpl() const; + +public: + /** + * First value of input range. + */ + float GetX0() const; + + /** + * + */ + void SetX0(float X0); + + /** + * Second value of input range. + */ + float GetX1() const; + + /** + * + */ + void SetX1(float X1); + + /** + * First value of output range. + */ + float GetY0() const; + + /** + * + */ + void SetY0(float Y0); + + /** + * Second value of output range. + */ + float GetY1() const; + + /** + * + */ + void SetY1(float Y1); + + /** + * Minimum range of the output value. + */ + float GetMin() const; + + /** + * + */ + void SetMin(float Min); + + /** + * Maximum range of the output value. + */ + float GetMax() const; + + /** + * + */ + void SetMax(float Max); + +public: + /** + * Calculate an output value in range [x0...x1] to [y0..y1] + */ + float Get(float Value, bool bLimit, bool bNormalizeAngle = false) const; + +public: + /** + * Returns true if this InterpolationSet has the same values as another set. + */ + bool Equals(const USGInterpolationSet* InterpolationSet) const; + +public: + /** + * + */ + FString ToString() const; + + /** + * + */ + FString ToString(bool bLimits) const; + + /** + * Convert this InterpolationSet into a string notation so it can be stored on disk. + */ + FString SGSerialize() const; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGInterpolationSetArray.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGInterpolationSetArray.h new file mode 100644 index 0000000..5a3dcba --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGInterpolationSetArray.h @@ -0,0 +1,50 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCore/SGInterpolationSet.h" + +#include "SGInterpolationSetArray.generated.h" + +USTRUCT(BlueprintType) +struct SENSEGLOVECORE_API FSGInterpolationSetArray +{ + GENERATED_BODY() + +public: + UPROPERTY(EditAnywhere, Category="SenseGlove | Types | Nested Arrays", BlueprintReadWrite) + TArray InterpolationSetArray; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGJointKinematics.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGJointKinematics.h new file mode 100644 index 0000000..5814f5d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGJointKinematics.h @@ -0,0 +1,89 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Contains kinematic formulae and wrappers for Sense Glove mathematics. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "UObject/ObjectMacros.h" + +#include "SGTypes/SGCoreTypes.h" + +#include "SGJointKinematics.generated.h" + +class USGBasicHandModel; + +/** + * + */ +USTRUCT() +struct SENSEGLOVECORE_API FSGJointKinematics +{ + GENERATED_BODY() + +public: + /** + * Perform forward Kinematics on a set of joints, defined by a start position- and rotation, + * joint angles and the lengths in between. Outputs the calculated positions and rotations. + */ + static bool ForwardKinematics( + const FVector& StartPosition, const FQuat& StartRotation, + const TArray& JointLengths, const TArray& JointAngles, + TArray& OutNewPositions, TArray& OutNewRotations); + + /** + * Perform forward Kinematics on a set of joints, defined by a start position- and rotation, + * joint angles and the lengths in between. Outputs the calculated positions and rotations. + */ + static bool ForwardKinematics( + const FVector& StartPosition, const FRotator& StartRotation, + const TArray& JointLengths, const TArray& JointAngles, + TArray& OutNewPositions, TArray& OutNewRotations); + + /** + * Calculate positions and rotations of a finger based on input angles and profile. + */ + static bool ForwardKinematics( + const USGBasicHandModel* Profile, ESGFinger Finger, const TArray& JointAngles, + TArray& OutNewPositions, TArray& OutNewRotations); + + /** + * Calculate positions and rotations of a finger based on input angles and profile. + */ + static bool ForwardKinematics( + const USGBasicHandModel* Profile, ESGFinger Finger, const TArray& JointAngles, + TArray& OutNewPositions, TArray& OutNewRotations); +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGLibrary.h new file mode 100644 index 0000000..3bf90bf --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGLibrary.h @@ -0,0 +1,73 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Information about the SGCore C++ Library. + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "UObject/ObjectMacros.h" + +#include "SGTypes/SGCoreTypes.h" + +#include "SGLibrary.generated.h" + +/** + * Provides information about this C++ Library. + */ +USTRUCT() +struct SENSEGLOVECORE_API FSGLibrary +{ + GENERATED_BODY() + +public: + /** + * The version of this C++ Library in string representation. + */ + static FString GetVersion(); + + /** + * Check what back-end connections are used for this version of SGConnect. + */ + static ESGBackendType GetBackendType(); + + /** + * Back-End version in string notation. + */ + static FString GetBackendVersion(); + + /** + * If possible, check what version of SGConnect is paired with this API. + */ + static FString GetSGConnectVersion(); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGNova2Glove.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGNova2Glove.h new file mode 100644 index 0000000..6bb50e9 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGNova2Glove.h @@ -0,0 +1,593 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Interface for Nova 2.0 Gloves. A soft glove with detachable force-feedback + * and sensor module, and active contact feedback in the front strap. + * Since the Nova 2.0 is significantly different from the Nova 1 Glove, it gets + * its own separate device interface. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGCore/SGHapticGlove.h" +#include "SGTypes/SGCoreTypes.h" + +#include "SGNova2Glove.generated.h" + +class FSGNova2GloveImpl; +class USGHandInterpolator; +class USGNovaGloveInfo; +class USGNova2GloveSensorData; +class USGSensorNormalization; +class USGThresholdCommand; + +/** + * Interface for Nova 2.0 Gloves. A soft glove with detachable force-feedback and sensor module, and active contact + * feedback in the front strap. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGNova2Glove final : public USGHapticGlove +{ + GENERATED_BODY() + +public: + static USGNova2Glove* NewNova2Glove(UObject* Outer, const FSGNova2GloveImpl& Nova2GloveImpl); + + static USGNova2Glove* NewNova2Glove(UObject* Outer, TSharedRef Nova2GloveImpl); + +public: + /** + * Default constructor for Nova2Glove. + */ + static USGNova2Glove* NewNova2Glove(UObject* Outer); + + /** + * Creates a new instance of a Nova Glove. + */ + static USGNova2Glove* NewNova2Glove(UObject* Outer, const USGNovaGloveInfo& DeviceInfo); + +public: + /** + * Deserializes a Nova 2.0 from its ConstantsString. Returns a nullptr if unsuccessful. + * + * @param ConstantsString + */ + static USGDevice* Parse(UObject* Outer, const FString& ConstantsString); + + /** + * Retrieve all Nova 2.0's. + */ + static TArray GetNova2Gloves(UObject* Outer); + + /** + * Retrieve the first connected Nova 2.0 there is. + */ + static bool GetNova2Glove(UObject* Outer, USGNova2Glove*& OutGlove); + + /** + * Retrieve the first (connected) right or left handed Nova 2.0. + */ + static bool GetNova2Glove(UObject* Outer, bool bRightHanded, USGNova2Glove*& OutGlove); + +public: + /** + * Retrieve the location of the glove origin, based on a reference location without requiring an object reference. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param bRightHanded Whether this is a left or right-handed glove. + * @param HardwareVersion + * @param OutGlovePosition The 3D Position of the glove, in mm, relative to your origin. + * @param OutGloveRotation The 3D Rotation of the glove, relative to your origin. + */ + static void CalculateGloveLocation( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, const FString& HardwareVersion, + FVector& OutGlovePosition, FQuat& OutGloveRotation); + + /** + * Retrieve the location of the glove origin, based on a reference location without requiring an object reference. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param bRightHanded Whether this is a left or right-handed glove. + * @param HardwareVersion + * @param OutGlovePosition The 3D Position of the glove, in mm, relative to your origin. + * @param OutGloveRotation The 3D Rotation of the glove, relative to your origin. + */ + static void CalculateGloveLocation( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, const FString& HardwareVersion, + FVector& OutGlovePosition, FRotator& OutGloveRotation); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets, without + * needing an object reference. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param bRightHanded Whether this is right or left hand. + * @param HardwareVersion + * @param OutWristPosition The 3D Position of the wrist, in mm, relative to your origin. + * @param OutWristRotation The 3D Rotation of the wrist, relative to your origin. + * + * @remarks The simplest interface, using default offsets. + */ + static void CalculateWristLocation( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, const FString& HardwareVersion, + FVector& OutWristPosition, FQuat& OutWristRotation); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets, without + * needing an object reference. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param bRightHanded Whether this is right or left hand. + * @param HardwareVersion + * @param OutWristPosition The 3D Position of the wrist, in mm, relative to your origin. + * @param OutWristRotation The 3D Rotation of the wrist, relative to your origin. + * + * @remarks The simplest interface, using default offsets. + */ + static void CalculateWristLocation( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, const FString& HardwareVersion, + FVector& OutWristPosition, FRotator& OutWristRotation); + +public: + /** + * Special Byte to identify the command as a Streaming Byte. + */ + static ANSICHAR GetStreamByte(); + + /** + * Ranges before a Nova 2.0 Sensor is allowed to move. + */ + static TArray GetNova2SensorRanges(); + +public: + /** + * Converts Nova 2.0 Sensor Data into floating point inputs for normalization. + * + * @param SensorData + */ + static TArray ToNormalizedValues(const USGNova2GloveSensorData* SensorData); + + /** + * Convert Sensor Data into a series of normalized values. + * + * @param Outer + * @param SensorData + * @param OutSensorNormalizer + */ + static TArray ToNormalizedValues( + UObject* Outer, + const USGNova2GloveSensorData* SensorData, USGSensorNormalization*& OutSensorNormalizer); + +public: + /** + * Calculate Hand Angles for a Nova 2.0 Glove, based on normalized input. + * + * @param NormalizedValues + * @param Interpolator + */ + static TArray> CalculateHandAngles( + const TArray& NormalizedValues, const USGHandInterpolator* Interpolator, bool bInfluenceIndex); + + /** + * Convert normalized inputs (5-6 sensors) to input for an Interpolator. + * + * @param NormalizedData + * @param GloveInfo + */ + static TArray> ToNormalizedAngles( + const TArray& NormalizedData, const USGNovaGloveInfo* GloveInfo); + +protected: + USGNova2Glove(); + + explicit USGNova2Glove(const USGNovaGloveInfo& DeviceInfo); + +public: + /** + * The cast from underlying parent type constructor. + */ + explicit USGNova2Glove(const FSGDeviceImpl& SGDeviceImpl); + + /** + * The cast from underlying parent type constructor. + */ + explicit USGNova2Glove(const FSGHapticGloveImpl& HapticGloveImpl); + + /** + * The cast from underlying type constructor. + */ + explicit USGNova2Glove(const FSGNova2GloveImpl& Nova2GloveImpl); + +protected: + /** + * The cast from underlying parent pointer type constructor. + */ + explicit USGNova2Glove(TSharedRef SGDeviceImpl); + + /** + * The cast from underlying parent pointer type constructor. + */ + explicit USGNova2Glove(TSharedRef HapticGloveImpl); + + /** + * The cast from underlying pointer type constructor. + */ + explicit USGNova2Glove(TSharedRef Nova2GloveImpl); + +public: + /** + * The destructor. + */ + virtual ~USGNova2Glove() override; + +public: + /** + * The cast to underlying type method. + */ + TSharedRef ToNova2GloveImpl() const; + +public: + /** + * Return the DeviceType of this Nova. + */ + virtual ESGDeviceType GetDeviceType() const override; + + /** + * Returns this device's unique identifier. + */ + virtual FString GetDeviceId() const override; + + /** + * Access this device's hardware designation. + */ + virtual FString GetHardwareVersion() const override; + + /** + * Access this device's main firmware version. (ex: v3.2 -> 3). + */ + virtual int32 GetFirmwareVersion() const override; + + /** + * Access this device's sub-firmware version. (ex: v3.2 -> 2). + */ + virtual int32 GetSubFirmwareVersion() const override; + +public: + /** + * Returns true if this device operates on a battery. + */ + virtual bool HasBattery() const override; + + /** + * Returns true if this device is currently charging. + */ + virtual bool IsCharging() override; + + /** + * Returns the device's battery level, as a value between 0 (empty) and 1 (full). + */ + virtual bool GetBatteryLevel(float& OutBatteryLevel) override; + +public: + /** + * Returns true if this glove is meant for right hands. + */ + virtual bool IsRight() const override; + + /** + * Retrieve this glove's latest IMU rotation, if one is present. + * + * @param OutImu + */ + virtual bool GetImuRotation(FQuat& OutImu) override; + + /** + * Retrieve this glove's latest IMU rotation, if one is present. + * + * @param OutImu + */ + virtual bool GetImuRotation(FRotator& OutImu) override; + + /* + * Calculate a HandPose from this glove's latest Sensor Data. + */ + virtual bool GetHandPose(UObject* Outer, const USGBasicHandModel* HandGeometry, + USGHandPose*& OutHandPose) const override; + + /** + * Returns the Hand Angles calculated by this Nova 2 Glove. Used for input for HandPoses, but can be used in and + * of itself. + * + * @param OutHandAngles + */ + virtual bool GetHandAngles(TArray>& OutHandAngles) const override; + +public: + /* + * Retrieve the calibration status of this Nova 2.0 Glove. + */ + virtual ESGHapticGloveCalibrationState GetCalibrationState() const override; + + /* + * Completes sensor Normalization on the Nova 2.0's end. + */ + virtual void EndCalibration() override; + + /* + * Completes sensor Normalization on the Nova 2.0's end. + */ + virtual void ResetCalibration() override; + +public: + /* + * Stop all haptic feedback effects playing on this device. + */ + virtual void StopHaptics() override; + + /** + * Stop only all vibrotactile feedback. + */ + virtual void StopVibrations() override; + + /** + * Flush all streaming haptic effects on the different fingers to the Nova 2.0 Glove. + */ + virtual bool SendHaptics() override; + +public: + /** + * Returns true if this Glove supports the chosen haptic location. + * + * @param AtLocation + */ + virtual bool SupportsCustomWaveform(ESGHapticLocation AtLocation) const override; + + /** + * Send a custom waveform to the Nova 2.0. + * + * @param OutWaveform + * @param Location + */ + virtual bool SendCustomWaveform(USGCustomWaveform* OutWaveform, ESGHapticLocation Location) override; + +public: + /** + * Queue a list of force-feedback levels, between 0.0 and 1.0. Your list should be sorted from thumb to pinky. + * + * @param Levels01 Array containing the Force-Feedback levels, from 0.0 (no FFB) to 1.0. A value < 0.0f will be + * ignored. + * + * @remarks Devices that 'only' have on/off FFB will treat any value > 0.0 as 1.0. + */ + virtual bool QueueForceFeedbackLevels(const TArray& Levels01) override; + + /** + * Set the Force-Feedback value of a particular finger to a specific level. + * + * @param Finger The finger to which to send the command. + * @param Level01 Value will be clamped between [0...1], where 0.0 means no Force-Feedback, and 1.0 means full + * force-feedback. + */ + virtual bool QueueForceFeedbackLevel(int32 Finger, float Level01) override; + + /** + * Queue a list of vibration levels, between 0.0 and 1.0. Your list should be sorted from thumb to pinky. + * + * @param Amplitudes Array containing the vibration levels, from 0.0 (no vibration) to 1.0. A value < 0.0f will be + * ignored. + * + * @remarks Devices that 'only' have on/off FFB will treat any value > 0.0 as 1.0. + */ + virtual bool QueueVibroLevels(const TArray& Amplitudes) override; + + /** + * Queue a command to set the (continuous) vibration level at a specific location to a set amplitude. This is to + * support backwards compatibility for older plugins. Use of Customwaveforms is encouraged. + * + * @param Location + * @param Level01 Value will be clamped between [0...1], where 0.0f means no vibration, and 1.0 means full + * vibration. + */ + virtual bool QueueVibroLevel(ESGHapticLocation Location, float Level01) override; + + /** + * Set the amount of squeeze-feedback to the desired level (0 = no squeeze, 1 = full squeeze). + * + * @param SqueezeLevel01 + */ + virtual bool QueueSqueezeLevel(float SqueezeLevel01); + +public: + /** + * Retrieve the location of the glove origin, based on a reference location. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the Nova2. + * @param OutGlovePosition The 3D Position of the glove, in mm, relative to your origin. + * @param OutGloveRotation The 3D Rotation of the glove, relative to your origin. + */ + virtual void GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const override; + + /** + * Retrieve the location of the glove origin, based on a reference location. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the Nova2. + * @param OutGlovePosition The 3D Position of the glove, in mm, relative to your origin. + * @param OutGloveRotation The 3D Rotation of the glove, relative to your origin. + */ + virtual void GetGloveLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FRotator& OutGloveRotation) const override; + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param OutWristPosition The 3D Position of the wrist, in mm, relative to your origin. + * @param OutWristRotation The 3D Rotation of the wrist, relative to your origin. + * + * @remarks The simplest interface, using default offsets. + */ + virtual void GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) const override; + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param OutWristPosition The 3D Position of the wrist, in mm, relative to your origin. + * @param OutWristRotation The 3D Rotation of the wrist, relative to your origin. + * + * @remarks The simplest interface, using default offsets. + */ + virtual void GetWristLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FRotator& OutWristRotation) const override; + +public: + /** + * Access DeviceInfo of this Nova. + */ + USGNovaGloveInfo* GetGloveInfo(UObject* Outer) const; + + /** + * If true, the Index Finger sensors will influence the tracking of the other fingers. + */ + bool DoesIndexInfluenceOthers() const; + + /** + * + * + * @param bInfluenceOthers + */ + void SetIndexInfluencesOthers(bool bInfluenceOthers); + + /** + * If true, the sensors of this Nova Glove are normalized on-board the device. Otherwise, sensor normalization runs + * inside the library. + */ + bool SupportsOnBoardNormalization() const; + +public: + /** + * Get the latest Sensor Data from this Glove. + */ + bool GetSensorData(UObject* Outer, USGNova2GloveSensorData*& OutSensorData); + + /** + * Returns the normalized Sensor Data of this Nova2 Glove. If no normalization is running on the glove(s), then + * it's done on the PC side. + * + * @param OutNormalizedValues + */ + bool GetNormalizedInput(TArray& OutNormalizedValues) const; + + /** + * Tell the Nova Glove to send Raw Data instead of normalized data. + */ + virtual bool SendRawData(); + + /** + * Tell the Nova Glove to send normalized data. + */ + virtual bool SendNormalizedData(); + +public: + /** + * Convert a HapticLocation into a Nova 2.0 Motor location. + * + * @param Location + */ + virtual ESGNova2VibroMotor ToNovaMotor(ESGHapticLocation Location) const; + + /** + * Returns the channel index for a particular motor. Can make this as complex as I want for the Nova2 GLove(s). + * + * @param Motor + */ + virtual int32 ChannelIndex(ESGNova2VibroMotor Motor) const; + + /** + * Ensures the waveform that is to be sent to this Nova 2.0 Glove has the appropriate parameters. + * + * @param OutWaveform + * @param Motor + */ + virtual void ValidateWaveform(USGCustomWaveform* OutWaveform, ESGNova2VibroMotor Motor) const; + + /** + * Directly sends a custom waveform to the Nova2 Glove motors, as opposed to specifying a Haptic Location. + * + * @param OutWaveform + * @param Motor + * @param bValidateWaveform + */ + virtual bool SendCustomWaveform_Nova2( + USGCustomWaveform* OutWaveform, ESGNova2VibroMotor Motor, bool bValidateWaveform = true); + +public: + /** + * Get a string representation of this Nova 2.0 Glove. + */ + virtual FString ToString() const override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGNova2GloveSensorData.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGNova2GloveSensorData.h new file mode 100644 index 0000000..50a2909 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGNova2GloveSensorData.h @@ -0,0 +1,280 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Sensor Data coming off the Nova 2.0 Glove. + * Has certain features the Nova 1.0 Glove does not have, such as multiple + * flexion sensors, normalization states and Active Strap info. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGTypes/SGCoreTypes.h" +#include "SGTypes/SGVectorArray.h" + +#include "SGNova2GloveSensorData.generated.h" + +class FSGNova2GloveSensorDataImpl; +class USGNovaGloveInfo; + +/** + * Nova Glove 2.0 Sensor data, which had additional feedback and calibration parameters. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGNova2GloveSensorData final : public UObject +{ + GENERATED_BODY() + +public: + static USGNova2GloveSensorData* NewNova2GloveSensorData( + UObject* Outer, const FSGNova2GloveSensorDataImpl& Nova2GloveSensorDataImpl); + +public: + /** + * Default constructor for Nova2GloveSensorData. + */ + static USGNova2GloveSensorData* NewNova2GloveSensorData(UObject* Outer); + + /** + * Create a new instance of a Nova2GloveSensorData. + */ + static USGNova2GloveSensorData* NewNova2GloveSensorData( + UObject* Outer, ESGNormalizationState NormalizationState, + const TArray>& Values, int32 ParsedValues, + const FQuat& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + + /** + * Create a new instance of a Nova2GloveSensorData. + */ + static USGNova2GloveSensorData* NewNova2GloveSensorData( + UObject* Outer, ESGNormalizationState NormalizationState, + const TArray& Values, int32 ParsedValues, + const FQuat& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + + /** + * Create a new instance of a Nova2GloveSensorData. + */ + static USGNova2GloveSensorData* NewNova2GloveSensorData( + UObject* Outer, ESGNormalizationState NormalizationState, + const TArray>& Values, int32 ParsedValues, + const FRotator& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + + /** + * Create a new instance of a Nova2GloveSensorData. + */ + static USGNova2GloveSensorData* NewNova2GloveSensorData( + UObject* Outer, ESGNormalizationState NormalizationState, + const TArray& Values, int32 ParsedValues, + const FRotator& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + +public: + /** + * Parse the bytes as they come in from the device into usable values. + * + * @param RawData + * @param GloveInfo + */ + static USGNova2GloveSensorData* Parse(UObject* Outer, const FString& RawData, const USGNovaGloveInfo* GloveInfo); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * Default constructor for Nova2GloveSensorData. + */ + USGNova2GloveSensorData(); + + /** + * Create a new instance of a Nova2GloveSensorData. + * + * @param NormalizationState + * @param Values + * @param ParsedValues + * @param ImuRotation + * @param bImuParsed + * @param BatteryLevel + * @param bCharging + */ + USGNova2GloveSensorData(ESGNormalizationState NormalizationState, + const TArray>& Values, int32 ParsedValues, + const FQuat& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + + /** + * Create a new instance of a Nova2GloveSensorData. + * + * @param NormalizationState + * @param Values + * @param ParsedValues + * @param ImuRotation + * @param bImuParsed + * @param BatteryLevel + * @param bCharging + */ + USGNova2GloveSensorData(ESGNormalizationState NormalizationState, + const TArray& Values, int32 ParsedValues, + const FQuat& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + + /** + * Create a new instance of a Nova2GloveSensorData. + * + * @param NormalizationState + * @param Values + * @param ParsedValues + * @param ImuRotation + * @param bImuParsed + * @param BatteryLevel + * @param bCharging + */ + USGNova2GloveSensorData(ESGNormalizationState NormalizationState, + const TArray>& Values, int32 ParsedValues, + const FRotator& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + + /** + * Create a new instance of a Nova2GloveSensorData. + * + * @param NormalizationState + * @param Values + * @param ParsedValues + * @param ImuRotation + * @param bImuParsed + * @param BatteryLevel + * @param bCharging + */ + USGNova2GloveSensorData(ESGNormalizationState NormalizationState, + const TArray& Values, int32 ParsedValues, + const FRotator& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGNova2GloveSensorData(const FSGNova2GloveSensorDataImpl& Nova2GloveSensorDataImpl); + +public: + /** + * The destructor. + */ + virtual ~USGNova2GloveSensorData() override; + +protected: + /** + * Allows to set the underlying object after construction. + */ + void SetNova2GloveSensorDataImpl(const FSGNova2GloveSensorDataImpl& Nova2GloveSensorDataImpl); + +public: + /** + * The cast to underlying type method. + */ + const FSGNova2GloveSensorDataImpl& ToNova2GloveSensorDataImpl() const; + +public: + /** + * Sensor Data State based on the internal data. + */ + ESGNormalizationState GetSensorState() const; + + /** + * Pronation/Supination, Flexion/Extension and Abduction/Adduction values for each finger. + */ + TArray> GetSensorValues() const; + + /** + * Returns the sensor movement of a specific finger. + * + * @param Finger + * @param Location If a Nova glove has only one flexion sensor, it will return the same value for FlexionProximal + * and FlexionDistal. + */ + float GetSensorValue(ESGFinger Finger, ESGNova2SensorLocation Location) const; + + /** + * The number of values that were parsed from the sensor string. + */ + int32 GetParsedValues() const; + +public: + /** + * Quaternion rotation relative to magnetic north. + */ + FQuat GetImuRotationQ() const; + + /** + * Rotation relative to magnetic north. + */ + FRotator GetImuRotation() const; + + /** + * Whether the IMU values were all successfully parsed, or not. + */ + bool IsImuParsed() const; + +public: + /** + * A value between 0..1 that represents the battery level of this Nova2 Glove (0 .. 100%). Returns -1 if the value + * wasn't received. + */ + float GetBatteryLevel() const; + + /** + * Returns true if this NovaGlove is connected to a power source. + */ + bool IsCharging() const; + +public: + /** + * Returns true if this sensor data contains the same values as another. + */ + bool Equals(const USGNova2GloveSensorData* Nova2GloveSensorData) const; + +public: + /** + * Create a readable string representation of this Sensor Data. + */ + FString ToString() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGNovaGlove.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGNovaGlove.h new file mode 100644 index 0000000..69c32c2 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGNovaGlove.h @@ -0,0 +1,640 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * An interface for the "Nova" - a soft glove. + * Contains methods for Kinematics, Haptics and Serialization. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGCore/SGHapticGlove.h" +#include "SGTypes/SGCoreTypes.h" + +#include "SGNovaGlove.generated.h" + +class FSGNovaGloveImpl; +class USGHandInterpolator; +class USGNovaGloveInfo; +class USGNovaGloveSensorData; +class USGSensorNormalization; +class USGThresholdCommand; + +/** + * A soft glove with Force- and Vibrotactile Feedback and limited tracking. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGNovaGlove final : public USGHapticGlove +{ + GENERATED_BODY() + +public: + static USGNovaGlove* NewNovaGlove(UObject* Outer, const FSGNovaGloveImpl& NovaGloveImpl); + + static USGNovaGlove* NewNovaGlove(UObject* Outer, TSharedRef NovaGloveImpl); + +public: + /** + * Default constructor for NovaGlove. + */ + static USGNovaGlove* NewNovaGlove(UObject* Outer); + + /** + * Creates a new instance of a Nova Glove. + */ + static USGNovaGlove* NewNovaGlove(UObject* Outer, const USGNovaGloveInfo& DeviceInfo); + +public: + /** + * Deserializes a Nova from its ConstantsString. Returns a nullptr if unsuccessful. + * + * @param ConstantsString + */ + static USGDevice* Parse(UObject* Outer, const FString& ConstantsString); + + /** + * Retrieve all Nova's. + */ + static TArray GetNovaGloves(UObject* Outer); + + /** + * Retrieve the first connected Nova there is. + */ + static bool GetNovaGlove(UObject* Outer, USGNovaGlove*& OutGlove); + + /** + * Retrieve the first (connected) right or left handed Nova. + */ + static bool GetNovaGlove(UObject* Outer, bool bRightHanded, USGNovaGlove*& OutGlove); + +public: + /** + * Retrieve the location of the glove origin, based on a reference location without requiring an object reference. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param bRightHanded Whether this is a left or right-handed glove. + * @param OutGlovePosition The 3D Position of the glove, in mm, relative to your origin. + * @param OutGloveRotation The 3D Rotation of the glove, relative to your origin. + */ + static void CalculateGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, + FVector& OutGlovePosition, FQuat& OutGloveRotation); + + /** + * Retrieve the location of the glove origin, based on a reference location without requiring an object reference. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param bRightHanded Whether this is a left or right-handed glove. + * @param OutGlovePosition The 3D Position of the glove, in mm, relative to your origin. + * @param OutGloveRotation The 3D Rotation of the glove, relative to your origin. + */ + static void CalculateGloveLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, + FVector& OutGlovePosition, FRotator& OutGloveRotation); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets, without + * needing an object reference. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param bRightHanded Whether this is right or left hand. + * @param OutWristPosition The 3D Position of the wrist, in mm, relative to your origin. + * @param OutWristRotation The 3D Rotation of the wrist, relative to your origin. + * + * @remarks The simplest interface, using default offsets. + */ + static void CalculateWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, + FVector& OutWristPosition, FQuat& OutWristRotation); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets, without + * needing an object reference. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param bRightHanded Whether this is right or left hand. + * @param OutWristPosition The 3D Position of the wrist, in mm, relative to your origin. + * @param OutWristRotation The 3D Rotation of the wrist, relative to your origin. + * + * @remarks The simplest interface, using default offsets. + */ + static void CalculateWristLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, + FVector& OutWristPosition, FRotator& OutWristRotation); + +public: + /** + * Byte indicating a new Nova haptic command. + */ + static ANSICHAR GetHapticsByte(); + + /** + * Byte indicating a new Nova thresholds command. + */ + static ANSICHAR GetThresholdsByte(); + + /** + * Byte to ignore Thresholds. + */ + static ANSICHAR GetIgnoreThresholdsByte(); + + /** + * Ranges before a Nova 1.0 Sensor is allowed to move. + */ + static TArray GetNovaSensorRanges(); + +public: + /** + * Converts Nova Sensor Data into floating point inputs for normalization. + * + * @param SensorData + */ + static TArray ToNormalizedValues(const USGNovaGloveSensorData* SensorData); + + /** + * Convert Sensor Data into a series of normalized values. + * + * @param Outer + * @param SensorData + * @param OutSensorNormalizer + */ + static TArray ToNormalizedValues( + UObject* Outer, + const USGNovaGloveSensorData* SensorData, USGSensorNormalization*& OutSensorNormalizer); + +public: + /** + * Calculate Hand Angles for a Nova Glove, based on normalized input. + * + * @param NormalizedValues + * @param Interpolator + */ + static TArray> CalculateHandAngles( + const TArray& NormalizedValues, const USGHandInterpolator* Interpolator); + +public: + /** + * Converts a Threshold command into a Nova Glove command. + * + * @param Thresholds + */ + static FString ToNovaCommandAsFlexion(const USGThresholdCommand* Thresholds); + + /** + * Converts a Threshold command into a Nova Glove command. + * + * @param Thresholds + * @param Interpolator + */ + static FString ToNovaCommandAsRaw( + const USGThresholdCommand* Thresholds, const USGSensorNormalization* Interpolator); + +protected: + USGNovaGlove(); + + explicit USGNovaGlove(const USGNovaGloveInfo& DeviceInfo); + +public: + /** + * The cast from underlying parent type constructor. + */ + explicit USGNovaGlove(const FSGDeviceImpl& SGDeviceImpl); + + /** + * The cast from underlying parent type constructor. + */ + explicit USGNovaGlove(const FSGHapticGloveImpl& HapticGloveImpl); + + /** + * The cast from underlying type constructor. + */ + explicit USGNovaGlove(const FSGNovaGloveImpl& NovaGloveImpl); + +protected: + /** + * The cast from underlying parent pointer type constructor. + */ + explicit USGNovaGlove(TSharedRef SGDeviceImpl); + + /** + * The cast from underlying parent pointer type constructor. + */ + explicit USGNovaGlove(TSharedRef HapticGloveImpl); + + /** + * The cast from underlying pointer type constructor. + */ + explicit USGNovaGlove(TSharedRef NovaGloveImpl); + +public: + /** + * The destructor. + */ + virtual ~USGNovaGlove() override; + +public: + /** + * The cast to underlying type method. + */ + TSharedRef ToNovaGloveImpl() const; + +public: + /** + * Return the DeviceType of this Nova. + */ + virtual ESGDeviceType GetDeviceType() const override; + + /** + * Returns this device's unique identifier. + */ + virtual FString GetDeviceId() const override; + + /** + * Access this device's hardware designation. + */ + virtual FString GetHardwareVersion() const override; + + /** + * Access this device's main firmware version. (ex: v3.2 -> 3). + */ + virtual int32 GetFirmwareVersion() const override; + + /** + * Access this device's sub-firmware version. (ex: v3.2 -> 2). + */ + virtual int32 GetSubFirmwareVersion() const override; + +public: + /** + * Change this device's index within the SenseCom. Warning: Can cause errors. + * + * @param NewIndex + */ + virtual void SetDeviceIndex(int32 NewIndex) override; + +public: + /** + * Returns true if this device operates on a battery. + */ + virtual bool HasBattery() const override; + + /** + * Returns true if this device is currently charging. + */ + virtual bool IsCharging() override; + + /** + * Returns the device's battery level, as a value between 0 (empty) and 1 (full). + */ + virtual bool GetBatteryLevel(float& OutBatteryLevel) override; + +public: + /** + * Returns true if this glove is meant for right hands. + */ + virtual bool IsRight() const override; + + /** + * Retrieve Nova rotation. + * + * @param OutImu + */ + virtual bool GetImuRotation(FQuat& OutImu) override; + + /** + * Retrieve Nova rotation. + * + * @param OutImu + */ + virtual bool GetImuRotation(FRotator& OutImu) override; + + /* + * Calculate a HandPose from this glove's latest Sensor Data. + */ + virtual bool GetHandPose(UObject* Outer, const USGBasicHandModel* HandGeometry, + USGHandPose*& OutHandPose) const override; + + /** + * Returns the Hand Angles calculated by this Nova Glove. Used for input for HandPoses, but can be used in and of + * itself. + * + * @param OutHandAngles + */ + virtual bool GetHandAngles(TArray>& OutHandAngles) const override; + +public: + /* + * Retrieve the calibration status of this Nova Glove. + */ + virtual ESGHapticGloveCalibrationState GetCalibrationState() const override; + + /* + * Completes sensor Normalization on the Nova's end. + */ + virtual void EndCalibration() override; + + /* + * Completes sensor Normalization on the Nova's end. + */ + virtual void ResetCalibration() override; + +public: + /* + * Stop all haptic feedback effects playing on this device. + */ + virtual void StopHaptics() override; + + /** + * Stop only all vibrotactile feedback. + */ + virtual void StopVibrations() override; + + /** + * Take all active commands in the device queue, compile them into one and send them to the device. + * + * @returns Returns true if the message was successfully sent to SenseCom. Returns false if no changes to commands + * were detected. + * + * @remarks Generic function across any Haptic Interface in SGCore. + */ + virtual bool SendHaptics() override; + +public: + /** + * Returns true if this Glove supports the chosen haptic location. + * + * @param AtLocation + */ + virtual bool SupportsCustomWaveform(ESGHapticLocation AtLocation) const override; + + /** + * Send a custom waveform to the Nova. + * + * @param OutWaveform + * @param Location + */ + virtual bool SendCustomWaveform(USGCustomWaveform* OutWaveform, ESGHapticLocation Location) override; + +public: + /** + * Queue a list of force-feedback levels, between 0.0 and 1.0. Your list should be sorted from thumb to pinky. + * + * @param Levels01 Array containing the Force-Feedback levels, from 0.0 (no FFB) to 1.0. A value < 0.0f will be + * ignored. + * + * @remarks Devices that 'only' have on/off FFB will treat any value > 0.0 as 1.0. + */ + virtual bool QueueForceFeedbackLevels(const TArray& Levels01) override; + + /** + * Set the Force-Feedback value of a particular finger to a specific level. + * + * @param Finger The finger to which to send the command. + * @param Level01 Value will be clamped between [0...1], where 0.0 means no Force-Feedback, and 1.0 means full + * force-feedback. + */ + virtual bool QueueForceFeedbackLevel(int32 Finger, float Level01) override; + + /** + * Queue a vibrotactile level for each finger. + * + * @param Amplitudes + */ + virtual bool QueueVibroLevels(const TArray& Amplitudes) override; + + /** + * Queue a command to set the (continuous) vibration level at a specific location to a set amplitude. + * + * @param Location + * @param Level01 Value will be clamped between [0...1], where 0.0f means no vibration, and 1.0 means full + * vibration. + */ + virtual bool QueueVibroLevel(ESGHapticLocation Location, float Level01) override; + +public: + /** + * Retrieve the location of the glove origin, based on a reference location. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the Nova. + * @param OutGlovePosition The 3D Position of the glove, in mm, relative to your origin. + * @param OutGloveRotation The 3D Rotation of the glove, relative to your origin. + */ + virtual void GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const override; + + /** + * Retrieve the location of the glove origin, based on a reference location. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the Nova. + * @param OutGlovePosition The 3D Position of the glove, in mm, relative to your origin. + * @param OutGloveRotation The 3D Rotation of the glove, relative to your origin. + */ + virtual void GetGloveLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FRotator& OutGloveRotation) const override; + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param OutWristPosition The 3D Position of the wrist, in mm, relative to your origin. + * @param OutWristRotation The 3D Rotation of the wrist, relative to your origin. + * + * @remarks The simplest interface, using default offsets. + */ + virtual void GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) const override; + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param OutWristPosition The 3D Position of the wrist, in mm, relative to your origin. + * @param OutWristRotation The 3D Rotation of the wrist, relative to your origin. + * + * @remarks The simplest interface, using default offsets. + */ + virtual void GetWristLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FRotator& OutWristRotation) const override; + +public: + /** + * Access all sorts of device info specific to this Nova. + */ + USGNovaGloveInfo* GetGloveInfo(UObject* Outer) const; + + /** + * If true, this Nova Glove supports sending special firmware commands to lock brakes at specific sensor values. + */ + bool SupportsThresholds() const; + + /** + * If true, this Nova Glove supports sending custom 'fire-and-forget' waveforms. + */ + bool SupportsCustomWaveforms() const; + + /** + * If true, this glove's sensor calibration runs on board the device. + */ + bool SupportsOnBoardNormalization() const; + +public: + /** + * Get the latest Sensor Data from this Glove. + */ + bool GetSensorData(UObject* Outer, USGNovaGloveSensorData*& OutSensorData); + + /** + * Returns the normalized Sensor Data of this Nova Glove. If no normalization is running on the glove(s), then it's + * done on the PC side. + * + * @param OutNormalizedValues + */ + bool GetNormalizedInput(TArray& OutNormalizedValues) const; + +public: + /** + * Converts a set of commands into a series of bytes (string) this glove can understand. + * + * @param ForceFeedbackLevels Force-Feedback levels for each finger. + * @param BuzzLevels Vibration levels for each finger. + * @param WristLevel Value between 0 and 1 for the wrist amplitude to set. + */ + virtual FString ToNovaCommand( + const TArray& ForceFeedbackLevels, const TArray& BuzzLevels, float WristLevel) const; + + /** + * Queue a vibrotactle level for a specific finger. + * + * @param Finger + * @param Amplitude + */ + virtual bool QueueVibroLevel(int32 Finger, float Amplitude); + + /** + * Queue a command to the vibration amplitude of a general wrist actuator to a set level. + * + * @param Amplitude The amplitude of the wrist vibration, where 0.0 means no vibration, and 1.0 means full + * vibration. + * + * @returns Returns true if the wrist command has been successfully queued. If false, the device might not support + * direct wrist control or have the appropriate firmware. + * + * @remarks This one isn't contained in an interface as it's not used outside of the NovaGlove class. + */ + virtual bool QueueWristLevel(float Amplitude); + +public: + /** + * Convert a HapticLocation into a Nova Motor location. + * + * @param Location + */ + virtual ESGNovaVibroMotor ToNovaMotor(ESGHapticLocation Location) const; + + /** + * Returns the channel index for a particular motor. Can make this as complex as I want for the Nova GLove(s). + * + * @param Motor + */ + virtual int32 ChannelIndex(ESGNovaVibroMotor Motor) const; + + /** + * Ensures the waveform that is to be sent to this Nova Glove has the appropriate parameters. + * + * @param OutWaveform + * @param Motor + */ + virtual void ValidateWaveform(USGCustomWaveform* OutWaveform, ESGNovaVibroMotor Motor) const; + + /** + * Directly sends a custom waveform to the Nova Glove motors, as opposed to specifying a Haptic Location. + * + * @param OutWaveform + * @param Motor + * @param bValidateWaveform + */ + virtual bool SendCustomWaveform_Nova( + USGCustomWaveform* OutWaveform, ESGNovaVibroMotor Motor, bool bValidateWaveform = true); + +public: + /** + * Stops the glove when flexing pas this point. + * + * @param Finger + * @param FlexionThreshold + */ + bool QueueThresholdCommand_Flexion(int32 Finger, float FlexionThreshold); + + /** + * Queue a command to clear the threshold for a specific finger. + * + * @param Finger + * + * @returns Returns true if the command was queued. If false, the device does not have the required firmware for + * these commands. + */ + virtual bool QueueClearThreshold(int32 Finger); + +public: + /** + * Create a string representation of this device for reporting purposes. + */ + virtual FString ToString() const override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGNovaGloveInfo.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGNovaGloveInfo.h new file mode 100644 index 0000000..1fa5c9d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGNovaGloveInfo.h @@ -0,0 +1,215 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Contains information on Nova's hardware, extracted from the device. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGNovaGloveInfo.generated.h" + +class FSGNovaGloveInfoImpl; + +/** + * Device information extracted from a Nova Glove. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGNovaGloveInfo final : public UObject +{ + GENERATED_BODY() + +public: + static USGNovaGloveInfo* NewNovaGloveInfo( + UObject* Outer, const FSGNovaGloveInfoImpl& NovaGloveInfoImpl); + +public: + /** + * The default constructor. + */ + static USGNovaGloveInfo* NewNovaGloveInfo(UObject* Outer); + + /** + * Create a new instance of a NovaGloveInfo. + */ + static USGNovaGloveInfo* NewNovaGloveInfo( + UObject* Outer, + const FString& DeviceId, const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion, + bool bRightHanded, const FQuat& ImuCorrection, int32 NumberOfSensors); + +public: + /** + * Parse a constants string into a NovaGloveInfo class. + */ + static bool Parse(UObject* Outer, const FString& ConstantsString, USGNovaGloveInfo*& OutGloveInfo); + + /** + * Convert a string representation back into a NovaGloveInfo class. + */ + static USGNovaGloveInfo* Deserialize(UObject* Outer, const FString& SerializedString); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * The default constructor. + */ + USGNovaGloveInfo(); + + /** + * Create a new instance of a NovaGloveInfo. + */ + USGNovaGloveInfo(const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion, + bool bRightHanded, const FQuat& ImuCorrection, int32 NumberOfSensors); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGNovaGloveInfo(const FSGNovaGloveInfoImpl& NovaGloveInfoImpl); + +public: + /** + * The destructor. + */ + virtual ~USGNovaGloveInfo() override; + +protected: + /** + * Allows to set the underlying object after construction. + */ + void SetNovaGloveInfoImpl(const FSGNovaGloveInfoImpl& NovaGloveInfoImpl); + +public: + /** + * The cast to underlying type method. + */ + const FSGNovaGloveInfoImpl& ToNovaGloveInfoImpl() const; + +protected: + /** + * The non-const cast to underlying type method. + */ + FSGNovaGloveInfoImpl& ToNovaGloveInfoImpl(); + +public: + /** + * Unique identifier of this device. + */ + FString GetDeviceId() const; + + /** + * Hardware (sub) version of this Sense Glove Device. + */ + FString GetHardwareVersion() const; + + /** + * Firmware version running on the device's MicroController. (as v4.12, this is the 4). + */ + int32 GetFirmwareVersion() const; + + /** + * Sub firmware version running on the device's microcontroller (as v4.12, this is the .12). + */ + int32 GetSubFirmwareVersion() const; + + /** + * Determines if this is a right-handed Nova. + */ + bool IsRight() const; + + /** + * The IMU correction of this Nova. + */ + FQuat GetImuCorrectionQ() const; + + /** + * The IMU correction of this Nova. + */ + FRotator GetImuCorrection() const; + + /** + * The number of sensors in this device. + */ + int32 GetNumberOfSensors() const; + +public: + /** + * Returns true if this glove's firmware is newer than certain version. + * + * @param FirmwareMain + * @param FirmwareSub + * @param bInclusive + */ + bool FirmwareNewerThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const; + + /** + * Returns true if this glove's firmware is older than certain version. + * + * @param FirmwareMain + * @param FirmwareSub + * @param bInclusive + */ + bool FirmwareOlderThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const; + +public: + /** + * Returns true if this GloveInfo contains the same information as another. + */ + bool Equals(const USGNovaGloveInfo* NovaGloveInfo) const; + +public: + /** + * Create a string representation of this Glove Info. + */ + FString ToString() const; + + /** + * Convert this class into a string representation so it can be unpacked later. + */ + FString SGSerialize() const; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGNovaGloveSensorData.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGNovaGloveSensorData.h new file mode 100644 index 0000000..9b7ecb2 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGNovaGloveSensorData.h @@ -0,0 +1,238 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 NovaGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Nova SensorData, parsed from rae string representations. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGTypes/SGCoreTypes.h" + +#include "SGNovaGloveSensorData.generated.h" + +class FSGNovaGloveSensorDataImpl; +class USGNovaGloveInfo; + +/** + * Sensor Data coming from a Nova, converted into useful values. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGNovaGloveSensorData final : public UObject +{ + GENERATED_BODY() + +public: + static USGNovaGloveSensorData* NewNovaGloveSensorData( + UObject* Outer, const FSGNovaGloveSensorDataImpl& NovaGloveSensorDataImpl); + +public: + /** + * Default constructor for NovaGloveSensorData. + */ + static USGNovaGloveSensorData* NewNovaGloveSensorData(UObject* Outer); + + /** + * Create a new instance of a NovaGloveSensorData. + */ + static USGNovaGloveSensorData* NewNovaGloveSensorData( + UObject* Outer, const TArray& Values, int32 ParsedValues, + const FQuat& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + + /** + * Create a new instance of a NovaGloveSensorData. + */ + static USGNovaGloveSensorData* NewNovaGloveSensorData( + UObject* Outer, const TArray& Values, int32 ParsedValues, + const FRotator& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + +public: + /** + * Returns a NovaGloveSensorData without any values. + */ + static USGNovaGloveSensorData* Empty(UObject* Outer); + + /** + * Parse the bytes as they come in from the device into usable values. + * + * @param RawData + * @param GloveInfo + * @return + */ + static USGNovaGloveSensorData* Parse(UObject* Outer, const FString& RawData, const USGNovaGloveInfo* GloveInfo); + + /** + * Convert this sensor data into ta string representation. + * + * @param SerializedString + */ + static USGNovaGloveSensorData* Deserialize(UObject* Outer, const FString& SerializedString); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * Default constructor for NovaGloveSensorData. + */ + USGNovaGloveSensorData(); + + /** + * Create a new instance of a NovaGloveSensorData. + * + * @param Values + * @param ParsedValues + * @param ImuRotation + * @param bImuParsed + * @param BatteryLevel + * @param bCharging + */ + USGNovaGloveSensorData(const TArray& Values, int32 ParsedValues, + const FQuat& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + + /** + * Create a new instance of a NovaGloveSensorData. + * + * @param Values + * @param ParsedValues + * @param ImuRotation + * @param bImuParsed + * @param BatteryLevel + * @param bCharging + */ + USGNovaGloveSensorData(const TArray& Values, int32 ParsedValues, + const FRotator& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGNovaGloveSensorData(const FSGNovaGloveSensorDataImpl& NovaGloveSensorDataImpl); + +public: + /** + * The destructor. + */ + virtual ~USGNovaGloveSensorData() override; + +protected: + /** + * Allows to set the underlying object after construction. + */ + void SetNovaGloveSensorDataImpl(const FSGNovaGloveSensorDataImpl& NovaGloveSensorDataImpl); + +public: + /** + * The cast to underlying type method. + */ + const FSGNovaGloveSensorDataImpl& ToNovaGloveSensorDataImpl() const; + +public: + /** + * Pronation/Supination, Flexion/Extension and Abduction/Adduction values for each finger. + */ + TArray GetSensorValues() const; + + /** + * Returns the sensor movement of a specific finger. + * + * @param Finger + * @param Location If a Nova glove has only one flexion sensor, it will return the same value for FlexionProximal + * and FlexionDistal. + */ + float GetSensorValue(ESGFinger Finger, ESGNovaSensorLocation Location) const; + + /** + * The number of values that were parsed from the sensor string. + */ + int32 GetParsedValues() const; + +public: + /** + * Quaternion rotation relative to magnetic north. + */ + FQuat GetImuRotationQ() const; + + /** + * Rotation relative to magnetic north. + */ + FRotator GetImuRotation() const; + + /** + * Whether the IMU values were all successfully parsed, or not. + */ + bool IsImuParsed() const; + +public: + /** + * A value between 0..1 that represents the battery level of this Nova Glove (0 .. 100%). Returns -1 if the value + * wasn't received. + */ + float GetBatteryLevel() const; + + /** + * Returns true if this NovaGlove is connected to a power source. + */ + bool IsCharging() const; + +public: + /** + * Returns true if this sensor data contains the same values as another. + */ + bool Equals(const USGNovaGloveSensorData* NovaGloveSensorData) const; + +public: + /** + * Create a readable string representation of this Sensor Data. + */ + FString ToString() const; + + /** + * Convert this sensor data into a string so it can be stored on disk. + */ + FString SGSerialize() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseCom.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseCom.h new file mode 100644 index 0000000..549fffa --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseCom.h @@ -0,0 +1,81 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "UObject/Object.h" + +#include "SGSenseCom.generated.h" + +/** + * + */ +USTRUCT() +struct SENSEGLOVECORE_API FSGSenseCom +{ + GENERATED_BODY() + +public: + /** + * Registers current process as the latest SenseCom build. + */ + static bool RegisterExe(); + + /** + * Register a particular path as the SenseGlove executable location. + */ + static bool RegisterExe(const FString& ExePath); + + /** + * Retrieve the location of SenseGlove executable. + */ + static bool GetExePath(FString& OutExePath); + + /** + * Returns true if SenseCom scanning is active. + */ + static bool ScanningActive(); + + /** + * Returns the directory of the current process. + */ + static bool GetCurrentExeDirectory(FString& OutDirectory); + + /** + * Force-starts the SenseCom application if it is active on the system. + */ + static bool StartupSenseCom(); +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGlove.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGlove.h new file mode 100644 index 0000000..cafe7da --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGlove.h @@ -0,0 +1,621 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * An interface for the Sense Glove exoskeleton glove. + * Contains methods for Kinematics, Haptics and Serialization. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGCore/SGBasicHandModel.h" +#include "SGCore/SGHandPose.h" +#include "SGCore/SGHapticGlove.h" +#include "SGCore/SGSenseGlovePose.h" +#include "SGCore/SGSenseGloveSensorData.h" +#include "SGTypes/SGCoreTypes.h" + +#include "SGSenseGlove.generated.h" + +class FSGSenseGloveImpl; +class USGHandInterpolator; +class USGHandPose; +class USGSenseGloveSensorNormalizer; + +/** + * Interface for the Sense Glove; and exoskeleton Force-Feedback glove. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGSenseGlove final : public USGHapticGlove +{ + GENERATED_BODY() + +public: + static USGSenseGlove* NewSenseGlove(UObject* Outer, const FSGSenseGloveImpl& SenseGloveImpl); + + static USGSenseGlove* NewSenseGlove(UObject* Outer, TSharedRef SenseGloveImpl); + +public: + /** + * Default constructor for SenseGlove. + */ + static USGSenseGlove* NewSenseGlove(UObject* Outer); + + /** + * Create a new instance of a Sense Glove. + */ + static USGSenseGlove* NewSenseGlove(UObject* Outer, const USGSenseGloveInfo& Model); + +public: + /** + * Deserializes a Sense Glove from its ConstantsString. Returns a nullptr if unsuccessful. + */ + static USGDevice* Parse(UObject* Outer, const FString& ConstantsString); + + /** + * Retrieve all Sense Gloves connected to this system. + */ + static TArray GetSenseGloves(UObject* Outer); + + /** + * Retrieve the first connected Sense Glove there is. + */ + static bool GetSenseGlove(UObject* Outer, USGSenseGlove*& OutGlove); + + /** + * Retrieve the first (connected) right or left handed sense glove. + */ + static bool GetSenseGlove(UObject* Outer, bool bRightHanded, USGSenseGlove*& OutGlove); + +public: + /** + * Retrieve the location of the glove origin, based on a reference location without requiring an object reference. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param bRightHanded Whether or not this is a left or right handed glove. + * @param MountedOn Which finger module the hardware is mounted on. Default is Middle finger. + * @param OutGlovePosition The 3D Position of the glove, in mm, relative to your origin. + * @param OutGloveRotation The 3D Rotation of the glove, relative to your origin. + */ + static void CalculateGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + bool bRightHanded, ESGFinger MountedOn, + FVector& OutGlovePosition, FQuat& OutGloveRotation); + + /** + * Retrieve the location of the glove origin, based on a reference location without requiring an object reference. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param bRightHanded Whether or not this is a left or right handed glove. + * @param MountedOn Which finger module the hardware is mounted on. Default is Middle finger. + * @param OutGlovePosition The 3D Position of the glove, in mm, relative to your origin. + * @param OutGloveRotation The 3D Rotation of the glove, relative to your origin. + */ + static void CalculateGloveLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + bool bRightHanded, ESGFinger MountedOn, + FVector& OutGlovePosition, FRotator& OutGloveRotation); + + /** + * Calculates the full wrist location. + * + * @param ReferencePosition + * @param ReferenceRotation + * @param TrackingHardware + * @param bRightHanded + * @param MountedOn + * @param GloveWristPositionOffset + * @param GloveWristRotationOffset + * @param OutWristPosition + * @param OutWristRotation + */ + static void CalculateWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + bool bRightHanded, ESGFinger MountedOn, + const FVector& GloveWristPositionOffset, + const FQuat& GloveWristRotationOffset, + FVector& OutWristPosition, FQuat& OutWristRotation); + + /** + * Calculates the full wrist location. + * + * @param ReferencePosition + * @param ReferenceRotation + * @param TrackingHardware + * @param bRightHanded + * @param MountedOn + * @param GloveWristPositionOffset + * @param GloveWristRotationOffset + * @param OutWristPosition + * @param OutWristRotation + */ + static void CalculateWristLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + bool bRightHanded, ESGFinger MountedOn, + const FVector& GloveWristPositionOffset, + const FRotator& GloveWristRotationOffset, + FVector& OutWristPosition, FRotator& OutWristRotation); + +public: + /** + * Byte indicating a new Sense Glove haptic command. + */ + static ANSICHAR GetHapticsByte(); + + /** + * Byte indicating a new Thumper command. + */ + static ANSICHAR GetThumperByte(); + + /** + * Default offset from thimble to fingertip. + */ + static FVector GetDefaultThimbleOffset(); + +public: + /** + * Calculates a GlovePose based on sensor angles and a glove model. + * + * @remarks Use this when you already have gloveAngles collected. + */ + static USGSenseGlovePose* CalculateGlovePose(UObject* Outer, + const USGSenseGloveSensorData* SensorData, + const USGSenseGloveInfo* GloveModel); + + /** + * Calculates a GlovePose based on gloveAngles and a glove model. + * + * @remarks Use this when you already have gloveAngles collected. + */ + static USGSenseGlovePose* CalculateGlovePose(UObject* Outer, + const TArray>& GloveAngles, + const USGSenseGloveInfo* GloveModel); + + /** + * Returns normalized flexions and abductions. + * + * @param SumAngles + * @param Normalizer + * @param OutFlexions + * @param OutAbductions + */ + static void NormalizeValues(const TArray& SumAngles, + const USGSenseGloveSensorNormalizer* Normalizer, + TArray& OutFlexions, TArray& OutAbductions); + +public: + /** + * Calculate Hand Angles from a GlovePose and relevant normalizers. + * + * @param GlovePose + * @param Normalizer + * @param NormalizedToAngles + * @param OutHandAngles + */ + static void CalculateHandAngles( + const USGSenseGlovePose* GlovePose, + const USGSenseGloveSensorNormalizer* Normalizer, const USGHandInterpolator* NormalizedToAngles, + TArray>& OutHandAngles); + + /** + * Calculate a HandPose based on a glovePose and a solver. + * + * @remarks Use this when you already have a GlovePose. + * + * @param GlovePose + * @param HandModel + * @param Normalizer + * @param NormalizedToAngles + * @param OutHandPose + */ + static void CalculateHandPose( + UObject* Outer, + const USGSenseGlovePose* GlovePose, const USGBasicHandModel* HandModel, + const USGSenseGloveSensorNormalizer* Normalizer, const USGHandInterpolator* NormalizedToAngles, + USGHandPose*& OutHandPose); + +protected: + /** + * + */ + USGSenseGlove(); + + /** + * Create a new instance of a Sense Glove. + */ + explicit USGSenseGlove(const USGSenseGloveInfo& Model); + +public: + /** + * The cast from underlying parent type constructor. + */ + explicit USGSenseGlove(const FSGDeviceImpl& SGDeviceImpl); + + /** + * The cast from underlying parent type constructor. + */ + explicit USGSenseGlove(const FSGHapticGloveImpl& HapticGloveImpl); + + /** + * The cast from underlying type constructor. + */ + explicit USGSenseGlove(const FSGSenseGloveImpl& SenseGloveImpl); + +protected: + /** + * The cast from underlying parent pointer type constructor. + */ + explicit USGSenseGlove(TSharedRef SGDeviceImpl); + + /** + * The cast from underlying parent pointer type constructor. + */ + explicit USGSenseGlove(TSharedRef HapticGloveImpl); + + /** + * The cast from underlying pointer type constructor. + */ + explicit USGSenseGlove(TSharedRef SenseGloveImpl); + +public: + /** + * The destructor. + */ + virtual ~USGSenseGlove() override; + +public: + /** + * The cast to underlying type method. + */ + TSharedRef ToSenseGloveImpl() const; + +public: + /** + * Get the DeviceType enumerator of this SenseGlove, used in DeviceList enumeration. + */ + virtual ESGDeviceType GetDeviceType() const override; + + /** + * Retrieve this Sense Glove's unique identifier. + */ + virtual FString GetDeviceId() const override; + + /** + * Retrieve this glove's hardware (sub) version. + */ + virtual FString GetHardwareVersion() const override; + + /** + * Retrieve this device's firmware version. + */ + virtual int32 GetFirmwareVersion() const override; + + /** + * Retrieve this device's sub-firmware version. + */ + virtual int32 GetSubFirmwareVersion() const override; + +public: + /** + * Check if this Sense Glove is right handed. + * + * @remarks While the variable is stored in SG_GloveModel, added direct access here since its frequently used. + */ + virtual bool IsRight() const override; + + /** + * + */ + virtual bool GetImuRotation(FQuat& OutImu) override; + + /** + * + */ + virtual bool GetImuRotation(FRotator& OutImu) override; + + /* + * Calculate a HandPose from this glove's latest Sensor Data. + * + * @param HandGeometry + * @param OutHandPose + */ + virtual bool GetHandPose(UObject* Outer, const USGBasicHandModel* HandGeometry, + USGHandPose*& OutHandPose) const override; + + /** + * Returns the Hand Angles calculated by this Sense Glove. Used for input for HandPoses, but can be used in and of + * itself. + * + * @param OutHandAngles + */ + virtual bool GetHandAngles(TArray>& OutHandAngles) const; + +public: + /* + * Retrieve the calibration status of this Sense Glove. + */ + virtual ESGHapticGloveCalibrationState GetCalibrationState() const override; + + /* + * Completes sensor Normalization on the Glove's end. + */ + virtual void EndCalibration() override; + + /* + * Completes sensor Normalization on the Glove's end. + */ + virtual void ResetCalibration() override; + +public: + /* + * Stop all haptic feedback effects playing on this device. + */ + virtual void StopHaptics() override; + + /** + * Stop only all vibrotactile feedback. + */ + virtual void StopVibrations() override; + + /** + * Flush all streaming haptic effects on the different fingers to the Glove. + */ + virtual bool SendHaptics() override; + +public: + /** + * Set the Force-Feedback value of a particular finger to a specific level. + * + * @param Levels01 Array containing the Force-Feedback levels, from 0.0 (no FFB) to 1.0. A value < 0.0f will be + * ignored. + * + * @remarks Devices that 'only' have on/off FFB will treat any value > 0.0 as 1.0. + */ + virtual bool QueueForceFeedbackLevels(const TArray& Levels01) override; + + /** + * Queue a list of force-feedback levels, between 0.0 and 1.0. Your list should be sorted from thumb to pinky. + * + * @param Finger Value will be clamped between [0...1], where 0.0 means no Force-Feedback, and 1.0 means + * full force-feedback. + * @param Level01 The finger to which to send the command. + */ + virtual bool QueueForceFeedbackLevel(int32 Finger, float Level01) override; + + /** + * Queue a vibrotactile level for each finger. + * + * @param Amplitudes + */ + virtual bool QueueVibroLevels(const TArray& Amplitudes) override; + + /** + * Queue a command to set the (continuous) vibration level at a specific location to a set amplitude. + * + * @param Location + * @param Level01 Value will be clamped between [0...1], where 0.0f means no vibration, and 1.0 means full + * vibration. + */ + virtual bool QueueVibroLevel(ESGHapticLocation Location, float Level01) override; + +public: + /** + * Retrieve the location of the glove origin, based on a reference location. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param OutGlovePosition The 3D Position of the glove, in mm, relative to your origin. + * @param OutGloveRotation The 3D Rotation of the glove, relative to your origin. + */ + virtual void GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const override; + + /** + * Retrieve the location of the glove origin, based on a reference location. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param OutGlovePosition The 3D Position of the glove, in mm, relative to your origin. + * @param OutGloveRotation The 3D Rotation of the glove, relative to your origin. + */ + virtual void GetGloveLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FRotator& OutGloveRotation) const override; + + /** + * Retrieve the location of the glove origin, based on a reference location. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param MountedOn Which finger module the hardware is mounted on. + * @param OutGlovePosition The 3D Position of the glove, in mm, relative to your origin. + * @param OutGloveRotation The 3D Rotation of the glove, relative to your origin. + */ + void GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, ESGFinger MountedOn, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const; + + /** + * Retrieve the location of the glove origin, based on a reference location. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param MountedOn Which finger module the hardware is mounted on. + * @param OutGlovePosition The 3D Position of the glove, in mm, relative to your origin. + * @param OutGloveRotation The 3D Rotation of the glove, relative to your origin. + */ + void GetGloveLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, ESGFinger MountedOn, + FVector& OutGlovePosition, FRotator& OutGloveRotation) const; + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param OutWristPosition The 3D Position of the wrist, in mm, relative to your origin. + * @param OutWristRotation The 3D Rotation of the wrist, relative to your origin. + * + * @remarks The simplest interface, using default offsets. + */ + virtual void GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) const override; + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + * + * @param ReferencePosition Position of the tracked object, in mm, relative to your origin. + * @param ReferenceRotation Rotation of the tracked object relative to your origin. + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param OutWristPosition The 3D Position of the wrist, in mm, relative to your origin. + * @param OutWristRotation The 3D Rotation of the wrist, relative to your origin. + * + * @remarks The simplest interface, using default offsets. + */ + virtual void GetWristLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FRotator& OutWristRotation) const override; + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + * + * @param ReferencePosition + * @param ReferenceRotation + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param GloveWristPositionOffset Position offset, in mm, from the glove origin to wrist (default = 0,0,-30 mm). + * @param GloveWristRotationOffset Rotation offset from the glove origin to wrist (default = 0,-5,0 degrees). + * @param OutWristPosition The 3D Position of the wrist, in mm, relative to your origin. + * @param OutWristRotation The 3D Rotation of the wrist, relative to your origin. + */ + void GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + const FVector& GloveWristPositionOffset, + const FQuat& GloveWristRotationOffset, + FVector& OutWristPosition, FQuat& OutWristRotation) const; + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + * + * @param ReferencePosition + * @param ReferenceRotation + * @param TrackingHardware The hardware mounted on the SenseGlove. + * @param GloveWristPositionOffset Position offset, in mm, from the glove origin to wrist (default = 0,0,-30 mm). + * @param GloveWristRotationOffset Rotation offset from the glove origin to wrist (default = 0,-5,0 degrees). + * @param OutWristPosition The 3D Position of the wrist, in mm, relative to your origin. + * @param OutWristRotation The 3D Rotation of the wrist, relative to your origin. + */ + void GetWristLocation(const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + const FVector& GloveWristPositionOffset, + const FRotator& GloveWristRotationOffset, + FVector& OutWristPosition, FRotator& OutWristRotation) const; + +public: + /** + * Retrieve this glove's hardware model, which contains its hardware data. + */ + USGSenseGloveInfo* GetGloveInfo(UObject* Outer) const; + + /** + * Offset from thimble to fingertip, used for Inverse Kinematics. + */ + TArray GetFingerThimbleOffsets() const; + + /** + * + * @param Finger + * @param Offset + */ + void SetFingerThimbleOffset(int32 Finger, const FVector& Offset); + + /** + * + */ + bool SupportsWristActuator() const; + +public: + /** + * Get the latest Sensor Data from this Sense Glove. + */ + bool GetSensorData(UObject* Outer, USGSenseGloveSensorData*& OutSensorData) const; + + /** + * Get the pose of this Sense Glove's hardware, based on its latest Sensor Data. + */ + bool GetGlovePose(UObject* Outer, USGSenseGlovePose*& OutGlovePose); + + /** + * Get the pose of this Sense Glove's hardware based on a set of Sensor Data. + */ + bool GetGlovePose(UObject* Outer, const USGSenseGloveSensorData* SensorData, USGSenseGlovePose*& OutGlovePose); + +public: + /** + * Queue a vibrotactle level for a specific finger. + * + * @param Finger + * @param Amplitude + */ + virtual bool QueueVibroLevel(int32 Finger, float Amplitude); + + /** + * Queue a command for the SenseGlove Thumper actuator. + * + * @param Command + */ + virtual bool QueueThumperCommand(ESGSenseGloveThumperCommand Command); + +public: + /** + * Create a string representation of this device for reporting purposes. + */ + virtual FString ToString() const override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGloveInfo.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGloveInfo.h new file mode 100644 index 0000000..153fb3a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGloveInfo.h @@ -0,0 +1,317 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Glove information taken from the Sense Glove. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGTypes/SGCoreTypes.h" +#include "SGTypes/SGVectorArray.h" + +#include "SGSenseGloveInfo.generated.h" + +class FSGSenseGloveInfoImpl; + +/** + * Glove Information taken from a SenseGlove. Contains everything from unique ID, firmware version, etc. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGSenseGloveInfo final : public UObject +{ + GENERATED_BODY() + +public: + static USGSenseGloveInfo* NewSenseGloveInfo( + UObject* Outer, const FSGSenseGloveInfoImpl& SenseGloveInfoImpl); + +public: + /** + * The default constructor. + */ + static USGSenseGloveInfo* NewSenseGloveInfo(UObject* Outer); + + /** + * Create a new Sense Glove device model. + */ + static USGSenseGloveInfo* NewSenseGloveInfo( + UObject* Outer, const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion, + bool bRightHanded, int32 NumberOfSensors, const FQuat& ImuCorrection, + const TArray& StartPositions, const TArray& StartRotations, + const TArray>& GloveLengths, const TArray& Functions); + + /** + * Create a new Sense Glove device model. + */ + static USGSenseGloveInfo* NewSenseGloveInfo( + UObject* Outer, const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion, + bool bRightHanded, int32 NumberOfSensors, const FRotator& ImuCorrection, + const TArray& StartPositions, const TArray& StartRotations, + const TArray>& GloveLengths, const TArray& Functions); + + /** + * Create a new Sense Glove device model. + */ + static USGSenseGloveInfo* NewSenseGloveInfo( + UObject* Outer, const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion, + bool bRightHanded, int32 NumberOfSensors, const FQuat& ImuCorrection, + const TArray& StartPositions, const TArray& StartRotations, + const TArray& GloveLengths, const TArray& Functions); + + /** + * Create a new Sense Glove device model. + */ + static USGSenseGloveInfo* NewSenseGloveInfo( + UObject* Outer, const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion, + bool bRightHanded, int32 NumberOfSensors, const FRotator& ImuCorrection, + const TArray& StartPositions, const TArray& StartRotations, + const TArray& GloveLengths, const TArray& Functions); + +public: + /** + * Create an instance of the SGModel from its string representation. + */ + static bool Parse(UObject* Outer, const FString& ConstantsString, USGSenseGloveInfo*& OutGloveInfo, + bool bUpdateOldModels = true); + + /** + * Deserialize a HandProfile back into usable values. + */ + static USGSenseGloveInfo* Deserialize(UObject* Outer, const FString& SerializedString); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * The default constructor. + */ + USGSenseGloveInfo(); + + /** + * Create a new Sense Glove device model. + */ + USGSenseGloveInfo(const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion, + bool bRightHanded, int32 NumberOfSensors, const FQuat& ImuCorrection, + const TArray& StartPositions, const TArray& StartRotations, + const TArray>& GloveLengths, const TArray& Functions); + + /** + * Create a new Sense Glove device model. + */ + USGSenseGloveInfo(const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion, + bool bRightHanded, int32 NumberOfSensors, const FRotator& ImuCorrection, + const TArray& StartPositions, const TArray& StartRotations, + const TArray>& GloveLengths, const TArray& Functions); + + /** + * Create a new Sense Glove device model. + */ + USGSenseGloveInfo(const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion, + bool bRightHanded, int32 NumberOfSensors, const FQuat& ImuCorrection, + const TArray& StartPositions, const TArray& StartRotations, + const TArray& GloveLengths, const TArray& Functions); + + /** + * Create a new Sense Glove device model. + */ + USGSenseGloveInfo(const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion, + bool bRightHanded, int32 NumberOfSensors, const FRotator& ImuCorrection, + const TArray& StartPositions, const TArray& StartRotations, + const TArray& GloveLengths, const TArray& Functions); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGSenseGloveInfo(const FSGSenseGloveInfoImpl& SenseGloveInfoImpl); + +public: + /** + * The destructor. + */ + virtual ~USGSenseGloveInfo() override; + +protected: + /** + * Allows to set the underlying object after construction. + */ + void SetSenseGloveInfoImpl(const FSGSenseGloveInfoImpl& SenseGloveInfoImpl); + +public: + /** + * The cast to underlying type method. + */ + const FSGSenseGloveInfoImpl& ToSenseGloveInfoImpl() const; + +protected: + /** + * The non-const cast to underlying type method. + */ + FSGSenseGloveInfoImpl& ToSenseGloveInfoImpl(); + +public: + /** + * Unique identifier of this device. + */ + FString GetDeviceId() const; + + /** + * Hardware (sub) version of this Sense Glove Device. + */ + FString GetHardwareVersion() const; + + /** + * Firmware version running on the device's MicroController. + */ + int32 GetFirmwareVersion() const; + + /** + * Sub-Firmware version running on the device's MicroController. + */ + int32 GetSubFirmwareVersion() const; + + /** + * Check if this Sense Glove belongs to a left or right hand. + */ + bool IsRight() const; + + /** + * The number of Sensors in this SenseGlove. + */ + int32 GetNumberOfSensors() const; + + /** + * The IMU correction of this Sense Glove. + */ + FQuat GetImuCorrectionQ() const; + + /** + * The IMU correction of this Sense Glove. + */ + FRotator GetImuCorrection() const; + + /** + * The starting positions of each Sense Glove finger, relative to the glove origin. + */ + TArray GetStartPositions() const; + + /** + * The starting rotations of each Sense Glove finger, relative to the glove origin. + */ + TArray GetStartRotationsQ() const; + + /** + * The starting rotations of each Sense Glove finger, relative to the glove origin. + */ + TArray GetStartRotations() const; + + /** + * The lengths of each Sense Glove finger section, in cm. + */ + TArray> GetGloveLengths() const; + + /** + * Whether this device has a specific function (T/F). + */ + TArray GetFunctions() const; + +public: + /** + * The starting position of one Sense Glove finger, relative to the glove origin. + */ + FVector GetStartPosition(ESGFinger Finger) const; + + /** + * The starting rotation of one Sense Glove finger, relative to the glove origin. + */ + FQuat GetStartRotationQ(ESGFinger Finger) const; + + /** + * The starting rotation of one Sense Glove finger, relative to the glove origin. + */ + FRotator GetStartRotation(ESGFinger Finger) const; + + /** + * The lengths of one Sense Glove finger's sections, in cm. + */ + TArray GetGloveLengths(ESGFinger Finger) const; + +public: + /** + * Place incoming sensor data into the right format, according to this glove's model. + */ + TArray> ToGloveAngles(const TArray>& SensorAngles) const; + + /** + * Returns true if this SG_Model has the same values as another. + */ + bool Equals(const USGSenseGloveInfo* SenseGloveInfo) const; + +public: + /** + * Create a string representation for fast logging. + */ + FString ToString(bool bShortNotation) const; + + /** + * Create a string representation for logging. If shortNotation is false, all values are reported. + */ + FString ToString() const; + + /** + * Serialize this HandProfile into a string representation. + */ + FString SGSerialize() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGlovePose.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGlovePose.h new file mode 100644 index 0000000..ebf6a0e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGlovePose.h @@ -0,0 +1,259 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Contains position and rotation data of a SenseGlove's exoskeleton, along + * with accessors for relevant variables. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGTypes/SGQuatArray.h" +#include "SGTypes/SGRotatorArray.h" +#include "SGTypes/SGVectorArray.h" + +#include "SGSenseGlovePose.generated.h" + +class FSGSenseGlovePoseImpl; +class USGSenseGloveInfo; + +/** + * Represents a pose of a Sense Glove exoskeleton. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGSenseGlovePose final : public UObject +{ + GENERATED_BODY() + +public: + static USGSenseGlovePose* NewSenseGlovePose( + UObject* Outer, const FSGSenseGlovePoseImpl& SenseGlovePoseImpl); + +public: + /** + * The basic constructor. + */ + static USGSenseGlovePose* NewSenseGlovePose(UObject* Outer); + + /** + * Creates a new instance of a SenseGlovePose. + */ + static USGSenseGlovePose* NewSenseGlovePose(UObject* Outer, bool bRightHanded, + const TArray>& JointPositions, + const TArray>& JointRotations, + const TArray>& GloveAngles); + + /** + * Creates a new instance of a SenseGlovePose. + */ + static USGSenseGlovePose* NewSenseGlovePose(UObject* Outer, bool bRightHanded, + const TArray>& JointPositions, + const TArray>& JointRotations, + const TArray>& GloveAngles); + + /** + * Creates a new instance of a SenseGlovePose. + */ + static USGSenseGlovePose* NewSenseGlovePose(UObject* Outer, bool bRightHanded, + const TArray& JointPositions, + const TArray& JointRotations, + const TArray& GloveAngles); + + /** + * Creates a new instance of a SenseGlovePose. + */ + static USGSenseGlovePose* NewSenseGlovePose(UObject* Outer, bool bRightHanded, + const TArray& JointPositions, + const TArray& JointRotations, + const TArray& GloveAngles); + +public: + /** + * Returns an idle pose for the Sense Glove if no data can be found. + */ + static USGSenseGlovePose* IdlePose(UObject* Outer, const USGSenseGloveInfo* GloveInfo); + + /** + * Deserialize a GlovePose back into usable values. + */ + static USGSenseGlovePose* Deserialize(UObject* Outer, const FString& SerializedString); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * The basic constructor. + */ + USGSenseGlovePose(); + + /** + * Creates a new instance of a SenseGlovePose. + */ + USGSenseGlovePose(bool bRightHanded, + const TArray>& JointPositions, + const TArray>& JointRotations, + const TArray>& GloveAngles); + + /** + * Creates a new instance of a SenseGlovePose. + */ + USGSenseGlovePose(bool bRightHanded, + const TArray>& JointPositions, + const TArray>& JointRotations, + const TArray>& GloveAngles); + + /** + * Creates a new instance of a SenseGlovePose. + */ + USGSenseGlovePose(bool bRightHanded, + const TArray& JointPositions, + const TArray& JointRotations, + const TArray& GloveAngles); + + /** + * Creates a new instance of a SenseGlovePose. + */ + USGSenseGlovePose(bool bRightHanded, + const TArray& JointPositions, + const TArray& JointRotations, + const TArray& GloveAngles); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGSenseGlovePose(const FSGSenseGlovePoseImpl& SenseGlovePoseImpl); + +public: + /** + * The destructor. + */ + virtual ~USGSenseGlovePose() override; + +protected: + /** + * Allows to set the underlying object after construction. + */ + void SetSenseGlovePoseImpl(const FSGSenseGlovePoseImpl& SenseGlovePoseImpl); + +public: + /** + * The cast to underlying type method. + */ + const FSGSenseGlovePoseImpl& ToSenseGlovePoseImpl() const; + +public: + /** + * Whether this Glove Pose was created for be a right- or left hand, or not. + */ + bool IsRight() const; + + /** + * Positions of each glove joint, relative to the Glove's Origin. + */ + TArray> GetJointPositions() const; + + /** + * Quaternion rotation of each glove joint, relative to the Glove Origin. + */ + TArray> GetJointRotationsQ() const; + + /** + * Rotation of each glove joint, relative to the Glove Origin. + */ + TArray> GetJointRotations() const; + + /** + * Glove joint angles in euler notation, relative to the last segment. + * + * @remarks Essentially sensor angles, though placed in their proper xyz notation. + */ + TArray> GetGloveAngles() const; + +public: + /** + * The position of the tip of the 'thimbles', the furthest link on each glove link. + */ + TArray GetThimblePositions() const; + + /** + * The (quaternion) rotation of the 'thimbles', the furthest link on each link. + */ + TArray GetThimbleRotationsQ() const; + + /** + * The rotation of the 'thimbles', the furthest link on each link. + */ + TArray GetThimbleRotations() const; + + /** + * Sum of the Sensor angles in each (xyz) direction. "Total Pronation / Flexion / Abduction". + */ + TArray GetTotalGloveAngles() const; + + /** + * Calculate fingertip positions, knowing the offset between thimble and fingertips. + */ + TArray CalculateFingertips(const TArray& FingerOffsets) const; + + /** + * Returns true if this glove pose equals another. + */ + bool Equals(const USGSenseGlovePose* SenseGlovePose) const; + +public: + /** + * Returns a user-friendly string representation of this GlovePose for reporting. + */ + FString ToString(bool bShortFormat = false) const; + + /** + * Serialize this GlovePose into a string representation. + */ + FString SGSerialize() const; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGloveSensorData.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGloveSensorData.h new file mode 100644 index 0000000..de7fe88 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGloveSensorData.h @@ -0,0 +1,232 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Parsed sensor data coming form a Sense Glove. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "Math/Quat.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGCore/SGSenseGloveInfo.h" +#include "SGTypes/SGFloatArray.h" + +#include "SGSenseGloveSensorData.generated.h" + +class FSGSenseGloveSensorDataImpl; + +/** + * Sense Glove Sensor Data, parsed from a sensor string. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGSenseGloveSensorData final : public UObject +{ + GENERATED_BODY() + +public: + static USGSenseGloveSensorData* NewSenseGloveSensorData( + UObject* Outer, const FSGSenseGloveSensorDataImpl& SenseGloveSensorDataImpl); + +public: + /** + * The basic constructor. + */ + static USGSenseGloveSensorData* NewSenseGloveSensorData(UObject* Outer); + + /** + * Create a new instance of a Sense Glove Sensor Data class. + */ + static USGSenseGloveSensorData* NewSenseGloveSensorData( + UObject* Outer, const TArray>& SensorAngles, + const FQuat& ImuRotation, int32 ParsedValues, bool bImuParsed); + + /** + * Create a new instance of a Sense Glove Sensor Data class. + */ + static USGSenseGloveSensorData* NewSenseGloveSensorData( + UObject* Outer, const TArray>& SensorAngles, + const FRotator& ImuRotation, int32 ParsedValues, bool bImuParsed); + + /** + * Create a new instance of a Sense Glove Sensor Data class. + */ + static USGSenseGloveSensorData* NewSenseGloveSensorData( + UObject* Outer, const TArray& SensorAngles, + const FQuat& ImuRotation, int32 ParsedValues, bool bImuParsed); + + /** + * Create a new instance of a Sense Glove Sensor Data class. + */ + static USGSenseGloveSensorData* NewSenseGloveSensorData( + UObject* Outer, const TArray& SensorAngles, + const FRotator& ImuRotation, int32 ParsedValues, bool bImuParsed); + +public: + /** + * Returns sensor data with no values. + */ + static USGSenseGloveSensorData* Empty(UObject* Outer); + + /** + * Deserialize Sense Glove sensor data from a raw char[] received through IPC. + */ + static USGSenseGloveSensorData* Parse(UObject* Outer, const FString& RawData, const USGSenseGloveInfo* GloveInfo); + + /** + * Deserialize a HandProfile back into usable values. + */ + static USGSenseGloveSensorData* Deserialize(UObject* Outer, const FString& SerializedString); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * The basic constructor. + */ + USGSenseGloveSensorData(); + + /** + * Create a new instance of a Sense Glove Sensor Data class. + */ + USGSenseGloveSensorData(const TArray>& SensorAngles, + const FQuat& ImuRotation, int32 ParsedValues, bool bImuParsed); + + /** + * Create a new instance of a Sense Glove Sensor Data class. + */ + USGSenseGloveSensorData(const TArray>& SensorAngles, + const FRotator& ImuRotation, int32 ParsedValues, bool bImuParsed); + + /** + * Create a new instance of a Sense Glove Sensor Data class. + */ + USGSenseGloveSensorData(const TArray& SensorAngles, + const FQuat& ImuRotation, int32 ParsedValues, bool bImuParsed); + + /** + * Create a new instance of a Sense Glove Sensor Data class. + */ + USGSenseGloveSensorData(const TArray& SensorAngles, + const FRotator& ImuRotation, int32 ParsedValues, bool bImuParsed); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGSenseGloveSensorData(const FSGSenseGloveSensorDataImpl& SenseGloveSensorDataImpl); + +public: + /** + * The destructor. + */ + virtual ~USGSenseGloveSensorData() override; + +protected: + /** + * Allows to set the underlying object after construction. + */ + void SetSenseGloveSensorDataImpl(const FSGSenseGloveSensorDataImpl& SenseGloveSensorDataImpl); + +public: + /** + * The cast to underlying type method. + */ + const FSGSenseGloveSensorDataImpl& ToSenseGloveSensorDataImpl() const; + +public: + /** + * Glove angles in degrees, sorted by finger, from proximal to distal. + */ + TArray> GetSensorAngles() const; + + /** + * Get the glove angles of a specific finger segment. + */ + TArray GetSensorAngles(ESGFinger Finger) const; + + /** + * Returns all glove angles in a sequence, without splitting them per finger. + */ + TArray GetAngleSequence() const; + + /** + * + */ + FQuat GetImuRotationQ() const; + + /** + * + */ + FRotator GetImuRotation() const; + + /** + * Check how many values have been parsed from the Sensor String. + */ + int32 GetParsedValues() const; + +public: + /** + * Check if the IMU was properly parsed. + */ + bool IsImuParsed() const; + +public: + /** + * Returns true if the values of both data are equal. + */ + bool Equals(const USGSenseGloveSensorData* SenseGloveSensorData) const; + +public: + /** + * Retrieve a simple representation of this sensor data for debugging purposes. + */ + FString ToString() const; + + /** + * Serialize this HandProfile into a string representation. + */ + FString SGSerialize() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGloveSensorNormalizer.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGloveSensorNormalizer.h new file mode 100644 index 0000000..317491a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGloveSensorNormalizer.h @@ -0,0 +1,137 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Internal class that acts as a sort of 'in between' handProfile. This class + * converts SG Dk1 Angles into 'normalized data' - between 0 .. 1. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGSenseGloveSensorNormalizer.generated.h" + +class FSGSenseGloveSensorNormalizerImpl; + +/** + * Internal class to hold 'Threshold Commands' for specific fingers. Can be sent to a Device, or used internally. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGSenseGloveSensorNormalizer final : public UObject +{ + GENERATED_BODY() + +public: + static USGSenseGloveSensorNormalizer* NewSenseGloveSensorNormalizer( + UObject* Outer, const FSGSenseGloveSensorNormalizerImpl& SenseGloveSensorNormalizerImpl); + +public: + /** + * The default constructor. + */ + static USGSenseGloveSensorNormalizer* NewSenseGloveSensorNormalizer(UObject* Outer); + + /** + * Create a new instance of SenseGloveSensorNormalizer. + */ + static USGSenseGloveSensorNormalizer* NewSenseGloveSensorNormalizer( + UObject* Outer, bool bRightHanded); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * The default constructor. + */ + USGSenseGloveSensorNormalizer(); + + /** + * Creates a new SenseGlove Sensor Normalizer based off the device's sensor angles. + * + * @param bRightHanded + */ + explicit USGSenseGloveSensorNormalizer(bool bRightHanded); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGSenseGloveSensorNormalizer(const FSGSenseGloveSensorNormalizerImpl& SenseGloveSensorNormalizerImpl); + +public: + /** + * The destructor. + */ + virtual ~USGSenseGloveSensorNormalizer() override; + +protected: + /** + * Allows to set the underlying object after construction. + */ + void SetSenseGloveSensorNormalizerImpl(const FSGSenseGloveSensorNormalizerImpl& SenseGloveSensorNormalizerImpl); + +public: + /** + * The cast to underlying type method. + */ + const FSGSenseGloveSensorNormalizerImpl& ToSenseGloveSensorNormalizerImpl() const; + +public: + /** + * Normalize a finger's flexion, based on the total flexion of the exoskeleton. + * + * @param Finger + * @param SumFlexionAngles + */ + float NormalizeFlexion(int32 Finger, float SumFlexionAngles) const; + + /** + * Normalize a finger's abduction, based on the total abduction of the exoskeleton. + * + * @param Finger + * @param SumAbductionAngles + */ + float NormalizeAbduction(int32 Finger, float SumAbductionAngles) const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGloveVars.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGloveVars.h new file mode 100644 index 0000000..90d7980 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSenseGloveVars.h @@ -0,0 +1,121 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Contains enumerators and classes to aid in Sense Glove Deserialization. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" +#include "Math/Quat.h" +#include "Math/Vector.h" + +#include "SGSenseGloveVars.generated.h" + +class USGSenseGloveInfo; + +/** + * "Database" class containing Sense Glove internal variables. + */ +USTRUCT() +struct SENSEGLOVECORE_API FSGSenseGloveVars +{ + GENERATED_BODY() + +public: + /** + * Retrieve a basic ConstantsString for a Sense Glove of a specific Hardware Version. Used for debugging / unit + * tests. + * + * @returns Returns an empty string when an invalid glove version is requested. + */ + static FString GetStandardConstantsString(const FString& HardwareVersion, float FirmwareVersion, bool bRightHanded); + + /** + * Retrieve an example sensor string of a Sense Glove with a particular hardware- and firmware version. + */ + static FString GetSensorString(const FString& HardwareVersion, float FirmwareVersion); + + /** + * Retrieve the starting positions of a particular Sense Glove. + */ + static TArray GetStartPositions(const FString& HardwareVersion, bool bRightHanded); + + /** + * Retrieve the starting rotations of a particular Sense Glove. + */ + static TArray GetStartRotationsQ(const FString& HardwareVersion, bool bRightHanded); + + /** + * Retrieve the starting rotations of a particular Sense Glove. + */ + static TArray GetStartRotations(const FString& HardwareVersion, bool bRightHanded); + + /** + * Retrieve the glove finger lengths of a particular Sense Glove. + */ + static TArray> GetGloveLengths(const FString& HardwareVersion); + + /** + * Get the number of sensors of a SenseGlove. + */ + static int32 GetSensors(const FString& HardwareVersion); + + /** + * Get the default IMUCorrection for the SenseGlove. + */ + static FQuat GetImuCorrectionQ(const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion); + + /** + * Get the default IMUCorrection for the SenseGlove. + */ + static FRotator GetImuCorrection(const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion); + + /** + * Check all functionality of a SenseGlove. + */ + static TArray GetFunctions(const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion); + + /** + * Generate a custom glove info. + */ + static USGSenseGloveInfo* GenerateGloveModel(UObject* Outer, const FString& HardwareVersion, int32 FirmwareVersion, + int32 SubFirmwareVersion, bool bRightHanded); + + /** + * Generate a custom glove info. + */ + static USGSenseGloveInfo* GenerateGloveModel(UObject* Outer, const FString& HardwareVersion, int32 FirmwareVersion, + int32 SubFirmwareVersion, bool bRightHanded, const FString& CustomId); +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSensorNormalization.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSensorNormalization.h new file mode 100644 index 0000000..f2f676c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGSensorNormalization.h @@ -0,0 +1,189 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * A script to normalize any set of floating point values by looking at their + * minimum and maximum values. Used for automagical calibration. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGSensorNormalization.generated.h" + +class FSGSensorNormalizationImpl; + +/** + * Internal class to hold 'Threshold Commands' for specific fingers. Can be sent to a Device, or used internally. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGSensorNormalization final : public UObject +{ + GENERATED_BODY() + +public: + static USGSensorNormalization* NewSensorNormalization( + UObject* Outer, const FSGSensorNormalizationImpl& SensorNormalizationImpl); + +public: + /** + * The default constructor. + */ + static USGSensorNormalization* NewSensorNormalization(UObject* Outer); + + /** + * Create a new instance of SensorNormalization. + */ + static USGSensorNormalization* NewSensorNormalization( + UObject* Outer, const TArray& MovementRanges); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * The default constructor. + */ + USGSensorNormalization(); + + /** + * Create a new instance of SensorNormalization. + */ + explicit USGSensorNormalization(const TArray& MovementRanges); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGSensorNormalization(const FSGSensorNormalizationImpl& SensorNormalizationImpl); + +public: + /** + * The destructor. + */ + virtual ~USGSensorNormalization() override; + +protected: + /** + * Allows to set the underlying object after construction. + */ + void SetSensorNormalizationImpl(const FSGSensorNormalizationImpl& SensorNormalizationImpl); + +public: + /** + * The cast to underlying type method. + */ + const FSGSensorNormalizationImpl& ToSensorNormalizationImpl() const; + +public: + /** + * If true, the normalization collection is active. If false, we're no longer collecting min / max values. + */ + bool CollectsNormalization() const; + + /** + * + * @param bCollectNormalization + */ + void SetCollectNormalization(bool bCollectNormalization); + +public: + /** + * The amount of items in this collector Useful for FOR loops. + */ + int32 GetLength() const; + + /** + * The amount of values that have moved the appropriate amount. + */ + int32 GetMoveCount() const; + + /** + * Returns true if all sensors are allowed to move. + */ + bool AllSensorsMoving() const; + + /** + * Reset the normalization of values. + */ + void ResetNormalization(); + + /** + * + * @param Value + * @param Index + */ + void UpdateNormalization(float Value, int32 Index); + + /** + * Normalize a value on a specific index, and update Normalization while you're at it. + * + * @param Value + * @param Index + */ + float NormalizeValue(float Value, int32 Index); + + /** + * Update and Normalize a set of values, provided this is the same length. + * + * @param Values + */ + TArray NormalizeValues(const TArray& Values); + + /** + * Returns true if a sensor on this index has moved enough. + * + * @param Index + */ + bool MovedEnough(int32 Index) const; + + /** + * Turn a value from 0 .. 1 back into [minValue ... maxValue] range for the Nova Glove. + * + * @param Value01 + * @param Index + * @param FallbackValue + */ + float Denormalize(float Value01, int32 Index, float FallbackValue = 1.0f) const; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGThresholdCommand.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGThresholdCommand.h new file mode 100644 index 0000000..c38b6b4 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGThresholdCommand.h @@ -0,0 +1,183 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Internal class to hold 'Threshold Commands' for specific fingers. Can be sent + * to a Device, or used internally. + * Threshold Commands tell our device "When your sensor data is higher than this + * threshold, lock FFB. Otherwise, turn it back off". + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGThresholdCommand.generated.h" + +class FSGThresholdCommandImpl; + +/** + * Interface for Nova 2.0 Gloves. A soft glove with detachable force-feedback and sensor module, and active contact + * feedback in the front strap. + */ +UCLASS(BlueprintType) +class SENSEGLOVECORE_API USGThresholdCommand final : public UObject +{ + GENERATED_BODY() + +public: + static USGThresholdCommand* NewThresholdCommand( + UObject* Outer, const FSGThresholdCommandImpl& ThresholdCommandImpl); + +public: + /** + * The default constructor. + */ + static USGThresholdCommand* NewThresholdCommand(UObject* Outer); + + /** + * Create a new instance of ThresholdCommand. + */ + static USGThresholdCommand* NewThresholdCommand( + UObject* Outer, + const TArray& AffectedFingers, const TArray& ThresholdValues); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * The default constructor. + */ + USGThresholdCommand(); + + /** + * Create a new instance of ThresholdCommand. + */ + USGThresholdCommand( + const TArray& AffectedFingers, const TArray& ThresholdValues); + +public: + /** + * The cast from underlying type constructor. + */ + explicit USGThresholdCommand(const FSGThresholdCommandImpl& ThresholdCommandImpl); + +public: + /** + * The destructor. + */ + virtual ~USGThresholdCommand() override; + +protected: + /** + * Allows to set the underlying object after construction. + */ + void SetThresholdCommandImpl(const FSGThresholdCommandImpl& ThresholdCommandImpl); + +public: + /** + * The cast to underlying type method. + */ + const FSGThresholdCommandImpl& ToThresholdCommandImpl() const; + +public: + /** + * Retrieve the threshold of a particular finger. + * + * @param Finger + */ + float GetThreshold(int32 Finger) const; + + /** + * Activates the threshold for a finger at a particular value. + * + * @param Finger + * @param ThresholdValue + */ + void SetThreshold(int32 Finger, float ThresholdValue); + + TArray GetThresholds() const; + + /** + * Activates the threshold for a finger at a particular value. + * + * @param AffectedFingers + * @param ThresholdValues + */ + void SetThresholds(const TArray& AffectedFingers, const TArray& ThresholdValues); + + /** + * If true, the threshold on a finger should be active. + * + * @param Finger + */ + bool GetFingerActive(int32 Finger) const; + + TArray GetActiveFingers() const; + + /** + * Deactivates Threshold Mode for a particular finger. + * + * @param Finger + */ + void ClearThreshold(int32 Finger); + + /** + * Disables Threshold mode for all fingers. Clears the ActiveFingers, but keeps the Thresholds value for now, in + * case you want to re-apply them later. + */ + void ClearThresholds(); + +public: + /** + * Returns true if both values are exactly equal. + */ + bool Equals(const USGThresholdCommand* ThresholdCommand) const; + +public: + /** + * Print the contents of this Threshold Command. If inactive, a '-' is shown. + */ + FString ToString() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGTracking.h b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGTracking.h new file mode 100644 index 0000000..b416fce --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/Public/SGCore/SGTracking.h @@ -0,0 +1,618 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "Math/Quat.h" +#include "Math/Vector.h" + +#include "SGTypes/SGCoreTypes.h" + +#include "SGTracking.generated.h" + +/** + * + */ +USTRUCT() +struct SENSEGLOVECORE_API FSGTracking +{ + GENERATED_BODY() + +public: + /** + * Knowing a position & rotation in 3D space, calculate a relative location based on offsets. + */ + static void CalculateLocation( + const FVector& TrackedPosition, const FQuat& TrackedRotation, + const FVector& PositionOffset, const FQuat& RotationOffset, + FVector& OutNewPosition, FQuat& OutNewRotation); + + /** + * Knowing a position & rotation in 3D space, calculate a relative location based on offsets. + */ + static void CalculateLocation( + const FVector& TrackedPosition, const FRotator& TrackedRotation, + const FVector& PositionOffset, const FRotator& RotationOffset, + FVector& OutNewPosition, FRotator& OutNewRotation); + + /** + * Positional offset from each finger to the glove origin. + */ + static TArray GetSenseGloveFingerToGlovePositionOrigin(); + + /** + * + */ + static TArray GetSenseGloveFingerToGloveRotationOriginQ(); + + /** + * + */ + static TArray GetSenseGloveFingerToGloveRotationOrigin(); + + /** + * Default position offset from glove origin to wrist location, in cm. + */ + static FVector GetSenseGloveWristPositionOffset(); + + /** + * Default rotation offset from glove origin to wrist location. + */ + static FQuat GetSenseGloveWristRotationOffsetQ(); + + /** + * Default rotation offset from glove origin to wrist location. + */ + static FRotator GetSenseGloveWristRotationOffset(); + + /** + * Get the position and rotation offsets to go from the glove origin to the mounted position. + * + * @remarks Based on CAD. needs to be inverted when going from tracker to glove origin. + */ + static void GetSenseGloveMountOffset(bool bRightHanded, ESGFinger ToFinger, + FVector& OutIPosition, FQuat& OutIRotation); + + /** + * Get the position and rotation offsets to go from the glove origin to the mounted position. + * + * @remarks Based on CAD. needs to be inverted when going from tracker to glove origin. + */ + static void GetSenseGloveMountOffset(bool bRightHanded, ESGFinger ToFinger, + FVector& OutIPosition, FRotator& OutIRotation); + + /** + * Get the offset to get from the TrackedHardware to a SenseGlove mounting location. Combined with Glove-Mount + * offset to get the glove location. + */ + static void GetSenseGloveTrackerMountOffset(ESGPositionalTrackingHardware Hardware, bool bRightHanded, + FVector& OutPositionOffset, FQuat& OutRotationOffset); + + /** + * Get the offset to get from the TrackedHardware to a SenseGlove mounting location. Combined with Glove-Mount + * offset to get the glove location. + */ + static void GetSenseGloveTrackerMountOffset(ESGPositionalTrackingHardware Hardware, bool bRightHanded, + FVector& OutPositionOffset, FRotator& OutRotationOffset); + + /** + * Vive Tracker origin to Finger rotational offset. + */ + static FVector GetSenseGloveViveToAttachPosition(); + + /** + * Vive Tracker origin to Finger rotational offset. + */ + static FQuat GetSenseGloveViveToAttachRotationQ(); + + /** + * Vive Tracker origin to Finger rotational offset. + */ + static FRotator GetSenseGloveViveToAttachRotation(); + + /** + * Oculus Touch origin to Finger rotational offset. + */ + static FVector GetSenseGloveOculusTouchToAttachPosition(); + + /** + * Oculus Touch origin to Finger rotational offset. + */ + static FQuat GetSenseGloveOculusTouchToAttachRotationQ(); + + /** + * Oculus Touch origin to Finger rotational offset. + */ + static FRotator GetSenseGloveOculusTouchToAttachRotation(); + + /** + * Positional offset between Nova Glove Origin and Wrist. + */ + static FVector GetNovaToWristPositionOffset(); + + /** + * Rotational offset between Nova Glove Origin and Wrist. + */ + static FQuat GetNovaToWristRotationOffsetQ(); + + /** + * Rotational offset between Nova Glove Origin and Wrist. + */ + static FRotator GetNovaToWristRotationOffset(); + + /** + * + */ + static FVector GetRightNovaViveToAttachPosition(); + + /** + * + */ + static FQuat GetRightNovaViveToAttachRotationQ(); + + /** + * + */ + static FRotator GetRightNovaViveToAttachRotation(); + + /** + * + */ + static FVector GetLeftNovaViveToAttachPosition(); + + /** + * + */ + static FQuat GetLeftNovaViveToAttachRotationQ(); + + /** + * + */ + static FRotator GetLeftNovaViveToAttachRotation(); + + /** + * + */ + static FVector GetRightNovaQuest2ToAttachPosition(); + + /** + * + */ + static FQuat GetRightNovaQuest2ToAttachRotationQ(); + + /** + * + */ + static FRotator GetRightNovaQuest2ToAttachRotation(); + + /** + * + */ + static FVector GetLeftNovaQuest2ToAttachPosition(); + + /** + * + */ + static FQuat GetLeftNovaQuest2ToAttachRotationQ(); + + /** + * + */ + static FRotator GetLeftNovaQuest2ToAttachRotation(); + + /** + * @remarks Left is a mirror, so we only need R pos. + */ + static FVector GetRightNovaPico2ToAttachPosition(); + + /** + * + */ + static FQuat GetRightNovaPico2ToAttachRotationQ(); + + /** + * + */ + static FRotator GetRightNovaPico2ToAttachRotation(); + + /** + * + */ + static FQuat GetLeftNovaPico2ToAttachRotationQ(); + + /** + * + */ + static FRotator GetLeftNovaPico2ToAttachRotation(); + + /** + * + */ + static FVector GetRightNovaQuestProToAttachPosition(); + + /** + * + */ + static FQuat GetRightNovaQuestProToAttachRotationQ(); + + /** + * + */ + static FRotator GetRightNovaQuestProToAttachRotation(); + + /** + * + */ + static FVector GetLeftNovaQuestProToAttachPosition(); + + /** + * + */ + static FQuat GetLeftNovaQuestProToAttachRotationQ(); + + /** + * + */ + static FRotator GetLeftNovaQuestProToAttachRotation(); + + /** + * + */ + static FVector GetRightNovaViveFocus3ToAttachPosition(); + + /** + * + */ + static FQuat GetRightNovaViveFocus3ToAttachRotationQ(); + + /** + * + */ + static FRotator GetRightNovaViveFocus3ToAttachRotation(); + + /** + * + */ + static FVector GetLeftNovaViveFocus3ToAttachPosition(); + + /** + * + */ + static FQuat GetLeftNovaViveFocus3ToAttachRotationQ(); + + /** + * + */ + static FRotator GetLeftNovaViveFocus3ToAttachRotation(); + + /** + * + */ + static FVector GetRightNovaQuest3ToAttachPosition(); + + /** + * + */ + static FQuat GetRightNovaQuest3ToAttachRotationQ(); + + /** + * + */ + static FRotator GetRightNovaQuest3ToAttachRotation(); + + /** + * + */ + static FVector GetLeftNovaQuest3ToAttachPosition(); + + /** + * + */ + static FQuat GetLeftNovaQuest3ToAttachRotationQ(); + + /** + * + */ + static FRotator GetLeftNovaQuest3ToAttachRotation(); + + /** + * Returns the Offsets that will bring us from the Nova origin to the wrist position. + */ + static void GetNovaGloveWristOffset(bool bRightHanded, FVector& OutPositionOffset, FQuat& OutRotationOffset); + + /** + * Returns the Offsets that will bring us from the Nova origin to the wrist position. + */ + static void GetNovaGloveWristOffset(bool bRightHanded, FVector& OutPositionOffset, FRotator& OutRotationOffset); + + /** + * Retrieves Offsets for a particular device. + * + * @param Hardware + * @param bRightHanded + * @param OutPositionOffset + * @param OutRotationOffset + */ + static void GetNovaGloveTrackerOffset(ESGPositionalTrackingHardware Hardware, bool bRightHanded, + FVector& OutPositionOffset, FQuat& OutRotationOffset); + + /** + * Retrieves Offsets for a particular device. + * + * @param Hardware + * @param bRightHanded + * @param OutPositionOffset + * @param OutRotationOffset + */ + static void GetNovaGloveTrackerOffset(ESGPositionalTrackingHardware Hardware, bool bRightHanded, + FVector& OutPositionOffset, FRotator& OutRotationOffset); + + /** + * + */ + static FVector GetRightNova2ToWristPositionOffset(); + + /** + * + */ + static FQuat GetRightNova2ToWristRotationOffsetQ(); + + /** + * + */ + static FRotator GetRightNova2ToWristRotationOffset(); + + /** + * + */ + + static FVector GetLeftNova2ToWristPositionOffset(); + + /** + * + */ + static FQuat GetLeftNova2ToWristRotationOffsetQ(); + + /** + * + */ + static FRotator GetLeftNova2ToWristRotationOffset(); + + /** + * + */ + static FVector GetRightNova2Quest2ToAttachPosition(); + + /** + * + */ + static FQuat GetRightNova2Quest2ToAttachRotationQ(); + + /** + * + */ + static FRotator GetRightNova2Quest2ToAttachRotation(); + + /** + * + */ + static FVector GetLeftNova2Quest2ToAttachPosition(); + + /** + * + */ + static FQuat GetLeftNova2Quest2ToAttachRotationQ(); + + /** + * + */ + static FRotator GetLeftNova2Quest2ToAttachRotation(); + + /** + * + */ + static FVector GetRightNova2QuestProToAttachPosition(); + + /** + * + */ + static FQuat GetRightNova2QuestProToAttachRotationQ(); + + /** + * + */ + static FRotator GetRightNova2QuestProToAttachRotation(); + + /** + * + */ + static FVector GetLeftNova2QuestProToAttachPosition(); + + /** + * + */ + static FQuat GetLeftNova2QuestProToAttachRotationQ(); + + /** + * + */ + static FRotator GetLeftNova2QuestProToAttachRotation(); + + /** + * + */ + static FVector GetRightNova2ViveTrackerToAttachPosition(); + + /** + * + */ + static FQuat GetRightNova2ViveTrackerToAttachRotationQ(); + + /** + * + */ + static FRotator GetRightNova2ViveTrackerToAttachRotation(); + + /** + * + */ + static FVector GetLeftNova2ViveTrackerToAttachPosition(); + + /** + * + */ + static FQuat GetLeftNova2ViveTrackerToAttachRotationQ(); + + /** + * + */ + static FRotator GetLeftNova2ViveTrackerToAttachRotation(); + + + /** + * + */ + static FVector GetRightNova2ViveWristTrackerToAttachPosition(); + + /** + * + */ + static FQuat GetRightNova2ViveWristTrackerToAttachRotationQ(); + + /** + * + */ + static FRotator GetRightNova2ViveWristTrackerToAttachRotation(); + + /** + * + */ + static FVector GetLeftNova2ViveWristTrackerToAttachPosition(); + + /** + * + */ + static FQuat GetLeftNova2ViveWristTrackerToAttachRotationQ(); + + /** + * + */ + static FRotator GetLeftNova2ViveWristTrackerToAttachRotation(); + + /** + * + */ + static FVector GetRightNova2Quest3ToAttachPosition(); + + /** + * + */ + static FQuat GetRightNova2Quest3ToAttachRotationQ(); + + /** + * + */ + static FRotator GetRightNova2Quest3ToAttachRotation(); + + /** + * + */ + static FVector GetLeftNova2Quest3ToAttachPosition(); + + /** + * + */ + static FQuat GetLeftNova2Quest3ToAttachRotationQ(); + + /** + * + */ + static FRotator GetLeftNova2Quest3ToAttachRotation(); + + /** + * Returns the Offsets that will bring us from the Nova origin to the wrist position. + * + * @param bRightHanded + * @param HardwareVersion + * @param OutPositionOffset + * @param OutRotationOffset + */ + static void GetNova2GloveWristOffset(bool bRightHanded, const FString& HardwareVersion, + FVector& OutPositionOffset, FQuat& OutRotationOffset); + + /** + * Returns the Offsets that will bring us from the Nova origin to the wrist position. + * + * @param bRightHanded + * @param HardwareVersion + * @param OutPositionOffset + * @param OutRotationOffset + */ + static void GetNova2GloveWristOffset(bool bRightHanded, const FString& HardwareVersion, + FVector& OutPositionOffset, FRotator& OutRotationOffset); + + /** + * Retrieves Offsets for a particular device. + * + * @param Hardware + * @param bRightHanded + * @param HardwareVersion + * @param OutPositionOffset + * @param OutRotationOffset + */ + static void GetNova2GloveTrackerOffset(ESGPositionalTrackingHardware Hardware, bool bRightHanded, + const FString& HardwareVersion, + FVector& OutPositionOffset, FQuat& OutRotationOffset); + + /** + * Retrieves Offsets for a particular device. + * + * @param Hardware + * @param bRightHanded + * @param HardwareVersion + * @param OutPositionOffset + * @param OutRotationOffset + */ + static void GetNova2GloveTrackerOffset(ESGPositionalTrackingHardware Hardware, bool bRightHanded, + const FString& HardwareVersion, + FVector& OutPositionOffset, FRotator& OutRotationOffset); + + /** + * + */ + static FString ToString(ESGPositionalTrackingHardware Hardware); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCore/SenseGloveCore.Build.cs b/Plugins/SenseGlove/Source/SenseGloveCore/SenseGloveCore.Build.cs new file mode 100644 index 0000000..d1042fc --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCore/SenseGloveCore.Build.cs @@ -0,0 +1,74 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGloveCore : ModuleRules +{ + public SenseGloveCore(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + } + ); + + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveAndroid", + "SenseGloveCoreImpl", + "SenseGloveLog", + "SenseGloveTypes", + "SenseGloveUtils", + } + ); + + PrivateIncludePathModuleNames.AddRange( + new string[] + { + "SenseGloveBuildHacks", + "SenseGloveInterop", + } + ); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGAnatomyImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGAnatomyImpl.cpp new file mode 100644 index 0000000..6dbbf83 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGAnatomyImpl.cpp @@ -0,0 +1,134 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGAnatomyImpl.h" + +#include "SGBuildHacks/SGInclude_Core_Anatomy.h" +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" +#include "SGCoreImpl/SGVect3DImpl.h" +#include "SGUtils/SGAngles.h" +#include "SGUtils/SGArrayUtils.h" + +float FSGAnatomyImpl::GetTotalFingerFlexion() +{ + return FAnatomyType::GetTotalFingerFlexion(); +} + +float FSGAnatomyImpl::GetTotalFingerExtension() +{ + return FAnatomyType::GetTotalFingerExtension(); +} + +float FSGAnatomyImpl::GetTotalThumbFlexion() +{ + return FAnatomyType::GetTotalThumbFlexion(); +} + +float FSGAnatomyImpl::GetTotalThumbExtension() +{ + return FAnatomyType::GetTotalThumbExtension(); +} + +float FSGAnatomyImpl::GetFingerJointLimit( + const bool bRightHanded, const int32 Joint, const int32 Movement, const bool bMax) +{ + return FSGAngles::TransformToUnreal( + Movement, FAnatomyType::GetFingerJointLimit(bRightHanded, Joint, Movement, bMax)); +} + +float FSGAnatomyImpl::GetThumbJointLimit( + const bool bRightHanded, const int32 Joint, const int32 Movement, const bool bMax) +{ + return FSGAngles::TransformToUnreal( + Movement, FAnatomyType::GetThumbJointLimit(bRightHanded, Joint, Movement, bMax)); +} + +float FSGAnatomyImpl::ClampJointAngle( + const float Value, const int32 Finger, const bool bRightHand, const int32 Joint, const int32 Movement) +{ + return FAnatomyType::ClampJointAngle(Value, Finger, bRightHand, Joint, Movement); +} + +float FSGAnatomyImpl::NormalizeFingerFlexion(const float FlexionInDegrees) +{ + return FSGAngles::TransformToUnreal( + FAnatomyType::NormalizeFingerFlexion( + FSGAngles::TransformToSenseGlove( + FlexionInDegrees))); +} + +float FSGAnatomyImpl::NormalizeThumbFlexion(const float FlexionInDegrees) +{ + return FSGAngles::TransformToUnreal( + FAnatomyType::NormalizeThumbFlexion( + FSGAngles::TransformToSenseGlove( + FlexionInDegrees))); +} + +TArray> FSGAnatomyImpl::GetDefaultHandAngles(const bool bRightHanded) +{ + const TArray> DefaultHandAngles{ + FSGArrayUtils::FromSenseGloveAngles( + FAnatomyType::GetDefaultHandAngles(bRightHanded)) + }; + return DefaultHandAngles; +} + +TArray> FSGAnatomyImpl::GetFlatHandAngles(const bool bRightHanded) +{ + const TArray> FlatHandAngles{ + FSGArrayUtils::FromSenseGloveAngles( + FAnatomyType::GetFlatHandAngles(bRightHanded)) + }; + return FlatHandAngles; +} + +TArray> FSGAnatomyImpl::GetThumbsUpHandAngles(const bool bRightHanded) +{ + const TArray> ThumbsUpHandAngles{ + FSGArrayUtils::FromSenseGloveAngles( + FAnatomyType::GetThumbsUpHandAngles(bRightHanded)) + }; + return ThumbsUpHandAngles; +} + +TArray> FSGAnatomyImpl::GetFistHandAngles(const bool bRightHanded) +{ + const TArray> FistHandAngles{ + FSGArrayUtils::FromSenseGloveAngles( + FAnatomyType::GetFistHandAngles(bRightHanded)) + }; + return FistHandAngles; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGBasicHandModelImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGBasicHandModelImpl.cpp new file mode 100644 index 0000000..5ab9698 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGBasicHandModelImpl.cpp @@ -0,0 +1,356 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGBasicHandModelImpl.h" + +#include +#include + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_BasicHandModel.h" +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGCoreImpl/SGQuatImpl.h" +#include "SGCoreImpl/SGVect3DImpl.h" +#include "SGUtils/SGArrayUtils.h" +#include "SGUtils/SGUnits.h" + +struct FSGBasicHandModelImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FBasicHandModelType BasicHandModel; + + /************************ + * Owner object + ************************/ + + FSGBasicHandModelImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGBasicHandModelImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +FSGBasicHandModelImpl FSGBasicHandModelImpl::Default(const bool bRightHanded) +{ + return FSGBasicHandModelImpl(FSGBasicHandModelImpl::FBasicHandModelType::Default(bRightHanded)); +} + +FSGBasicHandModelImpl FSGBasicHandModelImpl::Deserialize(const FString& SerializedString) +{ + std::string Serialized(TCHAR_TO_UTF8(*SerializedString)); + const FSGBasicHandModelImpl BasicHandModel(FBasicHandModelType::Deserialize(MoveTemp(Serialized))); + return BasicHandModel; +} + +const TArray>& FSGBasicHandModelImpl::GetBaseFingerLengths() +{ + static const TArray> BaseFingerLengths{ + FSGArrayUtils::FromMillimeters( + FSGBasicHandModelImpl::FBasicHandModelType::GetBaseFingerLengths()) + }; + return BaseFingerLengths; +} + +const TArray& FSGBasicHandModelImpl::GetBaseJointPositions() +{ + static const TArray BaseJointPositions{ + FSGArrayUtils::FromMillimeters( + FBasicHandModelType::GetBaseJointPositions()) + }; + return BaseJointPositions; +} + +const TArray& FSGBasicHandModelImpl::GetBaseJointAngles() +{ + static const TArray BaseJointAngles{ + FSGArrayUtils::FromStdVector( + FBasicHandModelType::GetBaseJointAngles()) + }; + return BaseJointAngles; +} + +FSGBasicHandModelImpl::FSGBasicHandModelImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGBasicHandModelImpl::FSGBasicHandModelImpl(const bool bRightHanded, const TArray>& Lengths, + const TArray& StartPositions) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + std::vector> LengthsVector{ + FSGArrayUtils::ToMillimeters(Lengths) + }; + + std::vector StartPositionsVector{ + FSGArrayUtils::ToMillimeters(StartPositions) + }; + + Pimpl->BasicHandModel = FBasicHandModelType(bRightHanded, MoveTemp(LengthsVector), MoveTemp(StartPositionsVector)); +} + +FSGBasicHandModelImpl::FSGBasicHandModelImpl(const bool bRightHanded, const TArray>& Lengths, + const TArray& StartPositions, const TArray& StartRotations) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + std::vector> LengthsVector{ + FSGArrayUtils::ToMillimeters(Lengths) + }; + + std::vector StartPositionsVector{ + FSGArrayUtils::ToMillimeters(StartPositions) + }; + + std::vector StartRotationsVector{ + FSGArrayUtils::ToStdVector(StartRotations) + }; + + Pimpl->BasicHandModel = FBasicHandModelType(bRightHanded, MoveTemp(LengthsVector), + MoveTemp(StartPositionsVector), MoveTemp(StartRotationsVector)); +} + +FSGBasicHandModelImpl::FSGBasicHandModelImpl(const FBasicHandModelType& BasicHandModel) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->BasicHandModel = BasicHandModel; +} + +FSGBasicHandModelImpl::FSGBasicHandModelImpl(const FSGBasicHandModelImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGBasicHandModelImpl::FSGBasicHandModelImpl(FSGBasicHandModelImpl&& Rhs) SG_NOEXCEPT = default; + +FSGBasicHandModelImpl::~FSGBasicHandModelImpl() = default; + +FSGBasicHandModelImpl& FSGBasicHandModelImpl::operator=(const FSGBasicHandModelImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGBasicHandModelImpl& FSGBasicHandModelImpl::operator=(FSGBasicHandModelImpl&& Rhs) SG_NOEXCEPT = default; + +const FSGBasicHandModelImpl::FBasicHandModelType& FSGBasicHandModelImpl::ToBasicHandModel() const +{ + return Pimpl->BasicHandModel; +} + +bool FSGBasicHandModelImpl::IsRight() const +{ + return Pimpl->BasicHandModel.IsRight(); +} + +TArray> FSGBasicHandModelImpl::GetFingerLengths() const +{ + const TArray> FingerLengths{ + FSGArrayUtils::FromMillimeters(Pimpl->BasicHandModel.GetFingerLengths()) + }; + return FingerLengths; +} + +TArray FSGBasicHandModelImpl::GetFingerLengths(const ESGFinger Finger) const +{ + const TArray FingerLengths{ + FSGArrayUtils::FromMillimeters(Pimpl->BasicHandModel.GetFingerLengths(FSGCoreEnumCast::ToEFinger(Finger))) + }; + return FingerLengths; +} + +void FSGBasicHandModelImpl::SetFingerLengths(const ESGFinger Finger, const TArray& Lengths) +{ + std::vector LengthsVector{ + FSGArrayUtils::ToMillimeters(Lengths) + }; + Pimpl->BasicHandModel.SetFingerLengths(FSGCoreEnumCast::ToEFinger(Finger), MoveTemp(LengthsVector)); +} + +void FSGBasicHandModelImpl::SetFingerLengths(const uint8 Finger, const TArray& Lengths) +{ + std::vector LengthsVector{ + FSGArrayUtils::ToMillimeters(Lengths) + }; + Pimpl->BasicHandModel.SetFingerLengths(Finger, MoveTemp(LengthsVector)); +} + +TArray> FSGBasicHandModelImpl::GetFingerRatios() const +{ + const TArray> FingerRatios{ + FSGArrayUtils::FromStdVector(Pimpl->BasicHandModel.GetFingerRatios()) + }; + return FingerRatios; +} + +TArray FSGBasicHandModelImpl::GetFingerRatios(const ESGFinger Finger) const +{ + const TArray FingerRatios{ + FSGArrayUtils::FromStdVector(Pimpl->BasicHandModel.GetFingerRatios(FSGCoreEnumCast::ToEFinger(Finger))) + }; + return FingerRatios; +} + +TArray FSGBasicHandModelImpl::GetStartJointPositions() const +{ + const TArray StartJointPositions{ + FSGArrayUtils::FromMillimeters( + Pimpl->BasicHandModel.GetStartJointPositions()) + }; + return StartJointPositions; +} + +void FSGBasicHandModelImpl::SetStartJointPosition(const ESGFinger Finger, const FVector& Position) +{ + Pimpl->BasicHandModel.SetStartJointPosition( + FSGCoreEnumCast::ToEFinger(Finger), + FSGUnits::CentimetersToMillimeters(Position)); +} + +void FSGBasicHandModelImpl::SetStartJointPosition(const uint8 Finger, const FVector& Position) +{ + Pimpl->BasicHandModel.SetStartJointPosition( + Finger, + FSGUnits::CentimetersToMillimeters(Position)); +} + +TArray FSGBasicHandModelImpl::GetStartJointRotations() const +{ + const TArray StartJointRotations{ + FSGArrayUtils::FromStdVector< + FSGQuatImpl::FQuatType, FQuat, FSGQuatImpl, &FSGQuatImpl::ToFQuat>( + Pimpl->BasicHandModel.GetStartJointRotations()) + }; + return StartJointRotations; +} + +FVector FSGBasicHandModelImpl::GetJointPosition(const ESGFinger Finger) const +{ + return FSGUnits::MillimetersToCentimeters( + Pimpl->BasicHandModel.GetJointPosition(FSGCoreEnumCast::ToEFinger(Finger))); +} + +void FSGBasicHandModelImpl::SetJointPosition(const FVector& NewPosition, const ESGFinger Finger) +{ + Pimpl->BasicHandModel.SetJointPosition( + FSGUnits::CentimetersToMillimeters(NewPosition), + FSGCoreEnumCast::ToEFinger(Finger)); +} + +FQuat FSGBasicHandModelImpl::GetJointRotation(const ESGFinger Finger) const +{ + const FSGQuatImpl Rotation(Pimpl->BasicHandModel.GetJointRotation(FSGCoreEnumCast::ToEFinger(Finger))); + return Rotation.ToFQuat(); +} + +void FSGBasicHandModelImpl::SetJointRotation(const FQuat& NewRotation, const ESGFinger Finger) +{ + Pimpl->BasicHandModel.SetJointRotation(FSGQuatImpl(NewRotation).ToQuat(), FSGCoreEnumCast::ToEFinger(Finger)); +} + +TArray FSGBasicHandModelImpl::GetTotalLengths() const +{ + const TArray TotalLengths{ + FSGArrayUtils::FromMillimeters(Pimpl->BasicHandModel.GetTotalLengths()) + }; + return TotalLengths; +} + +float FSGBasicHandModelImpl::GetTotalLength(const ESGFinger Finger) const +{ + return FSGUnits::MillimetersToCentimeters( + Pimpl->BasicHandModel.GetTotalLength(FSGCoreEnumCast::ToEFinger(Finger))); +} + +TArray FSGBasicHandModelImpl::Get3DLengths(const ESGFinger Finger) const +{ + const TArray Lengths{ + FSGArrayUtils::FromMillimeters( + Pimpl->BasicHandModel.Get3DLengths(FSGCoreEnumCast::ToEFinger(Finger))) + }; + return Lengths; +} + +bool FSGBasicHandModelImpl::Equals(const FSGBasicHandModelImpl& BasicHandModelImpl) const +{ + return Pimpl->BasicHandModel.Equals(BasicHandModelImpl.ToBasicHandModel()); +} + +FString FSGBasicHandModelImpl::ToString() const +{ + const FString String(UTF8_TO_TCHAR(Pimpl->BasicHandModel.ToString().c_str())); + return String; +} + +FString FSGBasicHandModelImpl::ToString(const bool bLengthsOnly) const +{ + const FString String(UTF8_TO_TCHAR(Pimpl->BasicHandModel.ToString(bLengthsOnly).c_str())); + return String; +} + +FString FSGBasicHandModelImpl::Serialize() const +{ + const FString Serialized(UTF8_TO_TCHAR(Pimpl->BasicHandModel.Serialize().c_str())); + return Serialized; +} + +FSGBasicHandModelImpl::FImpl::FImpl(FSGBasicHandModelImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGBasicHandModelImpl::FImpl::~FImpl() = default; + +void FSGBasicHandModelImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGBetaDeviceImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGBetaDeviceImpl.cpp new file mode 100644 index 0000000..27c869e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGBetaDeviceImpl.cpp @@ -0,0 +1,211 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGBetaDeviceImpl.h" + +#include "Containers/StringConv.h" +#include "Misc/AssertionMacros.h" + +#include "SGBuildHacks/SGInclude_Core_BetaDevice.h" +#include "SGBuildHacks/SGInclude_Core_SGDevice.h" +#include "SGCoreImpl/SGCoreEnumCast.h" + +struct FSGBetaDeviceImpl::FImpl +{ + /************************ + * Owner object + ************************/ + + FSGBetaDeviceImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGBetaDeviceImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +TSharedRef FSGBetaDeviceImpl::Parse(const FString& String) +{ + FSGDevicePtrType SGDevicePtr{FBetaDeviceType::Parse(TCHAR_TO_UTF8(*String))}; + ensureAlwaysMsgf(SGDevicePtr, TEXT("Invalid SGDevice!")); + const TSharedRef BetaDeviceImpl{ + MakeShared(std::dynamic_pointer_cast(MoveTemp(SGDevicePtr))) + }; + return BetaDeviceImpl; +} + +FSGBetaDeviceImpl::FSGBetaDeviceImpl() + : FSGDeviceImpl(), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGBetaDeviceImpl::FSGBetaDeviceImpl(const FString& ConstantsString, const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion) + : FSGDeviceImpl(std::make_shared( + TCHAR_TO_UTF8(*ConstantsString), + TCHAR_TO_UTF8(*DeviceId), + TCHAR_TO_UTF8(*HardwareVersion), + FirmwareVersion, + SubFirmwareVersion)), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGBetaDeviceImpl::FSGBetaDeviceImpl(const FBetaDeviceType BetaDevice) + : FSGDeviceImpl(std::make_shared(BetaDevice)), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGBetaDeviceImpl::FSGBetaDeviceImpl(const FBetaDevicePtrType BetaDevice) + : FSGDeviceImpl(BetaDevice), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGBetaDeviceImpl::FSGBetaDeviceImpl(const FSGBetaDeviceImpl& Rhs) + : FSGDeviceImpl(Rhs), + Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGBetaDeviceImpl::FSGBetaDeviceImpl(FSGBetaDeviceImpl&& Rhs) SG_NOEXCEPT = default; + +FSGBetaDeviceImpl::~FSGBetaDeviceImpl() = default; + +FSGBetaDeviceImpl& FSGBetaDeviceImpl::operator=(const FSGBetaDeviceImpl& Rhs) +{ + FSGDeviceImpl::operator=(Rhs); + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGBetaDeviceImpl& FSGBetaDeviceImpl::operator=(FSGBetaDeviceImpl&& Rhs) SG_NOEXCEPT = default; + +FSGBetaDeviceImpl::FBetaDeviceType FSGBetaDeviceImpl::ToBetaDevice() const +{ + return *ToBetaDevicePtr(); +} + +FSGBetaDeviceImpl::FBetaDevicePtrType FSGBetaDeviceImpl::ToBetaDevicePtr() const +{ + return std::dynamic_pointer_cast(ToSGDevicePtr()); +} + +FSGBetaDeviceImpl::FBetaDevicePtrType FSGBetaDeviceImpl::ToBetaDevicePtrChecked() const +{ + FBetaDevicePtrType BetaDevice = std::dynamic_pointer_cast(ToSGDevicePtr()); + ensureAlwaysMsgf(BetaDevice.get(), TEXT("Invalid BetaDevice")); + return BetaDevice; +} + +ESGDeviceType FSGBetaDeviceImpl::GetDeviceType() const +{ + return FSGCoreEnumCast::ToESGDeviceType(ToBetaDevicePtrChecked()->GetDeviceType()); +} + +FString FSGBetaDeviceImpl::GetDeviceId() const +{ + const FString Id{UTF8_TO_TCHAR(ToBetaDevicePtrChecked()->GetDeviceId().c_str())}; + return Id; +} + +FString FSGBetaDeviceImpl::GetHardwareVersion() const +{ + const FString Version{UTF8_TO_TCHAR(ToBetaDevicePtrChecked()->GetHardwareVersion().c_str())}; + return Version; +} + +int32 FSGBetaDeviceImpl::GetFirmwareVersion() const +{ + return ToBetaDevicePtrChecked()->GetFirmwareVersion(); +} + +int32 FSGBetaDeviceImpl::GetSubFirmwareVersion() const +{ + return ToBetaDevicePtrChecked()->GetSubFirmwareVersion(); +} + +FString FSGBetaDeviceImpl::GetConstantsString() const +{ + const FString String{UTF8_TO_TCHAR(ToBetaDevicePtrChecked()->GetConstantsString().c_str())}; + return String; +} + +FString FSGBetaDeviceImpl::GetSensorData() const +{ + const FString Data{UTF8_TO_TCHAR(ToBetaDevicePtrChecked()->GetSensorData().c_str())}; + return Data; +} + +FString FSGBetaDeviceImpl::GetLastCommand() const +{ + const FString Command{UTF8_TO_TCHAR(ToBetaDevicePtrChecked()->GetLastCommand().c_str())}; + return Command; +} + +bool FSGBetaDeviceImpl::SendHaptics(const FString& Command, const int32 Channel) const +{ + return ToBetaDevicePtrChecked()->SendHaptics(TCHAR_TO_UTF8(*Command), Channel); +} + +FString FSGBetaDeviceImpl::ToString() const +{ + return FSGDeviceImpl::ToString(); +} + +FSGBetaDeviceImpl::FImpl::FImpl(FSGBetaDeviceImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGBetaDeviceImpl::FImpl::~FImpl() = default; + +void FSGBetaDeviceImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGCoreEnumCast.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGCoreEnumCast.cpp new file mode 100644 index 0000000..c293fbd --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGCoreEnumCast.cpp @@ -0,0 +1,796 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGCoreEnumCast.h" + +#include "Misc/AssertionMacros.h" + +FSGCoreEnumCast::FEBackendType FSGCoreEnumCast::ToEBackendType(const ESGBackendType Enum) +{ + switch (Enum) + { + case ESGBackendType::SharedMemory: + return FEBackendType::SharedMemory; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + // Keep the compiler satisfied! + return FEBackendType::SharedMemory; +} + +ESGBackendType FSGCoreEnumCast::ToESGBackendType(const FEBackendType Enum) +{ + switch (Enum) + { + case FEBackendType::SharedMemory: + return ESGBackendType::SharedMemory; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + return ESGBackendType::None; +} + +FSGCoreEnumCast::FEConnectionType FSGCoreEnumCast::ToEConnectionType(const ESGConnectionType Enum) +{ + switch (Enum) + { + case ESGConnectionType::Unknown: + return FEConnectionType::Unknown; + case ESGConnectionType::Serial: + return FEConnectionType::Serial; + case ESGConnectionType::BluetoothSerial: + return FEConnectionType::BluetoothSerial; + case ESGConnectionType::BluetoothAndroid: + return FEConnectionType::BluetoothAndroid; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + // Keep the compiler satisfied! + return FEConnectionType::Unknown; +} + +ESGConnectionType FSGCoreEnumCast::ToESGConnectionType(const FEConnectionType Enum) +{ + switch (Enum) + { + case FEConnectionType::Unknown: + return ESGConnectionType::Unknown; + case FEConnectionType::Serial: + return ESGConnectionType::Serial; + case FEConnectionType::BluetoothSerial: + return ESGConnectionType::BluetoothSerial; + case FEConnectionType::BluetoothAndroid: + return ESGConnectionType::BluetoothAndroid; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + return ESGConnectionType::None; +} + +FSGCoreEnumCast::FEDeviceType FSGCoreEnumCast::ToEDeviceType(const ESGDeviceType Enum) +{ + switch (Enum) + { + case ESGDeviceType::Unknown: + return FEDeviceType::Unknown; + case ESGDeviceType::BetaDevice: + return FEDeviceType::BetaDevice; + case ESGDeviceType::SenseGlove: + return FEDeviceType::SenseGlove; + case ESGDeviceType::Nova: + return FEDeviceType::Nova; + case ESGDeviceType::Nova2: + return FEDeviceType::Nova2; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + // Keep the compiler satisfied! + return FEDeviceType::Unknown; +} + +ESGDeviceType FSGCoreEnumCast::ToESGDeviceType(const FEDeviceType Enum) +{ + switch (Enum) + { + case FEDeviceType::Unknown: + return ESGDeviceType::Unknown; + case FEDeviceType::BetaDevice: + return ESGDeviceType::BetaDevice; + case FEDeviceType::SenseGlove: + return ESGDeviceType::SenseGlove; + case FEDeviceType::Nova: + return ESGDeviceType::Nova; + case FEDeviceType::Nova2: + return ESGDeviceType::Nova2; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + return ESGDeviceType::None; +} + +FSGCoreEnumCast::FEFingerType FSGCoreEnumCast::ToEFinger(const ESGFinger Enum) +{ + switch (Enum) + { + case ESGFinger::Thumb: + return FEFingerType::Thumb; + case ESGFinger::Index: + return FEFingerType::Index; + case ESGFinger::Middle: + return FEFingerType::Middle; + case ESGFinger::Ring: + return FEFingerType::Ring; + case ESGFinger::Pinky: + return FEFingerType::Pinky; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + // Keep the compiler satisfied! + return FEFingerType::Thumb; +} + +ESGFinger FSGCoreEnumCast::ToESGFinger(const FSGCoreEnumCast::FEFingerType Enum) +{ + switch (Enum) + { + case FEFingerType::Thumb: + return ESGFinger::Thumb; + case FEFingerType::Index: + return ESGFinger::Index; + case FEFingerType::Middle: + return ESGFinger::Middle; + case FEFingerType::Ring: + return ESGFinger::Ring; + case FEFingerType::Pinky: + return ESGFinger::Pinky; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + return ESGFinger::None; +} + +FSGCoreEnumCast::FEFingerMovementType FSGCoreEnumCast::ToEFingerMovement(const ESGFingerMovement Enum) +{ + switch (Enum) + { + case ESGFingerMovement::McpFlexion: + return FEFingerMovementType::McpFlexion; + case ESGFingerMovement::McpAbduction: + return FEFingerMovementType::McpAbduction; + case ESGFingerMovement::PipFlexion: + return FEFingerMovementType::PipFlexion; + case ESGFingerMovement::DipFlexion: + return FEFingerMovementType::DipFlexion; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + // Keep the compiler satisfied! + return FEFingerMovementType::McpFlexion; +} + +ESGFingerMovement FSGCoreEnumCast::ToESGFingerMovement(const FEFingerMovementType Enum) +{ + switch (Enum) + { + case FEFingerMovementType::McpFlexion: + return ESGFingerMovement::McpFlexion; + case FEFingerMovementType::McpAbduction: + return ESGFingerMovement::McpAbduction; + case FEFingerMovementType::PipFlexion: + return ESGFingerMovement::PipFlexion; + case FEFingerMovementType::DipFlexion: + return ESGFingerMovement::DipFlexion; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + return ESGFingerMovement::None; +} + +FSGCoreEnumCast::FEHapticChannelType FSGCoreEnumCast::ToEHapticChannelType(const ESGHapticChannelType Enum) +{ + switch (Enum) + { + case ESGHapticChannelType::StreamingChannel: + return FEHapticChannelType::StreamingChannel; + case ESGHapticChannelType::FireAndForgetChannel: + return FEHapticChannelType::FireAndForgetChannel; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + // Keep the compiler satisfied! + return FEHapticChannelType::StreamingChannel; +} + +ESGHapticChannelType FSGCoreEnumCast::ToESGHapticChannelType(const FEHapticChannelType Enum) +{ + switch (Enum) + { + case FEHapticChannelType::StreamingChannel: + return ESGHapticChannelType::StreamingChannel; + case FEHapticChannelType::FireAndForgetChannel: + return ESGHapticChannelType::FireAndForgetChannel; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + return ESGHapticChannelType::None; +} + +FSGCoreEnumCast::FEHapticGloveCalibrationStateType FSGCoreEnumCast::ToEHapticGloveCalibrationState( + const ESGHapticGloveCalibrationState Enum) +{ + switch (Enum) + { + case ESGHapticGloveCalibrationState::Unknown: + return FEHapticGloveCalibrationStateType::Unknown; + case ESGHapticGloveCalibrationState::MoveFingers: + return FEHapticGloveCalibrationStateType::MoveFingers; + case ESGHapticGloveCalibrationState::AllSensorsMoved: + return FEHapticGloveCalibrationStateType::AllSensorsMoved; + case ESGHapticGloveCalibrationState::CalibrationLocked: + return FEHapticGloveCalibrationStateType::CalibrationLocked; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + // Keep the compiler satisfied! + return FEHapticGloveCalibrationStateType::Unknown; +} + +ESGHapticGloveCalibrationState FSGCoreEnumCast::ToESGHapticGloveCalibrationState( + const FEHapticGloveCalibrationStateType Enum) +{ + switch (Enum) + { + case FEHapticGloveCalibrationStateType::Unknown: + return ESGHapticGloveCalibrationState::Unknown; + case FEHapticGloveCalibrationStateType::MoveFingers: + return ESGHapticGloveCalibrationState::MoveFingers; + case FEHapticGloveCalibrationStateType::AllSensorsMoved: + return ESGHapticGloveCalibrationState::AllSensorsMoved; + case FEHapticGloveCalibrationStateType::CalibrationLocked: + return ESGHapticGloveCalibrationState::CalibrationLocked; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + return ESGHapticGloveCalibrationState::None; +} + +FSGCoreEnumCast::FEHapticLocationType FSGCoreEnumCast::ToEHapticLocation(const ESGHapticLocation Enum) +{ + switch (Enum) + { + case ESGHapticLocation::Unknown: + return FEHapticLocationType::Unknown; + case ESGHapticLocation::ThumbTip: + return FEHapticLocationType::ThumbTip; + case ESGHapticLocation::IndexTip: + return FEHapticLocationType::IndexTip; + case ESGHapticLocation::MiddleTip: + return FEHapticLocationType::MiddleTip; + case ESGHapticLocation::RingTip: + return FEHapticLocationType::RingTip; + case ESGHapticLocation::PinkyTip: + return FEHapticLocationType::PinkyTip; + case ESGHapticLocation::PalmIndexSide: + return FEHapticLocationType::PalmIndexSide; + case ESGHapticLocation::PalmPinkySide: + return FEHapticLocationType::PalmPinkySide; + case ESGHapticLocation::WholeHand: + return FEHapticLocationType::WholeHand; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + // Keep the compiler satisfied! + return FEHapticLocationType::Unknown; +} + +ESGHapticLocation FSGCoreEnumCast::ToESGHapticLocation(const FEHapticLocationType Enum) +{ + switch (Enum) + { + case FEHapticLocationType::Unknown: + return ESGHapticLocation::Unknown; + case FEHapticLocationType::ThumbTip: + return ESGHapticLocation::ThumbTip; + case FEHapticLocationType::IndexTip: + return ESGHapticLocation::IndexTip; + case FEHapticLocationType::MiddleTip: + return ESGHapticLocation::MiddleTip; + case FEHapticLocationType::RingTip: + return ESGHapticLocation::RingTip; + case FEHapticLocationType::PinkyTip: + return ESGHapticLocation::PinkyTip; + case FEHapticLocationType::PalmIndexSide: + return ESGHapticLocation::PalmIndexSide; + case FEHapticLocationType::PalmPinkySide: + return ESGHapticLocation::PalmPinkySide; + case FEHapticLocationType::WholeHand: + return ESGHapticLocation::WholeHand; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + return ESGHapticLocation::None; +} + +FSGCoreEnumCast::FENormalizationStateType FSGCoreEnumCast::ToENormalizationState(const ESGNormalizationState Enum) +{ + switch (Enum) + { + case ESGNormalizationState::Unknown: + return FENormalizationStateType::Unknown; + case ESGNormalizationState::SendingRawData: + return FENormalizationStateType::SendingRawData; + case ESGNormalizationState::Normalizing_MoveFingers: + return FENormalizationStateType::Normalizing_MoveFingers; + case ESGNormalizationState::Normalizing_AwaitConfirm: + return FENormalizationStateType::Normalizing_AwaitConfirm; + case ESGNormalizationState::NormalizationFinished: + return FENormalizationStateType::NormalizationFinished; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + // Keep the compiler satisfied! + return FENormalizationStateType::Unknown; +} + +ESGNormalizationState FSGCoreEnumCast::ToESGNormalizationState(const FENormalizationStateType Enum) +{ + switch (Enum) + { + case FENormalizationStateType::Unknown: + return ESGNormalizationState::Unknown; + case FENormalizationStateType::SendingRawData: + return ESGNormalizationState::SendingRawData; + case FENormalizationStateType::Normalizing_MoveFingers: + return ESGNormalizationState::Normalizing_MoveFingers; + case FENormalizationStateType::Normalizing_AwaitConfirm: + return ESGNormalizationState::Normalizing_AwaitConfirm; + case FENormalizationStateType::NormalizationFinished: + return ESGNormalizationState::NormalizationFinished; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + return ESGNormalizationState::None; +} + +FSGCoreEnumCast::FEPositionalTrackingHardwareType FSGCoreEnumCast::ToEPositionalTrackingHardware( + const ESGPositionalTrackingHardware Enum) +{ + switch (Enum) + { + case ESGPositionalTrackingHardware::Custom: + return FEPositionalTrackingHardwareType::Custom; + case ESGPositionalTrackingHardware::ViveTracker: + return FEPositionalTrackingHardwareType::ViveTracker; + case ESGPositionalTrackingHardware::Quest2Controller: + return FEPositionalTrackingHardwareType::Quest2Controller; + case ESGPositionalTrackingHardware::ViveFocus3WristTracker: + return FEPositionalTrackingHardwareType::ViveFocus3WristTracker; + case ESGPositionalTrackingHardware::QuestProController: + return FEPositionalTrackingHardwareType::QuestProController; + case ESGPositionalTrackingHardware::Quest3Controller: + return FEPositionalTrackingHardwareType::Quest3Controller; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + // Keep the compiler satisfied! + return FEPositionalTrackingHardwareType::Custom; +} + +ESGPositionalTrackingHardware FSGCoreEnumCast::ToESGPositionalTrackingHardware( + const FEPositionalTrackingHardwareType Enum) +{ + switch (Enum) + { + case FEPositionalTrackingHardwareType::Custom: + return ESGPositionalTrackingHardware::Custom; + case FEPositionalTrackingHardwareType::ViveTracker: + return ESGPositionalTrackingHardware::ViveTracker; + case FEPositionalTrackingHardwareType::Quest2Controller: + return ESGPositionalTrackingHardware::Quest2Controller; + case FEPositionalTrackingHardwareType::ViveFocus3WristTracker: + return ESGPositionalTrackingHardware::ViveFocus3WristTracker; + case FEPositionalTrackingHardwareType::QuestProController: + return ESGPositionalTrackingHardware::QuestProController; + case FEPositionalTrackingHardwareType::Quest3Controller: + return ESGPositionalTrackingHardware::Quest3Controller; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + return ESGPositionalTrackingHardware::None; +} + +FSGCoreEnumCast::FESenseGloveThumperCommandType FSGCoreEnumCast::ToESenseGloveThumperCommand( + const ESGSenseGloveThumperCommand Enum) +{ + switch (Enum) + { + case ESGSenseGloveThumperCommand::None: + return FESenseGloveThumperCommandType::None; + case ESGSenseGloveThumperCommand::TurnOff: + return FESenseGloveThumperCommandType::TurnOff; + case ESGSenseGloveThumperCommand::CueGameOver: + return FESenseGloveThumperCommandType::CueGameOver; + case ESGSenseGloveThumperCommand::ButtonDouble100: + return FESenseGloveThumperCommandType::ButtonDouble100; + case ESGSenseGloveThumperCommand::ButtonDouble60: + return FESenseGloveThumperCommandType::ButtonDouble60; + case ESGSenseGloveThumperCommand::ImpactThump100: + return FESenseGloveThumperCommandType::ImpactThump100; + case ESGSenseGloveThumperCommand::ImpactThump30: + return FESenseGloveThumperCommandType::ImpactThump30; + case ESGSenseGloveThumperCommand::ImpactThump10: + return FESenseGloveThumperCommandType::ImpactThump10; + case ESGSenseGloveThumperCommand::ObjectGrasp100: + return FESenseGloveThumperCommandType::ObjectGrasp100; + case ESGSenseGloveThumperCommand::ObjectGrasp60: + return FESenseGloveThumperCommandType::ObjectGrasp60; + case ESGSenseGloveThumperCommand::ObjectGrasp30: + return FESenseGloveThumperCommandType::ObjectGrasp30; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + // Keep the compiler satisfied! + return FESenseGloveThumperCommandType::None; +} + +ESGSenseGloveThumperCommand FSGCoreEnumCast::ToESGSenseGloveThumperCommand(const FESenseGloveThumperCommandType Enum) +{ + switch (Enum) + { + case FESenseGloveThumperCommandType::None: + return ESGSenseGloveThumperCommand::None; + case FESenseGloveThumperCommandType::TurnOff: + return ESGSenseGloveThumperCommand::TurnOff; + case FESenseGloveThumperCommandType::CueGameOver: + return ESGSenseGloveThumperCommand::CueGameOver; + case FESenseGloveThumperCommandType::ButtonDouble100: + return ESGSenseGloveThumperCommand::ButtonDouble100; + case FESenseGloveThumperCommandType::ButtonDouble60: + return ESGSenseGloveThumperCommand::ButtonDouble60; + case FESenseGloveThumperCommandType::ImpactThump100: + return ESGSenseGloveThumperCommand::ImpactThump100; + case FESenseGloveThumperCommandType::ImpactThump30: + return ESGSenseGloveThumperCommand::ImpactThump30; + case FESenseGloveThumperCommandType::ImpactThump10: + return ESGSenseGloveThumperCommand::ImpactThump10; + case FESenseGloveThumperCommandType::ObjectGrasp100: + return ESGSenseGloveThumperCommand::ObjectGrasp100; + case FESenseGloveThumperCommandType::ObjectGrasp60: + return ESGSenseGloveThumperCommand::ObjectGrasp60; + case FESenseGloveThumperCommandType::ObjectGrasp30: + return ESGSenseGloveThumperCommand::ObjectGrasp30; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + return ESGSenseGloveThumperCommand::None; +} + +FSGCoreEnumCast::FENova2SensorLocationType FSGCoreEnumCast::ToESensorLocation(const ESGNova2SensorLocation Enum) +{ + switch (Enum) + { + case ESGNova2SensorLocation::Abduction: + return FENova2SensorLocationType::Abduction; + case ESGNova2SensorLocation::FlexionProximal: + return FENova2SensorLocationType::FlexionProximal; + case ESGNova2SensorLocation::FlexionDistal: + return FENova2SensorLocationType::FlexionDistal; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + // Keep the compiler satisfied! + return FENova2SensorLocationType::Abduction; +} + +ESGNova2SensorLocation FSGCoreEnumCast::ToESGNova2SensorLocation(const FENova2SensorLocationType Enum) +{ + switch (Enum) + { + case FENova2SensorLocationType::Abduction: + return ESGNova2SensorLocation::Abduction; + case FENova2SensorLocationType::FlexionProximal: + return ESGNova2SensorLocation::FlexionProximal; + case FENova2SensorLocationType::FlexionDistal: + return ESGNova2SensorLocation::FlexionDistal; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + return ESGNova2SensorLocation::None; +} + +FSGCoreEnumCast::FENovaSensorLocationType FSGCoreEnumCast::ToESensorLocation(const ESGNovaSensorLocation Enum) +{ + switch (Enum) + { + case ESGNovaSensorLocation::Abduction: + return FENovaSensorLocationType::Abduction; + case ESGNovaSensorLocation::Flexion: + return FENovaSensorLocationType::Flexion; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + // Keep the compiler satisfied! + return FENovaSensorLocationType::Abduction; +} + +ESGNovaSensorLocation FSGCoreEnumCast::ToESGNovaSensorLocation(const FENovaSensorLocationType Enum) +{ + switch (Enum) + { + case FENovaSensorLocationType::Abduction: + return ESGNovaSensorLocation::Abduction; + case FENovaSensorLocationType::Flexion: + return ESGNovaSensorLocation::Flexion; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + return ESGNovaSensorLocation::None; +} + +FSGCoreEnumCast::FEThumbMovementType FSGCoreEnumCast::ToEThumbMovement(const ESGThumbMovement Enum) +{ + switch (Enum) + { + case ESGThumbMovement::CmcTwist: + return FEThumbMovementType::CmcTwist; + case ESGThumbMovement::CmcFlexion: + return FEThumbMovementType::CmcFlexion; + case ESGThumbMovement::CmcAbduction: + return FEThumbMovementType::CmcAbduction; + case ESGThumbMovement::McpFlexion: + return FEThumbMovementType::McpFlexion; + case ESGThumbMovement::IpFlexion: + return FEThumbMovementType::IpFlexion; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + // Keep the compiler satisfied! + return FEThumbMovementType::CmcTwist; +} + +ESGThumbMovement FSGCoreEnumCast::ToESGThumbMovement(const FEThumbMovementType Enum) +{ + switch (Enum) + { + case FEThumbMovementType::CmcTwist: + return ESGThumbMovement::CmcTwist; + case FEThumbMovementType::CmcFlexion: + return ESGThumbMovement::CmcFlexion; + case FEThumbMovementType::CmcAbduction: + return ESGThumbMovement::CmcAbduction; + case FEThumbMovementType::McpFlexion: + return ESGThumbMovement::McpFlexion; + case FEThumbMovementType::IpFlexion: + return ESGThumbMovement::IpFlexion; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + return ESGThumbMovement::None; +} + +FSGCoreEnumCast::FENova2VibroMotorType FSGCoreEnumCast::ToENova2VibroMotor(const ESGNova2VibroMotor Enum) +{ + switch (Enum) + { + case ESGNova2VibroMotor::Unknown: + return FENova2VibroMotorType::Unknown; + case ESGNova2VibroMotor::ThumbFingertip: + return FENova2VibroMotorType::ThumbFingertip; + case ESGNova2VibroMotor::IndexFingertip: + return FENova2VibroMotorType::IndexFingertip; + case ESGNova2VibroMotor::PalmIndexSide: + return FENova2VibroMotorType::PalmIndexSide; + case ESGNova2VibroMotor::PalmPinkySide: + return FENova2VibroMotorType::PalmPinkySide; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + // Keep the compiler satisfied! + return FENova2VibroMotorType::Unknown; +} + +ESGNova2VibroMotor FSGCoreEnumCast::ToESGNova2VibroMotor(const FENova2VibroMotorType Enum) +{ + switch (Enum) + { + case FENova2VibroMotorType::Unknown: + return ESGNova2VibroMotor::Unknown; + case FENova2VibroMotorType::ThumbFingertip: + return ESGNova2VibroMotor::ThumbFingertip; + case FENova2VibroMotorType::IndexFingertip: + return ESGNova2VibroMotor::IndexFingertip; + case FENova2VibroMotorType::PalmIndexSide: + return ESGNova2VibroMotor::PalmIndexSide; + case FENova2VibroMotorType::PalmPinkySide: + return ESGNova2VibroMotor::PalmPinkySide; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + return ESGNova2VibroMotor::None; +} + +FSGCoreEnumCast::FENovaVibroMotorType FSGCoreEnumCast::ToENovaVibroMotor(const ESGNovaVibroMotor Enum) +{ + switch (Enum) + { + case ESGNovaVibroMotor::Unknown: + return FENovaVibroMotorType::Unknown; + case ESGNovaVibroMotor::BackOfHand: + return FENovaVibroMotorType::BackOfHand; + case ESGNovaVibroMotor::ThumbTip: + return FENovaVibroMotorType::ThumbTip; + case ESGNovaVibroMotor::IndexFingertip: + return FENovaVibroMotorType::IndexFingertip; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + // Keep the compiler satisfied! + return FENovaVibroMotorType::Unknown; +} + +ESGNovaVibroMotor FSGCoreEnumCast::ToESGNovaVibroMotor(const FENovaVibroMotorType Enum) +{ + switch (Enum) + { + case FENovaVibroMotorType::Unknown: + return ESGNovaVibroMotor::Unknown; + case FENovaVibroMotorType::BackOfHand: + return ESGNovaVibroMotor::BackOfHand; + case FENovaVibroMotorType::ThumbTip: + return ESGNovaVibroMotor::ThumbTip; + case FENovaVibroMotorType::IndexFingertip: + return ESGNovaVibroMotor::IndexFingertip; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + return ESGNovaVibroMotor::None; +} + +FSGCoreEnumCast::FEWaveformType FSGCoreEnumCast::ToEWaveformType(const ESGWaveformType Enum) +{ + switch (Enum) + { + case ESGWaveformType::Unknown: + return FEWaveformType::Unknown; + case ESGWaveformType::Sine: + return FEWaveformType::Sine; + case ESGWaveformType::Square: + return FEWaveformType::Square; + case ESGWaveformType::SawDown: + return FEWaveformType::SawUp; + case ESGWaveformType::SawUp: + return FEWaveformType::SawDown; + case ESGWaveformType::Triangle: + return FEWaveformType::Triangle; + case ESGWaveformType::Noise: + return FEWaveformType::Noise; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + // Keep the compiler satisfied! + return FEWaveformType::Unknown; +} + +ESGWaveformType FSGCoreEnumCast::ToESGWaveformType(const FEWaveformType Enum) +{ + switch (Enum) + { + case FEWaveformType::Unknown: + return ESGWaveformType::Unknown; + case FEWaveformType::Sine: + return ESGWaveformType::Sine; + case FEWaveformType::Square: + return ESGWaveformType::Square; + case FEWaveformType::SawUp: + return ESGWaveformType::SawDown; + case FEWaveformType::SawDown: + return ESGWaveformType::SawUp; + case FEWaveformType::Triangle: + return ESGWaveformType::Triangle; + case FEWaveformType::Noise: + return ESGWaveformType::Noise; + default: + ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!")); + break; + } + + return ESGWaveformType::None; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGCoreEnumCast.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGCoreEnumCast.h new file mode 100644 index 0000000..19d7da7 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGCoreEnumCast.h @@ -0,0 +1,127 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + + +#include "SGBuildHacks/SGInclude_Core_CustomWaveform.h" +#include "SGBuildHacks/SGInclude_Core_Fingers.h" +#include "SGBuildHacks/SGInclude_Core_HapticChannelInfo.h" +#include "SGBuildHacks/SGInclude_Core_HapticGlove.h" +#include "SGBuildHacks/SGInclude_Core_Library.h" +#include "SGBuildHacks/SGInclude_Core_NormalizationState.h" +#include "SGBuildHacks/SGInclude_Core_Nova2Glove.h" +#include "SGBuildHacks/SGInclude_Core_Nova2GloveSensorData.h" +#include "SGBuildHacks/SGInclude_Core_NovaGlove.h" +#include "SGBuildHacks/SGInclude_Core_NovaGloveSensorData.h" +#include "SGBuildHacks/SGInclude_Core_SenseGloveThumperCommand.h" +#include "SGBuildHacks/SGInclude_Core_SGDevice.h" +#include "SGBuildHacks/SGInclude_Core_Tracking.h" +#include "SGCoreImpl/SGNova2GloveImpl.h" +#include "SGTypes/SGCoreTypes.h" + +class SENSEGLOVECOREIMPL_API FSGCoreEnumCast +{ +public: + typedef SGCore::EBackendType FEBackendType; + typedef SGCore::SGDevice::EConnectionType FEConnectionType; + typedef SGCore::EDeviceType FEDeviceType; + typedef SGCore::EFinger FEFingerType; + typedef SGCore::EHapticChannelType FEHapticChannelType; + typedef SGCore::EHapticGloveCalibrationState FEHapticGloveCalibrationStateType; + typedef SGCore::EHapticLocation FEHapticLocationType; + typedef SGCore::Kinematics::EFingerMovement FEFingerMovementType; + typedef SGCore::Nova::ENormalizationState FENormalizationStateType; + typedef SGCore::Nova::Nova2GloveSensorData::ESensorLocation FENova2SensorLocationType; + typedef SGCore::Nova::NovaGloveSensorData::ESensorLocation FENovaSensorLocationType; + typedef SGCore::EPositionalTrackingHardware FEPositionalTrackingHardwareType; + typedef SGCore::Haptics::ESenseGloveThumperCommand FESenseGloveThumperCommandType; + typedef SGCore::Kinematics::EThumbMovement FEThumbMovementType; + typedef SGCore::Nova::ENova2VibroMotor FENova2VibroMotorType; + typedef SGCore::Nova::ENovaVibroMotor FENovaVibroMotorType; + typedef SGCore::EWaveformType FEWaveformType; + +public: + static FEBackendType ToEBackendType(ESGBackendType Enum); + static ESGBackendType ToESGBackendType(FEBackendType Enum); + + static FEConnectionType ToEConnectionType(ESGConnectionType Enum); + static ESGConnectionType ToESGConnectionType(FEConnectionType Enum); + + static FEDeviceType ToEDeviceType(ESGDeviceType Enum); + static ESGDeviceType ToESGDeviceType(FEDeviceType Enum); + + static FEFingerType ToEFinger(ESGFinger Enum); + static ESGFinger ToESGFinger(FEFingerType Enum); + + static FEFingerMovementType ToEFingerMovement(ESGFingerMovement Enum); + static ESGFingerMovement ToESGFingerMovement(FEFingerMovementType Enum); + + static FEHapticChannelType ToEHapticChannelType(ESGHapticChannelType Enum); + static ESGHapticChannelType ToESGHapticChannelType(FEHapticChannelType Enum); + + static FEHapticGloveCalibrationStateType ToEHapticGloveCalibrationState(ESGHapticGloveCalibrationState Enum); + static ESGHapticGloveCalibrationState ToESGHapticGloveCalibrationState(FEHapticGloveCalibrationStateType Enum); + + static FEHapticLocationType ToEHapticLocation(ESGHapticLocation Enum); + static ESGHapticLocation ToESGHapticLocation(FEHapticLocationType Enum); + + static FENormalizationStateType ToENormalizationState(ESGNormalizationState Enum); + static ESGNormalizationState ToESGNormalizationState(FENormalizationStateType Enum); + + static FEPositionalTrackingHardwareType ToEPositionalTrackingHardware(ESGPositionalTrackingHardware Enum); + static ESGPositionalTrackingHardware ToESGPositionalTrackingHardware(FEPositionalTrackingHardwareType Enum); + + static FESenseGloveThumperCommandType ToESenseGloveThumperCommand(ESGSenseGloveThumperCommand Enum); + static ESGSenseGloveThumperCommand ToESGSenseGloveThumperCommand(FESenseGloveThumperCommandType Enum); + + static FENova2SensorLocationType ToESensorLocation(ESGNova2SensorLocation Enum); + static ESGNova2SensorLocation ToESGNova2SensorLocation(FENova2SensorLocationType Enum); + + static FENovaSensorLocationType ToESensorLocation(ESGNovaSensorLocation Enum); + static ESGNovaSensorLocation ToESGNovaSensorLocation(FENovaSensorLocationType Enum); + + static FEThumbMovementType ToEThumbMovement(ESGThumbMovement Enum); + static ESGThumbMovement ToESGThumbMovement(FEThumbMovementType Enum); + + static FENova2VibroMotorType ToENova2VibroMotor(ESGNova2VibroMotor Enum); + static ESGNova2VibroMotor ToESGNova2VibroMotor(FENova2VibroMotorType Enum); + + static FENovaVibroMotorType ToENovaVibroMotor(ESGNovaVibroMotor Enum); + static ESGNovaVibroMotor ToESGNovaVibroMotor(FENovaVibroMotorType Enum); + + static FEWaveformType ToEWaveformType(ESGWaveformType Enum); + static ESGWaveformType ToESGWaveformType(FEWaveformType Enum); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGCustomWaveformImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGCustomWaveformImpl.cpp new file mode 100644 index 0000000..4b78ca3 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGCustomWaveformImpl.cpp @@ -0,0 +1,276 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGCustomWaveformImpl.h" + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_CustomWaveform.h" +#include "SGCoreImpl/SGCoreEnumCast.h" + +struct FSGCustomWaveformImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FCustomWaveformType CustomWaveform; + + /************************ + * Owner object + ************************/ + + FSGCustomWaveformImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGCustomWaveformImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +FString FSGCustomWaveformImpl::ToString(const ESGWaveformType Type) +{ + const FString String{FCustomWaveformType::ToString(FSGCoreEnumCast::ToEWaveformType(Type)).c_str()}; + return String; +} + +FSGCustomWaveformImpl::FSGCustomWaveformImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGCustomWaveformImpl::FSGCustomWaveformImpl(const float Amplitude, const float Duration) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->CustomWaveform = FCustomWaveformType{Amplitude, Duration}; +} + +FSGCustomWaveformImpl::FSGCustomWaveformImpl(const float Amplitude, const float Duration, const float Frequency) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->CustomWaveform = FCustomWaveformType{Amplitude, Duration, Frequency}; +} + +FSGCustomWaveformImpl::FSGCustomWaveformImpl(const FCustomWaveformType& CustomWaveform) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->CustomWaveform = CustomWaveform; +} + +FSGCustomWaveformImpl::FSGCustomWaveformImpl(const FSGCustomWaveformImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGCustomWaveformImpl::FSGCustomWaveformImpl(FSGCustomWaveformImpl&& Rhs) SG_NOEXCEPT = default; + +FSGCustomWaveformImpl::~FSGCustomWaveformImpl() = default; + +FSGCustomWaveformImpl& FSGCustomWaveformImpl::operator=(const FSGCustomWaveformImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGCustomWaveformImpl& FSGCustomWaveformImpl::operator=(FSGCustomWaveformImpl&& Rhs) SG_NOEXCEPT = default; + +const FSGCustomWaveformImpl::FCustomWaveformType& FSGCustomWaveformImpl::ToCustomWaveform() const +{ + return Pimpl->CustomWaveform; +} + +FSGCustomWaveformImpl::FCustomWaveformType& FSGCustomWaveformImpl::ToCustomWaveform() +{ + return Pimpl->CustomWaveform; +} + +float FSGCustomWaveformImpl::GetAmplitude() const +{ + return Pimpl->CustomWaveform.GetAmplitude(); +} + +void FSGCustomWaveformImpl::SetAmplitude(const float Amplitude) +{ + Pimpl->CustomWaveform.SetAmplitude(Amplitude); +} + +ESGWaveformType FSGCustomWaveformImpl::GetWaveType() const +{ + return FSGCoreEnumCast::ToESGWaveformType(Pimpl->CustomWaveform.GetWaveType()); +} + +void FSGCustomWaveformImpl::SetWaveType(const ESGWaveformType Type) +{ + Pimpl->CustomWaveform.SetWaveType(FSGCoreEnumCast::ToEWaveformType(Type)); +} + +bool FSGCustomWaveformImpl::IsInfinite() const +{ + return Pimpl->CustomWaveform.IsInfinite(); +} + +void FSGCustomWaveformImpl::SetInfinite(const bool bInfinite) +{ + return Pimpl->CustomWaveform.SetInfinite(bInfinite); +} + +int32 FSGCustomWaveformImpl::GetRepeatAmount() const +{ + return Pimpl->CustomWaveform.GetRepeatAmount(); +} + +void FSGCustomWaveformImpl::SetRepeatAmount(const int32 Amount) +{ + Pimpl->CustomWaveform.SetRepeatAmount(Amount); +} + +float FSGCustomWaveformImpl::GetAttackTime() const +{ + return Pimpl->CustomWaveform.GetAttackTime(); +} + +void FSGCustomWaveformImpl::SetAttackTime(const float Time) +{ + Pimpl->CustomWaveform.SetAttackTime(Time); +} + +float FSGCustomWaveformImpl::GetSustainTime() const +{ + return Pimpl->CustomWaveform.GetSustainTime(); +} + +void FSGCustomWaveformImpl::SetSustainTime(const float Time) +{ + Pimpl->CustomWaveform.SetSustainTime(Time); +} + +float FSGCustomWaveformImpl::GetDecayTime() const +{ + return Pimpl->CustomWaveform.GetDecayTime(); +} + +void FSGCustomWaveformImpl::SetDecayTime(const float Time) +{ + Pimpl->CustomWaveform.SetDecayTime(Time); +} + +float FSGCustomWaveformImpl::GetFrequencyStart() const +{ + return Pimpl->CustomWaveform.GetFrequencyStart(); +} + +void FSGCustomWaveformImpl::SetFrequencyStart(const float Frequency) +{ + Pimpl->CustomWaveform.SetFrequencyStart(Frequency); +} + +float FSGCustomWaveformImpl::GetFrequencyEnd() const +{ + return Pimpl->CustomWaveform.GetFrequencyEnd(); +} + +void FSGCustomWaveformImpl::SetFrequencyEnd(const float Frequency) +{ + Pimpl->CustomWaveform.SetFrequencyEnd(Frequency); +} + +float FSGCustomWaveformImpl::GetFrequencySwitchTime() const +{ + return Pimpl->CustomWaveform.GetFrequencySwitchTime(); +} + +void FSGCustomWaveformImpl::SetFrequencySwitchTime(const float Time) +{ + Pimpl->CustomWaveform.SetFrequencySwitchTime(Time); +} + +float FSGCustomWaveformImpl::GetFrequencySwitchFactor() const +{ + return Pimpl->CustomWaveform.GetFrequencySwitchFactor(); +} + +void FSGCustomWaveformImpl::SetFrequencySwitchFactor(const float Factor) +{ + Pimpl->CustomWaveform.SetFrequencySwitchFactor(Factor); +} + +float FSGCustomWaveformImpl::GetEffectTime() const +{ + return Pimpl->CustomWaveform.GetEffectTime(); +} + +float FSGCustomWaveformImpl::GetTotalEffectTime() const +{ + return Pimpl->CustomWaveform.GetTotalEffectTime(); +} + +bool FSGCustomWaveformImpl::FrequencyJumps() const +{ + return Pimpl->CustomWaveform.FrequencyJumps(); +} + +bool FSGCustomWaveformImpl::Equals(const FSGCustomWaveformImpl& CustomWaveformImpl) const +{ + return Pimpl->CustomWaveform.Equals(CustomWaveformImpl.ToCustomWaveform()); +} + +FString FSGCustomWaveformImpl::ToString() const +{ + const FString String{UTF8_TO_TCHAR(Pimpl->CustomWaveform.ToString().c_str())}; + return String; +} + +FSGCustomWaveformImpl::FImpl::FImpl(FSGCustomWaveformImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGCustomWaveformImpl::FImpl::~FImpl() = default; + +void FSGCustomWaveformImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGDeviceImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGDeviceImpl.cpp new file mode 100644 index 0000000..df5b166 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGDeviceImpl.cpp @@ -0,0 +1,409 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGDeviceImpl.h" + +#include + +#include "Containers/StringConv.h" +#include "Misc/AssertionMacros.h" + +#include "SGBuildHacks/SGInclude_Core_BetaDevice.h" +#include "SGBuildHacks/SGInclude_Core_SGDevice.h" +#include "SGBuildHacks/SGInclude_Core_HapticChannelInfo.h" +#include "SGBuildHacks/SGInclude_Core_HapticGlove.h" +#include "SGBuildHacks/SGInclude_Core_Nova2Glove.h" +#include "SGBuildHacks/SGInclude_Core_NovaGlove.h" +#include "SGBuildHacks/SGInclude_Core_SenseGlove.h" +#include "SGCoreImpl/SGBetaDeviceImpl.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGCoreImpl/SGHapticChannelInfoImpl.h" +#include "SGCoreImpl/SGHapticGloveImpl.h" +#include "SGCoreImpl/SGNova2GloveImpl.h" +#include "SGCoreImpl/SGNovaGloveImpl.h" +#include "SGCoreImpl/SGSenseGloveImpl.h" +#include "Templates/Casts.h" + +struct FSGDeviceImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FSGDevicePtrType SGDevice; + + /************************ + * Owner object + ************************/ + + FSGDeviceImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGDeviceImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +void FSGDeviceImpl::ParseFirmware(const FString& RawFirmware, int32& OutMainVersion, int32& OutSubVersion) +{ + FSGDeviceType::ParseFirmware(TCHAR_TO_UTF8(*RawFirmware), OutMainVersion, OutSubVersion); +} + +bool FSGDeviceImpl::FirmwareNewerThan(const int32 MyFirmwareMain, const int32 MyFirmwareSub, + const int32 ReferenceMain, const int32 ReferenceSub, const bool bInclusive) +{ + return FSGDeviceType::FirmwareNewerThan(MyFirmwareMain, MyFirmwareSub, ReferenceMain, ReferenceSub, bInclusive); +} + +bool FSGDeviceImpl::FirmwareOlderThan(const int32 MyFirmwareMain, const int32 MyFirmwareSub, + const int32 ReferenceMain, const int32 ReferenceSub, const bool bInclusive) +{ + return FSGDeviceType::FirmwareOlderThan(MyFirmwareMain, MyFirmwareSub, ReferenceMain, ReferenceSub, bInclusive); +} + +FString FSGDeviceImpl::ToString(const ESGDeviceType DeviceType) +{ + const FString String{UTF8_TO_TCHAR(FSGDeviceType::ToString(FSGCoreEnumCast::ToEDeviceType(DeviceType)).c_str())}; + return String; +} + +FSGDeviceImpl::FSGDeviceImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGDeviceImpl::FSGDeviceImpl(const FSGDevicePtrType SGDevice) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + ensureAlwaysMsgf(SGDevice.get(), TEXT("Invalid SGDevice!")); + Pimpl->SGDevice = SGDevice; +} + +FSGDeviceImpl::FSGDeviceImpl(const FSGDeviceImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGDeviceImpl::FSGDeviceImpl(FSGDeviceImpl&& Rhs) SG_NOEXCEPT = default; + +FSGDeviceImpl::~FSGDeviceImpl() = default; + +FSGDeviceImpl& FSGDeviceImpl::operator=(const FSGDeviceImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGDeviceImpl& FSGDeviceImpl::operator=(FSGDeviceImpl&& Rhs) SG_NOEXCEPT = default; + +FSGDeviceImpl::FSGDevicePtrType FSGDeviceImpl::ToSGDevicePtr() const +{ + return Pimpl->SGDevice; +} + +FSGDeviceImpl::FSGDevicePtrType FSGDeviceImpl::ToSGDevicePtrChecked() const +{ + ensureAlwaysMsgf(Pimpl->SGDevice.get(), TEXT("Invalid Pimpl->SGDevice!")); + return Pimpl->SGDevice; +} + +TSharedRef FSGDeviceImpl::ToSGDeviceImplRef() +{ + return SharedThis(this); +} + +TSharedRef FSGDeviceImpl::ToBetaDeviceImplRef() +{ + FSGBetaDeviceImpl* BetaDevice{dynamic_cast(this)}; + ensureAlwaysMsgf(BetaDevice, TEXT("Invalid BetaDevice!")); + return SharedThis(BetaDevice); +} + +TSharedRef FSGDeviceImpl::ToHapticGloveImplRef() +{ + FSGHapticGloveImpl* HapticGlove{dynamic_cast(this)}; + ensureAlwaysMsgf(HapticGlove, TEXT("Invalid HapticGlove!")); + return SharedThis(HapticGlove); +} + +TSharedRef FSGDeviceImpl::ToNova2GloveImplRef() +{ + FSGNova2GloveImpl* Nova2Glove{dynamic_cast(this)}; + ensureAlwaysMsgf(Nova2Glove, TEXT("Invalid Nova2Glove!")); + return SharedThis(Nova2Glove); +} + +TSharedRef FSGDeviceImpl::ToNovaGloveImplRef() +{ + FSGNovaGloveImpl* NovaGlove{dynamic_cast(this)}; + ensureAlwaysMsgf(NovaGlove, TEXT("Invalid NovaGlove!")); + return SharedThis(NovaGlove); +} + +TSharedRef FSGDeviceImpl::ToSenseGloveImplRef() +{ + FSGSenseGloveImpl* SenseGlove{dynamic_cast(this)}; + ensureAlwaysMsgf(SenseGlove, TEXT("Invalid SenseGlove!")); + return SharedThis(SenseGlove); +} + +bool FSGDeviceImpl::IsABetaDevice() const +{ + const FSGBetaDeviceImpl::FBetaDevicePtrType BetaDevice{ + std::dynamic_pointer_cast(ToSGDevicePtr()) + }; + return BetaDevice != nullptr; +} + +bool FSGDeviceImpl::IsAHapticGlove() const +{ + const FSGHapticGloveImpl::FHapticGlovePtrType HapticGlove{ + std::dynamic_pointer_cast(ToSGDevicePtr()) + }; + return HapticGlove != nullptr; +} + +bool FSGDeviceImpl::IsANova2Glove() const +{ + const FSGNova2GloveImpl::FNova2GlovePtrType Nova2Glove{ + std::dynamic_pointer_cast(ToSGDevicePtr()) + }; + return Nova2Glove != nullptr; +} + +bool FSGDeviceImpl::IsANovaGlove() const +{ + const FSGNovaGloveImpl::FNovaGlovePtrType NovaGlove{ + std::dynamic_pointer_cast(ToSGDevicePtr()) + }; + return NovaGlove != nullptr; +} + +bool FSGDeviceImpl::IsASenseGlove() const +{ + const FSGSenseGloveImpl::FSenseGlovePtrType SenseGlove{ + std::dynamic_pointer_cast(ToSGDevicePtr()) + }; + return SenseGlove != nullptr; +} + +TSharedPtr FSGDeviceImpl::AsBetaDevice() const +{ + const FSGBetaDeviceImpl::FBetaDevicePtrType BetaDevice{ + std::dynamic_pointer_cast(ToSGDevicePtr()) + }; + ensureAlwaysMsgf(BetaDevice, TEXT("Invalid BetaDevice!")); + return MakeShared(BetaDevice); +} + +TSharedPtr FSGDeviceImpl::AsHapticGlove() const +{ + const FSGHapticGloveImpl::FHapticGlovePtrType HapticGlove{ + std::dynamic_pointer_cast(ToSGDevicePtr()) + }; + ensureAlwaysMsgf(HapticGlove, TEXT("Invalid HapticGlove!")); + return MakeShared(HapticGlove); +} + +TSharedPtr FSGDeviceImpl::AsNova2Glove() const +{ + const FSGNova2GloveImpl::FNova2GlovePtrType Nova2Glove{ + std::dynamic_pointer_cast(ToSGDevicePtr()) + }; + ensureAlwaysMsgf(Nova2Glove, TEXT("Invalid Nova2Glove!")); + return MakeShared(Nova2Glove); +} + +TSharedPtr FSGDeviceImpl::AsNovaGlove() const +{ + const FSGNovaGloveImpl::FNovaGlovePtrType NovaGlove{ + std::dynamic_pointer_cast(ToSGDevicePtr()) + }; + ensureAlwaysMsgf(NovaGlove, TEXT("Invalid NovaGlove!")); + return MakeShared(NovaGlove); +} + +TSharedPtr FSGDeviceImpl::AsSenseGlove() const +{ + const FSGSenseGloveImpl::FSenseGlovePtrType SenseGlove{ + std::dynamic_pointer_cast(ToSGDevicePtr()) + }; + ensureAlwaysMsgf(SenseGlove, TEXT("Invalid SenseGlove!")); + return MakeShared(SenseGlove); +} + +ESGDeviceType FSGDeviceImpl::GetDeviceType() const +{ + return FSGCoreEnumCast::ToESGDeviceType(ToSGDevicePtrChecked()->GetDeviceType()); +} + +FString FSGDeviceImpl::GetDeviceId() const +{ + const FString Id{UTF8_TO_TCHAR(ToSGDevicePtrChecked()->GetDeviceId().c_str())}; + return Id; +} + +FString FSGDeviceImpl::GetHardwareVersion() const +{ + const FString Version{UTF8_TO_TCHAR(ToSGDevicePtrChecked()->GetHardwareVersion().c_str())}; + return Version; +} + +int32 FSGDeviceImpl::GetFirmwareVersion() const +{ + return ToSGDevicePtrChecked()->GetFirmwareVersion(); +} + +int32 FSGDeviceImpl::GetSubFirmwareVersion() const +{ + return ToSGDevicePtrChecked()->GetSubFirmwareVersion(); +} + +FString FSGDeviceImpl::GetFirmwareString() const +{ + const FString String{UTF8_TO_TCHAR(ToSGDevicePtrChecked()->GetFirmwareString().c_str())}; + return String; +} + +bool FSGDeviceImpl::FirmwareNewerThan(const int32 FirmwareMain, const int32 FirmwareSub, const bool bInclusive) const +{ + return ToSGDevicePtrChecked()->FirmwareNewerThan(FirmwareMain, FirmwareSub, bInclusive); +} + +bool FSGDeviceImpl::FirmwareOlderThan(const int32 FirmwareMain, const int32 FirmwareSub, const bool bInclusive) const +{ + return ToSGDevicePtrChecked()->FirmwareOlderThan(FirmwareMain, FirmwareSub, bInclusive); +} + +FString FSGDeviceImpl::GetAddress() const +{ + const FString String(UTF8_TO_TCHAR(ToSGDevicePtrChecked()->GetAddress().c_str())); + return String; +} + +bool FSGDeviceImpl::IsConnected() const +{ + return ToSGDevicePtrChecked()->IsConnected(); +} + +ESGConnectionType FSGDeviceImpl::GetConnectionType() const +{ + return FSGCoreEnumCast::ToESGConnectionType(ToSGDevicePtrChecked()->GetConnectionType()); +} + +int32 FSGDeviceImpl::PacketsPerSecondReceived() const +{ + return ToSGDevicePtrChecked()->PacketsPerSecondReceived(); +} + +int32 FSGDeviceImpl::PacketsPerSecondSent() const +{ + return ToSGDevicePtrChecked()->PacketsPerSecondSent(); +} + +int32 FSGDeviceImpl::GetDeviceIndex() const +{ + return ToSGDevicePtrChecked()->GetDeviceIndex(); +} + +void FSGDeviceImpl::SetDeviceIndex(const int32 NewIndex) +{ + ToSGDevicePtrChecked()->SetDeviceIndex(NewIndex); +} + +bool FSGDeviceImpl::IsWireless() const +{ + return ToSGDevicePtrChecked()->IsWireless(); +} + +bool FSGDeviceImpl::HasBattery() const +{ + return ToSGDevicePtrChecked()->HasBattery(); +} + +bool FSGDeviceImpl::IsCharging() +{ + return ToSGDevicePtrChecked()->IsCharging(); +} + +bool FSGDeviceImpl::GetBatteryLevel(float& OutLevel) +{ + return ToSGDevicePtrChecked()->GetBatteryLevel(OutLevel); +} + +void FSGDeviceImpl::SetHapticChannels(const FSGHapticChannelInfoImpl& Channels) +{ + ToSGDevicePtrChecked()->SetHapticChannels(Channels.ToHapticChannelInfo()); +} + +int32 FSGDeviceImpl::GetHapticChannelCount() const +{ + return ToSGDevicePtrChecked()->GetHapticChannelCount(); +} + +int32 FSGDeviceImpl::GetHapticChannelCount(const ESGHapticChannelType ChannelType) const +{ + return ToSGDevicePtrChecked()->GetHapticChannelCount(FSGCoreEnumCast::ToEHapticChannelType(ChannelType)); +} + +FString FSGDeviceImpl::ToString() const +{ + const FString String(UTF8_TO_TCHAR(ToSGDevicePtrChecked()->ToString().c_str())); + return String; +} + +FSGDeviceImpl::FImpl::FImpl(FSGDeviceImpl* InOwner) + : SGDevice(std::make_shared()), + Owner(InOwner) +{ +} + +FSGDeviceImpl::FImpl::~FImpl() = default; + +void FSGDeviceImpl::FImplDeleter::operator()(const FSGDeviceImpl::FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGDeviceListImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGDeviceListImpl.cpp new file mode 100644 index 0000000..fe57f1c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGDeviceListImpl.cpp @@ -0,0 +1,209 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGDeviceListImpl.h" + +#include + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_BetaDevice.h" +#include "SGBuildHacks/SGInclude_Core_DeviceList.h" +#include "SGBuildHacks/SGInclude_Core_NovaGlove.h" +#include "SGBuildHacks/SGInclude_Core_SenseGlove.h" +#include "SGBuildHacks/SGInclude_Core_SGDevice.h" +#include "SGCoreImpl/SGBetaDeviceImpl.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGCoreImpl/SGNova2GloveImpl.h" +#include "SGCoreImpl/SGNovaGloveImpl.h" +#include "SGCoreImpl/SGSenseGloveImpl.h" +#include "SGLog/SGLog.h" + +int32 FSGDeviceListImpl::ActiveDevices() +{ + return FDeviceListType::ActiveDevices(); +} + +bool FSGDeviceListImpl::SenseCommRunning() +{ + return FDeviceListType::SenseComRunning(); +} + +void FSGDeviceListImpl::Dispose() +{ + FDeviceListType::Dispose(); +} + +void FSGDeviceListImpl::Reinitialize() +{ + FDeviceListType::Reinitialize(); +} + +TArray> FSGDeviceListImpl::GetDevices() +{ + const FSGDeviceImpl::FSGDevicePtrVectorType Devices = FDeviceListType::GetDevices(); + TArray> DeviceImpls; + + for (const FSGDeviceImpl::FSGDevicePtrType& Device: Devices) + { + switch (FSGCoreEnumCast::ToESGDeviceType(Device->GetDeviceType())) + { + case ESGDeviceType::BetaDevice: + { + FSGBetaDeviceImpl::FBetaDevicePtrType BetaDevice = + std::dynamic_pointer_cast(Device); + if (ensureAlwaysMsgf(BetaDevice, TEXT("Invalid BetaDevice!"))) + { + TSharedRef BetaDeviceImpl{ + MakeShared(BetaDevice) + }; + DeviceImpls.Push(MoveTemp(BetaDeviceImpl)); + } + } + break; + + case ESGDeviceType::Nova2: + { + FSGNova2GloveImpl::FNova2GlovePtrType Nova2Glove = + std::dynamic_pointer_cast(Device); + if (ensureAlwaysMsgf(Nova2Glove, TEXT("Invalid Nova2Glove device!"))) + { + TSharedRef Nova2GloveImpl{MakeShared(Nova2Glove)}; + DeviceImpls.Push(MoveTemp(Nova2GloveImpl)); + } + } + break; + + case ESGDeviceType::Nova: + { + FSGNovaGloveImpl::FNovaGlovePtrType NovaGlove = + std::dynamic_pointer_cast(Device); + if (ensureAlwaysMsgf(NovaGlove, TEXT("Invalid NovaGlove device!"))) + { + TSharedRef NovaGloveImpl{MakeShared(NovaGlove)}; + DeviceImpls.Push(MoveTemp(NovaGloveImpl)); + } + } + break; + + case ESGDeviceType::SenseGlove: + { + FSGSenseGloveImpl::FSenseGlovePtrType SenseGlove{ + std::dynamic_pointer_cast(Device)}; + if (ensureAlwaysMsgf(SenseGlove, TEXT("Invalid SenseGlove device!"))) + { + TSharedRef SenseGloveImpl{ + MakeShared(SenseGlove) + }; + DeviceImpls.Push(MoveTemp(SenseGloveImpl)); + } + } + break; + + default: + SGLOG_WARNING( + FString::Printf(TEXT("Unknown SenseGlove device '%s'!"), UTF8_TO_TCHAR(typeid(Device).name())), + FString::Printf(TEXT("Device ID: '%s'!"), UTF8_TO_TCHAR(Device->GetDeviceId().c_str())), + FString::Printf(TEXT("Hardware Version: '%s'!"), UTF8_TO_TCHAR(Device->GetHardwareVersion().c_str())), + FString::Printf(TEXT("Firmware Version: '%d'!"), Device->GetFirmwareVersion()), + FString::Printf(TEXT("Sub Firmware Version: '%d'!"), Device->GetSubFirmwareVersion()), + FString::Printf(TEXT("Firmware String: '%s'!"), UTF8_TO_TCHAR(Device->GetFirmwareString().c_str())) + ); + + break;; + } + } + + return DeviceImpls; +} + +bool FSGDeviceListImpl::GetSensorDataString(const int32 IpcIndex, const FString& IpcAddress, FString& OutString) +{ + std::string IpcAddressString(TCHAR_TO_UTF8(*IpcAddress)); + std::string OutSensorData; + const bool bReturn = FDeviceListType::GetSensorDataString(IpcIndex, MoveTemp(IpcAddressString), OutSensorData); + OutString = UTF8_TO_TCHAR(OutSensorData.c_str()); + return bReturn; +} + +bool FSGDeviceListImpl::SendHaptics( + const int32 IpcIndex, const FString& IpcAddress, const int32 ChannelIndex, const FString& Commands) +{ + std::string IpcAddressString(TCHAR_TO_UTF8(*IpcAddress)); + std::string CommandsString(TCHAR_TO_UTF8(*Commands)); + return FDeviceListType::SendHaptics(IpcIndex, MoveTemp(IpcAddressString), ChannelIndex, MoveTemp(CommandsString)); +} + +FString FSGDeviceListImpl::GetDeviceStringAt(const int32 IpcIndex, const FString& IpcAddress, const int32 Index) +{ + std::string IpcAddressString(TCHAR_TO_UTF8(*IpcAddress)); + const FString String( + UTF8_TO_TCHAR(FDeviceListType::GetDeviceStringAt(IpcIndex, MoveTemp(IpcAddressString), Index).c_str())); + return String; +} + +FString FSGDeviceListImpl::GetAddress(const int32 IpcIndex, const FString& IpcAddress) +{ + std::string IpcAddressString(TCHAR_TO_UTF8(*IpcAddress)); + const FString Address(UTF8_TO_TCHAR(FDeviceListType::GetAddress(IpcIndex, MoveTemp(IpcAddressString)).c_str())); + return Address; +} + +ESGConnectionType FSGDeviceListImpl::GetConnectionType(const int32 IpcIndex, const FString& IpcAddress) +{ + std::string IpcAddressString(TCHAR_TO_UTF8(*IpcAddress)); + const ESGConnectionType Type( + FSGCoreEnumCast::ToESGConnectionType( + FDeviceListType::GetConnectionType(IpcIndex, MoveTemp(IpcAddressString)))); + return Type; +} + +bool FSGDeviceListImpl::IsConnected(const int32 IpcIndex, const FString& IpcAddress) +{ + std::string IpcAddressString(TCHAR_TO_UTF8(*IpcAddress)); + return FDeviceListType::IsConnected(IpcIndex, MoveTemp(IpcAddressString)); +} + +int32 FSGDeviceListImpl::PacketsPerSecondReceived(const int32 IpcIndex, const FString& IpcAddress) +{ + std::string IpcAddressString(TCHAR_TO_UTF8(*IpcAddress)); + return FDeviceListType::PacketsPerSecondReceived(IpcIndex, MoveTemp(IpcAddressString)); +} + +int32 FSGDeviceListImpl::PacketsPerSecondSent(const int32 IpcIndex, const FString& IpcAddress) +{ + std::string IpcAddressString(TCHAR_TO_UTF8(*IpcAddress)); + return FDeviceListType::PacketsPerSecondSent(IpcIndex, MoveTemp(IpcAddressString)); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGDeviceModelImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGDeviceModelImpl.cpp new file mode 100644 index 0000000..5c04ce5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGDeviceModelImpl.cpp @@ -0,0 +1,186 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGDeviceModelImpl.h" + +#include +#include + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_DeviceModel.h" + +struct FSGDeviceModelImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FDeviceModelType DeviceModel; + + /************************ + * Owner object + ************************/ + + FSGDeviceModelImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGDeviceModelImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +TArray FSGDeviceModelImpl::ParseFunctions(int32 Value, int32 Size) +{ + /// NOTE + /// std::vector is a non conforming container. Since it packs bools to be stored in one bit, + /// it cannot provide a bool reference. Thus FSGArrayUtils::FromStdVector() cannot be used. + + static TArray ParsedFunctionsArray; + + std::vector ParsedFunctionsVector{FDeviceModelType::ParseFunctions(Value, Size)}; + for (const bool bValue: ParsedFunctionsVector) + { + ParsedFunctionsArray.Add(bValue); + } + + return ParsedFunctionsArray; +} + +void FSGDeviceModelImpl::ParseFirmware(const FString& RawFirmware, int32& OutMainVersion, int32& OutSubVersion) +{ + std::string RawFirmwareString(TCHAR_TO_UTF8(*RawFirmware)); + FDeviceModelType::ParseFirmware(MoveTemp(RawFirmwareString), OutMainVersion, OutSubVersion); +} + +FSGDeviceModelImpl::FSGDeviceModelImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGDeviceModelImpl::FSGDeviceModelImpl( + const FString& Id, const FString& HardwareVersion, const int32 FirmwareVersion, const int32 SubFirmwareVersion) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + std::string IdString(TCHAR_TO_UTF8(*Id)); + std::string HardwareVersionString(TCHAR_TO_UTF8(*HardwareVersion)); + Pimpl->DeviceModel = FDeviceModelType(MoveTemp(IdString), MoveTemp(HardwareVersionString), + FirmwareVersion, SubFirmwareVersion); +} + +FSGDeviceModelImpl::FSGDeviceModelImpl(const FDeviceModelType& DeviceModel) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->DeviceModel = DeviceModel; +} + +FSGDeviceModelImpl::FSGDeviceModelImpl(const FSGDeviceModelImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGDeviceModelImpl::FSGDeviceModelImpl(FSGDeviceModelImpl&& Rhs) SG_NOEXCEPT = default; + +FSGDeviceModelImpl::~FSGDeviceModelImpl() = default; + +FSGDeviceModelImpl& FSGDeviceModelImpl::operator=(const FSGDeviceModelImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGDeviceModelImpl& FSGDeviceModelImpl::operator=(FSGDeviceModelImpl&& Rhs) SG_NOEXCEPT = default; + +const FSGDeviceModelImpl::FDeviceModelType& FSGDeviceModelImpl::ToDeviceModel() const +{ + return Pimpl->DeviceModel; +} + +FString FSGDeviceModelImpl::GetDeviceId() const +{ + const FString DeviceId(UTF8_TO_TCHAR(Pimpl->DeviceModel.GetDeviceId().c_str())); + return DeviceId; +} + +FString FSGDeviceModelImpl::GetHardwareVersion() const +{ + const FString HardwareVersion(UTF8_TO_TCHAR(Pimpl->DeviceModel.GetHardwareVersion().c_str())); + return HardwareVersion; +} + +int32 FSGDeviceModelImpl::GetFirmwareVersion() const +{ + return Pimpl->DeviceModel.GetFirmwareVersion(); +} + +int32 FSGDeviceModelImpl::GetSubFirmwareVersion() const +{ + return Pimpl->DeviceModel.GetSubFirmwareVersion(); +} + +bool FSGDeviceModelImpl::FirmwareNewerThan( + const int32 FirmwareMain, const int32 FirmwareSub, const bool bInclusive) const +{ + return Pimpl->DeviceModel.FirmwareNewerThan(FirmwareMain, FirmwareSub, bInclusive); +} + +bool FSGDeviceModelImpl::FirmwareOlderThan( + const int32 FirmwareMain, const int32 FirmwareSub, const bool bInclusive) const +{ + return Pimpl->DeviceModel.FirmwareOlderThan(FirmwareMain, FirmwareSub, bInclusive); +} + +FSGDeviceModelImpl::FImpl::FImpl(FSGDeviceModelImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGDeviceModelImpl::FImpl::~FImpl() = default; + +void FSGDeviceModelImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGExportedFunctions.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGExportedFunctions.cpp new file mode 100644 index 0000000..9ddc16d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGExportedFunctions.cpp @@ -0,0 +1,6246 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGExportedFunctions.h" + +#if PLATFORM_ANDROID +#include "Android/AndroidApplication.h" +#include "Android/AndroidJava.h" +#endif /* PLATFORM_ANDROID */ + +#include "Templates/UnrealTemplate.h" + +#if PLATFORM_ANDROID +#include "SGBuildHacks/SGInclude_Core_Android.h" +#endif /* PLATFORM_ANDROID */ + +#include "SGCoreImpl/SGAnatomyImpl.h" +#include "SGCoreImpl/SGDeviceListImpl.h" +#include "SGCoreImpl/SGHandLayerImpl.h" +#include "SGCoreImpl/SGJointKinematicsImpl.h" +#include "SGCoreImpl/SGLibraryImpl.h" +#include "SGCoreImpl/SGSenseComImpl.h" +#include "SGCoreImpl/SGSenseGloveVarsImpl.h" +#include "SGCoreImpl/SGTrackingImpl.h" +#include "SGInterop/SGIC_ESGBackendType.h" +#include "SGInterop/SGIC_ESGConnectionType.h" +#include "SGInterop/SGIC_ESGDeviceType.h" +#include "SGInterop/SGIC_ESGFinger.h" +#include "SGInterop/SGIC_ESGFingerMovement.h" +#include "SGInterop/SGIC_ESGFingerSolver.h" +#include "SGInterop/SGIC_ESGHapticChannelType.h" +#include "SGInterop/SGIC_ESGHapticGloveCalibrationState.h" +#include "SGInterop/SGIC_ESGHapticLocation.h" +#include "SGInterop/SGIC_ESGListFormat.h" +#include "SGInterop/SGIC_ESGNormalizationState.h" +#include "SGInterop/SGIC_ESGNova2SensorLocation.h" +#include "SGInterop/SGIC_ESGNova2VibroMotor.h" +#include "SGInterop/SGIC_ESGNovaCVar.h" +#include "SGInterop/SGIC_ESGNovaData.h" +#include "SGInterop/SGIC_ESGNovaSensorLocation.h" +#include "SGInterop/SGIC_ESGNovaVibroMotor.h" +#include "SGInterop/SGIC_ESGPositionalTrackingHardware.h" +#include "SGInterop/SGIC_ESGSenseGloveCVar.h" +#include "SGInterop/SGIC_ESGSenseGloveSVar.h" +#include "SGInterop/SGIC_ESGSenseGloveThumperCommand.h" +#include "SGInterop/SGIC_ESGSensorFormat.h" +#include "SGInterop/SGIC_ESGThumbMovement.h" +#include "SGInterop/SGIC_ESGThumbSolver.h" +#include "SGInterop/SGIC_ESGWaveformType.h" +#include "SGInterop/SGIC_FQuat.h" +#include "SGInterop/SGIC_FSGBasicHandModelImpl.h" +#include "SGInterop/SGIC_FSGBetaDeviceImpl.h" +#include "SGInterop/SGIC_FSGCustomWaveformImpl.h" +#include "SGInterop/SGIC_FSGDeviceImpl.h" +#include "SGInterop/SGIC_FSGDeviceModelImpl.h" +#include "SGInterop/SGIC_FSGHandInterpolatorImpl.h" +#include "SGInterop/SGIC_FSGHandPoseImpl.h" +#include "SGInterop/SGIC_FSGHapticChannelInfoImpl.h" +#include "SGInterop/SGIC_FSGHapticGloveImpl.h" +#include "SGInterop/SGIC_FSGInterpolationSetImpl.h" +#include "SGInterop/SGIC_FSGNova2GloveImpl.h" +#include "SGInterop/SGIC_FSGNova2GloveSensorDataImpl.h" +#include "SGInterop/SGIC_FSGNovaGloveImpl.h" +#include "SGInterop/SGIC_FSGNovaGloveInfoImpl.h" +#include "SGInterop/SGIC_FSGNovaGloveSensorDataImpl.h" +#include "SGInterop/SGIC_FSGSenseGloveImpl.h" +#include "SGInterop/SGIC_FSGSenseGloveInfoImpl.h" +#include "SGInterop/SGIC_FSGSenseGlovePoseImpl.h" +#include "SGInterop/SGIC_FSGSenseGloveSensorDataImpl.h" +#include "SGInterop/SGIC_FSGSenseGloveSensorNormalizerImpl.h" +#include "SGInterop/SGIC_FSGSensorNormalizationImpl.h" +#include "SGInterop/SGIC_FSGThresholdCommandImpl.h" +#include "SGInterop/SGIC_FString.h" +#include "SGInterop/SGIC_FVector.h" + +#if PLATFORM_ANDROID +#include "SGInterop/SGIC_jclass.h" +#include "SGInterop/SGIC_jmethodID.h" +#include "SGInterop/SGIC_JNIEnv_Ptr.h" +#endif /* PLATFORM_ANDROID */ + +#include "SGInterop/SGIC_TArray_bool.h" +#include "SGInterop/SGIC_TArray_float.h" +#include "SGInterop/SGIC_TArray_FQuat.h" +#include "SGInterop/SGIC_TArray_FSGNova2GloveImpl.h" +#include "SGInterop/SGIC_TArray_FSGNovaGloveImpl.h" +#include "SGInterop/SGIC_TArray_FSGSenseGloveImpl.h" +#include "SGInterop/SGIC_TArray_FString.h" +#include "SGInterop/SGIC_TArray_FVector.h" +#include "SGInterop/SGIC_TArray_int32.h" +#include "SGInterop/SGIC_TArray_TArray_float.h" +#include "SGInterop/SGIC_TArray_TArray_FQuat.h" +#include "SGInterop/SGIC_TArray_TArray_FSGInterpolationSetImpl.h" +#include "SGInterop/SGIC_TArray_TArray_FVector.h" +#include "SGInterop/SGIC_TArray_TSharedRef_FSGDeviceImpl.h" +#include "SGInterop/SGIC_TArray_TSharedRef_FSGHapticGloveImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGBetaDeviceImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGDeviceImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGHapticGloveImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGNova2GloveImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGNovaGloveImpl.h" +#include "SGInterop/SGIC_TSharedPtr_FSGSenseGloveImpl.h" + +/******************************************************************************* + * Exceptional function calls + ******************************************************************************/ + +#if PLATFORM_ANDROID +int32 SGCoreImpl_Android_Initialize( + void* InEnv, + void* InClass, + void* InActiveDevicesMethodID, + void* InGetDeviceStringMethodID, + void* InGetSensorStringMethodID, + void* InWriteHapticsMethodID, + void* StoragePath) +{ + return SGCore::Android::Initialize( + StaticCast(InEnv)->Ptr, + StaticCast(InClass)->Class, + StaticCast(InActiveDevicesMethodID)->MethodID, + StaticCast(InGetDeviceStringMethodID)->MethodID, + StaticCast(InGetSensorStringMethodID)->MethodID, + StaticCast(InWriteHapticsMethodID)->MethodID, + std::string{TCHAR_TO_UTF8(*StaticCast(StoragePath)->String)}); +} +#endif /* PLATFORM_ANDROID */ + +/******************************************************************************* + * SGAnatomyImpl.h + ******************************************************************************/ + +float SGCoreImpl_FSGAnatomyImpl_GetTotalFingerFlexion() +{ + return FSGAnatomyImpl::GetTotalFingerFlexion(); +} + +float SGCoreImpl_FSGAnatomyImpl_GetTotalFingerExtension() +{ + return FSGAnatomyImpl::GetTotalFingerExtension(); +} + +float SGCoreImpl_FSGAnatomyImpl_GetTotalThumbFlexion() +{ + return FSGAnatomyImpl::GetTotalThumbFlexion(); +} + +float SGCoreImpl_FSGAnatomyImpl_GetTotalThumbExtension() +{ + return FSGAnatomyImpl::GetTotalThumbExtension(); +} + +float SGCoreImpl_FSGAnatomyImpl_GetFingerJointLimit( + const bool bRightHanded, + const int32 Joint, + const int32 Movement, + const bool bMax) +{ + return FSGAnatomyImpl::GetFingerJointLimit(bRightHanded, Joint, Movement, bMax); +} + +float SGCoreImpl_FSGAnatomyImpl_GetThumbJointLimit( + const bool bRightHanded, + const int32 Joint, + const int32 Movement, + const bool bMax) +{ + return FSGAnatomyImpl::GetThumbJointLimit(bRightHanded, Joint, Movement, bMax); +} + +float SGCoreImpl_FSGAnatomyImpl_ClampJointAngle( + const float Value, + const int32 Finger, + const bool bRightHand, + const int32 Joint, + const int32 Movement) +{ + return FSGAnatomyImpl::ClampJointAngle(Value, Finger, bRightHand, Joint, Movement); +} + +float SGCoreImpl_FSGAnatomyImpl_NormalizeFingerFlexion( + const float FlexionInDegrees) +{ + return FSGAnatomyImpl::NormalizeFingerFlexion(FlexionInDegrees); +} + +float SGCoreImpl_FSGAnatomyImpl_NormalizeThumbFlexion( + const float FlexionInDegrees) +{ + return FSGAnatomyImpl::NormalizeThumbFlexion(FlexionInDegrees); +} + +void SGCoreImpl_FSGAnatomyImpl_GetDefaultHandAngles( + void* OutAngles, + const bool bRightHanded) +{ + StaticCast(OutAngles)->Array = FSGAnatomyImpl::GetDefaultHandAngles( + bRightHanded); +} + +void SGCoreImpl_FSGAnatomyImpl_GetFlatHandAngles( + void* OutAngles, + const bool bRightHanded) +{ + StaticCast(OutAngles)->Array = FSGAnatomyImpl::GetFlatHandAngles( + bRightHanded); +} + +void SGCoreImpl_FSGAnatomyImpl_GetThumbsUpHandAngles( + void* OutAngles, + const bool bRightHanded) +{ + StaticCast(OutAngles)->Array = FSGAnatomyImpl::GetThumbsUpHandAngles( + bRightHanded); +} + +void SGCoreImpl_FSGAnatomyImpl_GetFistHandAngles( + void* OutAngles, + const bool bRightHanded) +{ + StaticCast(OutAngles)->Array = FSGAnatomyImpl::GetFistHandAngles( + bRightHanded); +} + +/******************************************************************************* + * SGBasicHandModelImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGBasicHandModelImpl_Default( + void* OutBasicHandModelImpl, + const bool bRightHanded) +{ + StaticCast(OutBasicHandModelImpl)->BasicHandModelImpl = + FSGBasicHandModelImpl::Default(bRightHanded); +} + +void SGCoreImpl_FSGBasicHandModelImpl_Deserialize( + void* OutBasicHandModelImpl, + void* SerializedString) +{ + StaticCast(OutBasicHandModelImpl)->BasicHandModelImpl = + FSGBasicHandModelImpl::Deserialize( + StaticCast(SerializedString)->String); +} + +void SGCoreImpl_FSGBasicHandModelImpl_GetBaseFingerLengths( + void* OutLengths) +{ + StaticCast(OutLengths)->Array = FSGBasicHandModelImpl::GetBaseFingerLengths(); +} + +void SGCoreImpl_FSGBasicHandModelImpl_GetBaseJointPositions( + void* OutPositions) +{ + StaticCast(OutPositions)->Array = FSGBasicHandModelImpl::GetBaseJointPositions(); +} + +void SGCoreImpl_FSGBasicHandModelImpl_GetBaseJointAngles( + void* OutRotations) +{ + StaticCast(OutRotations)->Array = FSGBasicHandModelImpl::GetBaseJointAngles(); +} + +void SGCoreImpl_FSGBasicHandModelImpl_ctor( + void* OutBasicHandModelImpl) +{ + StaticCast(OutBasicHandModelImpl)->BasicHandModelImpl = FSGBasicHandModelImpl(); +} + +void SGCoreImpl_FSGBasicHandModelImpl_ctor_bRightHanded_Lengths_StartPosition( + void* OutBasicHandModelImpl, + const bool bRightHanded, + void* Lengths, + void* StartPositions) +{ + StaticCast(OutBasicHandModelImpl)->BasicHandModelImpl = + FSGBasicHandModelImpl( + bRightHanded, + StaticCast(Lengths)->Array, + StaticCast(StartPositions)->Array); +} + +void SGCoreImpl_FSGBasicHandModelImpl_ctor_bRightHanded_Lengths_StartPositions_StartRotations( + void* OutBasicHandModelImpl, + const bool bRightHanded, + void* Lengths, + void* StartPositions, + void* StartRotations) +{ + StaticCast(OutBasicHandModelImpl)->BasicHandModelImpl = + FSGBasicHandModelImpl( + bRightHanded, + StaticCast(Lengths)->Array, + StaticCast(StartPositions)->Array, + StaticCast(StartRotations)->Array); +} + +void SGCoreImpl_FSGBasicHandModelImpl_ctor_copy( + void* OutBasicHandModelImpl, + void* Rhs) +{ + StaticCast(OutBasicHandModelImpl)->BasicHandModelImpl = + FSGBasicHandModelImpl(StaticCast(Rhs)->BasicHandModelImpl); +} + +void SGCoreImpl_FSGBasicHandModelImpl_ctor_copy_assignment( + void* OutBasicHandModelImpl, + void* Rhs) +{ + StaticCast(OutBasicHandModelImpl)->BasicHandModelImpl = + StaticCast(Rhs)->BasicHandModelImpl; +} + +bool SGCoreImpl_FSGBasicHandModelImpl_IsRight( + void* Instance) +{ + return StaticCast(Instance)->BasicHandModelImpl.IsRight(); +} + +void SGCoreImpl_FSGBasicHandModelImpl_GetFingerLengths( + void* Instance, + void* OutLengths) +{ + StaticCast(OutLengths)->Array = + StaticCast(Instance)->BasicHandModelImpl.GetFingerLengths(); +} + +void SGCoreImpl_FSGBasicHandModelImpl_GetFingerLengths_Finger( + void* Instance, + void* OutLengths, + void* Finger) +{ + StaticCast(OutLengths)->Array = + StaticCast(Instance)->BasicHandModelImpl.GetFingerLengths( + StaticCast(Finger)->Finger); +} + +void SGCoreImpl_FSGBasicHandModelImpl_SetFingerLengths_ESGFinger( + void* Instance, + void* Finger, + void* Lengths) +{ + StaticCast(Instance)->BasicHandModelImpl.SetFingerLengths( + StaticCast(Finger)->Finger, + StaticCast(Lengths)->Array); +} + +void SGCoreImpl_FSGBasicHandModelImpl_SetFingerLengths_uint8Finger( + void* Instance, + const uint8 Finger, + void* Lengths) +{ + StaticCast(Instance)->BasicHandModelImpl.SetFingerLengths( + Finger, + StaticCast(Lengths)->Array); +} + +void SGCoreImpl_FSGBasicHandModelImpl_GetFingerRatios( + void* Instance, + void* OutRatios) +{ + StaticCast(OutRatios)->Array = + StaticCast(Instance)->BasicHandModelImpl.GetFingerRatios(); +} + +void SGCoreImpl_FSGBasicHandModelImpl_GetFingerRatios_Finger( + void* Instance, + void* OutRatios, + void* Finger) +{ + StaticCast(OutRatios)->Array = + StaticCast(Instance)->BasicHandModelImpl.GetFingerRatios( + StaticCast(Finger)->Finger); +} + +void SGCoreImpl_FSGBasicHandModelImpl_GetStartJointPositions( + void* Instance, + void* OutPositions) +{ + StaticCast(OutPositions)->Array = + StaticCast(Instance)->BasicHandModelImpl.GetStartJointPositions(); +} + +void SGCoreImpl_FSGBasicHandModelImpl_SetStartJointPosition_ESGFinger( + void* Instance, + void* Finger, + void* Position) +{ + StaticCast(Instance)->BasicHandModelImpl.SetStartJointPosition( + StaticCast(Finger)->Finger, + StaticCast(Position)->Vector); +} + +void SGCoreImpl_FSGBasicHandModelImpl_SetStartJointPosition_uin8Finger( + void* Instance, + const uint8 Finger, + void* Position) +{ + StaticCast(Instance)->BasicHandModelImpl.SetStartJointPosition( + Finger, + StaticCast(Position)->Vector); +} + +void SGCoreImpl_FSGBasicHandModelImpl_GetStartJointRotations( + void* Instance, + void* OutRotations) +{ + StaticCast(OutRotations)->Array = + StaticCast(Instance)->BasicHandModelImpl.GetStartJointRotations(); +} + +void SGCoreImpl_FSGBasicHandModelImpl_GetJointPosition( + void* Instance, + void* OutPosition, + void* Finger) +{ + StaticCast(OutPosition)->Vector = + StaticCast(Instance)->BasicHandModelImpl.GetJointPosition( + StaticCast(Finger)->Finger); +} + +void SGCoreImpl_FSGBasicHandModelImpl_SetJointPosition( + void* Instance, + void* NewPosition, + void* Finger) +{ + StaticCast(Instance)->BasicHandModelImpl.SetJointPosition( + StaticCast(NewPosition)->Vector, + StaticCast(Finger)->Finger); +} + +void SGCoreImpl_FSGBasicHandModelImpl_GetJointRotation( + void* Instance, + void* OutRotation, + void* Finger) +{ + StaticCast(OutRotation)->Quat = + StaticCast(Instance)->BasicHandModelImpl.GetJointRotation( + StaticCast(Finger)->Finger); +} + +void SGCoreImpl_FSGBasicHandModelImpl_SetJointRotation( + void* Instance, + void* NewRotation, + void* Finger) +{ + StaticCast(Instance)->BasicHandModelImpl.SetJointRotation( + StaticCast(NewRotation)->Quat, + StaticCast(Finger)->Finger); +} + +void SGCoreImpl_FSGBasicHandModelImpl_GetTotalLengths( + void* Instance, + void* OutLengths) +{ + StaticCast(OutLengths)->Array = + StaticCast(Instance)->BasicHandModelImpl.GetTotalLengths(); +} + +float SGCoreImpl_FSGBasicHandModelImpl_GetTotalLength( + void* Instance, + void* Finger) +{ + return StaticCast(Instance)->BasicHandModelImpl.GetTotalLength( + StaticCast(Finger)->Finger); +} + +void SGCoreImpl_FSGBasicHandModelImpl_Get3DLengths( + void* Instance, + void* OutLengths, + void* Finger) +{ + StaticCast(OutLengths)->Array = + StaticCast(Instance)->BasicHandModelImpl.Get3DLengths( + StaticCast(Finger)->Finger); +} + +bool SGCoreImpl_FSGBasicHandModelImpl_Equals( + void* Instance, + void* BasicHandModelImpl) +{ + return StaticCast(Instance)->BasicHandModelImpl.Equals( + StaticCast(BasicHandModelImpl)->BasicHandModelImpl); +} + +void SGCoreImpl_FSGBasicHandModelImpl_ToString( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->BasicHandModelImpl.ToString(); +} + +void SGCoreImpl_FSGBasicHandModelImpl_ToString_bLengthsOnly( + void* Instance, + void* OutString, + const bool bLengthsOnly) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->BasicHandModelImpl.ToString(bLengthsOnly); +} + +void SGCoreImpl_FSGBasicHandModelImpl_Serialize( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->BasicHandModelImpl.Serialize(); +} + +/******************************************************************************* + * SGBetaDeviceImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGBetaDeviceImpl_Parse( + void* OutBetaDevice, + void* String) +{ + StaticCast(OutBetaDevice)->Ptr = + FSGBetaDeviceImpl::Parse(StaticCast(String)->String); +} + +void SGCoreImpl_FSGBetaDeviceImpl_ctor( + void* OutBetaDeviceImpl) +{ + StaticCast(OutBetaDeviceImpl)->BetaDeviceImpl = FSGBetaDeviceImpl(); +} + +void SGCoreImpl_FSGBetaDeviceImpl_ctor_ConstantsString_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion( + void* OutBetaDeviceImpl, + void* ConstantsString, + void* DeviceId, + void* HardwareVersion, + const int32 FirmwareVersion, + const int32 SubFirmwareVersion) +{ + StaticCast(OutBetaDeviceImpl)->BetaDeviceImpl = + FSGBetaDeviceImpl{ + StaticCast(ConstantsString)->String, + StaticCast(DeviceId)->String, + StaticCast(HardwareVersion)->String, + FirmwareVersion, + SubFirmwareVersion + }; +} + +void +SGCoreImpl_FSGBetaDeviceImpl_ctor_ConstantsString_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_MakeShared( + void* OutSharedPtr, + void* ConstantsString, + void* DeviceId, + void* HardwareVersion, + const int32 FirmwareVersion, + const int32 SubFirmwareVersion) +{ + StaticCast(OutSharedPtr)->Ptr = + MakeShared( + StaticCast(ConstantsString)->String, + StaticCast(DeviceId)->String, + StaticCast(HardwareVersion)->String, + FirmwareVersion, + SubFirmwareVersion); +} + +void SGCoreImpl_FSGBetaDeviceImpl_ctor_MakeShared( + void* OutSharedPtr) +{ + StaticCast(OutSharedPtr)->Ptr = + MakeShared(); +} + +void SGCoreImpl_FSGBetaDeviceImpl_ctor_copy( + void* OutBetaDeviceImpl, + void* Rhs) +{ + StaticCast(OutBetaDeviceImpl)->BetaDeviceImpl = + FSGBetaDeviceImpl(StaticCast(Rhs)->BetaDeviceImpl); +} + +void SGCoreImpl_FSGBetaDeviceImpl_ctor_copy_MakeShared( + void* OutSharedPtr, + void* Rhs) +{ + StaticCast(OutSharedPtr)->Ptr = + MakeShared(StaticCast(Rhs)->BetaDeviceImpl); +} + +void SGCoreImpl_FSGBetaDeviceImpl_ctor_copy_assignment( + void* OutBetaDeviceImpl, + void* Rhs) +{ + StaticCast(OutBetaDeviceImpl)->BetaDeviceImpl = + StaticCast(Rhs)->BetaDeviceImpl; +} + +void SGCoreImpl_FSGBetaDeviceImpl_GetDeviceType( + void* Instance, + void* OutType) +{ + StaticCast(OutType)->Type = + StaticCast(Instance)->Ptr->GetDeviceType(); +} + +void SGCoreImpl_FSGBetaDeviceImpl_GetDeviceId( + void* Instance, + void* OutId) +{ + StaticCast(OutId)->String = + StaticCast(Instance)->Ptr->GetDeviceId(); +} + +void SGCoreImpl_FSGBetaDeviceImpl_GetHardwareVersion( + void* Instance, + void* OutVersion) +{ + StaticCast(OutVersion)->String = + StaticCast(Instance)->Ptr->GetHardwareVersion(); +} + +int32 SGCoreImpl_FSGBetaDeviceImpl_GetFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->Ptr->GetFirmwareVersion(); +} + +int32 SGCoreImpl_FSGBetaDeviceImpl_GetSubFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->Ptr->GetSubFirmwareVersion(); +} + +void SGCoreImpl_FSGBetaDeviceImpl_GetConstantsString( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->Ptr->GetConstantsString(); +} + +void SGCoreImpl_FSGBetaDeviceImpl_GetSensorData( + void* Instance, + void* OutData) +{ + StaticCast(OutData)->String = + StaticCast(Instance)->Ptr->GetSensorData(); +} + +void SGCoreImpl_FSGBetaDeviceImpl_GetLastCommand( + void* Instance, + void* OutCommand) +{ + StaticCast(OutCommand)->String = + StaticCast(Instance)->Ptr->GetLastCommand(); +} + +bool SGCoreImpl_FSGBetaDeviceImpl_SendHaptics( + void* Instance, + void* Command) +{ + return StaticCast(Instance)->Ptr->SendHaptics( + StaticCast(Command)->String); +} + +void SGCoreImpl_FSGBetaDeviceImpl_ToString( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->Ptr->ToString(); +} + +/******************************************************************************* + * SGCustomWaveformImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGCustomWaveformImpl_ToString_Type( + void* OutString, + void* Type) +{ + StaticCast(OutString)->String = FSGCustomWaveformImpl::ToString( + StaticCast(Type)->Type); +} + +void SGCoreImpl_FSGCustomWaveformImpl_ctor( + void* OutCustomWaveformImpl) +{ + StaticCast(OutCustomWaveformImpl)->CustomWaveformImpl = + FSGCustomWaveformImpl{}; +} + +void SGCoreImpl_FSGCustomWaveformImpl_ctor_Amplitude_Duration( + void* OutCustomWaveformImpl, + const float Amplitude, + const float Duration) +{ + StaticCast(OutCustomWaveformImpl)->CustomWaveformImpl = + FSGCustomWaveformImpl{Amplitude, Duration}; +} + +void SGCoreImpl_FSGCustomWaveformImpl_ctor_Amplitude_Duration_Frequency( + void* OutCustomWaveformImpl, + const float Amplitude, + const float Duration, + const float Frequency) +{ + StaticCast(OutCustomWaveformImpl)->CustomWaveformImpl = + FSGCustomWaveformImpl{Amplitude, Duration, Frequency}; +} + +void SGCoreImpl_FSGCustomWaveformImpl_ctor_copy( + void* OutCustomWaveformImpl, + void* Rhs) +{ + StaticCast(OutCustomWaveformImpl)->CustomWaveformImpl = + FSGCustomWaveformImpl(StaticCast(Rhs)->CustomWaveformImpl); +} + +void SGCoreImpl_FSGCustomWaveformImpl_ctor_copy_assignment( + void* OutCustomWaveformImpl, + void* Rhs) +{ + StaticCast(OutCustomWaveformImpl)->CustomWaveformImpl = + StaticCast(Rhs)->CustomWaveformImpl; +} + +float SGCoreImpl_FSGCustomWaveformImpl_GetAmplitude( + void* Instance) +{ + return StaticCast(Instance)->CustomWaveformImpl.GetAmplitude(); +} + +void SGCoreImpl_FSGCustomWaveformImpl_SetAmplitude( + void* Instance, + const float Amplitude) +{ + return StaticCast(Instance)->CustomWaveformImpl.SetAmplitude(Amplitude); +} + +void SGCoreImpl_FSGCustomWaveformImpl_GetWaveType( + void* Instance, + void* OutType) +{ + StaticCast(OutType)->Type = + StaticCast(Instance)->CustomWaveformImpl.GetWaveType(); +} + +void SGCoreImpl_FSGCustomWaveformImpl_SetWaveType( + void* Instance, + void* Type) +{ + StaticCast(Instance)->CustomWaveformImpl.SetWaveType( + StaticCast(Type)->Type); +} + +bool SGCoreImpl_FSGCustomWaveformImpl_IsInfinite( + void* Instance) +{ + return StaticCast(Instance)->CustomWaveformImpl.IsInfinite(); +} + +void SGCoreImpl_FSGCustomWaveformImpl_SetInfinite( + void* Instance, + const bool bInfinite) +{ + return StaticCast(Instance)->CustomWaveformImpl.SetInfinite(bInfinite); +} + +int32 SGCoreImpl_FSGCustomWaveformImpl_GetRepeatAmount( + void* Instance) +{ + return StaticCast(Instance)->CustomWaveformImpl.GetRepeatAmount(); +} + +void SGCoreImpl_FSGCustomWaveformImpl_SetRepeatAmount( + void* Instance, + const int32 Amount) +{ + return StaticCast(Instance)->CustomWaveformImpl.SetRepeatAmount(Amount); +} + +float SGCoreImpl_FSGCustomWaveformImpl_GetAttackTime( + void* Instance) +{ + return StaticCast(Instance)->CustomWaveformImpl.GetAttackTime(); +} + +void SGCoreImpl_FSGCustomWaveformImpl_SetAttackTime( + void* Instance, + const float Time) +{ + return StaticCast(Instance)->CustomWaveformImpl.SetAttackTime(Time); +} + +float SGCoreImpl_FSGCustomWaveformImpl_GetSustainTime( + void* Instance) +{ + return StaticCast(Instance)->CustomWaveformImpl.GetSustainTime(); +} + +void SGCoreImpl_FSGCustomWaveformImpl_SetSustainTime( + void* Instance, + const float Time) +{ + return StaticCast(Instance)->CustomWaveformImpl.SetSustainTime(Time); +} + +float SGCoreImpl_FSGCustomWaveformImpl_GetDecayTime( + void* Instance) +{ + return StaticCast(Instance)->CustomWaveformImpl.GetDecayTime(); +} + +void SGCoreImpl_FSGCustomWaveformImpl_SetDecayTime( + void* Instance, + const float Time) +{ + return StaticCast(Instance)->CustomWaveformImpl.SetDecayTime(Time); +} + +float SGCoreImpl_FSGCustomWaveformImpl_GetFrequencyStart( + void* Instance) +{ + return StaticCast(Instance)->CustomWaveformImpl.GetFrequencyStart(); +} + +void SGCoreImpl_FSGCustomWaveformImpl_SetFrequencyStart( + void* Instance, + const float Frequency) +{ + return StaticCast(Instance)->CustomWaveformImpl.SetFrequencyStart(Frequency); +} + +float SGCoreImpl_FSGCustomWaveformImpl_GetFrequencyEnd( + void* Instance) +{ + return StaticCast(Instance)->CustomWaveformImpl.GetFrequencyEnd(); +} + +void SGCoreImpl_FSGCustomWaveformImpl_SetFrequencyEnd( + void* Instance, + const float Frequency) +{ + return StaticCast(Instance)->CustomWaveformImpl.SetFrequencyEnd(Frequency); +} + +float SGCoreImpl_FSGCustomWaveformImpl_GetFrequencySwitchTime( + void* Instance) +{ + return StaticCast(Instance)->CustomWaveformImpl.GetFrequencySwitchTime(); +} + +void SGCoreImpl_FSGCustomWaveformImpl_SetFrequencySwitchTime( + void* Instance, + const float Time) +{ + return StaticCast(Instance)->CustomWaveformImpl.SetFrequencySwitchTime(Time); +} + +float SGCoreImpl_FSGCustomWaveformImpl_GetFrequencySwitchFactor( + void* Instance) +{ + return StaticCast(Instance)->CustomWaveformImpl.GetFrequencySwitchFactor(); +} + +void SGCoreImpl_FSGCustomWaveformImpl_SetFrequencySwitchFactor( + void* Instance, + const float Factor) +{ + return StaticCast(Instance)->CustomWaveformImpl.SetFrequencySwitchFactor(Factor); +} + +float SGCoreImpl_FSGCustomWaveformImpl_GetEffectTime( + void* Instance) +{ + return StaticCast(Instance)->CustomWaveformImpl.GetEffectTime(); +} + +float SGCoreImpl_FSGCustomWaveformImpl_GetTotalEffectTime( + void* Instance) +{ + return StaticCast(Instance)->CustomWaveformImpl.GetTotalEffectTime(); +} + +bool SGCoreImpl_FSGCustomWaveformImpl_FrequencyJumps( + void* Instance) +{ + return StaticCast(Instance)->CustomWaveformImpl.FrequencyJumps(); +} + +bool SGCoreImpl_FSGCustomWaveformImpl_Equals( + void* Instance, + void* CustomWaveformImpl) +{ + return StaticCast(Instance)->CustomWaveformImpl.Equals( + StaticCast(CustomWaveformImpl)->CustomWaveformImpl); +} + +void SGCoreImpl_FSGCustomWaveformImpl_ToString( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->CustomWaveformImpl.ToString(); +} + +/******************************************************************************* + * SGDeviceImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGDeviceImpl_ParseFirmware( + void* RawFirmware, int32* OutMainVersion, int32* OutSubVersion) +{ + FSGDeviceImpl::ParseFirmware( + StaticCast(RawFirmware)->String, + *OutMainVersion, + *OutSubVersion); +} + +bool SGCoreImpl_FSGDeviceImpl_FirmwareNewerThan_MyFirmwareMain_MyFirmwareSub_ReferenceMain_ReferenceSub_bInclusive( + const int32 MyFirmwareMain, + const int32 MyFirmwareSub, + const int32 ReferenceMain, + const int32 ReferenceSub, + const bool bInclusive) +{ + return FSGDeviceImpl::FirmwareNewerThan( + MyFirmwareMain, + MyFirmwareSub, + ReferenceMain, + ReferenceSub, + bInclusive); +} + +bool SGCoreImpl_FSGDeviceImpl_FirmwareOlderThan_MyFirmwareMain_MyFirmwareSub_ReferenceMain_ReferenceSub_bInclusive( + const int32 MyFirmwareMain, + const int32 MyFirmwareSub, + const int32 ReferenceMain, + const int32 ReferenceSub, + const bool bInclusive) +{ + return FSGDeviceImpl::FirmwareOlderThan( + MyFirmwareMain, + MyFirmwareSub, + ReferenceMain, + ReferenceSub, + bInclusive); +} + +void SGCoreImpl_FSGDeviceImpl_ToString_DeviceType( + void* DeviceType, + void* OutString) +{ + StaticCast(OutString)->String = + FSGDeviceImpl::ToString( + StaticCast(DeviceType)->Type); +} + +void SGCoreImpl_FSGDeviceImpl_ctor( + void* OutSGDeviceImpl) +{ + StaticCast(OutSGDeviceImpl)->SGDeviceImpl = FSGDeviceImpl(); +} + +void SGCoreImpl_FSGDeviceImpl_ctor_MakeShared( + void* OutSharedPtr) +{ + StaticCast(OutSharedPtr)->Ptr = + MakeShared(); +} + +void SGCoreImpl_FSGDeviceImpl_ctor_copy( + void* OutSGDeviceImpl, + void* Rhs) +{ + StaticCast(OutSGDeviceImpl)->SGDeviceImpl = + FSGDeviceImpl(StaticCast(Rhs)->SGDeviceImpl); +} + +void SGCoreImpl_FSGDeviceImpl_ctor_copy_MakeShared( + void* OutSharedPtr, + void* Rhs) +{ + StaticCast(OutSharedPtr)->Ptr = + MakeShared(StaticCast(Rhs)->SGDeviceImpl); +} + +void SGCoreImpl_FSGDeviceImpl_ctor_copy_assignment( + void* OutSGDeviceImpl, + void* Rhs) +{ + StaticCast(OutSGDeviceImpl)->SGDeviceImpl = + StaticCast(Rhs)->SGDeviceImpl; +} + +void SGCoreImpl_FSGDeviceImpl_ToSGDeviceImplRef( + void* Instance, + void* OutSharedPtr) +{ + StaticCast(OutSharedPtr)->Ptr = + StaticCast(Instance)->Ptr->ToSGDeviceImplRef(); +} + +void SGCoreImpl_FSGDeviceImpl_ToBetaDeviceImplRef( + void* Instance, + void* OutSharedPtr) +{ + StaticCast(OutSharedPtr)->Ptr = + StaticCast(Instance)->Ptr->ToBetaDeviceImplRef(); +} + +void SGCoreImpl_FSGDeviceImpl_ToHapticGloveImplRef( + void* Instance, + void* OutSharedPtr) +{ + StaticCast(OutSharedPtr)->Ptr = + StaticCast(Instance)->Ptr->ToHapticGloveImplRef(); +} + +void SGCoreImpl_FSGDeviceImpl_ToNova2GloveImplRef( + void* Instance, + void* OutSharedPtr) +{ + StaticCast(OutSharedPtr)->Ptr = + StaticCast(Instance)->Ptr->ToNova2GloveImplRef(); +} + +void SGCoreImpl_FSGDeviceImpl_ToNovaGloveImplRef( + void* Instance, + void* OutSharedPtr) +{ + StaticCast(OutSharedPtr)->Ptr = + StaticCast(Instance)->Ptr->ToNovaGloveImplRef(); +} + +void SGCoreImpl_FSGDeviceImpl_ToSenseGloveImplRef( + void* Instance, + void* OutSharedPtr) +{ + StaticCast(OutSharedPtr)->Ptr = + StaticCast(Instance)->Ptr->ToSenseGloveImplRef(); +} + +bool SGCoreImpl_FSGDeviceImpl_IsABetaDevice( + void* Instance) +{ + return StaticCast(Instance)->Ptr->IsABetaDevice(); +} + +bool SGCoreImpl_FSGDeviceImpl_IsAHapticGlove( + void* Instance) +{ + return StaticCast(Instance)->Ptr->IsAHapticGlove(); +} + +bool SGCoreImpl_FSGDeviceImpl_IsANova2Glove( + void* Instance) +{ + return StaticCast(Instance)->Ptr->IsANova2Glove(); +} + +bool SGCoreImpl_FSGDeviceImpl_IsANovaGlove( + void* Instance) +{ + return StaticCast(Instance)->Ptr->IsANovaGlove(); +} + +bool SGCoreImpl_FSGDeviceImpl_IsASenseGlove( + void* Instance) +{ + return StaticCast(Instance)->Ptr->IsASenseGlove(); +} + +void SGCoreImpl_FSGDeviceImpl_AsBetaDevice( + void* Instance, + void* OutSharedPtr) +{ + StaticCast(OutSharedPtr)->Ptr = + StaticCast(Instance)->Ptr->AsBetaDevice(); +} + +void SGCoreImpl_FSGDeviceImpl_AsHapticGlove( + void* Instance, + void* OutSharedPtr) +{ + StaticCast(OutSharedPtr)->Ptr = + StaticCast(Instance)->Ptr->AsHapticGlove(); +} + +void SGCoreImpl_FSGDeviceImpl_AsNova2Glove( + void* Instance, + void* OutSharedPtr) +{ + StaticCast(OutSharedPtr)->Ptr = + StaticCast(Instance)->Ptr->AsNova2Glove(); +} + +void SGCoreImpl_FSGDeviceImpl_AsNovaGlove( + void* Instance, + void* OutSharedPtr) +{ + StaticCast(OutSharedPtr)->Ptr = + StaticCast(Instance)->Ptr->AsNovaGlove(); +} + +void SGCoreImpl_FSGDeviceImpl_AsSenseGlove( + void* Instance, + void* OutSharedPtr) +{ + StaticCast(OutSharedPtr)->Ptr = + StaticCast(Instance)->Ptr->AsSenseGlove(); +} + +void SGCoreImpl_FSGDeviceImpl_GetDeviceType( + void* Instance, + void* OutType) +{ + StaticCast(OutType)->Type = + StaticCast(Instance)->Ptr->GetDeviceType(); +} + +void SGCoreImpl_FSGDeviceImpl_GetDeviceId( + void* Instance, + void* OutId) +{ + StaticCast(OutId)->String = + StaticCast(Instance)->Ptr->GetDeviceId(); +} + +void SGCoreImpl_FSGDeviceImpl_GetHardwareVersion( + void* Instance, + void* OutVersion) +{ + StaticCast(OutVersion)->String = + StaticCast(Instance)->Ptr->GetHardwareVersion(); +} + +int32 SGCoreImpl_FSGDeviceImpl_GetFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->Ptr->GetFirmwareVersion(); +} + +int32 SGCoreImpl_FSGDeviceImpl_GetSubFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->Ptr->GetSubFirmwareVersion(); +} + +void SGCoreImpl_FSGDeviceImpl_GetFirmwareString( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->Ptr->GetFirmwareString(); +} + +bool SGCoreImpl_FSGDeviceImpl_FirmwareNewerThan_MyFirmwareMain_MyFirmwareSub_bInclusive( + void* Instance, + const int32 MyFirmwareMain, + const int32 MyFirmwareSub, + const bool bInclusive) +{ + return StaticCast(Instance)->Ptr->FirmwareNewerThan( + MyFirmwareMain, + MyFirmwareSub, + bInclusive); +} + +bool SGCoreImpl_FSGDeviceImpl_FirmwareOlderThan_MyFirmwareMain_MyFirmwareSub_bInclusive( + void* Instance, + const int32 MyFirmwareMain, + const int32 MyFirmwareSub, + const bool bInclusive) +{ + return StaticCast(Instance)->Ptr->FirmwareOlderThan( + MyFirmwareMain, + MyFirmwareSub, + bInclusive); +} + +void SGCoreImpl_FSGDeviceImpl_GetAddress( + void* Instance, + void* Address) +{ + StaticCast(Address)->String = + StaticCast(Instance)->Ptr->GetAddress(); +} + +bool SGCoreImpl_FSGDeviceImpl_IsConnected( + void* Instance) +{ + return StaticCast(Instance)->Ptr->IsConnected(); +} + +void SGCoreImpl_FSGDeviceImpl_GetConnectionType( + void* Instance, + void* OutType) +{ + StaticCast(OutType)->Type = + StaticCast(Instance)->Ptr->GetConnectionType(); +} + +int32 SGCoreImpl_FSGDeviceImpl_PacketsPerSecondReceived( + void* Instance) +{ + return StaticCast(Instance)->Ptr->PacketsPerSecondReceived(); +} + +int32 SGCoreImpl_FSGDeviceImpl_PacketsPerSecondSent( + void* Instance) +{ + return StaticCast(Instance)->Ptr->PacketsPerSecondSent(); +} + +int32 SGCoreImpl_FSGDeviceImpl_GetDeviceIndex( + void* Instance) +{ + return StaticCast(Instance)->Ptr->GetDeviceIndex(); +} + +void SGCoreImpl_FSGDeviceImpl_SetDeviceIndex( + void* Instance, + const int32 NewIndex) +{ + return StaticCast(Instance)->Ptr->SetDeviceIndex(NewIndex); +} + +bool SGCoreImpl_FSGDeviceImpl_IsWireless( + void* Instance) +{ + return StaticCast(Instance)->Ptr->IsWireless(); +} + +bool SGCoreImpl_FSGDeviceImpl_HasBattery( + void* Instance) +{ + return StaticCast(Instance)->Ptr->HasBattery(); +} + +bool SGCoreImpl_FSGDeviceImpl_IsCharging( + void* Instance) +{ + return StaticCast(Instance)->Ptr->IsCharging(); +} + +bool SGCoreImpl_FSGDeviceImpl_GetBatteryLevel( + void* Instance, + float* OutLevel) +{ + return StaticCast(Instance)->Ptr->GetBatteryLevel( + *OutLevel); +} + +void SGCoreImpl_FSGDeviceImpl_SetHapticChannels( + void* Instance, + void* Channels) +{ + StaticCast(Instance)->Ptr->SetHapticChannels( + StaticCast(Channels)->HapticChannelInfoImpl); +} + +int32 SGCoreImpl_FSGDeviceImpl_GetHapticChannelCount( + void* Instance) +{ + return StaticCast(Instance)->Ptr->GetHapticChannelCount(); +} + +int32 SGCoreImpl_FSGDeviceImpl_GetHapticChannelCount_ChannelType( + void* Instance, + void* ChannelType) +{ + return StaticCast(Instance)->Ptr->GetHapticChannelCount( + StaticCast(ChannelType)->Type); +} + +void SGCoreImpl_FSGDeviceImpl_ToString( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->Ptr->ToString(); +} + +/******************************************************************************* + * SGDeviceListImpl.h + ******************************************************************************/ + +int32 SGCoreImpl_FSGDeviceListImpl_ActiveDevices() +{ + return FSGDeviceListImpl::ActiveDevices(); +} + +bool SGCoreImpl_FSGDeviceListImpl_SenseCommRunning() +{ + return FSGDeviceListImpl::SenseCommRunning(); +} + +void SGCoreImpl_FSGDeviceListImpl_Dispose() +{ + FSGDeviceListImpl::Dispose(); +} + +void SGCoreImpl_FSGDeviceListImpl_Reinitialize() +{ + FSGDeviceListImpl::Reinitialize(); +} + +void SGCoreImpl_FSGDeviceListImpl_GetDevices( + void* OutDevices) +{ + StaticCast(OutDevices)->Array = + FSGDeviceListImpl::GetDevices(); +} + +bool SGCoreImpl_FSGDeviceListImpl_GetSensorDataString( + const int32 IpcIndex, + void* IpcAddress, + void* OutString) +{ + return FSGDeviceListImpl::GetSensorDataString( + IpcIndex, + StaticCast(IpcAddress)->String, + StaticCast(OutString)->String); +} + +bool SGCoreImpl_FSGDeviceListImpl_SendHaptics( + const int32 IpcIndex, + void* IpcAddress, + const int32 ChannelIndex, + void* Commands) +{ + return FSGDeviceListImpl::SendHaptics( + IpcIndex, + StaticCast(IpcAddress)->String, + ChannelIndex, + StaticCast(Commands)->String); +} + +void SGCoreImpl_FSGDeviceListImpl_GetDeviceStringAt( + void* OutString, + const int32 IpcIndex, + void* IpcAddress, + const int32 Index) +{ + StaticCast(OutString)->String = FSGDeviceListImpl::GetDeviceStringAt( + IpcIndex, + StaticCast(IpcAddress)->String, Index); +} + +void SGCoreImpl_FSGDeviceListImpl_GetAddress( + void* OutAddress, const int32 IpcIndex, + void* IpcAddress) +{ + StaticCast(OutAddress)->String = FSGDeviceListImpl::GetAddress( + IpcIndex, + StaticCast(IpcAddress)->String); +} + +void SGCoreImpl_FSGDeviceListImpl_GetConnectionType( + void* OutType, + const int32 IpcIndex, + void* IpcAddress) +{ + StaticCast(OutType)->Type = + FSGDeviceListImpl::GetConnectionType( + IpcIndex, + StaticCast(IpcAddress)->String); +} + +bool SGCoreImpl_FSGDeviceListImpl_IsConnected( + const int32 IpcIndex, + void* IpcAddress) +{ + return FSGDeviceListImpl::IsConnected(IpcIndex, StaticCast(IpcAddress)->String); +} + +int32 SGCoreImpl_FSGDeviceListImpl_PacketsPerSecondReceived( + const int32 IpcIndex, + void* IpcAddress) +{ + return FSGDeviceListImpl::PacketsPerSecondReceived(IpcIndex, StaticCast(IpcAddress)->String); +} + +int32 SGCoreImpl_FSGDeviceListImpl_PacketsPerSecondSent( + const int32 IpcIndex, + void* IpcAddress) +{ + return FSGDeviceListImpl::PacketsPerSecondSent(IpcIndex, StaticCast(IpcAddress)->String); +} + +/******************************************************************************* + * SGDeviceModelImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGDeviceModelImpl_ParseFunctions( + void* OutParseFunctions, + const int32 Value, + const int32 Size) +{ + StaticCast(OutParseFunctions)->Array = FSGDeviceModelImpl::ParseFunctions(Value, Size); +} + +void SGCoreImpl_FSGDeviceModelImpl_ParseFirmware( + void* RawFirmware, + int32* OutMainVersion, + int32* OutSubVersion) +{ + FSGDeviceModelImpl::ParseFirmware( + StaticCast(RawFirmware)->String, + *OutMainVersion, + *OutSubVersion); +} + +void SGCoreImpl_FSGDeviceModelImpl_ctor( + void* OutDeviceModelImpl) +{ + StaticCast(OutDeviceModelImpl)->DeviceModelImpl = FSGDeviceModelImpl(); +} + +void SGCoreImpl_FSGDeviceModelImpl_ctor_Id_HardwareVersion_FirmwareVersion_SubFirmwareVersion( + void* OutDeviceModelImpl, + void* Id, + void* HardwareVersion, + const int32 FirmwareVersion, + const int32 SubFirmwareVersion) +{ + StaticCast(OutDeviceModelImpl)->DeviceModelImpl = + FSGDeviceModelImpl( + StaticCast(Id)->String, + StaticCast(HardwareVersion)->String, + FirmwareVersion, + SubFirmwareVersion); +} + +void SGCoreImpl_FSGDeviceModelImpl_ctor_copy( + void* OutDeviceModelImpl, + void* Rhs) +{ + StaticCast(OutDeviceModelImpl)->DeviceModelImpl = + FSGDeviceModelImpl(StaticCast(Rhs)->DeviceModelImpl); +} + +void SGCoreImpl_FSGDeviceModelImpl_ctor_copy_assignment( + void* OutDeviceModelImpl, + void* Rhs) +{ + StaticCast(OutDeviceModelImpl)->DeviceModelImpl = + StaticCast(Rhs)->DeviceModelImpl; +} + +void SGCoreImpl_FSGDeviceModelImpl_GetDeviceId( + void* Instance, + void* OutId) +{ + StaticCast(OutId)->String = + StaticCast(Instance)->DeviceModelImpl.GetDeviceId(); +} + +void SGCoreImpl_FSGDeviceModelImpl_GetHardwareVersion( + void* Instance, + void* OutVersion) +{ + StaticCast(OutVersion)->String = + StaticCast(Instance)->DeviceModelImpl.GetHardwareVersion(); +} + +int32 SGCoreImpl_FSGDeviceModelImpl_GetFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->DeviceModelImpl.GetFirmwareVersion(); +} + +int32 SGCoreImpl_FSGDeviceModelImpl_GetSubFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->DeviceModelImpl.GetSubFirmwareVersion(); +} + +bool SGCoreImpl_FSGDeviceModelImpl_FirmwareNewerThan( + void* Instance, + const int32 FirmwareMain, + const int32 FirmwareSub, + const bool bInclusive) +{ + return StaticCast(Instance)->DeviceModelImpl.FirmwareNewerThan( + FirmwareMain, + FirmwareSub, + bInclusive); +} + +bool SGCoreImpl_FSGDeviceModelImpl_FirmwareOlderThan( + void* Instance, + const int32 FirmwareMain, + const int32 FirmwareSub, + const bool bInclusive) +{ + return StaticCast(Instance)->DeviceModelImpl.FirmwareOlderThan( + FirmwareMain, + FirmwareSub, + bInclusive); +} + +/******************************************************************************* + * SGHandInterpolatorImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGHandInterpolatorImpl_Deserialize( + void* OutHandInterpolatorImpl, + void* SerializedString, + const bool bRightHanded) +{ + StaticCast(OutHandInterpolatorImpl)->HandInterpolatorImpl = + FSGHandInterpolatorImpl::Deserialize( + StaticCast(SerializedString)->String, + bRightHanded); +} + +void SGCoreImpl_FSGHandInterpolatorImpl_ctor( + void* OutHandInterpolatorImpl) +{ + StaticCast(OutHandInterpolatorImpl)->HandInterpolatorImpl = + FSGHandInterpolatorImpl(); +} + +void SGCoreImpl_FSGHandInterpolatorImpl_ctor_bRightHanded( + void* OutHandInterpolatorImpl, + const bool bRightHanded) +{ + StaticCast(OutHandInterpolatorImpl)->HandInterpolatorImpl = + FSGHandInterpolatorImpl(bRightHanded); +} + +void SGCoreImpl_FSGHandInterpolatorImpl_ctor_copy( + void* OutHandInterpolatorImpl, + void* Rhs) +{ + StaticCast(OutHandInterpolatorImpl)->HandInterpolatorImpl = + FSGHandInterpolatorImpl(StaticCast(Rhs)->HandInterpolatorImpl); +} + +void SGCoreImpl_FSGHandInterpolatorImpl_ctor_copy_assignment( + void* OutHandInterpolatorImpl, + void* Rhs) +{ + StaticCast(OutHandInterpolatorImpl)->HandInterpolatorImpl = + StaticCast(Rhs)->HandInterpolatorImpl; +} + +float SGCoreImpl_FSGHandInterpolatorImpl_CalculateAngle_ESGFingerMovement_Value_bApplyLimits( + void* Instance, + void* Movement, + const float Value, + const bool bApplyLimits) +{ + return StaticCast(Instance)->HandInterpolatorImpl.CalculateAngle( + StaticCast(Movement)->Movement, + Value, + bApplyLimits); +} + +float SGCoreImpl_FSGHandInterpolatorImpl_CalculateAngle_ESGThumbMovement_Value_bApplyLimits( + void* Instance, + void* Movement, + const float Value, + const bool bApplyLimits) +{ + return StaticCast(Instance)->HandInterpolatorImpl.CalculateAngle( + StaticCast(Movement)->Movement, + Value, + bApplyLimits); +} + +void SGCoreImpl_FSGHandInterpolatorImpl_InterpolateHandAngles( + void* Instance, + void* OutAngles, + void* Flexions, + void* Abductions, + const float CmcTwist) +{ + StaticCast(OutAngles)->Array = + StaticCast(Instance)->HandInterpolatorImpl.InterpolateHandAngles( + StaticCast(Flexions)->Array, + StaticCast(Abductions)->Array, + CmcTwist); +} + +bool SGCoreImpl_FSGHandInterpolatorImpl_Equals( + void* Instance, + void* HandInterpolatorImpl) +{ + return StaticCast(Instance)->HandInterpolatorImpl.Equals( + StaticCast(HandInterpolatorImpl)->HandInterpolatorImpl); +} + +void SGCoreImpl_FSGHandInterpolatorImpl_Serialize( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->HandInterpolatorImpl.Serialize(); +} + +/******************************************************************************* + * SGHandLayerImpl.h + ******************************************************************************/ + +bool SGCoreImpl_FSGHandLayerImpl_DeviceConnected( + const bool bRightHanded) +{ + return FSGHandLayerImpl::DeviceConnected( + bRightHanded); +} + +void SGCoreImpl_FSGHandLayerImpl_GetDeviceType( + void* OutDeviceType, + const bool bRightHanded) +{ + StaticCast(OutDeviceType)->Type = + FSGHandLayerImpl::GetDeviceType( + bRightHanded); +} + +bool SGCoreImpl_FSGHandLayerImpl_GetFirstGloveHandedness() +{ + return FSGHandLayerImpl::GetFirstGloveHandedness(); +} + +int32 SGCoreImpl_FSGHandLayerImpl_GlovesConnected() +{ + return FSGHandLayerImpl::GlovesConnected(); +} + +bool SGCoreImpl_FSGHandLayerImpl_GetGloveInstance( + const bool bRightHanded, + void* OutGlove) +{ + return FSGHandLayerImpl::GetGloveInstance( + bRightHanded, + StaticCast(OutGlove)->Ptr); +} + +void SGCoreImpl_FSGHandLayerImpl_GetCalibrationState( + void* OutHapticGloveCalibrationState, + const bool bRightHanded) +{ + StaticCast(OutHapticGloveCalibrationState)->State = + FSGHandLayerImpl::GetCalibrationState(bRightHanded); +} + +void SGCoreImpl_FSGHandLayerImpl_GetCalibrationInstructions( + void* OutString, + const bool bRightHanded) +{ + StaticCast(OutString)->String = + FSGHandLayerImpl::GetCalibrationInstructions( + bRightHanded); +} + +void SGCoreImpl_FSGHandLayerImpl_ResetCalibration( + const bool bRightHanded) +{ + FSGHandLayerImpl::ResetCalibration( + bRightHanded); +} + +void SGCoreImpl_FSGHandLayerImpl_EndCalibration( + const bool bRightHanded) +{ + FSGHandLayerImpl::EndCalibration( + bRightHanded); +} + +bool SGCoreImpl_FSGHandLayerImpl_GetHandPose( + const bool bRightHanded, + void* OutHandPose) +{ + return FSGHandLayerImpl::GetHandPose( + bRightHanded, + StaticCast(OutHandPose)->HandPoseImpl); +} + +void SGCoreImpl_FSGHandLayerImpl_GetWristLocation( + const bool bRightHanded, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutWristPosition, + void* OutWristRotation) +{ + FSGHandLayerImpl::GetWristLocation( + bRightHanded, + StaticCast(ReferencePosition)->Vector, + StaticCast(ReferenceRotation)->Quat, + StaticCast(TrackingHardware)->Hardware, + StaticCast(OutWristPosition)->Vector, + StaticCast(OutWristRotation)->Quat); +} + +void SGCoreImpl_FSGHandLayerImpl_StopAllHaptics( + const bool bRightHanded) +{ + FSGHandLayerImpl::StopAllHaptics( + bRightHanded); +} + +bool SGCoreImpl_FSGHandLayerImpl_SendHaptics( + const bool bRightHanded) +{ + return FSGHandLayerImpl::SendHaptics( + bRightHanded); +} + +bool SGCoreImpl_FSGHandLayerImpl_SupportsCustomWaveform( + const bool bRightHanded, + void* AtLocation) +{ + return FSGHandLayerImpl::SupportsCustomWaveform( + bRightHanded, + StaticCast(AtLocation)->Location); +} + +bool SGCoreImpl_FSGHandLayerImpl_SendCustomWaveform( + const bool bRightHanded, + void* OutWaveform, + void* Location) +{ + return FSGHandLayerImpl::SendCustomWaveform( + bRightHanded, + StaticCast(OutWaveform)->CustomWaveformImpl, + StaticCast(Location)->Location); +} + +bool SGCoreImpl_FSGHandLayerImpl_QueueCommand_ForceFeedbackLevel( + const bool bRightHanded, + const int32 Finger, + const float Level01, + const bool bSendImmediate) +{ + return FSGHandLayerImpl::QueueCommand_ForceFeedbackLevel( + bRightHanded, + Finger, + Level01, + bSendImmediate); +} + +bool SGCoreImpl_FSGHandLayerImpl_QueueCommand_ForceFeedbackLevels( + const bool bRightHanded, + void* Levels01, + const bool bSendImmediate) +{ + return FSGHandLayerImpl::QueueCommand_ForceFeedbackLevels( + bRightHanded, + StaticCast(Levels01)->Array, + bSendImmediate); +} + +bool SGCoreImpl_FSGHandLayerImpl_QueueCommand_VibroLevels( + const bool bRightHanded, + void* Levels01, + const bool bSendImmediate) +{ + return FSGHandLayerImpl::QueueCommand_VibroLevels( + bRightHanded, + StaticCast(Levels01)->Array, + bSendImmediate); +} + +bool SGCoreImpl_FSGHandLayerImpl_QueueCommand_VibroLevel_bRightHanded_Finger_Level0_bSendImmediate( + const bool bRightHanded, + const int32 Finger, + const float Level01, + const bool bSendImmediate) +{ + return FSGHandLayerImpl::QueueCommand_VibroLevel( + bRightHanded, + Finger, + Level01, + bSendImmediate); +} + +bool SGCoreImpl_FSGHandLayerImpl_QueueCommand_VibroLevel_bRightHanded_AtLocation_Level01_bSendImmediate( + const bool bRightHanded, + void* AtLocation, + const float Level01, + const bool bSendImmediate) +{ + return FSGHandLayerImpl::QueueCommand_VibroLevel( + bRightHanded, + StaticCast(AtLocation)->Location, + Level01, + bSendImmediate); +} + +bool SGCoreImpl_FSGHandLayerImpl_SupportsWristSqueeze( + const bool bRightHanded) +{ + return FSGHandLayerImpl::SupportsWristSqueeze( + bRightHanded); +} + +bool SGCoreImpl_FSGHandLayerImpl_QueueCommand_WristSqueeze( + const bool bRightHanded, + const float SqueezeLevel01, + const bool bSendImmediate) +{ + return FSGHandLayerImpl::QueueCommand_WristSqueeze( + bRightHanded, + SqueezeLevel01, + bSendImmediate); +} + +bool SGCoreImpl_FSGHandLayerImpl_SupportsFlexionLocks( + const bool bRightHanded) +{ + return FSGHandLayerImpl::SupportsFlexionLocks( + bRightHanded); +} + +bool SGCoreImpl_FSGHandLayerImpl_QueueCommand_FlexionLock( + const bool bRightHanded, + const int32 Finger, + const float Flexion01, + const bool bSendImmediate) +{ + return FSGHandLayerImpl::QueueCommand_FlexionLock( + bRightHanded, + Finger, + Flexion01, + bSendImmediate); +} + +bool SGCoreImpl_FSGHandLayerImpl_QueueCommand_ClearFlexionLock( + const bool bRightHanded, + const int32 Finger, + const bool bSendImmediate) +{ + return FSGHandLayerImpl::QueueCommand_ClearFlexionLock( + bRightHanded, + Finger, + bSendImmediate); +} + +/******************************************************************************* + * SGHandPoseImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGHandPoseImpl_Deserialize( + void* OutHandPoseImpl, + void* SerializedString) +{ + StaticCast(OutHandPoseImpl)->HandPoseImpl = + FSGHandPoseImpl::Deserialize(StaticCast(SerializedString)->String); +} + +void SGCoreImpl_FSGHandPoseImpl_FromHandAngles_HandAngles_bRightHanded_HandDimensions( + void* OutHandPoseImpl, + void* HandAngles, + const bool bRightHanded, + void* HandDimensions) +{ + StaticCast(OutHandPoseImpl)->HandPoseImpl = + FSGHandPoseImpl::FromHandAngles( + StaticCast(HandAngles)->Array, + bRightHanded, + StaticCast(HandDimensions)->BasicHandModelImpl); +} + +void SGCoreImpl_FSGHandPoseImpl_FromHandAngles_HandAngles_bRightHanded( + void* OutHandPoseImpl, + void* HandAngles, + const bool bRightHanded) +{ + StaticCast(OutHandPoseImpl)->HandPoseImpl = + FSGHandPoseImpl::FromHandAngles( + StaticCast(HandAngles)->Array, + bRightHanded); +} + +void SGCoreImpl_FSGHandPoseImpl_DefaultIdle_bRightHanded_HandDimensions( + void* OutHandPoseImpl, + const bool bRightHanded, + void* HandDimensions) +{ + StaticCast(OutHandPoseImpl)->HandPoseImpl = + FSGHandPoseImpl::DefaultIdle( + bRightHanded, + StaticCast(HandDimensions)->BasicHandModelImpl); +} + +void SGCoreImpl_FSGHandPoseImpl_DefaultIdle_bRightHanded( + void* OutHandPoseImpl, + const bool bRightHanded) +{ + StaticCast(OutHandPoseImpl)->HandPoseImpl = + FSGHandPoseImpl::DefaultIdle( + bRightHanded); +} + +void SGCoreImpl_FSGHandPoseImpl_FlatHand_bRightHanded_HandDimensions( + void* OutHandPoseImpl, + const bool bRightHanded, + void* HandDimensions) +{ + StaticCast(OutHandPoseImpl)->HandPoseImpl = + FSGHandPoseImpl::FlatHand( + bRightHanded, + StaticCast(HandDimensions)->BasicHandModelImpl); +} + +void SGCoreImpl_FSGHandPoseImpl_FlatHand_bRightHanded( + void* OutHandPoseImpl, + const bool bRightHanded) +{ + StaticCast(OutHandPoseImpl)->HandPoseImpl = + FSGHandPoseImpl::FlatHand( + bRightHanded); +} + +void SGCoreImpl_FSGHandPoseImpl_ThumbsUp_bRightHanded_HandDimensions( + void* OutHandPoseImpl, + const bool bRightHanded, + void* HandDimensions) +{ + StaticCast(OutHandPoseImpl)->HandPoseImpl = + FSGHandPoseImpl::ThumbsUp( + bRightHanded, + StaticCast(HandDimensions)->BasicHandModelImpl); +} + +void SGCoreImpl_FSGHandPoseImpl_ThumbsUp_bRightHanded( + void* OutHandPoseImpl, + const bool bRightHanded) +{ + StaticCast(OutHandPoseImpl)->HandPoseImpl = + FSGHandPoseImpl::ThumbsUp( + bRightHanded); +} + +void SGCoreImpl_FSGHandPoseImpl_Fist_bRightHanded_HandDimensions( + void* OutHandPoseImpl, + const bool bRightHanded, + void* HandDimensions) +{ + StaticCast(OutHandPoseImpl)->HandPoseImpl = + FSGHandPoseImpl::Fist( + bRightHanded, + StaticCast(HandDimensions)->BasicHandModelImpl); +} + +void SGCoreImpl_FSGHandPoseImpl_Fist_bRightHanded( + void* OutHandPoseImpl, + const bool bRightHanded) +{ + StaticCast(OutHandPoseImpl)->HandPoseImpl = + FSGHandPoseImpl::Fist( + bRightHanded); +} + +void SGCoreImpl_FSGHandPoseImpl_ctor( + void* OutHandPoseImpl) +{ + StaticCast(OutHandPoseImpl)->HandPoseImpl = FSGHandPoseImpl(); +} + +void SGCoreImpl_FSGHandPoseImpl_ctor_bRightHanded_JointPositions_JointRotations_HandAngles( + void* OutHandPoseImpl, + const bool bRightHanded, + void* JointPositions, + void* JointRotations, + void* HandAngles) +{ + StaticCast(OutHandPoseImpl)->HandPoseImpl = + FSGHandPoseImpl( + bRightHanded, + StaticCast(JointPositions)->Array, + StaticCast(JointRotations)->Array, + StaticCast(HandAngles)->Array); +} + +void SGCoreImpl_FSGHandPoseImpl_ctor_copy( + void* OutHandPoseImpl, + void* Rhs) +{ + StaticCast(OutHandPoseImpl)->HandPoseImpl = + FSGHandPoseImpl(StaticCast(Rhs)->HandPoseImpl); +} + +void SGCoreImpl_FSGHandPoseImpl_ctor_copy_assignment( + void* OutHandPoseImpl, + void* Rhs) +{ + StaticCast(OutHandPoseImpl)->HandPoseImpl = + StaticCast(Rhs)->HandPoseImpl; +} + +bool SGCoreImpl_FSGHandPoseImpl_IsRight( + void* Instance) +{ + return StaticCast(Instance)->HandPoseImpl.IsRight(); +} + +void SGCoreImpl_FSGHandPoseImpl_GetJointPositions( + void* Instance, + void* OutPositions) +{ + StaticCast(OutPositions)->Array = + StaticCast(Instance)->HandPoseImpl.GetJointPositions(); +} + +void SGCoreImpl_FSGHandPoseImpl_GetJointRotations( + void* Instance, + void* OutRotations) +{ + StaticCast(OutRotations)->Array = + StaticCast(Instance)->HandPoseImpl.GetJointRotations(); +} + +void SGCoreImpl_FSGHandPoseImpl_GetHandAngles( + void* Instance, + void* OutAngles) +{ + StaticCast(OutAngles)->Array = + StaticCast(Instance)->HandPoseImpl.GetHandAngles(); +} + +bool SGCoreImpl_FSGHandPoseImpl_Equals( + void* Instance, + void* HandPoseImpl) +{ + return StaticCast(Instance)->HandPoseImpl.Equals( + StaticCast(HandPoseImpl)->HandPoseImpl); +} + +float SGCoreImpl_FSGHandPoseImpl_GetNormalizedFlexion_Finger_bClamp01( + void* Instance, + void* Finger, + const bool bClamp01) +{ + return StaticCast(Instance)->HandPoseImpl.GetNormalizedFlexion( + StaticCast(Finger)->Finger, + bClamp01); +} + +void SGCoreImpl_FSGHandPoseImpl_GetNormalizedFlexion_bClamp01( + void* Instance, + void* OutFlexion, + const bool bClamp01) +{ + StaticCast(OutFlexion)->Array = + StaticCast(Instance)->HandPoseImpl.GetNormalizedFlexion( + bClamp01); +} + +void SGCoreImpl_FSGHandPoseImpl_ToString( + void* Instance, + void* OutString, + const bool bShortFormat) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->HandPoseImpl.ToString(bShortFormat); +} + +void SGCoreImpl_FSGHandPoseImpl_Serialize( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->HandPoseImpl.Serialize(); +} + +/******************************************************************************* + * SGHapticChannelInfoImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGHapticChannelInfoImpl_GenerateAddress( + void* OutString, + const int32 DeviceIndex, + const int32 ChannelIndex) +{ + StaticCast(OutString)->String = + FSGHapticChannelInfoImpl::GenerateAddress(DeviceIndex, ChannelIndex); +} + +void SGCoreImpl_FSGHapticChannelInfoImpl_Parse( + void* OutHapticChannelInfoImpl, + void* IpcString) +{ + StaticCast(OutHapticChannelInfoImpl)->HapticChannelInfoImpl = + FSGHapticChannelInfoImpl::Parse(StaticCast(IpcString)->String); +} + +int32 SGCoreImpl_FSGHapticChannelInfoImpl_GetStreamingType() +{ + return FSGHapticChannelInfoImpl::GetStreamingType(); +} + +int32 SGCoreImpl_FSGHapticChannelInfoImpl_GetFireAndForgetType() +{ + return FSGHapticChannelInfoImpl::GetFireAndForgetType(); +} + +void SGCoreImpl_FSGHapticChannelInfoImpl_ctor( + void* OutHapticChannelInfoImpl) +{ + StaticCast(OutHapticChannelInfoImpl)->HapticChannelInfoImpl = + FSGHapticChannelInfoImpl(); +} + +void SGCoreImpl_FSGHapticChannelInfoImpl_ctor_StreamIndex_FireAndForgetIndex( + void* OutHapticChannelInfoImpl, + void* StreamIndex, + void* FireAndForgetIndex) +{ + StaticCast(OutHapticChannelInfoImpl)->HapticChannelInfoImpl = + FSGHapticChannelInfoImpl( + StaticCast(StreamIndex)->Array, + StaticCast(FireAndForgetIndex)->Array); +} + +void SGCoreImpl_FSGHapticChannelInfoImpl_ctor_copy( + void* OutHapticChannelInfoImpl, + void* Rhs) +{ + StaticCast(OutHapticChannelInfoImpl)->HapticChannelInfoImpl = + FSGHapticChannelInfoImpl(StaticCast(Rhs)->HapticChannelInfoImpl); +} + +void SGCoreImpl_FSGHapticChannelInfoImpl_ctor_copy_assignment( + void* OutHapticChannelInfoImpl, + void* Rhs) +{ + StaticCast(OutHapticChannelInfoImpl)->HapticChannelInfoImpl = + StaticCast(Rhs)->HapticChannelInfoImpl; +} + +int32 SGCoreImpl_FSGHapticChannelInfoImpl_GetStreamChannelCount( + void* Instance) +{ + return StaticCast(Instance)->HapticChannelInfoImpl.GetStreamChannelCount(); +} + +int32 SGCoreImpl_FSGHapticChannelInfoImpl_GetFireAndForgetChannelCount( + void* Instance) +{ + return + StaticCast(Instance)->HapticChannelInfoImpl.GetFireAndForgetChannelCount(); +} + +int32 SGCoreImpl_FSGHapticChannelInfoImpl_GetTotalChannelCount( + void* Instance) +{ + return StaticCast(Instance)->HapticChannelInfoImpl.GetTotalChannelCount(); +} + +void SGCoreImpl_FSGHapticChannelInfoImpl_GetAddress_Unguarded( + void* Instance, + void* OutString, + void* Type, + const int32 TypeIndex) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->HapticChannelInfoImpl.GetAddress_Unguarded( + StaticCast(Type)->Type, + TypeIndex); + +} + +void SGCoreImpl_FSGHapticChannelInfoImpl_GetIpcParams_Unguarded( + void* Instance, + void* Type, + const int32 TypeIndex, + int32* OutIndex, + void* OutAddressString) +{ + StaticCast(Instance)->HapticChannelInfoImpl.GetIpcParams_Unguarded( + StaticCast(Type)->Type, + TypeIndex, + *OutIndex, + StaticCast(OutAddressString)->String); +} + +void SGCoreImpl_FSGHapticChannelInfoImpl_RegenerateAddresses( + void* Instance, + const int32 ForDeviceIndex) +{ + StaticCast(Instance)->HapticChannelInfoImpl.RegenerateAddresses( + ForDeviceIndex); +} + +void SGCoreImpl_FSGHapticChannelInfoImpl_GetAllAddresses( + void* Instance, + void* OutArray) +{ + StaticCast(OutArray)->Array = + StaticCast(Instance)->HapticChannelInfoImpl.GetAllAddresses(); +} + +/******************************************************************************* + * SGHapticGloveImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGHapticGloveImpl_GetHapticGloves( + void* OutGloves, + const bool bConnectedOnly) +{ + StaticCast(OutGloves)->Array = + FSGHapticGloveImpl::GetHapticGloves(bConnectedOnly); +} + +bool SGCoreImpl_FSGHapticGloveImpl_GetGlove_OutGlove( + void* OutGlove) +{ + return FSGHapticGloveImpl::GetGlove( + StaticCast(OutGlove)->Ptr); +} + +bool SGCoreImpl_FSGHapticGloveImpl_GetGlove_bRightHanded_OutGlove( + const bool bRightHanded, + void* OutGlove) +{ + return FSGHapticGloveImpl::GetGlove( + bRightHanded, + StaticCast(OutGlove)->Ptr); +} + +void SGCoreImpl_FSGHapticGloveImpl_ToString_State( + void* OutString, + void* State) +{ + StaticCast(OutString)->String = + FSGHapticGloveImpl::ToString( + StaticCast(State)->State); +} + +void SGCoreImpl_FSGHapticGloveImpl_ToString_Location( + void* OutString, + void* Location) +{ + StaticCast(OutString)->String = + FSGHapticGloveImpl::ToString( + StaticCast(Location)->Location); +} + +void SGCoreImpl_FSGHapticGloveImpl_ctor( + void* OutHapticGloveImpl) +{ + StaticCast(OutHapticGloveImpl)->HapticGloveImpl = FSGHapticGloveImpl(); +} + +void SGCoreImpl_FSGHapticGloveImpl_ctor_MakeShared( + void* OutSharedPtr) +{ + StaticCast(OutSharedPtr)->Ptr = + MakeShared(); +} + +void SGCoreImpl_FSGHapticGloveImpl_ctor_copy( + void* OutHapticGloveImpl, + void* Rhs) +{ + StaticCast(OutHapticGloveImpl)->HapticGloveImpl = + FSGHapticGloveImpl(StaticCast(Rhs)->HapticGloveImpl); +} + +void SGCoreImpl_FSGHapticGloveImpl_ctor_copy_MakeShared( + void* OutSharedPtr, + void* Rhs) +{ + StaticCast(OutSharedPtr)->Ptr = + MakeShared(StaticCast(Rhs)->HapticGloveImpl); +} + +void SGCoreImpl_FSGHapticGloveImpl_ctor_copy_assignment( + void* OutHapticGloveImpl, + void* Rhs) +{ + StaticCast(OutHapticGloveImpl)->HapticGloveImpl = + StaticCast(Rhs)->HapticGloveImpl; +} + +void SGCoreImpl_FSGHapticGloveImpl_GetDeviceType( + void* Instance, + void* OutType) +{ + StaticCast(OutType)->Type = + StaticCast(Instance)->Ptr->GetDeviceType(); +} + +void SGCoreImpl_FSGHapticGloveImpl_GetDeviceId( + void* Instance, + void* OutId) +{ + StaticCast(OutId)->String = + StaticCast(Instance)->Ptr->GetDeviceId(); +} + +void SGCoreImpl_FSGHapticGloveImpl_GetHardwareVersion( + void* Instance, + void* OutVersion) +{ + StaticCast(OutVersion)->String = + StaticCast(Instance)->Ptr->GetHardwareVersion(); +} + +int32 SGCoreImpl_FSGHapticGloveImpl_GetFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->Ptr->GetFirmwareVersion(); +} + +int32 SGCoreImpl_FSGHapticGloveImpl_GetSubFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->Ptr->GetSubFirmwareVersion(); +} + +bool SGCoreImpl_FSGHapticGloveImpl_IsRight( + void* Instance) +{ + return StaticCast(Instance)->Ptr->IsRight(); +} + +bool SGCoreImpl_FSGHapticGloveImpl_GetImuRotation( + void* Instance, + void* OutImu) +{ + return StaticCast(Instance)->Ptr->GetImuRotation( + StaticCast(OutImu)->Quat); +} + +bool SGCoreImpl_FSGHapticGloveImpl_GetHandPose_HandGeometry_OutHandPose( + void* Instance, + void* HandGeometry, + void* OutHandPose) +{ + return StaticCast(Instance)->Ptr->GetHandPose( + StaticCast(HandGeometry)->BasicHandModelImpl, + StaticCast(OutHandPose)->HandPoseImpl); +} + +bool SGCoreImpl_FSGHapticGloveImpl_GetHandPose_OutHandPose( + void* Instance, + void* OutHandPose) +{ + return StaticCast(Instance)->Ptr->GetHandPose( + StaticCast(OutHandPose)->HandPoseImpl); +} + +bool SGCoreImpl_FSGHapticGloveImpl_GetHandAngles_OutHandAngles( + void* Instance, + void* OutHandAngles) +{ + return StaticCast(Instance)->Ptr->GetHandAngles( + StaticCast(OutHandAngles)->Array); +} + +void SGCoreImpl_FSGHapticGloveImpl_GetHandGeometry( + void* Instance, + void* OutBasicHandModel) +{ + StaticCast(OutBasicHandModel)->BasicHandModelImpl = + StaticCast(Instance)->Ptr->GetHandGeometry(); +} + +void SGCoreImpl_FSGHapticGloveImpl_SetHandGeometry( + void* Instance, + void* HandGeometry) +{ + StaticCast(Instance)->Ptr->SetHandGeometry( + StaticCast(HandGeometry)->BasicHandModelImpl); +} + +void SGCoreImpl_FSGHapticGloveImpl_GetCalibrationState( + void* Instance, + void* OutHapticGloveCalibrationState) +{ + StaticCast(OutHapticGloveCalibrationState)->State = + StaticCast(Instance)->Ptr->GetCalibrationState(); +} + +void SGCoreImpl_FSGHapticGloveImpl_EndCalibration( + void* Instance) +{ + StaticCast(Instance)->Ptr->EndCalibration(); +} + +void SGCoreImpl_FSGHapticGloveImpl_ResetCalibration( + void* Instance) +{ + StaticCast(Instance)->Ptr->ResetCalibration(); +} + +void SGCoreImpl_FSGHapticGloveImpl_GetCalibrationInstruction( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->Ptr->GetCalibrationInstruction(); +} + +void SGCoreImpl_FSGHapticGloveImpl_StopHaptics( + void* Instance) +{ + return StaticCast(Instance)->Ptr->StopHaptics(); +} + +void SGCoreImpl_FSGHapticGloveImpl_StopVibrations( + void* Instance) +{ + return StaticCast(Instance)->Ptr->StopVibrations(); +} + +bool SGCoreImpl_FSGHapticGloveImpl_SendHaptics( + void* Instance) +{ + return StaticCast(Instance)->Ptr->SendHaptics(); +} + +bool SGCoreImpl_FSGHapticGloveImpl_SupportsCustomWaveform( + void* Instance, + void* AtLocation) +{ + return StaticCast(Instance)->Ptr->SupportsCustomWaveform( + StaticCast(AtLocation)->Location); +} + +bool SGCoreImpl_FSGHapticGloveImpl_SendCustomWaveform( + void* Instance, + void* OutWaveform, + void* Location) +{ + return StaticCast(Instance)->Ptr->SendCustomWaveform( + StaticCast(OutWaveform)->CustomWaveformImpl, + StaticCast(Location)->Location); +} + +bool SGCoreImpl_FSGHapticGloveImpl_QueueForceFeedbackLevels( + void* Instance, + void* Levels01) +{ + return StaticCast(Instance)->Ptr->QueueForceFeedbackLevels( + StaticCast(Levels01)->Array); +} + +bool SGCoreImpl_FSGHapticGloveImpl_QueueForceFeedbackLevel( + void* Instance, + const int32 Finger, + const float Level01) +{ + return StaticCast(Instance)->Ptr->QueueForceFeedbackLevel( + Finger, + Level01); +} + +bool SGCoreImpl_FSGHapticGloveImpl_QueueVibroLevels( + void* Instance, + void* Levels01) +{ + return StaticCast(Instance)->Ptr->QueueVibroLevels( + StaticCast(Levels01)->Array); +} + +bool SGCoreImpl_FSGHapticGloveImpl_QueueVibroLevel( + void* Instance, + void* Location, + const float Level01) +{ + return StaticCast(Instance)->Ptr->QueueVibroLevel( + StaticCast(Location)->Location, + Level01); +} + +void SGCoreImpl_FSGHapticGloveImpl_GetWristLocation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutWristPosition, + void* OutWristRotation) +{ + StaticCast(Instance)->Ptr->GetWristLocation( + StaticCast(ReferencePosition)->Vector, + StaticCast(ReferenceRotation)->Quat, + StaticCast(TrackingHardware)->Hardware, + StaticCast(OutWristPosition)->Vector, + StaticCast(OutWristRotation)->Quat); +} + +void SGCoreImpl_FSGHapticGloveImpl_GetGloveLocation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutGlovePosition, + void* OutGloveRotation) +{ + StaticCast(Instance)->Ptr->GetGloveLocation( + StaticCast(ReferencePosition)->Vector, + StaticCast(ReferenceRotation)->Quat, + StaticCast(TrackingHardware)->Hardware, + StaticCast(OutGlovePosition)->Vector, + StaticCast(OutGloveRotation)->Quat); +} + +void SGCoreImpl_FSGHapticGloveImpl_ToString( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->Ptr->ToString(); +} + +/******************************************************************************* + * SGInterpolationSetImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGInterpolationSetImpl_Deserialize( + void* OutInterpolationSetImpl, + void* SerializedString) +{ + StaticCast(OutInterpolationSetImpl)->InterpolationSetImpl = + FSGInterpolationSetImpl::Deserialize( + StaticCast(SerializedString)->String); +} + +void SGCoreImpl_FSGInterpolationSetImpl_ctor( + void* OutInterpolationSetImpl) +{ + StaticCast(OutInterpolationSetImpl)->InterpolationSetImpl = + FSGInterpolationSetImpl(); +} + +void SGCoreImpl_FSGInterpolationSetImpl_ctor_From1_From2_To1_To2( + void* OutInterpolationSetImpl, + const float From1, + const float From2, + const float To1, + const float To2) +{ + StaticCast(OutInterpolationSetImpl)->InterpolationSetImpl = + FSGInterpolationSetImpl( + From1, + From2, + To1, + To2); +} + +void SGCoreImpl_FSGInterpolationSetImpl_ctor_From1_From2_To1_To2_Min_Max( + void* OutInterpolationSetImpl, + const float From1, + const float From2, + const float To1, + const float To2, + const float Min, + const float Max) +{ + StaticCast(OutInterpolationSetImpl)->InterpolationSetImpl = + FSGInterpolationSetImpl( + From1, + From2, + To1, + To2, + Min, + Max); +} + +void SGCoreImpl_FSGInterpolationSetImpl_ctor_copy( + void* OutInterpolationSetImpl, + void* Rhs) +{ + StaticCast(OutInterpolationSetImpl)->InterpolationSetImpl = + FSGInterpolationSetImpl(StaticCast(Rhs)->InterpolationSetImpl); +} + +void SGCoreImpl_FSGInterpolationSetImpl_ctor_copy_assignment( + void* OutInterpolationSetImpl, + void* Rhs) +{ + StaticCast(OutInterpolationSetImpl)->InterpolationSetImpl = + StaticCast(Rhs)->InterpolationSetImpl; +} + +float SGCoreImpl_FSGInterpolationSetImpl_GetX0( + void* Instance) +{ + return StaticCast(Instance)->InterpolationSetImpl.GetX0(); +} + +void SGCoreImpl_FSGInterpolationSetImpl_SetX0( + void* Instance, + const float X0) +{ + return StaticCast(Instance)->InterpolationSetImpl.SetX0(X0); +} + +float SGCoreImpl_FSGInterpolationSetImpl_GetX1( + void* Instance) +{ + return StaticCast(Instance)->InterpolationSetImpl.GetX1(); +} + +void SGCoreImpl_FSGInterpolationSetImpl_SetX1( + void* Instance, + const float X1) +{ + return StaticCast(Instance)->InterpolationSetImpl.SetX1(X1); +} + +float SGCoreImpl_FSGInterpolationSetImpl_GetY0( + void* Instance) +{ + return StaticCast(Instance)->InterpolationSetImpl.GetY0(); +} + +void SGCoreImpl_FSGInterpolationSetImpl_SetY0( + void* Instance, + const float Y0) +{ + return StaticCast(Instance)->InterpolationSetImpl.SetY0(Y0); +} + +float SGCoreImpl_FSGInterpolationSetImpl_GetY1( + void* Instance) +{ + return StaticCast(Instance)->InterpolationSetImpl.GetY1(); +} + +void SGCoreImpl_FSGInterpolationSetImpl_SetY1( + void* Instance, + const float Y1) +{ + return StaticCast(Instance)->InterpolationSetImpl.SetY1(Y1); +} + +float SGCoreImpl_FSGInterpolationSetImpl_GetMin( + void* Instance) +{ + return StaticCast(Instance)->InterpolationSetImpl.GetMin(); +} + +void SGCoreImpl_FSGInterpolationSetImpl_SetMin( + void* Instance, + const float Min) +{ + StaticCast(Instance)->InterpolationSetImpl.SetMin(Min); +} + +float SGCoreImpl_FSGInterpolationSetImpl_GetMax( + void* Instance) +{ + return StaticCast(Instance)->InterpolationSetImpl.GetMax(); +} + +void SGCoreImpl_FSGInterpolationSetImpl_SetMax( + void* Instance, + const float Max) +{ + StaticCast(Instance)->InterpolationSetImpl.SetMax(Max); +} + +float SGCoreImpl_FSGInterpolationSetImpl_Get( + void* Instance, + const float Value, + const bool bLimit, + const bool bNormalizeAngle) +{ + return StaticCast(Instance)->InterpolationSetImpl.Get( + Value, + bLimit, + bNormalizeAngle); +} + +bool SGCoreImpl_FSGInterpolationSetImpl_Equals( + void* Instance, + void* InterpolationSetImpl) +{ + return StaticCast(Instance)->InterpolationSetImpl.Equals( + StaticCast(InterpolationSetImpl)->InterpolationSetImpl); +} + +void SGCoreImpl_FSGInterpolationSetImpl_ToString( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->InterpolationSetImpl.ToString(); +} + +void SGCoreImpl_FSGInterpolationSetImpl_ToString_bLimits( + void* Instance, + void* OutString, + const bool bLimits) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->InterpolationSetImpl.ToString(bLimits); +} + +void SGCoreImpl_FSGInterpolationSetImpl_Serialize( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->InterpolationSetImpl.Serialize(); +} + +/******************************************************************************* + * SGJointKinematicsImpl.h + ******************************************************************************/ + +bool +SGCoreImpl_FSGJointKinematicsImpl_ForwardKinematics_StartPosition_StartRotation_JointLengths_JointAngles_OutNewPositions_OutNewRotations( + void* StartPosition, + void* StartRotation, + void* JointLengths, + void* JointAngles, + void* OutNewPositions, + void* OutNewRotations) +{ + return FSGJointKinematicsImpl::ForwardKinematics( + StaticCast(StartPosition)->Vector, + StaticCast(StartRotation)->Quat, + StaticCast(JointLengths)->Array, + StaticCast(JointAngles)->Array, + StaticCast(OutNewPositions)->Array, + StaticCast(OutNewRotations)->Array); +} + +bool SGCoreImpl_FSGJointKinematicsImpl_ForwardKinematics_Profile_Finger_JointAngles_OutNewPositions_OutNewRotations( + void* Profile, + void* Finger, + void* JointAngles, + void* OutNewPositions, + void* OutNewRotations) +{ + return FSGJointKinematicsImpl::ForwardKinematics( + StaticCast(Profile)->BasicHandModelImpl, + StaticCast(Finger)->Finger, + StaticCast(JointAngles)->Array, + StaticCast(OutNewPositions)->Array, + StaticCast(OutNewRotations)->Array); +} + +/******************************************************************************* + * SGLibraryImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGLibraryImpl_Version( + void* OutVersion) +{ + StaticCast(OutVersion)->String = FSGLibraryImpl::Version(); +} + +void SGCoreImpl_FSGLibraryImpl_GetBackendType( + void* OutType) +{ + StaticCast(OutType)->Type = FSGLibraryImpl::GetBackendType(); +} + +void SGCoreImpl_FSGLibraryImpl_BackendVersion( + void* OutVersion) +{ + StaticCast(OutVersion)->String = FSGLibraryImpl::BackendVersion(); +} + +void SGCoreImpl_FSGLibraryImpl_SGConnectVersion( + void* OutVersion) +{ + StaticCast(OutVersion)->String = FSGLibraryImpl::SGConnectVersion(); +} + +/******************************************************************************* + * SGNova2GloveImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGNova2GloveImpl_Parse( + void* OutNova2GloveImpl, + void* ConstantsString) +{ + StaticCast(OutNova2GloveImpl)->Ptr = + FSGNova2GloveImpl::Parse(StaticCast(ConstantsString)->String); +} + +void SGCoreImpl_FSGNova2GloveImpl_GetNova2Gloves( + void* OutGloves) +{ + StaticCast(OutGloves)->Array = + FSGNova2GloveImpl::GetNova2Gloves(); +} + +bool SGCoreImpl_FSGNova2GloveImpl_GetNova2Glove_OutGlove( + void* OutGlove) +{ + return FSGNova2GloveImpl::GetNova2Glove( + StaticCast(OutGlove)->Nova2GloveImpl); +} + +bool SGCoreImpl_FSGNova2GloveImpl_GetNova2Glove_bRightHanded_OutGlove( + const bool bRightHanded, + void* OutGlove) +{ + return FSGNova2GloveImpl::GetNova2Glove( + bRightHanded, + StaticCast(OutGlove)->Nova2GloveImpl); +} + +void SGCoreImpl_FSGNova2GloveImpl_CalculateGloveLocation( + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + const bool bRightHanded, + void* HardwareVersion, + void* OutGlovePosition, + void* OutGloveRotation) +{ + FSGNova2GloveImpl::CalculateGloveLocation( + StaticCast(ReferencePosition)->Vector, + StaticCast(ReferenceRotation)->Quat, + StaticCast(TrackingHardware)->Hardware, + bRightHanded, + StaticCast(HardwareVersion)->String, + StaticCast(OutGlovePosition)->Vector, + StaticCast(OutGloveRotation)->Quat); +} + +void SGCoreImpl_FSGNova2GloveImpl_CalculateWristLocation( + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + const bool bRightHanded, + void* HardwareVersion, + void* OutWristPosition, + void* OutWristRotation) +{ + FSGNova2GloveImpl::CalculateWristLocation( + StaticCast(ReferencePosition)->Vector, + StaticCast(ReferenceRotation)->Quat, + StaticCast(TrackingHardware)->Hardware, + bRightHanded, + StaticCast(HardwareVersion)->String, + StaticCast(OutWristPosition)->Vector, + StaticCast(OutWristRotation)->Quat); +} + +ANSICHAR SGCoreImpl_FSGNova2GloveImpl_GetStreamByte() +{ + return FSGNova2GloveImpl::GetStreamByte(); +} + +void SGCoreImpl_FSGNova2GloveImpl_GetNova2SensorRanges( + void* OutNova2SensorRanges) +{ + StaticCast(OutNova2SensorRanges)->Array = + FSGNova2GloveImpl::GetNova2SensorRanges(); +} + +void SGCoreImpl_FSGNova2GloveImpl_ToNormalizedValues_SensorData( + void* OutNormalizedValues, + void* SensorData) +{ + StaticCast(OutNormalizedValues)->Array = + FSGNova2GloveImpl::ToNormalizedValues( + StaticCast(SensorData)->Nova2GloveSensorDataImpl); +} + +void SGCoreImpl_FSGNova2GloveImpl_ToNormalizedValues_SensorData_OutSensorNormalizer( + void* OutNormalizedValues, + void* SensorData, + void* OutSensorNormalizer) +{ + StaticCast(OutNormalizedValues)->Array = + FSGNova2GloveImpl::ToNormalizedValues( + StaticCast(SensorData)->Nova2GloveSensorDataImpl, + StaticCast(OutSensorNormalizer)->SensorNormalizationImpl); +} + +void SGCoreImpl_FSGNova2GloveImpl_CalculateHandAngles( + void* OutHandAngles, + void* NormalizedValues, + void* Interpolator, + const bool bInfluenceIndex) +{ + StaticCast(OutHandAngles)->Array = + FSGNova2GloveImpl::CalculateHandAngles( + StaticCast(NormalizedValues)->Array, + StaticCast(Interpolator)->HandInterpolatorImpl, + bInfluenceIndex); +} + +void SGCoreImpl_FSGNova2GloveImpl_ToNormalizedAngles( + void* OutNormalizedAngles, + void* NormalizedData, + void* GloveInfo) +{ + StaticCast(OutNormalizedAngles)->Array = + FSGNova2GloveImpl::ToNormalizedAngles( + StaticCast(NormalizedData)->Array, + StaticCast(GloveInfo)->NovaGloveInfoImpl); +} + +void SGCoreImpl_FSGNova2GloveImpl_ctor( + void* OutNova2GloveImpl) +{ + StaticCast(OutNova2GloveImpl)->Nova2GloveImpl = FSGNova2GloveImpl{}; +} + +void SGCoreImpl_FSGNova2GloveImpl_ctor_MakeShared( + void* OutSharedPtr) +{ + StaticCast(OutSharedPtr)->Ptr = + MakeShared(); +} + +void SGCoreImpl_FSGNova2GloveImpl_ctor_DeviceInfo( + void* OutNova2GloveImpl, + void* DeviceInfo) +{ + StaticCast(OutNova2GloveImpl)->Nova2GloveImpl = + FSGNova2GloveImpl{ + StaticCast(DeviceInfo)->NovaGloveInfoImpl}; +} + +void SGCoreImpl_FSGNova2GloveImpl_ctor_DeviceInfo_MakeShared( + void* OutSharedPtr, + void* DeviceInfo) +{ + StaticCast(OutSharedPtr)->Ptr = + MakeShared( + StaticCast(DeviceInfo)->NovaGloveInfoImpl); +} + +void SGCoreImpl_FSGNova2GloveImpl_ctor_copy( + void* OutNova2GloveImpl, + void* Rhs) +{ + StaticCast(OutNova2GloveImpl)->Nova2GloveImpl = + FSGNova2GloveImpl(StaticCast(Rhs)->Nova2GloveImpl); +} + +void SGCoreImpl_FSGNova2GloveImpl_ctor_copy_MakeShared( + void* OutSharedPtr, + void* Rhs) +{ + StaticCast(OutSharedPtr)->Ptr = + MakeShared(StaticCast(Rhs)->Nova2GloveImpl); +} + +void SGCoreImpl_FSGNova2GloveImpl_ctor_copy_assignment( + void* OutNova2GloveImpl, + void* Rhs) +{ + StaticCast(OutNova2GloveImpl)->Nova2GloveImpl = + StaticCast(Rhs)->Nova2GloveImpl; +} + +void SGCoreImpl_FSGNova2GloveImpl_GetDeviceType( + void* Instance, + void* OutType) +{ + StaticCast(OutType)->Type = + StaticCast(Instance)->Ptr->GetDeviceType(); +} + +void SGCoreImpl_FSGNova2GloveImpl_GetDeviceId( + void* Instance, + void* OutId) +{ + StaticCast(OutId)->String = + StaticCast(Instance)->Ptr->GetDeviceId(); +} + +void SGCoreImpl_FSGNova2GloveImpl_GetHardwareVersion( + void* Instance, + void* OutVersion) +{ + StaticCast(OutVersion)->String = + StaticCast(Instance)->Ptr->GetHardwareVersion(); +} + +int32 SGCoreImpl_FSGNova2GloveImpl_GetFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->Ptr->GetFirmwareVersion(); +} + +int32 SGCoreImpl_FSGNova2GloveImpl_GetSubFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->Ptr->GetSubFirmwareVersion(); +} + +bool SGCoreImpl_FSGNova2GloveImpl_HasBattery( + void* Instance) +{ + return StaticCast(Instance)->Ptr->HasBattery(); +} + +bool SGCoreImpl_FSGNova2GloveImpl_IsCharging( + void* Instance) +{ + return StaticCast(Instance)->Ptr->IsCharging(); +} + +bool SGCoreImpl_FSGNova2GloveImpl_GetBatteryLevel( + void* Instance, + float* OutBatteryLevel) +{ + return StaticCast(Instance)->Ptr->GetBatteryLevel( + *OutBatteryLevel); +} + +bool SGCoreImpl_FSGNova2GloveImpl_IsRight( + void* Instance) +{ + return StaticCast(Instance)->Ptr->IsRight(); +} + +bool SGCoreImpl_FSGNova2GloveImpl_GetImuRotation( + void* Instance, + void* OutImu) +{ + return StaticCast(Instance)->Ptr->GetImuRotation( + StaticCast(OutImu)->Quat); +} + +bool SGCoreImpl_FSGNova2GloveImpl_GetHandPose( + void* Instance, + void* HandGeometry, + void* OutHandPose) +{ + return StaticCast(Instance)->Ptr->GetHandPose( + StaticCast(HandGeometry)->BasicHandModelImpl, + StaticCast(OutHandPose)->HandPoseImpl); +} + +bool SGCoreImpl_FSGNova2GloveImpl_GetHandAngles( + void* Instance, + void* OutHandAngles) +{ + return StaticCast(Instance)->Ptr->GetHandAngles( + StaticCast(OutHandAngles)->Array); +} + +void SGCoreImpl_FSGNova2GloveImpl_GetCalibrationState( + void* Instance, + void* OutHapticGloveCalibrationState) +{ + StaticCast(OutHapticGloveCalibrationState)->State = + StaticCast(Instance)->Ptr->GetCalibrationState(); +} + +void SGCoreImpl_FSGNova2GloveImpl_EndCalibration( + void* Instance) +{ + StaticCast(Instance)->Ptr->EndCalibration(); +} + +void SGCoreImpl_FSGNova2GloveImpl_ResetCalibration( + void* Instance) +{ + StaticCast(Instance)->Ptr->ResetCalibration(); +} + +void SGCoreImpl_FSGNova2GloveImpl_StopHaptics( + void* Instance) +{ + StaticCast(Instance)->Ptr->StopHaptics(); +} + +void SGCoreImpl_FSGNova2GloveImpl_StopVibrations( + void* Instance) +{ + StaticCast(Instance)->Ptr->StopVibrations(); +} + +bool SGCoreImpl_FSGNova2GloveImpl_SendHaptics( + void* Instance) +{ + return StaticCast(Instance)->Ptr->SendHaptics(); +} + +bool SGCoreImpl_FSGNova2GloveImpl_SupportsCustomWaveform( + void* Instance, + void* AtLocation) +{ + return StaticCast(Instance)->Ptr->SupportsCustomWaveform( + StaticCast(AtLocation)->Location); +} + +bool SGCoreImpl_FSGNova2GloveImpl_SendCustomWaveform( + void* Instance, + void* OutWaveform, + void* Location) +{ + return StaticCast(Instance)->Ptr->SendCustomWaveform( + StaticCast(OutWaveform)->CustomWaveformImpl, + StaticCast(Location)->Location); +} + +bool SGCoreImpl_FSGNova2GloveImpl_QueueForceFeedbackLevels( + void* Instance, + void* Levels01) +{ + return StaticCast(Instance)->Ptr->QueueForceFeedbackLevels( + StaticCast(Levels01)->Array); +} + +bool SGCoreImpl_FSGNova2GloveImpl_QueueForceFeedbackLevel( + void* Instance, + const int32 Finger, + const float Level01) +{ + return StaticCast(Instance)->Ptr->QueueForceFeedbackLevel( + Finger, + Level01); +} + +bool SGCoreImpl_FSGNova2GloveImpl_QueueVibroLevels( + void* Instance, + void* Amplitudes) +{ + return StaticCast(Instance)->Ptr->QueueVibroLevels( + StaticCast(Amplitudes)->Array); +} + +bool SGCoreImpl_FSGNova2GloveImpl_QueueVibroLevel( + void* Instance, + void* Location, + const float Level01) +{ + return StaticCast(Instance)->Ptr->QueueVibroLevel( + StaticCast(Location)->Location, + Level01); +} + +bool SGCoreImpl_FSGNova2GloveImpl_QueueSqueezeLevel( + void* Instance, + const float SqueezeLevel01) +{ + return StaticCast(Instance)->Ptr->QueueSqueezeLevel( + SqueezeLevel01); +} + +void SGCoreImpl_FSGNova2GloveImpl_GetGloveLocation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutGlovePosition, + void* OutGloveRotation) +{ + StaticCast(Instance)->Ptr->GetGloveLocation( + StaticCast(ReferencePosition)->Vector, + StaticCast(ReferenceRotation)->Quat, + StaticCast(TrackingHardware)->Hardware, + StaticCast(OutGlovePosition)->Vector, + StaticCast(OutGloveRotation)->Quat); +} + +void SGCoreImpl_FSGNova2GloveImpl_GetWristLocation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutWristPosition, + void* OutWristRotation) +{ + StaticCast(Instance)->Ptr->GetWristLocation( + StaticCast(ReferencePosition)->Vector, + StaticCast(ReferenceRotation)->Quat, + StaticCast(TrackingHardware)->Hardware, + StaticCast(OutWristPosition)->Vector, + StaticCast(OutWristRotation)->Quat); +} + +void SGCoreImpl_FSGNova2GloveImpl_GetGloveInfo( + void* Instance, + void* OutGloveInfo) +{ + StaticCast(OutGloveInfo)->NovaGloveInfoImpl = + StaticCast(Instance)->Ptr->GetGloveInfo(); +} + +bool SGCoreImpl_FSGNova2GloveImpl_DoesIndexInfluenceOthers( + void* Instance) +{ + return StaticCast(Instance)->Ptr->DoesIndexInfluenceOthers(); +} + +void SGCoreImpl_FSGNova2GloveImpl_SetIndexInfluencesOthers( + void* Instance, + const bool bInfluenceOthers) +{ + StaticCast(Instance)->Ptr->SetIndexInfluencesOthers( + bInfluenceOthers); +} + +bool SGCoreImpl_FSGNova2GloveImpl_SupportsOnBoardNormalization( + void* Instance) +{ + return StaticCast(Instance)->Ptr->SupportsOnBoardNormalization(); +} + +bool SGCoreImpl_FSGNova2GloveImpl_GetSensorData( + void* Instance, + void* OutSensorData) +{ + return StaticCast(Instance)->Ptr->GetSensorData( + StaticCast(OutSensorData)->Nova2GloveSensorDataImpl); +} + +bool SGCoreImpl_FSGNova2GloveImpl_GetNormalizedInput( + void* Instance, + void* OutNormalizedValues) +{ + return StaticCast(Instance)->Ptr->GetNormalizedInput( + StaticCast(OutNormalizedValues)->Array); +} + +bool SGCoreImpl_FSGNova2GloveImpl_SendRawData( + void* Instance) +{ + return StaticCast(Instance)->Ptr->SendRawData(); +} + +bool SGCoreImpl_FSGNova2GloveImpl_SendNormalizedData( + void* Instance) +{ + return StaticCast(Instance)->Ptr->SendNormalizedData(); +} + +void SGCoreImpl_FSGNova2GloveImpl_ToNovaMotor( + void* Instance, + void* OutNova2Motor, + void* Location) +{ + StaticCast(OutNova2Motor)->Motor = + StaticCast(Instance)->Ptr->ToNovaMotor( + StaticCast(Location)->Location); +} + +int32 SGCoreImpl_FSGNova2GloveImpl_ChannelIndex( + void* Instance, + void* Motor) +{ + return StaticCast(Instance)->Ptr->ChannelIndex( + StaticCast(Motor)->Motor); +} + +void SGCoreImpl_FSGNova2GloveImpl_ValidateWaveform( + void* Instance, + void* OutWaveform, + void* Motor) +{ + return StaticCast(Instance)->Ptr->ValidateWaveform( + StaticCast(OutWaveform)->CustomWaveformImpl, + StaticCast(Motor)->Motor); +} + +bool SGCoreImpl_FSGNova2GloveImpl_SendCustomWaveform_Nova2( + void* Instance, + void* OutWaveform, + void* Motor, + const bool bValidateWaveform) +{ + return StaticCast(Instance)->Ptr->SendCustomWaveform_Nova2( + StaticCast(OutWaveform)->CustomWaveformImpl, + StaticCast(Motor)->Motor, + bValidateWaveform); +} + +void SGCoreImpl_FSGNova2GloveImpl_ToString( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->Ptr->ToString(); +} + +/******************************************************************************* + * SGNova2GloveSensorDataImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGNova2GloveSensorDataImpl_Parse( + void* OutNova2GloveSensorDataImpl, + void* RawData, + void* GloveInfo) +{ + StaticCast(OutNova2GloveSensorDataImpl)->Nova2GloveSensorDataImpl = + FSGNova2GloveSensorDataImpl::Parse( + StaticCast(RawData)->String, + StaticCast(GloveInfo)->NovaGloveInfoImpl); +} + +void +SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor_NormalizationState_Values_ParsedValues_ImuRotation_bImuParsed_BatteryLevel_bCharging( + void* OutNova2GloveSensorDataImpl, + void* NormalizationState, + void* Values, + const int32 ParsedValues, + void* ImuRotation, + const bool bImuParsed, + const float BatteryLevel, + const bool bCharging) +{ + StaticCast(OutNova2GloveSensorDataImpl)->Nova2GloveSensorDataImpl = + FSGNova2GloveSensorDataImpl( + StaticCast(NormalizationState)->State, + StaticCast(Values)->Array, + ParsedValues, + StaticCast(ImuRotation)->Quat, + bImuParsed, + BatteryLevel, + bCharging); +} + +void SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor( + void* OutNova2GloveSensorDataImpl) +{ + StaticCast(OutNova2GloveSensorDataImpl)->Nova2GloveSensorDataImpl = + FSGNova2GloveSensorDataImpl(); +} + +void SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor_copy( + void* OutNova2GloveSensorDataImpl, + void* Rhs) +{ + StaticCast(OutNova2GloveSensorDataImpl)->Nova2GloveSensorDataImpl = + FSGNova2GloveSensorDataImpl(StaticCast(Rhs)->Nova2GloveSensorDataImpl); +} + +void SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor_copy_assignment( + void* OutNova2GloveSensorDataImpl, + void* Rhs) +{ + StaticCast(OutNova2GloveSensorDataImpl)->Nova2GloveSensorDataImpl = + StaticCast(Rhs)->Nova2GloveSensorDataImpl; +} + +void SGCoreImpl_FSGNova2GloveSensorDataImpl_GetSensorState( + void* Instance, + void* OutNormalizationState) +{ + StaticCast(OutNormalizationState)->State = + StaticCast(Instance)->Nova2GloveSensorDataImpl.GetSensorState(); +} + +void SGCoreImpl_FSGNova2GloveSensorDataImpl_GetSensorValues( + void* Instance, + void* OutValues) +{ + StaticCast(OutValues)->Array = + StaticCast(Instance)->Nova2GloveSensorDataImpl.GetSensorValues(); +} + +float SGCoreImpl_FSGNova2GloveSensorDataImpl_GetSensorValue( + void* Instance, + void* Finger, + void* Location) +{ + return StaticCast(Instance)->Nova2GloveSensorDataImpl.GetSensorValue( + StaticCast(Finger)->Finger, + StaticCast(Location)->Location); +} + +int32 SGCoreImpl_FSGNova2GloveSensorDataImpl_GetParsedValues( + void* Instance) +{ + return StaticCast(Instance)->Nova2GloveSensorDataImpl.GetParsedValues(); +} + +void SGCoreImpl_FSGNova2GloveSensorDataImpl_GetImuRotation( + void* Instance, + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = + StaticCast(Instance)->Nova2GloveSensorDataImpl.GetImuRotation(); +} + +bool SGCoreImpl_FSGNova2GloveSensorDataImpl_IsImuParsed( + void* Instance) +{ + return StaticCast(Instance)->Nova2GloveSensorDataImpl.IsImuParsed(); +} + +float SGCoreImpl_FSGNova2GloveSensorDataImpl_GetBatteryLevel( + void* Instance) +{ + return StaticCast(Instance)->Nova2GloveSensorDataImpl.GetBatteryLevel(); +} + +bool SGCoreImpl_FSGNova2GloveSensorDataImpl_IsCharging( + void* Instance) +{ + return StaticCast(Instance)->Nova2GloveSensorDataImpl.IsCharging(); +} + +bool SGCoreImpl_FSGNova2GloveSensorDataImpl_Equals( + void* Instance, + void* Nova2GloveSensorDataImpl) +{ + return StaticCast(Instance)->Nova2GloveSensorDataImpl.Equals( + StaticCast(Nova2GloveSensorDataImpl)->Nova2GloveSensorDataImpl); +} + +void SGCoreImpl_FSGNova2GloveSensorDataImpl_ToString( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->Nova2GloveSensorDataImpl.ToString(); +} + +/******************************************************************************* + * SGNovaGloveImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGNovaGloveImpl_Parse( + void* OutNovaGloveImpl, + void* ConstantsString) +{ + StaticCast(OutNovaGloveImpl)->Ptr = + FSGNovaGloveImpl::Parse(StaticCast(ConstantsString)->String); +} + +void SGCoreImpl_FSGNovaGloveImpl_GetNovaGloves( + void* OutGloves) +{ + StaticCast(OutGloves)->Array = + FSGNovaGloveImpl::GetNovaGloves(); +} + +bool SGCoreImpl_FSGNovaGloveImpl_GetNovaGlove_OutGlove( + void* OutGlove) +{ + return FSGNovaGloveImpl::GetNovaGlove( + StaticCast(OutGlove)->NovaGloveImpl); +} + +bool SGCoreImpl_FSGNovaGloveImpl_GetNovaGlove_bRightHanded_OutGlove( + const bool bRightHanded, + void* OutGlove) +{ + return FSGNovaGloveImpl::GetNovaGlove( + bRightHanded, + StaticCast(OutGlove)->NovaGloveImpl); +} + +void SGCoreImpl_FSGNovaGloveImpl_CalculateGloveLocation( + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + const bool bRightHanded, + void* OutGlovePosition, + void* OutGloveRotation) +{ + FSGNovaGloveImpl::CalculateGloveLocation( + StaticCast(ReferencePosition)->Vector, + StaticCast(ReferenceRotation)->Quat, + StaticCast(TrackingHardware)->Hardware, + bRightHanded, + StaticCast(OutGlovePosition)->Vector, + StaticCast(OutGloveRotation)->Quat); +} + +void SGCoreImpl_FSGNovaGloveImpl_CalculateWristLocation( + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + const bool bRightHanded, + void* OutWristPosition, + void* OutWristRotation) +{ + FSGNovaGloveImpl::CalculateWristLocation( + StaticCast(ReferencePosition)->Vector, + StaticCast(ReferenceRotation)->Quat, + StaticCast(TrackingHardware)->Hardware, + bRightHanded, + StaticCast(OutWristPosition)->Vector, + StaticCast(OutWristRotation)->Quat); +} + +ANSICHAR SGCoreImpl_FSGNovaGloveImpl_GetHapticsByte() +{ + return FSGNovaGloveImpl::GetHapticsByte(); +} + +ANSICHAR SGCoreImpl_FSGNovaGloveImpl_GetThresholdsByte() +{ + return FSGNovaGloveImpl::GetThresholdsByte(); +} + +ANSICHAR SGCoreImpl_FSGNovaGloveImpl_GetIgnoreThresholdsByte() +{ + return FSGNovaGloveImpl::GetIgnoreThresholdsByte(); +} + +void SGCoreImpl_FSGNovaGloveImpl_GetNovaSensorRanges( + void* OutNovaSensorRanges) +{ + StaticCast(OutNovaSensorRanges)->Array = + FSGNovaGloveImpl::GetNovaSensorRanges(); +} + +void SGCoreImpl_FSGNovaGloveImpl_ToNormalizedValues_SensorData( + void* OutNormalizedValues, + void* SensorData) +{ + StaticCast(OutNormalizedValues)->Array = + FSGNovaGloveImpl::ToNormalizedValues( + StaticCast(SensorData)->NovaGloveSensorDataImpl); +} + +void SGCoreImpl_FSGNovaGloveImpl_ToNormalizedValues_SensorData_OutSensorNormalizer( + void* OutNormalizedValues, + void* SensorData, + void* OutSensorNormalizer) +{ + StaticCast(OutNormalizedValues)->Array = + FSGNovaGloveImpl::ToNormalizedValues( + StaticCast(SensorData)->NovaGloveSensorDataImpl, + StaticCast(OutSensorNormalizer)->SensorNormalizationImpl); +} + +void SGCoreImpl_FSGNovaGloveImpl_CalculateHandAngles( + void* OutHandAngles, + void* NormalizedValues, + void* Interpolator) +{ + StaticCast(OutHandAngles)->Array = + FSGNovaGloveImpl::CalculateHandAngles( + StaticCast(NormalizedValues)->Array, + StaticCast(Interpolator)->HandInterpolatorImpl); +} + +void SGCoreImpl_FSGNovaGloveImpl_ToNovaCommandAsFlexion( + void* OutString, + void* Thresholds) +{ + StaticCast(OutString)->String = + FSGNovaGloveImpl::ToNovaCommandAsFlexion( + StaticCast(Thresholds)->ThresholdCommandImpl); +} + +void SGCoreImpl_FSGNovaGloveImpl_ToNovaCommandAsRaw( + void* OutString, + void* Thresholds, + void* Interpolator) +{ + StaticCast(OutString)->String = + FSGNovaGloveImpl::ToNovaCommandAsRaw( + StaticCast(Thresholds)->ThresholdCommandImpl, + StaticCast(Interpolator)->SensorNormalizationImpl); +} + +void SGCoreImpl_FSGNovaGloveImpl_ctor( + void* OutNovaGloveImpl) +{ + StaticCast(OutNovaGloveImpl)->NovaGloveImpl = FSGNovaGloveImpl{}; +} + +void SGCoreImpl_FSGNovaGloveImpl_ctor_MakeShared( + void* OutSharedPtr) +{ + StaticCast(OutSharedPtr)->Ptr = + MakeShared(); +} + +void SGCoreImpl_FSGNovaGloveImpl_ctor_DeviceInfo( + void* OutNovaGloveImpl, + void* DeviceInfo) +{ + StaticCast(OutNovaGloveImpl)->NovaGloveImpl = + FSGNovaGloveImpl{ + StaticCast(DeviceInfo)->NovaGloveInfoImpl}; +} + +void SGCoreImpl_FSGNovaGloveImpl_ctor_DeviceInfo_MakeShared( + void* OutSharedPtr, + void* DeviceInfo) +{ + StaticCast(OutSharedPtr)->Ptr = + MakeShared( + StaticCast(DeviceInfo)->NovaGloveInfoImpl); +} + +void SGCoreImpl_FSGNovaGloveImpl_ctor_copy( + void* OutNovaGloveImpl, + void* Rhs) +{ + StaticCast(OutNovaGloveImpl)->NovaGloveImpl = + FSGNovaGloveImpl(StaticCast(Rhs)->NovaGloveImpl); +} + +void SGCoreImpl_FSGNovaGloveImpl_ctor_copy_MakeShared( + void* OutSharedPtr, + void* Rhs) +{ + StaticCast(OutSharedPtr)->Ptr = + MakeShared(StaticCast(Rhs)->NovaGloveImpl); +} + +void SGCoreImpl_FSGNovaGloveImpl_ctor_copy_assignment( + void* OutNovaGloveImpl, + void* Rhs) +{ + StaticCast(OutNovaGloveImpl)->NovaGloveImpl = + StaticCast(Rhs)->NovaGloveImpl; +} + +void SGCoreImpl_FSGNovaGloveImpl_GetDeviceType( + void* Instance, + void* OutType) +{ + StaticCast(OutType)->Type = + StaticCast(Instance)->Ptr->GetDeviceType(); +} + +void SGCoreImpl_FSGNovaGloveImpl_GetDeviceId( + void* Instance, + void* OutId) +{ + StaticCast(OutId)->String = + StaticCast(Instance)->Ptr->GetDeviceId(); +} + +void SGCoreImpl_FSGNovaGloveImpl_GetHardwareVersion( + void* Instance, + void* OutVersion) +{ + StaticCast(OutVersion)->String = + StaticCast(Instance)->Ptr->GetHardwareVersion(); +} + +int32 SGCoreImpl_FSGNovaGloveImpl_GetFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->Ptr->GetFirmwareVersion(); +} + +int32 SGCoreImpl_FSGNovaGloveImpl_GetSubFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->Ptr->GetSubFirmwareVersion(); +} + +void SGCoreImpl_FSGNovaGloveImpl_SetDeviceIndex( + void* Instance, + const int32 Index) +{ + StaticCast(Instance)->Ptr->SetDeviceIndex(Index); +} + +bool SGCoreImpl_FSGNovaGloveImpl_HasBattery( + void* Instance) +{ + return StaticCast(Instance)->Ptr->HasBattery(); +} + +bool SGCoreImpl_FSGNovaGloveImpl_IsCharging( + void* Instance) +{ + return StaticCast(Instance)->Ptr->IsCharging(); +} + +bool SGCoreImpl_FSGNovaGloveImpl_GetBatteryLevel( + void* Instance, + float* OutBatteryLevel) +{ + return StaticCast(Instance)->Ptr->GetBatteryLevel( + *OutBatteryLevel); +} + +bool SGCoreImpl_FSGNovaGloveImpl_IsRight( + void* Instance) +{ + return StaticCast(Instance)->Ptr->IsRight(); +} + +bool SGCoreImpl_FSGNovaGloveImpl_GetImuRotation( + void* Instance, + void* OutImu) +{ + return StaticCast(Instance)->Ptr->GetImuRotation( + StaticCast(OutImu)->Quat); +} + +bool SGCoreImpl_FSGNovaGloveImpl_GetHandPose( + void* Instance, + void* HandGeometry, + void* OutHandPose) +{ + return StaticCast(Instance)->Ptr->GetHandPose( + StaticCast(HandGeometry)->BasicHandModelImpl, + StaticCast(OutHandPose)->HandPoseImpl); +} + +bool SGCoreImpl_FSGNovaGloveImpl_GetHandAngles( + void* Instance, + void* OutHandAngles) +{ + return StaticCast(Instance)->Ptr->GetHandAngles( + StaticCast(OutHandAngles)->Array); +} + +void SGCoreImpl_FSGNovaGloveImpl_GetCalibrationState( + void* Instance, + void* OutHapticGloveCalibrationState) +{ + StaticCast(OutHapticGloveCalibrationState)->State = + StaticCast(Instance)->Ptr->GetCalibrationState(); +} + +void SGCoreImpl_FSGNovaGloveImpl_EndCalibration( + void* Instance) +{ + StaticCast(Instance)->Ptr->EndCalibration(); +} + +void SGCoreImpl_FSGNovaGloveImpl_ResetCalibration( + void* Instance) +{ + StaticCast(Instance)->Ptr->ResetCalibration(); +} + +void SGCoreImpl_FSGNovaGloveImpl_StopHaptics( + void* Instance) +{ + StaticCast(Instance)->Ptr->StopHaptics(); +} + +void SGCoreImpl_FSGNovaGloveImpl_StopVibrations( + void* Instance) +{ + StaticCast(Instance)->Ptr->StopVibrations(); +} + +bool SGCoreImpl_FSGNovaGloveImpl_SendHaptics( + void* Instance) +{ + return StaticCast(Instance)->Ptr->SendHaptics(); +} + +bool SGCoreImpl_FSGNovaGloveImpl_SupportsCustomWaveform( + void* Instance, + void* AtLocation) +{ + return StaticCast(Instance)->Ptr->SupportsCustomWaveform( + StaticCast(AtLocation)->Location); +} + +bool SGCoreImpl_FSGNovaGloveImpl_SendCustomWaveform( + void* Instance, + void* OutWaveform, + void* Location) +{ + return StaticCast(Instance)->Ptr->SendCustomWaveform( + StaticCast(OutWaveform)->CustomWaveformImpl, + StaticCast(Location)->Location); +} + +bool SGCoreImpl_FSGNovaGloveImpl_QueueForceFeedbackLevels( + void* Instance, + void* Levels01) +{ + return StaticCast(Instance)->Ptr->QueueForceFeedbackLevels( + StaticCast(Levels01)->Array); +} + +bool SGCoreImpl_FSGNovaGloveImpl_QueueForceFeedbackLevel( + void* Instance, + const int32 Finger, + const float Level01) +{ + return StaticCast(Instance)->Ptr->QueueForceFeedbackLevel( + Finger, + Level01); +} + +bool SGCoreImpl_FSGNovaGloveImpl_QueueVibroLevels( + void* Instance, + void* Amplitudes) +{ + return StaticCast(Instance)->Ptr->QueueVibroLevels( + StaticCast(Amplitudes)->Array); +} + +bool SGCoreImpl_FSGNovaGloveImpl_QueueVibroLevel_Localtion_Level01( + void* Instance, + void* Location, + const float Level01) +{ + return StaticCast(Instance)->Ptr->QueueVibroLevel( + StaticCast(Location)->Location, + Level01); +} + +void SGCoreImpl_FSGNovaGloveImpl_GetGloveLocation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutGlovePosition, + void* OutGloveRotation) +{ + StaticCast(Instance)->Ptr->GetGloveLocation( + StaticCast(ReferencePosition)->Vector, + StaticCast(ReferenceRotation)->Quat, + StaticCast(TrackingHardware)->Hardware, + StaticCast(OutGlovePosition)->Vector, + StaticCast(OutGloveRotation)->Quat); +} + +void SGCoreImpl_FSGNovaGloveImpl_GetWristLocation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutWristPosition, + void* OutWristRotation) +{ + StaticCast(Instance)->Ptr->GetWristLocation( + StaticCast(ReferencePosition)->Vector, + StaticCast(ReferenceRotation)->Quat, + StaticCast(TrackingHardware)->Hardware, + StaticCast(OutWristPosition)->Vector, + StaticCast(OutWristRotation)->Quat); +} + +void SGCoreImpl_FSGNovaGloveImpl_GetGloveInfo( + void* Instance, + void* OutGloveInfo) +{ + StaticCast(OutGloveInfo)->NovaGloveInfoImpl = + StaticCast(Instance)->Ptr->GetGloveInfo(); +} + +bool SGCoreImpl_FSGNovaGloveImpl_SupportsThresholds( + void* Instance) +{ + return StaticCast(Instance)->Ptr->SupportsThresholds(); +} + +bool SGCoreImpl_FSGNovaGloveImpl_SupportsCustomWaveforms( + void* Instance) +{ + return StaticCast(Instance)->Ptr->SupportsCustomWaveforms(); +} + +bool SGCoreImpl_FSGNovaGloveImpl_SupportsOnBoardNormalization( + void* Instance) +{ + return StaticCast(Instance)->Ptr->SupportsOnBoardNormalization(); +} + +bool SGCoreImpl_FSGNovaGloveImpl_GetSensorData( + void* Instance, + void* OutSensorData) +{ + return StaticCast(Instance)->Ptr->GetSensorData( + StaticCast(OutSensorData)->NovaGloveSensorDataImpl); +} + +bool SGCoreImpl_FSGNovaGloveImpl_GetNormalizedInput( + void* Instance, + void* OutNormalizedValues) +{ + return StaticCast(Instance)->Ptr->GetNormalizedInput( + StaticCast(OutNormalizedValues)->Array); +} + +void SGCoreImpl_FSGNovaGloveImpl_ToNovaCommand( + void* Instance, + void* OutString, + void* ForceFeedbackLevels, + void* BuzzLevels, + const float WristLevel) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->Ptr->ToNovaCommand( + StaticCast(ForceFeedbackLevels)->Array, + StaticCast(BuzzLevels)->Array, + WristLevel); +} + +bool SGCoreImpl_FSGNovaGloveImpl_QueueVibroLevel_Finger_Amplitude( + void* Instance, + const int32 Finger, + const float Amplitude) +{ + return StaticCast(Instance)->Ptr->QueueVibroLevel( + Finger, + Amplitude); +} + +bool SGCoreImpl_FSGNovaGloveImpl_QueueWristLevel( + void* Instance, + const float Amplitude) +{ + return StaticCast(Instance)->Ptr->QueueWristLevel( + Amplitude); +} + +void SGCoreImpl_FSGNovaGloveImpl_ToNovaMotor( + void* Instance, + void* OutNovaMotor, + void* Location) +{ + StaticCast(OutNovaMotor)->Motor = + StaticCast(Instance)->Ptr->ToNovaMotor( + StaticCast(Location)->Location); +} + +int32 SGCoreImpl_FSGNovaGloveImpl_ChannelIndex( + void* Instance, + void* Motor) +{ + return StaticCast(Instance)->Ptr->ChannelIndex( + StaticCast(Motor)->Motor); +} + +void SGCoreImpl_FSGNovaGloveImpl_ValidateWaveform( + void* Instance, + void* OutWaveform, + void* Motor) +{ + return StaticCast(Instance)->Ptr->ValidateWaveform( + StaticCast(OutWaveform)->CustomWaveformImpl, + StaticCast(Motor)->Motor); +} + +bool SGCoreImpl_FSGNovaGloveImpl_SendCustomWaveform_Nova( + void* Instance, + void* OutWaveform, + void* Motor, + const bool bValidateWaveform) +{ + return StaticCast(Instance)->Ptr->SendCustomWaveform_Nova( + StaticCast(OutWaveform)->CustomWaveformImpl, + StaticCast(Motor)->Motor, + bValidateWaveform); +} + +bool SGCoreImpl_FSGNovaGloveImpl_QueueThresholdCommand_Flexion( + void* Instance, + const int32 Finger, + const float FlexionThreshold) +{ + return StaticCast(Instance)->Ptr->QueueThresholdCommand_Flexion( + Finger, + FlexionThreshold); +} + +bool SGCoreImpl_FSGNovaGloveImpl_QueueClearThreshold( + void* Instance, + const int32 Finger) +{ + return StaticCast(Instance)->Ptr->QueueClearThreshold( + Finger); +} + +void SGCoreImpl_FSGNovaGloveImpl_ToString( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->Ptr->ToString(); +} + +/******************************************************************************* + * SGNovaGloveInfoImpl.h + ******************************************************************************/ + +bool SGCoreImpl_FSGNovaGloveInfoImpl_Parse( + void* ConstantsString, + void* OutGloveInfo) +{ + return FSGNovaGloveInfoImpl::Parse( + StaticCast(ConstantsString)->String, + StaticCast(OutGloveInfo)->NovaGloveInfoImpl); +} + +void SGCoreImpl_FSGNovaGloveInfoImpl_Deserialize( + void* OutNovaGloveInfoImpl, + void* SerializedString) +{ + StaticCast(OutNovaGloveInfoImpl)->NovaGloveInfoImpl = + FSGNovaGloveInfoImpl::Deserialize( + StaticCast(SerializedString)->String); +} + +void SGCoreImpl_FSGNovaGloveInfoImpl_ctor( + void* OutNovaGloveInfoImpl) +{ + StaticCast(OutNovaGloveInfoImpl)->NovaGloveInfoImpl = FSGNovaGloveInfoImpl(); +} + +void +SGCoreImpl_FSGNovaGloveInfoImpl_ctor_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded_ImuCorrection_NumberOfSensors( + void* OutNovaGloveInfoImpl, + void* DeviceId, + void* HardwareVersion, + const int32 FirmwareVersion, + const int32 SubFirmwareVersion, + const bool bRightHanded, + void* ImuCorrection, + const int32 NumberOfSensors) +{ + StaticCast(OutNovaGloveInfoImpl)->NovaGloveInfoImpl = + FSGNovaGloveInfoImpl( + StaticCast(DeviceId)->String, + StaticCast(HardwareVersion)->String, + FirmwareVersion, + SubFirmwareVersion, + bRightHanded, + StaticCast(ImuCorrection)->Quat, + NumberOfSensors); +} + +void SGCoreImpl_FSGNovaGloveInfoImpl_ctor_copy( + void* OutNovaGloveInfoImpl, + void* Rhs) +{ + StaticCast(OutNovaGloveInfoImpl)->NovaGloveInfoImpl = + FSGNovaGloveInfoImpl(StaticCast(Rhs)->NovaGloveInfoImpl); +} + +void SGCoreImpl_FSGNovaGloveInfoImpl_ctor_copy_assignment( + void* OutNovaGloveInfoImpl, + void* Rhs) +{ + StaticCast(OutNovaGloveInfoImpl)->NovaGloveInfoImpl = + StaticCast(Rhs)->NovaGloveInfoImpl; +} + +void SGCoreImpl_FSGNovaGloveInfoImpl_GetDeviceId( + void* Instance, + void* OutId) +{ + StaticCast(OutId)->String = + StaticCast(Instance)->NovaGloveInfoImpl.GetDeviceId(); +} + +void SGCoreImpl_FSGNovaGloveInfoImpl_GetHardwareVersion( + void* Instance, + void* OutVersion) +{ + StaticCast(OutVersion)->String = + StaticCast(Instance)->NovaGloveInfoImpl.GetHardwareVersion(); +} + +int32 SGCoreImpl_FSGNovaGloveInfoImpl_GetFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->NovaGloveInfoImpl.GetFirmwareVersion(); +} + +int32 SGCoreImpl_FSGNovaGloveInfoImpl_GetSubFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->NovaGloveInfoImpl.GetSubFirmwareVersion(); +} + +bool SGCoreImpl_FSGNovaGloveInfoImpl_IsRight( + void* Instance) +{ + return StaticCast(Instance)->NovaGloveInfoImpl.IsRight(); +} + +void SGCoreImpl_FSGNovaGloveInfoImpl_GetImuCorrection( + void* Instance, + void* OutCorrection) +{ + StaticCast(OutCorrection)->Quat = + StaticCast(Instance)->NovaGloveInfoImpl.GetImuCorrection(); +} + +int32 SGCoreImpl_FSGNovaGloveInfoImpl_GetNumberOfSensors( + void* Instance) +{ + return StaticCast(Instance)->NovaGloveInfoImpl.GetNumberOfSensors(); +} + +bool SGCoreImpl_FSGNovaGloveInfoImpl_FirmwareNewerThan( + void* Instance, + const int32 FirmwareMain, + const int32 FirmwareSub, + const bool bInclusive) +{ + return StaticCast(Instance)->NovaGloveInfoImpl.FirmwareNewerThan( + FirmwareMain, + FirmwareSub, + bInclusive); +} + +bool SGCoreImpl_FSGNovaGloveInfoImpl_FirmwareOlderThan( + void* Instance, + const int32 FirmwareMain, + const int32 FirmwareSub, + const bool bInclusive) +{ + return StaticCast(Instance)->NovaGloveInfoImpl.FirmwareOlderThan( + FirmwareMain, + FirmwareSub, + bInclusive); +} + +bool SGCoreImpl_FSGNovaGloveInfoImpl_Equals( + void* Instance, + void* NovaGloveInfoImpl) +{ + return StaticCast(Instance)->NovaGloveInfoImpl.Equals( + StaticCast(NovaGloveInfoImpl)->NovaGloveInfoImpl); +} + +void SGCoreImpl_FSGNovaGloveInfoImpl_ToString( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->NovaGloveInfoImpl.ToString(); +} + +void SGCoreImpl_FSGNovaGloveInfoImpl_Serialize( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->NovaGloveInfoImpl.Serialize(); +} + +/******************************************************************************* + * SGNovaGloveSensorDataImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGNovaGloveSensorDataImpl_Empty( + void* OutNovaGloveSensorDataImpl) +{ + StaticCast(OutNovaGloveSensorDataImpl)->NovaGloveSensorDataImpl = + FSGNovaGloveSensorDataImpl::Empty(); +} + +void SGCoreImpl_FSGNovaGloveSensorDataImpl_Parse( + void* OutNovaGloveSensorDataImpl, + void* RawData, + void* GloveInfo) +{ + StaticCast(OutNovaGloveSensorDataImpl)->NovaGloveSensorDataImpl = + FSGNovaGloveSensorDataImpl::Parse( + StaticCast(RawData)->String, + StaticCast(GloveInfo)->NovaGloveInfoImpl); +} + +void SGCoreImpl_FSGNovaGloveSensorDataImpl_Deserialize( + void* OutNovaGloveSensorDataImpl, + void* SerializedString) +{ + StaticCast(OutNovaGloveSensorDataImpl)->NovaGloveSensorDataImpl = + FSGNovaGloveSensorDataImpl::Deserialize( + StaticCast(SerializedString)->String); +} + +void SGCoreImpl_FSGNovaGloveSensorDataImpl_ctor( + void* OutNovaGloveSensorDataImpl) +{ + StaticCast(OutNovaGloveSensorDataImpl)->NovaGloveSensorDataImpl = + FSGNovaGloveSensorDataImpl(); +} + +void SGCoreImpl_FSGNovaGloveSensorDataImpl_ctor_Values_ParsedValues_ImuRotation_bImuParsed_BatteryLevel_bCharging( + void* OutNovaGloveSensorDataImpl, + void* Values, + const int32 ParsedValues, + void* ImuRotation, + const bool bImuParsed, + const float BatteryLevel, + const bool bCharging) +{ + StaticCast(OutNovaGloveSensorDataImpl)->NovaGloveSensorDataImpl = + FSGNovaGloveSensorDataImpl( + StaticCast(Values)->Array, + ParsedValues, + StaticCast(ImuRotation)->Quat, + bImuParsed, + BatteryLevel, + bCharging); +} + +void SGCoreImpl_FSGNovaGloveSensorDataImpl_ctor_copy( + void* OutNovaGloveSensorDataImpl, + void* Rhs) +{ + StaticCast(OutNovaGloveSensorDataImpl)->NovaGloveSensorDataImpl = + FSGNovaGloveSensorDataImpl(StaticCast(Rhs)->NovaGloveSensorDataImpl); +} + +void SGCoreImpl_FSGNovaGloveSensorDataImpl_ctor_copy_assignment( + void* OutNovaGloveSensorDataImpl, + void* Rhs) +{ + StaticCast(OutNovaGloveSensorDataImpl)->NovaGloveSensorDataImpl = + StaticCast(Rhs)->NovaGloveSensorDataImpl; +} + +void SGCoreImpl_FSGNovaGloveSensorDataImpl_GetSensorValues( + void* Instance, + void* OutValues) +{ + StaticCast(OutValues)->Array = + StaticCast(Instance)->NovaGloveSensorDataImpl.GetSensorValues(); +} + +float SGCoreImpl_FSGNovaGloveSensorDataImpl_GetSensorValue( + void* Instance, + void* Finger, + void* Location) +{ + return StaticCast(Instance)->NovaGloveSensorDataImpl.GetSensorValue( + StaticCast(Finger)->Finger, + StaticCast(Location)->Location); +} + +int32 SGCoreImpl_FSGNovaGloveSensorDataImpl_GetParsedValues( + void* Instance) +{ + return StaticCast(Instance)->NovaGloveSensorDataImpl.GetParsedValues(); +} + +void SGCoreImpl_FSGNovaGloveSensorDataImpl_GetImuRotation( + void* Instance, + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = + StaticCast(Instance)->NovaGloveSensorDataImpl.GetImuRotation(); +} + +bool SGCoreImpl_FSGNovaGloveSensorDataImpl_IsImuParsed( + void* Instance) +{ + return StaticCast(Instance)->NovaGloveSensorDataImpl.IsImuParsed(); +} + +float SGCoreImpl_FSGNovaGloveSensorDataImpl_GetBatteryLevel( + void* Instance) +{ + return StaticCast(Instance)->NovaGloveSensorDataImpl.GetBatteryLevel(); +} + +bool SGCoreImpl_FSGNovaGloveSensorDataImpl_IsCharging( + void* Instance) +{ + return StaticCast(Instance)->NovaGloveSensorDataImpl.IsCharging(); +} + +bool SGCoreImpl_FSGNovaGloveSensorDataImpl_Equals( + void* Instance, + void* NovaGloveSensorDataImpl) +{ + return StaticCast(Instance)->NovaGloveSensorDataImpl.Equals( + StaticCast(NovaGloveSensorDataImpl)->NovaGloveSensorDataImpl); +} + +void SGCoreImpl_FSGNovaGloveSensorDataImpl_ToString( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->NovaGloveSensorDataImpl.ToString(); +} + +void SGCoreImpl_FSGNovaGloveSensorDataImpl_Serialize( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->NovaGloveSensorDataImpl.Serialize(); +} + +/******************************************************************************* + * SGSenseComImpl.h + ******************************************************************************/ + +bool SGCoreImpl_FSGSenseComImpl_RegisterExe() +{ + return FSGSenseComImpl::RegisterExe(); +} + +bool SGCoreImpl_FSGSenseComImpl_RegisterExe_ExePath(void* ExePath) +{ + return FSGSenseComImpl::RegisterExe(StaticCast(ExePath)->String); +} + +bool SGCoreImpl_FSGSenseComImpl_GetExePath(void* OutExePath) +{ + return FSGSenseComImpl::GetExePath(StaticCast(OutExePath)->String); +} + +bool SGCoreImpl_FSGSenseComImpl_ScanningActive() +{ + return FSGSenseComImpl::ScanningActive(); +} + +bool SGCoreImpl_FSGSenseComImpl_GetCurrentExeDirectory(void* OutDirectory) +{ + return FSGSenseComImpl::GetCurrentExeDirectory(StaticCast(OutDirectory)->String); +} + +bool SGCoreImpl_FSGSenseComImpl_StartupSenseCom() +{ + return FSGSenseComImpl::StartupSenseCom(); +} + +/******************************************************************************* + * SGSenseGloveImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGSenseGloveImpl_Parse( + void* OutSenseGloveImpl, + void* ConstantsString) +{ + StaticCast(OutSenseGloveImpl)->Ptr = + FSGSenseGloveImpl::Parse(StaticCast(ConstantsString)->String); +} + +void SGCoreImpl_FSGSenseGloveImpl_GetSenseGloves( + void* OutGloves) +{ + StaticCast(OutGloves)->Array = + FSGSenseGloveImpl::GetSenseGloves(); +} + +bool SGCoreImpl_FSGSenseGloveImpl_GetSenseGlove_OutGlove( + void* OutGlove) +{ + return FSGSenseGloveImpl::GetSenseGlove( + StaticCast(OutGlove)->SenseGloveImpl); +} + +bool SGCoreImpl_FSGSenseGloveImpl_GetSenseGlove_bRightHanded_OutGlove( + const bool bRightHanded, + void* OutGlove) +{ + return FSGSenseGloveImpl::GetSenseGlove( + bRightHanded, + StaticCast(OutGlove)->SenseGloveImpl); +} + +void SGCoreImpl_FSGSenseGloveImpl_CalculateGloveLocation( + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + const bool bRightHanded, + void* MountedOn, + void* OutGlovePosition, + void* OutGloveRotation) +{ + FSGSenseGloveImpl::CalculateGloveLocation( + StaticCast(ReferencePosition)->Vector, + StaticCast(ReferenceRotation)->Quat, + StaticCast(TrackingHardware)->Hardware, + bRightHanded, + StaticCast(MountedOn)->Finger, + StaticCast(OutGlovePosition)->Vector, + StaticCast(OutGloveRotation)->Quat); +} + +void SGCoreImpl_FSGSenseGloveImpl_CalculateWristLocation( + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + const bool bRightHanded, + void* MountedOn, + void* GloveWristPositionOffset, + void* GloveWristRotationOffset, + void* OutWristPosition, + void* OutWristRotation) +{ + FSGSenseGloveImpl::CalculateWristLocation( + StaticCast(ReferencePosition)->Vector, + StaticCast(ReferenceRotation)->Quat, + StaticCast(TrackingHardware)->Hardware, + bRightHanded, + StaticCast(MountedOn)->Finger, + StaticCast(GloveWristPositionOffset)->Vector, + StaticCast(GloveWristRotationOffset)->Quat, + StaticCast(OutWristPosition)->Vector, + StaticCast(OutWristRotation)->Quat); +} + +ANSICHAR SGCoreImpl_FSGSenseGloveImpl_GetHapticsByte() +{ + return FSGSenseGloveImpl::GetHapticsByte(); +} + +ANSICHAR SGCoreImpl_FSGSenseGloveImpl_GetThumperByte() +{ + return FSGSenseGloveImpl::GetThumperByte(); +} + +void SGCoreImpl_FSGSenseGloveImpl_GetDefaultThimbleOffset( + void* OutOffset) +{ + StaticCast(OutOffset)->Vector = + FSGSenseGloveImpl::GetDefaultThimbleOffset(); +} + +void SGCoreImpl_FSGSenseGloveImpl_CalculateGlovePose_SensorData_GloveModel( + void* OutPose, + void* SensorData, + void* GloveModel) +{ + StaticCast(OutPose)->SenseGlovePoseImpl = + FSGSenseGloveImpl::CalculateGlovePose( + StaticCast(SensorData)->SenseGloveSensorDataImpl, + StaticCast(GloveModel)->SenseGloveInfoImpl); +} + +void SGCoreImpl_FSGSenseGloveImpl_CalculateGlovePose_GloveAngles_GloveModel( + void* OutPose, + void* GloveAngles, + void* GloveModel) +{ + StaticCast(OutPose)->SenseGlovePoseImpl = + FSGSenseGloveImpl::CalculateGlovePose( + StaticCast(GloveAngles)->Array, + StaticCast(GloveModel)->SenseGloveInfoImpl); +} + +void SGCoreImpl_FSGSenseGloveImpl_NormalizeValues( + void* SumAngles, + void* Normalizer, + void* OutFlexions, + void* OutAbductions) +{ + FSGSenseGloveImpl::NormalizeValues( + StaticCast(SumAngles)->Array, + StaticCast(Normalizer)->SenseGloveSensorNormalizerImpl, + StaticCast(OutFlexions)->Array, + StaticCast(OutAbductions)->Array); +} + +void SGCoreImpl_FSGSenseGloveImpl_CalculateHandAngles( + void* GlovePose, + void* Normalizer, + void* NormalizedToAngles, + void* OutHandAngles) +{ + FSGSenseGloveImpl::CalculateHandAngles( + StaticCast(GlovePose)->SenseGlovePoseImpl, + StaticCast(Normalizer)->SenseGloveSensorNormalizerImpl, + StaticCast(NormalizedToAngles)->HandInterpolatorImpl, + StaticCast(OutHandAngles)->Array); +} + +void SGCoreImpl_FSGSenseGloveImpl_CalculateHandPose( + void* GlovePose, + void* HandModel, + void* Normalizer, + void* NormalizedToAngles, + void* OutHandPose) +{ + FSGSenseGloveImpl::CalculateHandPose( + StaticCast(GlovePose)->SenseGlovePoseImpl, + StaticCast(HandModel)->BasicHandModelImpl, + StaticCast(Normalizer)->SenseGloveSensorNormalizerImpl, + StaticCast(NormalizedToAngles)->HandInterpolatorImpl, + StaticCast(OutHandPose)->HandPoseImpl); +} + +void SGCoreImpl_FSGSenseGloveImpl_ctor( + void* OutSenseGloveImpl) +{ + StaticCast(OutSenseGloveImpl)->SenseGloveImpl = FSGSenseGloveImpl{}; +} + +void SGCoreImpl_FSGSenseGloveImpl_ctor_MakeShared( + void* OutSharedPtr) +{ + StaticCast(OutSharedPtr)->Ptr = + MakeShared(); +} + +void SGCoreImpl_FSGSenseGloveImpl_ctor_Model( + void* OutSenseGloveImpl, + void* Model) +{ + StaticCast(OutSenseGloveImpl)->SenseGloveImpl = + FSGSenseGloveImpl{ + StaticCast(Model)->SenseGloveInfoImpl}; +} + +void SGCoreImpl_FSGSenseGloveImpl_ctor_Model_MakeShared( + void* OutSharedPtr, + void* Model) +{ + StaticCast(OutSharedPtr)->Ptr = + MakeShared( + StaticCast(Model)->SenseGloveInfoImpl); +} + +void SGCoreImpl_FSGSenseGloveImpl_ctor_copy( + void* OutSenseGloveImpl, + void* Rhs) +{ + StaticCast(OutSenseGloveImpl)->SenseGloveImpl = + FSGSenseGloveImpl(StaticCast(Rhs)->SenseGloveImpl); +} + +void SGCoreImpl_FSGSenseGloveImpl_ctor_copy_MakeShared( + void* OutSharedPtr, + void* Rhs) +{ + StaticCast(OutSharedPtr)->Ptr = + MakeShared(StaticCast(Rhs)->SenseGloveImpl); +} + +void SGCoreImpl_FSGSenseGloveImpl_ctor_copy_assignment( + void* OutSenseGloveImpl, + void* Rhs) +{ + StaticCast(OutSenseGloveImpl)->SenseGloveImpl = + StaticCast(Rhs)->SenseGloveImpl; +} + +void SGCoreImpl_FSGSenseGloveImpl_GetDeviceType( + void* Instance, + void* OutType) +{ + StaticCast(OutType)->Type = + StaticCast(Instance)->Ptr->GetDeviceType(); +} + +void SGCoreImpl_FSGSenseGloveImpl_GetDeviceId( + void* Instance, + void* OutId) +{ + StaticCast(OutId)->String = + StaticCast(Instance)->Ptr->GetDeviceId(); +} + +void SGCoreImpl_FSGSenseGloveImpl_GetHardwareVersion( + void* Instance, + void* OutVersion) +{ + StaticCast(OutVersion)->String = + StaticCast(Instance)->Ptr->GetHardwareVersion(); +} + +int32 SGCoreImpl_FSGSenseGloveImpl_GetFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->Ptr->GetFirmwareVersion(); +} + +int32 SGCoreImpl_FSGSenseGloveImpl_GetSubFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->Ptr->GetSubFirmwareVersion(); +} + +bool SGCoreImpl_FSGSenseGloveImpl_IsRight( + void* Instance) +{ + return StaticCast(Instance)->Ptr->IsRight(); +} + +bool SGCoreImpl_FSGSenseGloveImpl_GetImuRotation( + void* Instance, + void* OutImu) +{ + return StaticCast(Instance)->Ptr->GetImuRotation( + StaticCast(OutImu)->Quat); +} + +bool SGCoreImpl_FSGSenseGloveImpl_GetHandPose( + void* Instance, + void* HandGeometry, + void* OutHandPose) +{ + return StaticCast(Instance)->Ptr->GetHandPose( + StaticCast(HandGeometry)->BasicHandModelImpl, + StaticCast(OutHandPose)->HandPoseImpl); +} + +bool SGCoreImpl_FSGSenseGloveImpl_GetHandAngles( + void* Instance, + void* OutHandAngles) +{ + return StaticCast(Instance)->Ptr->GetHandAngles( + StaticCast(OutHandAngles)->Array); +} + +void SGCoreImpl_FSGSenseGloveImpl_GetCalibrationState( + void* Instance, + void* OutHapticGloveCalibrationState) +{ + StaticCast(OutHapticGloveCalibrationState)->State = + StaticCast(Instance)->Ptr->GetCalibrationState(); +} + +void SGCoreImpl_FSGSenseGloveImpl_EndCalibration( + void* Instance) +{ + StaticCast(Instance)->Ptr->EndCalibration(); +} + +void SGCoreImpl_FSGSenseGloveImpl_ResetCalibration( + void* Instance) +{ + StaticCast(Instance)->Ptr->ResetCalibration(); +} + +void SGCoreImpl_FSGSenseGloveImpl_StopHaptics( + void* Instance) +{ + StaticCast(Instance)->Ptr->StopHaptics(); +} + +void SGCoreImpl_FSGSenseGloveImpl_StopVibrations( + void* Instance) +{ + StaticCast(Instance)->Ptr->StopVibrations(); +} + +bool SGCoreImpl_FSGSenseGloveImpl_SendHaptics( + void* Instance) +{ + return StaticCast(Instance)->Ptr->SendHaptics(); +} + +bool SGCoreImpl_FSGSenseGloveImpl_QueueForceFeedbackLevels( + void* Instance, + void* Levels01) +{ + return StaticCast(Instance)->Ptr->QueueForceFeedbackLevels( + StaticCast(Levels01)->Array); +} + +bool SGCoreImpl_FSGSenseGloveImpl_QueueForceFeedbackLevel( + void* Instance, + const int32 Finger, + const float Level01) +{ + return StaticCast(Instance)->Ptr->QueueForceFeedbackLevel( + Finger, + Level01); +} + +bool SGCoreImpl_FSGSenseGloveImpl_QueueVibroLevels( + void* Instance, + void* Amplitudes) +{ + return StaticCast(Instance)->Ptr->QueueVibroLevels( + StaticCast(Amplitudes)->Array); +} + +bool SGCoreImpl_FSGSenseGloveImpl_QueueVibroLevel_Location_Level01( + void* Instance, + void* Location, + const float Level01) +{ + return StaticCast(Instance)->Ptr->QueueVibroLevel( + StaticCast(Location)->Location, + Level01); +} + +void +SGCoreImpl_FSGSenseGloveImpl_GetGloveLocation_ReferencePosition_ReferenceRotation_TrackingHardware_OutGlovePosition_OutGloveRotation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutGlovePosition, + void* OutGloveRotation) +{ + StaticCast(Instance)->Ptr->GetGloveLocation( + StaticCast(ReferencePosition)->Vector, + StaticCast(ReferenceRotation)->Quat, + StaticCast(TrackingHardware)->Hardware, + StaticCast(OutGlovePosition)->Vector, + StaticCast(OutGloveRotation)->Quat); +} + +void +SGCoreImpl_FSGSenseGloveImpl_GetGloveLocation_ReferencePosition_ReferenceRotation_TrackingHardware_MountedOn_OutGlovePosition_OutGloveRotation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* MountedOn, + void* OutGlovePosition, + void* OutGloveRotation) +{ + StaticCast(Instance)->Ptr->GetGloveLocation( + StaticCast(ReferencePosition)->Vector, + StaticCast(ReferenceRotation)->Quat, + StaticCast(TrackingHardware)->Hardware, + StaticCast(MountedOn)->Finger, + StaticCast(OutGlovePosition)->Vector, + StaticCast(OutGloveRotation)->Quat); +} + +void +SGCoreImpl_FSGSenseGloveImpl_GetWristLocation_ReferencePosition_ReferenceRotation_TrackingHardware_OutWristPosition_OutWristRotation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutWristPosition, + void* OutWristRotation) +{ + StaticCast(Instance)->Ptr->GetWristLocation( + StaticCast(ReferencePosition)->Vector, + StaticCast(ReferenceRotation)->Quat, + StaticCast(TrackingHardware)->Hardware, + StaticCast(OutWristPosition)->Vector, + StaticCast(OutWristRotation)->Quat); +} + +void +SGCoreImpl_FSGSenseGloveImpl_GetWristLocation_ReferencePosition_ReferenceRotation_TrackingHardware_GloveWristPositionOffset_GloveWristRotationOffset_OutWristPosition_OutWristRotation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* GloveWristPositionOffset, + void* GloveWristRotationOffset, + void* OutWristPosition, + void* OutWristRotation) +{ + StaticCast(Instance)->Ptr->GetWristLocation( + StaticCast(ReferencePosition)->Vector, + StaticCast(ReferenceRotation)->Quat, + StaticCast(TrackingHardware)->Hardware, + StaticCast(GloveWristPositionOffset)->Vector, + StaticCast(GloveWristRotationOffset)->Quat, + StaticCast(OutWristPosition)->Vector, + StaticCast(OutWristRotation)->Quat); +} + +void SGCoreImpl_FSGSenseGloveImpl_GetGloveInfo( + void* Instance, + void* OutGloveInfo) +{ + StaticCast(OutGloveInfo)->SenseGloveInfoImpl = + StaticCast(Instance)->Ptr->GetGloveInfo(); +} + +void SGCoreImpl_FSGSenseGloveImpl_GetFingerThimbleOffsets( + void* Instance, + void* OutFingerThimbleOffsets) +{ + StaticCast(OutFingerThimbleOffsets)->Array = + StaticCast(Instance)->Ptr->GetFingerThimbleOffsets(); +} + +void SGCoreImpl_FSGSenseGloveImpl_SetFingerThimbleOffset( + void* Instance, + const int32 Finger, + void* Offset) +{ + StaticCast(Instance)->Ptr->SetFingerThimbleOffset( + Finger, + StaticCast(Offset)->Vector); +} + +bool SGCoreImpl_FSGSenseGloveImpl_SupportsWristActuator( + void* Instance) +{ + return StaticCast(Instance)->Ptr->SupportsWristActuator(); +} + + +bool SGCoreImpl_FSGSenseGloveImpl_GetSensorData( + void* Instance, + void* OutSensorData) +{ + return StaticCast(Instance)->Ptr->GetSensorData( + StaticCast(OutSensorData)->NovaGloveSensorDataImpl); +} + +bool SGCoreImpl_FSGSenseGloveImpl_GetGlovePose_OutGlovePose( + void* Instance, + void* OutGlovePose) +{ + return StaticCast(Instance)->Ptr->GetGlovePose( + StaticCast(OutGlovePose)->SenseGlovePoseImpl); +} + +bool SGCoreImpl_FSGSenseGloveImpl_GetGlovePose_SensorData_OutGlovePose( + void* Instance, + void* SensorData, + void* OutGlovePose) +{ + return StaticCast(Instance)->Ptr->GetGlovePose( + StaticCast(SensorData)->SenseGloveSensorDataImpl, + StaticCast(OutGlovePose)->SenseGlovePoseImpl); +} + +bool SGCoreImpl_FSGSenseGloveImpl_QueueVibroLevel_Finger_Amplitude( + void* Instance, + const int32 Finger, + const float Amplitude) +{ + return StaticCast(Instance)->Ptr->QueueVibroLevel( + Finger, + Amplitude); +} + +bool SGCoreImpl_FSGSenseGloveImpl_QueueThumperCommand( + void* Instance, + void* Command) +{ + return StaticCast(Instance)->Ptr->QueueThumperCommand( + StaticCast(Command)->Command); +} + +void SGCoreImpl_FSGSenseGloveImpl_ToString( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->Ptr->ToString(); +} + +/******************************************************************************* + * SGSenseGloveInfoImpl.h + ******************************************************************************/ + +bool SGCoreImpl_FSGSenseGloveInfoImpl_Parse( + void* ConstantsString, + void* OutGloveInfo, + const bool bUpdateOldModels) +{ + return FSGSenseGloveInfoImpl::Parse( + StaticCast(ConstantsString)->String, + StaticCast(OutGloveInfo)->SenseGloveInfoImpl, + bUpdateOldModels); +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_Deserialize( + void* OutSenseGloveInfoImpl, + void* SerializedString) +{ + StaticCast(OutSenseGloveInfoImpl)->SenseGloveInfoImpl = + FSGSenseGloveInfoImpl::Deserialize( + StaticCast(SerializedString)->String); +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_ctor( + void* OutSenseGloveInfoImpl) +{ + StaticCast(OutSenseGloveInfoImpl)->SenseGloveInfoImpl = FSGSenseGloveInfoImpl(); +} + +void +SGCoreImpl_FSGSenseGloveInfoImpl_ctor_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded_NumberOfSensors_ImuCorrection_StartPositions_StartRotations_GloveLengths_Functions( + void* OutSenseGloveInfoImpl, + void* DeviceId, + void* HardwareVersion, + const int32 FirmwareVersion, + const int32 SubFirmwareVersion, + const bool bRightHanded, + const int32 NumberOfSensors, + void* ImuCorrection, + void* StartPositions, + void* StartRotations, + void* GloveLengths, + void* Functions) +{ + StaticCast(OutSenseGloveInfoImpl)->SenseGloveInfoImpl = + FSGSenseGloveInfoImpl( + StaticCast(DeviceId)->String, + StaticCast(HardwareVersion)->String, + FirmwareVersion, + SubFirmwareVersion, + bRightHanded, + NumberOfSensors, + StaticCast(ImuCorrection)->Quat, + StaticCast(StartPositions)->Array, + StaticCast(StartRotations)->Array, + StaticCast(GloveLengths)->Array, + StaticCast(Functions)->Array); +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_ctor_copy( + void* OutSenseGloveInfoImpl, + void* Rhs) +{ + StaticCast(OutSenseGloveInfoImpl)->SenseGloveInfoImpl = + FSGSenseGloveInfoImpl(StaticCast(Rhs)->SenseGloveInfoImpl); +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_ctor_copy_assignment( + void* OutSenseGloveInfoImpl, + void* Rhs) +{ + StaticCast(OutSenseGloveInfoImpl)->SenseGloveInfoImpl = + StaticCast(Rhs)->SenseGloveInfoImpl; +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_GetDeviceId( + void* Instance, + void* OutId) +{ + StaticCast(OutId)->String = + StaticCast(Instance)->SenseGloveInfoImpl.GetDeviceId(); +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_GetHardwareVersion( + void* Instance, + void* OutVersion) +{ + StaticCast(OutVersion)->String = + StaticCast(Instance)->SenseGloveInfoImpl.GetHardwareVersion(); +} + +int32 SGCoreImpl_FSGSenseGloveInfoImpl_GetFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->SenseGloveInfoImpl.GetFirmwareVersion(); +} + +int32 SGCoreImpl_FSGSenseGloveInfoImpl_GetSubFirmwareVersion( + void* Instance) +{ + return StaticCast(Instance)->SenseGloveInfoImpl.GetSubFirmwareVersion(); +} + +bool SGCoreImpl_FSGSenseGloveInfoImpl_IsRight( + void* Instance) +{ + return StaticCast(Instance)->SenseGloveInfoImpl.IsRight(); +} + +int32 SGCoreImpl_FSGSenseGloveInfoImpl_GetNumberOfSensors( + void* Instance) +{ + return StaticCast(Instance)->SenseGloveInfoImpl.GetNumberOfSensors(); +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_GetImuCorrection( + void* Instance, + void* OutCorrection) +{ + StaticCast(OutCorrection)->Quat = + StaticCast(Instance)->SenseGloveInfoImpl.GetImuCorrection(); +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_GetStartPositions( + void* Instance, + void* OutPositions) +{ + StaticCast(OutPositions)->Array = + StaticCast(Instance)->SenseGloveInfoImpl.GetStartPositions(); +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_GetStartRotations( + void* Instance, + void* OutRotations) +{ + StaticCast(OutRotations)->Array = + StaticCast(Instance)->SenseGloveInfoImpl.GetStartRotations(); +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_GetGloveLengths( + void* Instance, + void* OutLengths) +{ + StaticCast(OutLengths)->Array = + StaticCast(Instance)->SenseGloveInfoImpl.GetGloveLengths(); +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_GetFunctions( + void* Instance, + void* OutFunctions) +{ + StaticCast(OutFunctions)->Array = + StaticCast(Instance)->SenseGloveInfoImpl.GetFunctions(); +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_GetStartPosition( + void* Instance, + void* OutPosition, + void* Finger) +{ + StaticCast(OutPosition)->Vector = + StaticCast(Instance)->SenseGloveInfoImpl.GetStartPosition( + StaticCast(Finger)->Finger); +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_GetStartRotation( + void* Instance, + void* OutRotation, + void* Finger) +{ + StaticCast(OutRotation)->Quat = + StaticCast(Instance)->SenseGloveInfoImpl.GetStartRotation( + StaticCast(Finger)->Finger); +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_GetGloveLengths_Finger( + void* Instance, + void* OutLengths, + void* Finger) +{ + StaticCast(OutLengths)->Array = + StaticCast(Instance)->SenseGloveInfoImpl.GetGloveLengths( + StaticCast(Finger)->Finger); +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_ToGloveAngles( + void* Instance, + void* OutAngles, + void* SensorAngles) +{ + StaticCast(OutAngles)->Array = + StaticCast(Instance)->SenseGloveInfoImpl.ToGloveAngles( + StaticCast(SensorAngles)->Array); +} + +bool SGCoreImpl_FSGSenseGloveInfoImpl_Equals( + void* Instance, + void* SenseGloveInfoImpl) +{ + return StaticCast(Instance)->SenseGloveInfoImpl.Equals( + StaticCast(SenseGloveInfoImpl)->SenseGloveInfoImpl); +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_ToString_bShortNotation( + void* Instance, + void* OutString, + const bool bShortNotation) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->SenseGloveInfoImpl.ToString(bShortNotation); +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_ToString( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->SenseGloveInfoImpl.ToString(); +} + +void SGCoreImpl_FSGSenseGloveInfoImpl_Serialize( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->SenseGloveInfoImpl.Serialize(); +} + +/******************************************************************************* + * SGSenseGlovePoseImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGSenseGlovePoseImpl_IdlePose( + void* OutSenseGlovePoseImpl, + void* GloveInfo) +{ + StaticCast(OutSenseGlovePoseImpl)->SenseGlovePoseImpl = + FSGSenseGlovePoseImpl::IdlePose( + StaticCast(GloveInfo)->SenseGloveInfoImpl); +} + +void SGCoreImpl_FSGSenseGlovePoseImpl_Deserialize( + void* OutSenseGlovePoseImpl, + void* SerializedString) +{ + StaticCast(OutSenseGlovePoseImpl)->SenseGlovePoseImpl = + FSGSenseGlovePoseImpl::Deserialize( + StaticCast(SerializedString)->String); +} + +void SGCoreImpl_FSGSenseGlovePoseImpl_ctor( + void* OutSenseGlovePoseImpl) +{ + StaticCast(OutSenseGlovePoseImpl)->SenseGlovePoseImpl = FSGSenseGlovePoseImpl(); +} + +void SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( + void* OutSenseGlovePoseImpl, + const bool bRightHanded, + void* JointPositions, + void* JointRotations, + void* GloveAngles) +{ + StaticCast(OutSenseGlovePoseImpl)->SenseGlovePoseImpl = + FSGSenseGlovePoseImpl( + bRightHanded, + StaticCast(JointPositions)->Array, + StaticCast(JointRotations)->Array, + StaticCast(GloveAngles)->Array); +} + +void SGCoreImpl_FSGSenseGlovePoseImpl_ctor_copy( + void* OutSenseGlovePoseImpl, + void* Rhs) +{ + StaticCast(OutSenseGlovePoseImpl)->SenseGlovePoseImpl = + FSGSenseGlovePoseImpl(StaticCast(Rhs)->SenseGlovePoseImpl); +} + +void SGCoreImpl_FSGSenseGlovePoseImpl_ctor_copy_assignment( + void* OutSenseGlovePoseImpl, + void* Rhs) +{ + StaticCast(OutSenseGlovePoseImpl)->SenseGlovePoseImpl = + StaticCast(Rhs)->SenseGlovePoseImpl; +} + +bool SGCoreImpl_FSGSenseGlovePoseImpl_IsRight( + void* Instance) +{ + return StaticCast(Instance)->SenseGlovePoseImpl.IsRight(); +} + +void SGCoreImpl_FSGSenseGlovePoseImpl_GetJointPositions( + void* Instance, + void* OutPositions) +{ + StaticCast(OutPositions)->Array = + StaticCast(Instance)->SenseGlovePoseImpl.GetJointPositions(); +} + +void SGCoreImpl_FSGSenseGlovePoseImpl_GetJointRotations( + void* Instance, + void* OutRotations) +{ + StaticCast(OutRotations)->Array = + StaticCast(Instance)->SenseGlovePoseImpl.GetJointRotations(); +} + +void SGCoreImpl_FSGSenseGlovePoseImpl_GetGloveAngles( + void* Instance, + void* OutAngles) +{ + StaticCast(OutAngles)->Array = + StaticCast(Instance)->SenseGlovePoseImpl.GetGloveAngles(); +} + +void SGCoreImpl_FSGSenseGlovePoseImpl_GetThimblePositions( + void* Instance, + void* OutPositions) +{ + StaticCast(OutPositions)->Array = + StaticCast(Instance)->SenseGlovePoseImpl.GetThimblePositions(); +} + +void SGCoreImpl_FSGSenseGlovePoseImpl_GetThimbleRotations( + void* Instance, + void* OutRotations) +{ + StaticCast(OutRotations)->Array = + StaticCast(Instance)->SenseGlovePoseImpl.GetThimbleRotations(); +} + +void SGCoreImpl_FSGSenseGlovePoseImpl_GetTotalGloveAngles( + void* Instance, + void* OutAngles) +{ + StaticCast(OutAngles)->Array = + StaticCast(Instance)->SenseGlovePoseImpl.GetTotalGloveAngles(); +} + +void SGCoreImpl_FSGSenseGlovePoseImpl_CalculateFingertips( + void* Instance, + void* OutFingertips, + void* FingerOffsets) +{ + StaticCast(OutFingertips)->Array = + StaticCast(Instance)->SenseGlovePoseImpl.CalculateFingertips( + StaticCast(FingerOffsets)->Array); +} + +bool SGCoreImpl_FSGSenseGlovePoseImpl_Equals( + void* Instance, + void* SenseGlovePoseImpl) +{ + return StaticCast(Instance)->SenseGlovePoseImpl.Equals( + StaticCast(SenseGlovePoseImpl)->SenseGlovePoseImpl); +} + +void SGCoreImpl_FSGSenseGlovePoseImpl_ToString( + void* Instance, + void* OutString, + const bool bShortFormat) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->SenseGlovePoseImpl.ToString(bShortFormat); +} + +void SGCoreImpl_FSGSenseGlovePoseImpl_Serialize( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->SenseGlovePoseImpl.Serialize(); +} + +/******************************************************************************* + * SGSenseGloveSensorDataImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGSenseGloveSensorDataImpl_Empty( + void* OutSenseGloveSensorDataImpl) +{ + StaticCast(OutSenseGloveSensorDataImpl)->SenseGloveSensorDataImpl = + FSGSenseGloveSensorDataImpl::Empty(); +} + +void SGCoreImpl_FSGSenseGloveSensorDataImpl_Parse( + void* OutSenseGloveSensorDataImpl, + void* RawData, + void* GloveInfo) +{ + StaticCast(OutSenseGloveSensorDataImpl)->SenseGloveSensorDataImpl = + FSGSenseGloveSensorDataImpl::Parse( + StaticCast(RawData)->String, + StaticCast(GloveInfo)->SenseGloveInfoImpl); +} + +void SGCoreImpl_FSGSenseGloveSensorDataImpl_Deserialize( + void* OutSenseGloveSensorDataImpl, + void* SerializedString) +{ + StaticCast(OutSenseGloveSensorDataImpl)->SenseGloveSensorDataImpl = + FSGSenseGloveSensorDataImpl::Deserialize( + StaticCast(SerializedString)->String); +} + +void SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor( + void* OutSenseGloveSensorDataImpl) +{ + StaticCast(OutSenseGloveSensorDataImpl)->SenseGloveSensorDataImpl = + FSGSenseGloveSensorDataImpl(); +} + +void SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor_SensorAngles_ImuRotation_ParsedValues_bImuParsed( + void* OutSenseGloveSensorDataImpl, + void* SensorAngles, + void* ImuRotation, + const int32 ParsedValues, + const bool bImuParsed) +{ + StaticCast(OutSenseGloveSensorDataImpl)->SenseGloveSensorDataImpl = + FSGSenseGloveSensorDataImpl( + StaticCast(SensorAngles)->Array, + StaticCast(ImuRotation)->Quat, + ParsedValues, + bImuParsed); +} + +void SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor_copy( + void* OutSenseGloveSensorDataImpl, + void* Rhs) +{ + StaticCast(OutSenseGloveSensorDataImpl)->SenseGloveSensorDataImpl = + FSGSenseGloveSensorDataImpl(StaticCast(Rhs)->SenseGloveSensorDataImpl); +} + +void SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor_copy_assignment( + void* OutSenseGloveSensorDataImpl, + void* Rhs) +{ + StaticCast(OutSenseGloveSensorDataImpl)->SenseGloveSensorDataImpl = + StaticCast(Rhs)->SenseGloveSensorDataImpl; +} + +void SGCoreImpl_FSGSenseGloveSensorDataImpl_GetSensorAngles( + void* Instance, + void* OutAngles) +{ + StaticCast(OutAngles)->Array = + StaticCast(Instance)->SenseGloveSensorDataImpl.GetSensorAngles(); +} + +void SGCoreImpl_FSGSenseGloveSensorDataImpl_GetSensorAngles_Finger( + void* Instance, + void* OutAngles, + void* Finger) +{ + StaticCast(OutAngles)->Array = + StaticCast(Instance)->SenseGloveSensorDataImpl.GetSensorAngles( + StaticCast(Finger)->Finger); +} + +void SGCoreImpl_FSGSenseGloveSensorDataImpl_GetAngleSequence( + void* Instance, + void* OutSequence) +{ + StaticCast(OutSequence)->Array = + StaticCast(Instance)->SenseGloveSensorDataImpl.GetAngleSequence(); +} + +void SGCoreImpl_FSGSenseGloveSensorDataImpl_GetImuRotation( + void* Instance, + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = + StaticCast(Instance)->SenseGloveSensorDataImpl.GetImuRotation(); +} + +int32 SGCoreImpl_FSGSenseGloveSensorDataImpl_GetParsedValues( + void* Instance) +{ + return StaticCast(Instance)->SenseGloveSensorDataImpl.GetParsedValues(); +} + +bool SGCoreImpl_FSGSenseGloveSensorDataImpl_IsImuParsed( + void* Instance) +{ + return StaticCast(Instance)->SenseGloveSensorDataImpl.IsImuParsed(); +} + +bool SGCoreImpl_FSGSenseGloveSensorDataImpl_Equals( + void* Instance, + void* SenseGloveSensorDataImpl) +{ + return StaticCast(Instance)->SenseGloveSensorDataImpl.Equals( + StaticCast(SenseGloveSensorDataImpl)->SenseGloveSensorDataImpl); +} + +void SGCoreImpl_FSGSenseGloveSensorDataImpl_ToString( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->SenseGloveSensorDataImpl.ToString(); +} + +void SGCoreImpl_FSGSenseGloveSensorDataImpl_Serialize( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->SenseGloveSensorDataImpl.Serialize(); +} + +/******************************************************************************* + * SGSenseGloveSensorNormalizerImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_ctor( + void* OutSenseGloveSensorNormalizerImpl) +{ + StaticCast(OutSenseGloveSensorNormalizerImpl)-> + SenseGloveSensorNormalizerImpl = + FSGSenseGloveSensorNormalizerImpl(); +} + +void SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_ctor_bRightHanded( + void* OutSenseGloveSensorNormalizerImpl, + const bool bRightHanded) +{ + StaticCast(OutSenseGloveSensorNormalizerImpl)-> + SenseGloveSensorNormalizerImpl = + FSGSenseGloveSensorNormalizerImpl( + bRightHanded); +} + +void SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_ctor_copy( + void* OutSenseGloveSensorNormalizerImpl, + void* Rhs) +{ + StaticCast(OutSenseGloveSensorNormalizerImpl)-> + SenseGloveSensorNormalizerImpl = + FSGSenseGloveSensorNormalizerImpl( + StaticCast(Rhs)->SenseGloveSensorNormalizerImpl); +} + +void SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_ctor_copy_assignment( + void* OutSenseGloveSensorNormalizerImpl, + void* Rhs) +{ + StaticCast(OutSenseGloveSensorNormalizerImpl)-> + SenseGloveSensorNormalizerImpl = + StaticCast(Rhs)->SenseGloveSensorNormalizerImpl; +} + +float SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_NormalizeFlexion( + void* Instance, + const int32 Finger, + const float SumFlexionAngles) +{ + return StaticCast( + Instance)->SenseGloveSensorNormalizerImpl.NormalizeFlexion( + Finger, SumFlexionAngles); +} + +float SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_NormalizeAbduction( + void* Instance, + const int32 Finger, + const float SumAbductionAngles) +{ + return StaticCast( + Instance)->SenseGloveSensorNormalizerImpl.NormalizeAbduction( + Finger, SumAbductionAngles); +} + +/******************************************************************************* + * SGSenseGloveVarsImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGSenseGloveVarsImpl_GetStandardConstantsString( + void* OutString, + void* HardwareVersion, + const float FirmwareVersion, + const bool bRightHanded) +{ + StaticCast(OutString)->String = FSGSenseGloveVarsImpl::GetStandardConstantsString( + StaticCast(HardwareVersion)->String, + FirmwareVersion, + bRightHanded); +} + +void SGCoreImpl_FSGSenseGloveVarsImpl_GetSensorString( + void* OutString, + void* HardwareVersion, + const float FirmwareVersion) +{ + StaticCast(OutString)->String = FSGSenseGloveVarsImpl::GetSensorString( + StaticCast(HardwareVersion)->String, + FirmwareVersion); +} + +void SGCoreImpl_FSGSenseGloveVarsImpl_GetStartPositions( + void* OutPositions, + void* HardwareVersion, + const bool bRightHanded) +{ + StaticCast(OutPositions)->Array = FSGSenseGloveVarsImpl::GetStartPositions( + StaticCast(HardwareVersion)->String, + bRightHanded); +} + +void SGCoreImpl_FSGSenseGloveVarsImpl_GetStartRotations( + void* OutRotations, + void* HardwareVersion, + const bool bRightHanded) +{ + StaticCast(OutRotations)->Array = FSGSenseGloveVarsImpl::GetStartRotations( + StaticCast(HardwareVersion)->String, + bRightHanded); +} + +void SGCoreImpl_FSGSenseGloveVarsImpl_GetGloveLengths( + void* OutLengths, + void* HardwareVersion) +{ + StaticCast(OutLengths)->Array = FSGSenseGloveVarsImpl::GetGloveLengths( + StaticCast(HardwareVersion)->String); +} + +int32 SGCoreImpl_FSGSenseGloveVarsImpl_GetSensors( + void* HardwareVersion) +{ + return FSGSenseGloveVarsImpl::GetSensors(StaticCast(HardwareVersion)->String); +} + +void SGCoreImpl_FSGSenseGloveVarsImpl_GetImuCorrection( + void* OutCorrection, + void* HardwareVersion, + const int32 FirmwareVersion, + const int32 SubFirmwareVersion) +{ + StaticCast(OutCorrection)->Quat = FSGSenseGloveVarsImpl::GetImuCorrection( + StaticCast(HardwareVersion)->String, + FirmwareVersion, + SubFirmwareVersion); +} + +void SGCoreImpl_FSGSenseGloveVarsImpl_GetFunctions( + void* OutFunctions, + void* HardwareVersion, + const int32 FirmwareVersion, + const int32 SubFirmwareVersion) +{ + StaticCast(OutFunctions)->Array = FSGSenseGloveVarsImpl::GetFunctions( + StaticCast(HardwareVersion)->String, + FirmwareVersion, + SubFirmwareVersion); +} + +void +SGCoreImpl_FSGSenseGloveVarsImpl_GenerateGloveModel_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded( + void* OutModel, + void* HardwareVersion, + const int32 FirmwareVersion, + const int32 SubFirmwareVersion, + const bool bRightHanded) +{ + StaticCast(OutModel)->SenseGloveInfoImpl = + FSGSenseGloveVarsImpl::GenerateGloveModel( + StaticCast(HardwareVersion)->String, + FirmwareVersion, + SubFirmwareVersion, + bRightHanded); +} + +void +SGCoreImpl_FSGSenseGloveVarsImpl_GenerateGloveModel_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded_CustomId( + void* OutModel, + void* HardwareVersion, + const int32 FirmwareVersion, + const int32 SubFirmwareVersion, + const bool bRightHanded, + void* CustomId) +{ + StaticCast(OutModel)->SenseGloveInfoImpl = + FSGSenseGloveVarsImpl::GenerateGloveModel( + StaticCast(HardwareVersion)->String, + FirmwareVersion, + SubFirmwareVersion, + bRightHanded, + StaticCast(CustomId)->String); +} + +/******************************************************************************* + * SGSensorNormalizationImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGSensorNormalizationImpl_ctor( + void* OutSensorNormalizationImpl) +{ + StaticCast(OutSensorNormalizationImpl)->SensorNormalizationImpl = + FSGSensorNormalizationImpl{}; +} + +void SGCoreImpl_FSGSensorNormalizationImpl_ctor_MovementRanges( + void* OutSensorNormalizationImpl, + void* MovementRanges) +{ + StaticCast(OutSensorNormalizationImpl)->SensorNormalizationImpl = + FSGSensorNormalizationImpl{ + StaticCast(MovementRanges)->Array + }; +} + +void SGCoreImpl_FSGSensorNormalizationImpl_ctor_copy( + void* OutSensorNormalizationImpl, + void* Rhs) +{ + StaticCast(OutSensorNormalizationImpl)->SensorNormalizationImpl = + FSGSensorNormalizationImpl(StaticCast(Rhs)->SensorNormalizationImpl); +} + +void SGCoreImpl_FSGSensorNormalizationImpl_ctor_copy_assignment( + void* OutSensorNormalizationImpl, + void* Rhs) +{ + StaticCast(OutSensorNormalizationImpl)->SensorNormalizationImpl = + StaticCast(Rhs)->SensorNormalizationImpl; +} + +bool SGCoreImpl_FSGSensorNormalizationImpl_CollectsNormalization( + void* Instance) +{ + return StaticCast(Instance)->SensorNormalizationImpl.CollectsNormalization(); +} + +void SGCoreImpl_FSGSensorNormalizationImpl_SetCollectNormalization( + void* Instance, + const bool bCollectNormalization) +{ + StaticCast(Instance)->SensorNormalizationImpl.SetCollectNormalization( + bCollectNormalization); +} + +int32 SGCoreImpl_FSGSensorNormalizationImpl_GetLength( + void* Instance) +{ + return StaticCast(Instance)->SensorNormalizationImpl.GetLength(); +} + +int32 SGCoreImpl_FSGSensorNormalizationImpl_GetMoveCount( + void* Instance) +{ + return StaticCast(Instance)->SensorNormalizationImpl.GetMoveCount(); +} + +bool SGCoreImpl_FSGSensorNormalizationImpl_AllSensorsMoving( + void* Instance) +{ + return StaticCast(Instance)->SensorNormalizationImpl.AllSensorsMoving(); +} + +void SGCoreImpl_FSGSensorNormalizationImpl_ResetNormalization( + void* Instance) +{ + return StaticCast(Instance)->SensorNormalizationImpl.ResetNormalization(); +} + +void SGCoreImpl_FSGSensorNormalizationImpl_UpdateNormalization( + void* Instance, + const float Value, + const int32 Index) +{ + StaticCast(Instance)->SensorNormalizationImpl.UpdateNormalization( + Value, Index); +} + +float SGCoreImpl_FSGSensorNormalizationImpl_NormalizeValue( + void* Instance, + const float Value, + const int32 Index) +{ + return StaticCast(Instance)->SensorNormalizationImpl.NormalizeValue( + Value, Index); +} + +void SGCoreImpl_FSGSensorNormalizationImpl_NormalizeValues( + void* Instance, + void* Values, + void* OutNormalizedValues) +{ + StaticCast(OutNormalizedValues)->Array = + StaticCast(Instance)->SensorNormalizationImpl.NormalizeValues( + StaticCast(Values)->Array); +} + +bool SGCoreImpl_FSGSensorNormalizationImpl_MovedEnough( + void* Instance, + const int32 Index) +{ + return StaticCast(Instance)->SensorNormalizationImpl.MovedEnough( + Index); +} + +float SGCoreImpl_FSGSensorNormalizationImpl_Denormalize( + void* Instance, + const float Value01, + const int32 Index, + const float FallbackValue) +{ + return StaticCast(Instance)->SensorNormalizationImpl.Denormalize( + Value01, + Index, + FallbackValue); +} + +/******************************************************************************* + * SGThresholdCommandImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGThresholdCommandImpl_ctor( + void* OutThresholdCommandImpl) +{ + StaticCast(OutThresholdCommandImpl)->ThresholdCommandImpl = + FSGThresholdCommandImpl{}; +} + +void SGCoreImpl_FSGThresholdCommandImpl_ctor_AffectedFingers_ThresholdValues( + void* OutThresholdCommandImpl, + void* AffectedFingers, + void* ThresholdValues) +{ + StaticCast(OutThresholdCommandImpl)->ThresholdCommandImpl = + FSGThresholdCommandImpl{ + StaticCast(AffectedFingers)->Array, + StaticCast(ThresholdValues)->Array + }; +} + +void SGCoreImpl_FSGThresholdCommandImpl_ctor_copy( + void* OutThresholdCommandImpl, + void* Rhs) +{ + StaticCast(OutThresholdCommandImpl)->ThresholdCommandImpl = + FSGThresholdCommandImpl(StaticCast(Rhs)->ThresholdCommandImpl); +} + +void SGCoreImpl_FSGThresholdCommandImpl_ctor_copy_assignment( + void* OutThresholdCommandImpl, + void* Rhs) +{ + StaticCast(OutThresholdCommandImpl)->ThresholdCommandImpl = + StaticCast(Rhs)->ThresholdCommandImpl; +} + +float SGCoreImpl_FSGThresholdCommandImpl_GetThreshold( + void* Instance, + const int32 Finger) +{ + return StaticCast(Instance)->ThresholdCommandImpl.GetThreshold( + Finger); +} + +void SGCoreImpl_FSGThresholdCommandImpl_SetThreshold( + void* Instance, + const int32 Finger, + const float ThresholdValue) +{ + return StaticCast(Instance)->ThresholdCommandImpl.SetThreshold( + Finger, + ThresholdValue); +} + +void SGCoreImpl_FSGThresholdCommandImpl_GetThresholds( + void* Instance, + void* OutThresholds) +{ + StaticCast(OutThresholds)->Array = + StaticCast(Instance)->ThresholdCommandImpl.GetThresholds(); +} + +void SGCoreImpl_FSGThresholdCommandImpl_SetThresholds( + void* Instance, + void* AffectedFingers, + void* ThresholdValues) +{ + return StaticCast(Instance)->ThresholdCommandImpl.SetThresholds( + StaticCast(AffectedFingers)->Array, + StaticCast(ThresholdValues)->Array); +} + +bool SGCoreImpl_FSGThresholdCommandImpl_GetFingerActive( + void* Instance, + const int32 Finger) +{ + return StaticCast(Instance)->ThresholdCommandImpl.GetFingerActive( + Finger); +} + +void SGCoreImpl_FSGThresholdCommandImpl_GetActiveFingers( + void* Instance, + void* OutActiveFingers) +{ + StaticCast(OutActiveFingers)->Array = + StaticCast(Instance)->ThresholdCommandImpl.GetActiveFingers(); +} + +void SGCoreImpl_FSGThresholdCommandImpl_ClearThreshold( + void* Instance, + const int32 Finger) +{ + return StaticCast(Instance)->ThresholdCommandImpl.ClearThreshold( + Finger); +} + +void SGCoreImpl_FSGThresholdCommandImpl_ClearThresholds( + void* Instance) +{ + return StaticCast(Instance)->ThresholdCommandImpl.ClearThresholds(); +} + +bool SGCoreImpl_FSGThresholdCommandImpl_Equals( + void* Instance, + void* ThresholdCommandImpl) +{ + return StaticCast(Instance)->ThresholdCommandImpl.Equals( + StaticCast(ThresholdCommandImpl)->ThresholdCommandImpl); +} + +void SGCoreImpl_FSGThresholdCommandImpl_ToString( + void* Instance, + void* OutString) +{ + StaticCast(OutString)->String = + StaticCast(Instance)->ThresholdCommandImpl.ToString(); +} + +/******************************************************************************* + * SGTrackingImpl.h + ******************************************************************************/ + +void SGCoreImpl_FSGTrackingImpl_CalculateLocation( + void* TrackedPosition, + void* TrackedRotation, + void* PositionOffset, + void* RotationOffset, + void* OutNewPosition, + void* OutNewRotation) +{ + FSGTrackingImpl::CalculateLocation( + StaticCast(TrackedPosition)->Vector, + StaticCast(TrackedRotation)->Quat, + StaticCast(PositionOffset)->Vector, + StaticCast(RotationOffset)->Quat, + StaticCast(OutNewPosition)->Vector, + StaticCast(OutNewRotation)->Quat); +} + +void SGCoreImpl_FSGTrackingImpl_GetSenseGloveFingerToGlovePositionOrigin( + void* OutOrigin) +{ + StaticCast(OutOrigin)->Array = + FSGTrackingImpl::GetSenseGloveFingerToGlovePositionOrigin(); +} + +void SGCoreImpl_FSGTrackingImpl_GetSenseGloveFingerToGloveRotationOrigin( + void* OutOrigin) +{ + StaticCast(OutOrigin)->Array = FSGTrackingImpl::GetSenseGloveFingerToGloveRotationOrigin(); +} + +void SGCoreImpl_FSGTrackingImpl_GetSenseGloveWristPositionOffset( + void* OutOffset) +{ + StaticCast(OutOffset)->Vector = FSGTrackingImpl::GetSenseGloveWristPositionOffset(); +} + +void SGCoreImpl_FSGTrackingImpl_GetSenseGloveWristRotationOffset( + void* OutOffset) +{ + StaticCast(OutOffset)->Quat = FSGTrackingImpl::GetSenseGloveWristRotationOffset(); +} + +void SGCoreImpl_FSGTrackingImpl_GetSenseGloveMountOffset( + const bool bRightHanded, + void* ToFinger, + void* OutIPosition, + void* OutIRotation) +{ + FSGTrackingImpl::GetSenseGloveMountOffset( + bRightHanded, + StaticCast(ToFinger)->Finger, + StaticCast(OutIPosition)->Vector, + StaticCast(OutIRotation)->Quat); +} + +void SGCoreImpl_FSGTrackingImpl_GetSenseGloveTrackerMountOffset( + void* Hardware, + const bool bRightHanded, + void* OutPositionOffset, + void* OutRotationOffset) +{ + FSGTrackingImpl::GetSenseGloveTrackerMountOffset( + StaticCast(Hardware)->Hardware, + bRightHanded, + StaticCast(OutPositionOffset)->Vector, + StaticCast(OutRotationOffset)->Quat); +} + +void SGCoreImpl_FSGTrackingImpl_GetSenseGloveViveToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetSenseGloveViveToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetSenseGloveViveToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetSenseGloveViveToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetSenseGloveOculusTouchToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetSenseGloveOculusTouchToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetSenseGloveOculusTouchToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetSenseGloveOculusTouchToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetNovaToWristPositionOffset( + void* OutOffset) +{ + StaticCast(OutOffset)->Vector = FSGTrackingImpl::GetNovaToWristPositionOffset(); +} + +void SGCoreImpl_FSGTrackingImpl_GetNovaToWristRotationOffset( + void* OutOffset) +{ + StaticCast(OutOffset)->Quat = FSGTrackingImpl::GetNovaToWristRotationOffset(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNovaViveToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetRightNovaViveToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNovaViveToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetRightNovaViveToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNovaViveToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetLeftNovaViveToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNovaViveToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetLeftNovaViveToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNovaQuest2ToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetRightNovaQuest2ToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNovaQuest2ToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetRightNovaQuest2ToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuest2ToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetLeftNovaQuest2ToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuest2ToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetLeftNovaQuest2ToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNovaPico2ToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetRightNovaPico2ToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNovaPico2ToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetRightNovaPico2ToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNovaPico2ToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetLeftNovaPico2ToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNovaQuestProToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetRightNovaQuestProToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNovaQuestProToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetRightNovaQuestProToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuestProToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetLeftNovaQuestProToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuestProToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetLeftNovaQuestProToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNovaViveFocus3ToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetRightNovaViveFocus3ToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNovaViveFocus3ToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetRightNovaViveFocus3ToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNovaViveFocus3ToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetLeftNovaViveFocus3ToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNovaViveFocus3ToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetLeftNovaViveFocus3ToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNovaQuest3ToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetRightNovaQuest3ToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNovaQuest3ToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetRightNovaQuest3ToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuest3ToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetLeftNovaQuest3ToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuest3ToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetLeftNovaQuest3ToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetNovaGloveWristOffset( + const bool bRightHanded, + void* OutPositionOffset, + void* OutRotationOffset) +{ + FSGTrackingImpl::GetNovaGloveWristOffset( + bRightHanded, + StaticCast(OutPositionOffset)->Vector, + StaticCast(OutRotationOffset)->Quat); +} + +void SGCoreImpl_FSGTrackingImpl_GetNovaGloveTrackerOffset( + void* Hardware, + const bool bRightHanded, + void* OutPositionOffset, + void* OutRotationOffset) +{ + FSGTrackingImpl::GetNovaGloveTrackerOffset( + StaticCast(Hardware)->Hardware, + bRightHanded, + StaticCast(OutPositionOffset)->Vector, + StaticCast(OutRotationOffset)->Quat); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNova2ToWristPositionOffset( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetRightNova2ToWristPositionOffset(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNova2ToWristRotationOffset( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetRightNova2ToWristRotationOffset(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNova2ToWristPositionOffset( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetLeftNova2ToWristPositionOffset(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNova2ToWristRotationOffset( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetLeftNova2ToWristRotationOffset(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNova2Quest2ToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetRightNova2Quest2ToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNova2Quest2ToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetRightNova2Quest2ToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNova2Quest2ToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetLeftNova2Quest2ToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNova2Quest2ToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetLeftNova2Quest2ToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNova2QuestProToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetRightNova2QuestProToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNova2QuestProToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetRightNova2QuestProToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNova2QuestProToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetLeftNova2QuestProToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNova2QuestProToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetLeftNova2QuestProToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNova2ViveTrackerToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetRightNova2ViveTrackerToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNova2ViveTrackerToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetRightNova2ViveTrackerToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNova2ViveTrackerToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetLeftNova2ViveTrackerToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNova2ViveTrackerToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetLeftNova2ViveTrackerToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNova2ViveWristTrackerToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = + FSGTrackingImpl::GetRightNova2ViveWristTrackerToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNova2ViveWristTrackerToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetRightNova2ViveWristTrackerToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNova2ViveWristTrackerToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = + FSGTrackingImpl::GetLeftNova2ViveWristTrackerToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNova2ViveWristTrackerToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetLeftNova2ViveWristTrackerToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNova2Quest3ToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetRightNova2Quest3ToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetRightNova2Quest3ToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetRightNova2Quest3ToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNova2Quest3ToAttachPosition( + void* OutPosition) +{ + StaticCast(OutPosition)->Vector = FSGTrackingImpl::GetLeftNova2Quest3ToAttachPosition(); +} + +void SGCoreImpl_FSGTrackingImpl_GetLeftNova2Quest3ToAttachRotation( + void* OutRotation) +{ + StaticCast(OutRotation)->Quat = FSGTrackingImpl::GetLeftNova2Quest3ToAttachRotation(); +} + +void SGCoreImpl_FSGTrackingImpl_GetNova2GloveWristOffset( + const bool bRightHanded, + void* HardwareVersion, + void* OutPositionOffset, + void* OutRotationOffset) +{ + FSGTrackingImpl::GetNova2GloveWristOffset( + bRightHanded, + StaticCast(HardwareVersion)->String, + StaticCast(OutPositionOffset)->Vector, + StaticCast(OutRotationOffset)->Quat); +} + +void SGCoreImpl_FSGTrackingImpl_GetNova2GloveTrackerOffset( + void* Hardware, + const bool bRightHanded, + void* HardwareVersion, + void* OutPositionOffset, + void* OutRotationOffset) +{ + FSGTrackingImpl::GetNova2GloveTrackerOffset( + StaticCast(Hardware)->Hardware, + bRightHanded, + StaticCast(HardwareVersion)->String, + StaticCast(OutPositionOffset)->Vector, + StaticCast(OutRotationOffset)->Quat); +} + +void SGCoreImpl_FSGTrackingImpl_ToString( + void* OutString, + void* Hardware) +{ + StaticCast(OutString)->String = FSGTrackingImpl::ToString( + StaticCast(Hardware)->Hardware); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGHandInterpolatorImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGHandInterpolatorImpl.cpp new file mode 100644 index 0000000..3e7d84b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGHandInterpolatorImpl.cpp @@ -0,0 +1,186 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGHandInterpolatorImpl.h" + +#include +#include + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_HandInterpolator.h" +#include "SGBuildHacks/SGInclude_Core_InterpolationSet.h" +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGCoreImpl/SGInterpolationSetImpl.h" +#include "SGCoreImpl/SGQuatImpl.h" +#include "SGCoreImpl/SGVect3DImpl.h" +#include "SGUtils/SGAngles.h" +#include "SGUtils/SGArrayUtils.h" + +struct FSGHandInterpolatorImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FHandInterpolatorType HandInterpolator; + + /************************ + * Owner object + ************************/ + + FSGHandInterpolatorImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGHandInterpolatorImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +FSGHandInterpolatorImpl FSGHandInterpolatorImpl::Deserialize(const FString& SerializedString, const bool bRightHanded) +{ + std::string Serialized(TCHAR_TO_UTF8(*SerializedString)); + const FSGHandInterpolatorImpl GlovePose(FHandInterpolatorType::Deserialize(MoveTemp(Serialized), bRightHanded)); + return GlovePose; +} + +FSGHandInterpolatorImpl::FSGHandInterpolatorImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGHandInterpolatorImpl::FSGHandInterpolatorImpl(const bool bRightHanded) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->HandInterpolator = FHandInterpolatorType(bRightHanded); +} + +FSGHandInterpolatorImpl::FSGHandInterpolatorImpl(const FHandInterpolatorType& HandInterpolator) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->HandInterpolator = HandInterpolator; +} + +FSGHandInterpolatorImpl::FSGHandInterpolatorImpl(const FSGHandInterpolatorImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGHandInterpolatorImpl::FSGHandInterpolatorImpl(FSGHandInterpolatorImpl&& Rhs) SG_NOEXCEPT = default; + +FSGHandInterpolatorImpl::~FSGHandInterpolatorImpl() = default; + +FSGHandInterpolatorImpl& FSGHandInterpolatorImpl::operator=(const FSGHandInterpolatorImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGHandInterpolatorImpl& FSGHandInterpolatorImpl::operator=(FSGHandInterpolatorImpl&& Rhs) SG_NOEXCEPT = default; + +const FSGHandInterpolatorImpl::FHandInterpolatorType& FSGHandInterpolatorImpl::ToHandInterpolator( + ) const +{ + return Pimpl->HandInterpolator; +} + +float FSGHandInterpolatorImpl::CalculateAngle( + const ESGFingerMovement Movement, const float Value, const bool bApplyLimits) const +{ + return FSGAngles::TransformToUnreal( + Movement, Pimpl->HandInterpolator.CalculateAngle( + FSGCoreEnumCast::ToEFingerMovement(Movement), Value, bApplyLimits)); +} + +float FSGHandInterpolatorImpl::CalculateAngle( + const ESGThumbMovement Movement, const float Value, const bool bApplyLimits) const +{ + return FSGAngles::TransformToUnreal( + Movement, Pimpl->HandInterpolator.CalculateAngle( + FSGCoreEnumCast::ToEThumbMovement(Movement), Value, bApplyLimits)); +} + +TArray> FSGHandInterpolatorImpl::InterpolateHandAngles( + const TArray>& Flexions, const TArray& Abductions, const float CmcTwist) +{ + std::vector> FlexionsVector{ + FSGArrayUtils::ToSenseGloveAngles(Flexions) + }; + std::vector AbductionsVector{ + FSGArrayUtils::ToSenseGloveAngles(Abductions) + }; + const TArray> Angles{ + FSGArrayUtils::FromSenseGloveAngles( + Pimpl->HandInterpolator.InterpolateHandAngles( + MoveTemp(FlexionsVector), MoveTemp(AbductionsVector), CmcTwist)) + }; + return Angles; +} + +bool FSGHandInterpolatorImpl::Equals(const FSGHandInterpolatorImpl& HandInterpolatorImpl) const +{ + return Pimpl->HandInterpolator.Equals(HandInterpolatorImpl.ToHandInterpolator()); +} + +FString FSGHandInterpolatorImpl::Serialize() const +{ + const FString Serialized(UTF8_TO_TCHAR(Pimpl->HandInterpolator.Serialize().c_str())); + return Serialized; +} + +FSGHandInterpolatorImpl::FImpl::FImpl(FSGHandInterpolatorImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGHandInterpolatorImpl::FImpl::~FImpl() = default; + +void FSGHandInterpolatorImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGHandLayerImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGHandLayerImpl.cpp new file mode 100644 index 0000000..32f208c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGHandLayerImpl.cpp @@ -0,0 +1,221 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGHandLayerImpl.h" + +#include + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_CustomWaveform.h" +#include "SGBuildHacks/SGInclude_Core_HandLayer.h" +#include "SGBuildHacks/SGInclude_Core_HandPose.h" +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" +#include "SGCoreImpl/SGCustomWaveformImpl.h" +#include "SGCoreImpl/SGCustomWaveformImpl.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGCoreImpl/SGHandPoseImpl.h" +#include "SGCoreImpl/SGHapticGloveImpl.h" +#include "SGCoreImpl/SGQuatImpl.h" +#include "SGCoreImpl/SGVect3DImpl.h" +#include "SGUtils/SGArrayUtils.h" + +bool FSGHandLayerImpl::DeviceConnected(const bool bRightHanded) +{ + return FHandLayerType::DeviceConnected(bRightHanded); +} + +ESGDeviceType FSGHandLayerImpl::GetDeviceType(const bool bRightHanded) +{ + return FSGCoreEnumCast::ToESGDeviceType(FHandLayerType::GetDeviceType(bRightHanded)); +} + +bool FSGHandLayerImpl::GetFirstGloveHandedness() +{ + return FHandLayerType::GetFirstGloveHandedness(); +} + +int32 FSGHandLayerImpl::GlovesConnected() +{ + return FHandLayerType::GlovesConnected(); +} + +bool FSGHandLayerImpl::GetGloveInstance(const bool bRightHanded, TSharedPtr& OutGlove) +{ + FSGHapticGloveImpl::FHapticGlovePtrType Glove; + const bool bResult = FHandLayerType::GetGloveInstance(bRightHanded, Glove); + + if (bResult) + { + OutGlove = MakeShared(MoveTemp(Glove)); + } + + return bResult; +} + +ESGHapticGloveCalibrationState FSGHandLayerImpl::GetCalibrationState(const bool bRightHanded) +{ + return FSGCoreEnumCast::ToESGHapticGloveCalibrationState(FHandLayerType::GetCalibrationState(bRightHanded)); +} + +FString FSGHandLayerImpl::GetCalibrationInstructions(const bool bRightHanded) +{ + const FString Instructions{UTF8_TO_TCHAR(FHandLayerType::GetCalibrationInstructions(bRightHanded).c_str())}; + return Instructions; +} + +void FSGHandLayerImpl::ResetCalibration(const bool bRightHanded) +{ + FHandLayerType::ResetCalibration(bRightHanded); +} + +void FSGHandLayerImpl::EndCalibration(const bool bRightHanded) +{ + FHandLayerType::EndCalibration(bRightHanded); +} + +bool FSGHandLayerImpl::GetHandPose(const bool bRightHanded, FSGHandPoseImpl& OutHandPose) +{ + FSGHandPoseImpl::FHandPoseType HandPose; + + const bool bResult = FHandLayerType::GetHandPose(bRightHanded, HandPose); + OutHandPose = FSGHandPoseImpl{HandPose}; + + return bResult; +} + +void FSGHandLayerImpl::GetWristLocation( + const bool bRightHanded, const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, + FQuat& OutWristRotation) +{ + FSGVect3DImpl::FVect3DType WristPosition; + FSGQuatImpl::FQuatType WristRotation; + + FHandLayerType::GetWristLocation( + bRightHanded, + FSGVect3DImpl{ReferencePosition}.ToVect3D(), FSGQuatImpl{ReferenceRotation}.ToQuat(), + FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), + WristPosition, WristRotation); + + OutWristPosition = FSGVect3DImpl{WristPosition}.ToFVector(); + OutWristRotation = FSGQuatImpl{WristRotation}.ToFQuat(); +} + +void FSGHandLayerImpl::StopAllHaptics(const bool bRightHanded) +{ + FHandLayerType::StopAllHaptics(bRightHanded); +} + +bool FSGHandLayerImpl::SendHaptics(const bool bRightHanded) +{ + return FHandLayerType::SendHaptics(bRightHanded); +} + +bool FSGHandLayerImpl::SupportsCustomWaveform(const bool bRightHanded, const ESGHapticLocation AtLocation) +{ + return FHandLayerType::SupportsCustomWaveform(bRightHanded, FSGCoreEnumCast::ToEHapticLocation(AtLocation)); +} + +bool FSGHandLayerImpl::SendCustomWaveform( + const bool bRightHanded, FSGCustomWaveformImpl& OutWaveform, const ESGHapticLocation Location) +{ + const bool bResult = FHandLayerType::SendCustomWaveform( + bRightHanded, OutWaveform.ToCustomWaveform(), FSGCoreEnumCast::ToEHapticLocation(Location)); + return bResult; +} + +bool FSGHandLayerImpl::QueueCommand_ForceFeedbackLevels( + const bool bRightHanded, const TArray& Levels01, const bool bSendImmediate) +{ + std::vector Levels01Vector{FSGArrayUtils::ToStdVector(Levels01)}; + return FHandLayerType::QueueCommand_ForceFeedbackLevels(bRightHanded, MoveTemp(Levels01Vector), bSendImmediate); +} + +bool FSGHandLayerImpl::QueueCommand_ForceFeedbackLevel( + const bool bRightHanded, const int32 Finger, const float Level01, const bool bSendImmediate) +{ + return FHandLayerType::QueueCommand_ForceFeedbackLevel(bRightHanded, Finger, Level01, bSendImmediate); +} + +bool FSGHandLayerImpl::QueueCommand_VibroLevels( + const bool bRightHanded, const TArray& Levels01, const bool bSendImmediate) +{ + std::vector Levels01Vector{FSGArrayUtils::ToStdVector(Levels01)}; + return FHandLayerType::QueueCommand_VibroLevels(bRightHanded, MoveTemp(Levels01Vector), bSendImmediate); +} + +bool FSGHandLayerImpl::QueueCommand_VibroLevel( + const bool bRightHanded, const int32 Finger, const float Level01, const bool bSendImmediate) +{ + return FHandLayerType::QueueCommand_VibroLevel(bRightHanded, Finger, Level01, bSendImmediate); +} + +bool FSGHandLayerImpl::QueueCommand_VibroLevel( + const bool bRightHanded, const ESGHapticLocation AtLocation, const float Level01, const bool bSendImmediate) +{ + return FHandLayerType::QueueCommand_VibroLevel( + bRightHanded, FSGCoreEnumCast::ToEHapticLocation(AtLocation), Level01, bSendImmediate); +} + +bool FSGHandLayerImpl::SupportsWristSqueeze(const bool bRightHanded) +{ + return FHandLayerType::SupportsWristSqueeze(bRightHanded); +} + +bool FSGHandLayerImpl::QueueCommand_WristSqueeze( + const bool bRightHanded, const float SqueezeLevel01, const bool bSendImmediate) +{ + return FHandLayerType::QueueCommand_WristSqueeze(bRightHanded, SqueezeLevel01, bSendImmediate); +} + +bool FSGHandLayerImpl::SupportsFlexionLocks(const bool bRightHanded) +{ + return FHandLayerType::SupportsFlexionLocks(bRightHanded); +} + +bool FSGHandLayerImpl::QueueCommand_FlexionLock( + const bool bRightHanded, const int32 Finger, const float Flexion01, const bool bSendImmediate) +{ + return FHandLayerType::QueueCommand_FlexionLock(bRightHanded, Finger, Flexion01, bSendImmediate); +} + +bool FSGHandLayerImpl::QueueCommand_ClearFlexionLock( + const bool bRightHanded, const int32 Finger, const bool bSendImmediate) +{ + return FHandLayerType::QueueCommand_ClearFlexionLock(bRightHanded, Finger, bSendImmediate); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGHandPoseImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGHandPoseImpl.cpp new file mode 100644 index 0000000..f944f2b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGHandPoseImpl.cpp @@ -0,0 +1,272 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGHandPoseImpl.h" + +#include + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_HandPose.h" +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" +#include "SGCoreImpl/SGBasicHandModelImpl.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGCoreImpl/SGQuatImpl.h" +#include "SGCoreImpl/SGVect3DImpl.h" +#include "SGUtils/SGAngles.h" +#include "SGUtils/SGArrayUtils.h" + +struct FSGHandPoseImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FHandPoseType HandPose; + + /************************ + * Owner object + ************************/ + + FSGHandPoseImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGHandPoseImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +FSGHandPoseImpl FSGHandPoseImpl::Deserialize(const FString& SerializedString) +{ + std::string Serialized(TCHAR_TO_UTF8(*SerializedString)); + const FSGHandPoseImpl HandPose(FHandPoseType::Deserialize(MoveTemp(Serialized))); + return HandPose; +} + +FSGHandPoseImpl FSGHandPoseImpl::FromHandAngles(const TArray>& HandAngles, const bool bRightHanded, + const FSGBasicHandModelImpl& HandDimensions) +{ + std::vector> HandAnglesVector{ + FSGArrayUtils::ToSenseGloveAngles(HandAngles) + }; + return FSGHandPoseImpl(FHandPoseType::FromHandAngles( + MoveTemp(HandAnglesVector), bRightHanded, HandDimensions.ToBasicHandModel())); +} + +FSGHandPoseImpl FSGHandPoseImpl::FromHandAngles(const TArray>& HandAngles, const bool bRightHanded) +{ + std::vector> HandAnglesVector{ + FSGArrayUtils::ToSenseGloveAngles(HandAngles) + }; + return FSGHandPoseImpl(FHandPoseType::FromHandAngles(MoveTemp(HandAnglesVector), bRightHanded)); +} + +FSGHandPoseImpl FSGHandPoseImpl::DefaultIdle(const bool bRightHanded, const FSGBasicHandModelImpl& HandDimensions) +{ + return FSGHandPoseImpl(FHandPoseType::DefaultIdle(bRightHanded, HandDimensions.ToBasicHandModel())); +} + +FSGHandPoseImpl FSGHandPoseImpl::DefaultIdle(const bool bRightHanded) +{ + return FSGHandPoseImpl(FHandPoseType::DefaultIdle(bRightHanded)); +} + +FSGHandPoseImpl FSGHandPoseImpl::FlatHand(const bool bRightHanded, const FSGBasicHandModelImpl& HandDimensions) +{ + return FSGHandPoseImpl(FHandPoseType::FlatHand(bRightHanded, HandDimensions.ToBasicHandModel())); +} + +FSGHandPoseImpl FSGHandPoseImpl::FlatHand(const bool bRightHanded) +{ + return FSGHandPoseImpl(FHandPoseType::FlatHand(bRightHanded)); +} + +FSGHandPoseImpl FSGHandPoseImpl::ThumbsUp(const bool bRightHanded, const FSGBasicHandModelImpl& HandDimensions) +{ + return FSGHandPoseImpl(FHandPoseType::ThumbsUp(bRightHanded, HandDimensions.ToBasicHandModel())); +} + +FSGHandPoseImpl FSGHandPoseImpl::ThumbsUp(const bool bRightHanded) +{ + return FSGHandPoseImpl(FHandPoseType::ThumbsUp(bRightHanded)); +} + +FSGHandPoseImpl FSGHandPoseImpl::Fist(const bool bRightHanded, const FSGBasicHandModelImpl& HandDimensions) +{ + return FSGHandPoseImpl(FHandPoseType::Fist(bRightHanded, HandDimensions.ToBasicHandModel())); +} + +FSGHandPoseImpl FSGHandPoseImpl::Fist(const bool bRightHanded) +{ + return FSGHandPoseImpl(FHandPoseType::Fist(bRightHanded)); +} + +FSGHandPoseImpl::FSGHandPoseImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGHandPoseImpl::FSGHandPoseImpl(const bool bRightHanded, const TArray>& JointPositions, + const TArray>& JointRotations, const TArray>& HandAngles) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + std::vector> JointPositionsVector{ + FSGArrayUtils::ToMillimeters(JointPositions) + }; + + std::vector> JointRotationsVector{ + FSGArrayUtils::ToStdVector(JointRotations) + }; + + std::vector> HandAnglesVector{ + FSGArrayUtils::ToSenseGloveAngles(HandAngles) + }; + + Pimpl->HandPose = FHandPoseType( + bRightHanded, MoveTemp(JointPositionsVector), MoveTemp(JointRotationsVector), MoveTemp(HandAnglesVector)); +} + +FSGHandPoseImpl::FSGHandPoseImpl(const FHandPoseType& SenseGloveHandPose) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->HandPose = SenseGloveHandPose; +} + +FSGHandPoseImpl::FSGHandPoseImpl(const FSGHandPoseImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGHandPoseImpl::FSGHandPoseImpl(FSGHandPoseImpl&& Rhs) SG_NOEXCEPT = default; + +FSGHandPoseImpl::~FSGHandPoseImpl() = default; + +FSGHandPoseImpl& FSGHandPoseImpl::operator=(const FSGHandPoseImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGHandPoseImpl& FSGHandPoseImpl::operator=(FSGHandPoseImpl&& Rhs) SG_NOEXCEPT = default; + +const FSGHandPoseImpl::FHandPoseType& FSGHandPoseImpl::ToHandPose() const +{ + return Pimpl->HandPose; +} + +bool FSGHandPoseImpl::IsRight() const +{ + return Pimpl->HandPose.IsRight(); +} + +TArray> FSGHandPoseImpl::GetJointPositions() const +{ + const TArray> JointPositions{ + FSGArrayUtils::FromMillimeters( + Pimpl->HandPose.GetJointPositions()) + }; + return JointPositions; +} + +TArray> FSGHandPoseImpl::GetJointRotations() const +{ + const TArray> JointRotations{ + FSGArrayUtils::FromStdVector( + Pimpl->HandPose.GetJointRotations()) + }; + return JointRotations; +} + +TArray> FSGHandPoseImpl::GetHandAngles() const +{ + const TArray> HandAngles{ + FSGArrayUtils::FromSenseGloveAngles(Pimpl->HandPose.GetHandAngles()) + }; + return HandAngles; +} + +bool FSGHandPoseImpl::Equals(const FSGHandPoseImpl& HandPoseImpl) const +{ + return Pimpl->HandPose.Equals(HandPoseImpl.ToHandPose()); +} + +float FSGHandPoseImpl::GetNormalizedFlexion(ESGFinger Finger, bool bClamp01) const +{ + return Pimpl->HandPose.GetNormalizedFlexion(FSGCoreEnumCast::ToEFinger(Finger), bClamp01); +} + +TArray FSGHandPoseImpl::GetNormalizedFlexion(bool bClamp01) const +{ + const TArray NormalizedFlexion{ + FSGArrayUtils::FromStdVector(Pimpl->HandPose.GetNormalizedFlexion(bClamp01)) + }; + return NormalizedFlexion; +} + +FString FSGHandPoseImpl::ToString(bool bShortFormat) const +{ + const FString String(UTF8_TO_TCHAR(Pimpl->HandPose.ToString(bShortFormat).c_str())); + return String; +} + +FString FSGHandPoseImpl::Serialize() const +{ + const FString Serialized(UTF8_TO_TCHAR(Pimpl->HandPose.Serialize().c_str())); + return Serialized; +} + +FSGHandPoseImpl::FImpl::FImpl(FSGHandPoseImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGHandPoseImpl::FImpl::~FImpl() = default; + +void FSGHandPoseImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGHapticChannelInfoImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGHapticChannelInfoImpl.cpp new file mode 100644 index 0000000..7467070 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGHapticChannelInfoImpl.cpp @@ -0,0 +1,206 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseChannelInfo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGHapticChannelInfoImpl.h" + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_HapticChannelInfo.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGUtils/SGArrayUtils.h" + +struct FSGHapticChannelInfoImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FHapticChannelInfoType HapticChannelInfo; + + /************************ + * Owner object + ************************/ + + FSGHapticChannelInfoImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGHapticChannelInfoImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +FString FSGHapticChannelInfoImpl::GenerateAddress(const int32 DeviceIndex, const int32 ChannelIndex) +{ + const FString Address{UTF8_TO_TCHAR(FHapticChannelInfoType::GenerateAddress(DeviceIndex, ChannelIndex).c_str())}; + return Address; +} + +FSGHapticChannelInfoImpl FSGHapticChannelInfoImpl::Parse(const FString& IpcString) +{ + std::string IpcStdString{TCHAR_TO_UTF8(*IpcString)}; + FHapticChannelInfoType HapticChannelInfo{FHapticChannelInfoType::Parse(MoveTemp(IpcStdString))}; + const FSGHapticChannelInfoImpl HapticChannelInfoImpl{MoveTemp(HapticChannelInfo)}; + return HapticChannelInfoImpl; +} + +int32 FSGHapticChannelInfoImpl::GetStreamingType() +{ + return FHapticChannelInfoType::GetStreamingType(); +} + +int32 FSGHapticChannelInfoImpl::GetFireAndForgetType() +{ + return FHapticChannelInfoType::GetFireAndForgetType(); +} + +FSGHapticChannelInfoImpl::FSGHapticChannelInfoImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGHapticChannelInfoImpl::FSGHapticChannelInfoImpl( + const TArray& StreamIndex, const TArray& FireAndForgetIndex) +{ + std::vector StreamIndexVector{ + FSGArrayUtils::ToStdVector(StreamIndex) + }; + std::vector FireAndForgetIndexVector{ + FSGArrayUtils::ToStdVector(FireAndForgetIndex) + }; + + Pimpl->HapticChannelInfo = FHapticChannelInfoType{ + MoveTemp(StreamIndexVector), + MoveTemp(FireAndForgetIndexVector) + }; +} + +FSGHapticChannelInfoImpl::FSGHapticChannelInfoImpl(const FHapticChannelInfoType& HapticChannelInfo) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->HapticChannelInfo = HapticChannelInfo; +} + +FSGHapticChannelInfoImpl::FSGHapticChannelInfoImpl(const FSGHapticChannelInfoImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGHapticChannelInfoImpl::FSGHapticChannelInfoImpl(FSGHapticChannelInfoImpl&& Rhs) SG_NOEXCEPT = default; + +FSGHapticChannelInfoImpl::~FSGHapticChannelInfoImpl() = default; + +FSGHapticChannelInfoImpl& FSGHapticChannelInfoImpl::operator=(const FSGHapticChannelInfoImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGHapticChannelInfoImpl& FSGHapticChannelInfoImpl::operator=(FSGHapticChannelInfoImpl&& Rhs) SG_NOEXCEPT = default; + +const FSGHapticChannelInfoImpl::FHapticChannelInfoType& FSGHapticChannelInfoImpl::ToHapticChannelInfo() const +{ + return Pimpl->HapticChannelInfo; +} + +int32 FSGHapticChannelInfoImpl::GetStreamChannelCount() const +{ + return Pimpl->HapticChannelInfo.GetStreamChannelCount(); +} + +int32 FSGHapticChannelInfoImpl::GetFireAndForgetChannelCount() const +{ + return Pimpl->HapticChannelInfo.GetFireAndForgetChannelCount(); +} + +int32 FSGHapticChannelInfoImpl::GetTotalChannelCount() const +{ + return Pimpl->HapticChannelInfo.GetTotalChannelCount(); +} + +FString FSGHapticChannelInfoImpl::GetAddress_Unguarded(const ESGHapticChannelType Type, const int32 TypeIndex) const +{ + const FString Address{ + UTF8_TO_TCHAR( + Pimpl->HapticChannelInfo.GetAddress_Unguarded( + FSGCoreEnumCast::ToEHapticChannelType(Type), TypeIndex).c_str( + )) + }; + return Address; +} + +void FSGHapticChannelInfoImpl::GetIpcParams_Unguarded( + const ESGHapticChannelType Type, const int32 TypeIndex, int32& OutIndex, FString& OutAddressString) const +{ + std::string OutAddressStdString; + Pimpl->HapticChannelInfo.GetIpcParams_Unguarded( + FSGCoreEnumCast::ToEHapticChannelType(Type), TypeIndex, OutIndex, OutAddressStdString); + OutAddressString = FString{UTF8_TO_TCHAR(OutAddressStdString.c_str())}; +} + +void FSGHapticChannelInfoImpl::RegenerateAddresses(const int32 ForDeviceIndex) +{ + Pimpl->HapticChannelInfo.RegenerateAddresses(ForDeviceIndex); +} + +TArray FSGHapticChannelInfoImpl::GetAllAddresses() const +{ + const TArray AddressesArray{ + FSGArrayUtils::FromStdVector(Pimpl->HapticChannelInfo.GetAllAddresses()) + }; + return AddressesArray; +} + +FSGHapticChannelInfoImpl::FImpl::FImpl(FSGHapticChannelInfoImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGHapticChannelInfoImpl::FImpl::~FImpl() = default; + +void FSGHapticChannelInfoImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGHapticGloveImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGHapticGloveImpl.cpp new file mode 100644 index 0000000..c6c4532 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGHapticGloveImpl.cpp @@ -0,0 +1,377 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGHapticGloveImpl.h" + +#include +#include + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_BasicHandModel.h" +#include "SGBuildHacks/SGInclude_Core_CustomWaveform.h" +#include "SGBuildHacks/SGInclude_Core_HandPose.h" +#include "SGBuildHacks/SGInclude_Core_HapticGlove.h" +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" +#include "SGCoreImpl/SGBasicHandModelImpl.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGCoreImpl/SGCustomWaveformImpl.h" +#include "SGCoreImpl/SGHandPoseImpl.h" +#include "SGCoreImpl/SGQuatImpl.h" +#include "SGCoreImpl/SGVect3DImpl.h" +#include "SGUtils/SGArrayUtils.h" + +struct FSGHapticGloveImpl::FImpl +{ + /************************ + * Owner object + ************************/ + + FSGHapticGloveImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGHapticGloveImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +TArray> FSGHapticGloveImpl::GetHapticGloves(const bool bConnectedOnly) +{ + const FHapticGlovePtrVectorType HapticGloves{FHapticGloveType::GetHapticGloves(bConnectedOnly)}; + TArray> HapticGloveImpls; + + for (FHapticGlovePtrType HapticGlove: HapticGloves) + { + TSharedRef HapticGloveImpl{MakeShared(MoveTemp(HapticGlove))}; + HapticGloveImpls.Push(MoveTemp(HapticGloveImpl)); + } + + return HapticGloveImpls; +} + +bool FSGHapticGloveImpl::GetGlove(TSharedPtr& OutGlove) +{ + FHapticGlovePtrType Glove; + const bool bReturn = FHapticGloveType::GetGlove(Glove); + + if (bReturn) + { + OutGlove = MakeShared(MoveTemp(Glove)); + } + + return bReturn; +} + +bool FSGHapticGloveImpl::GetGlove(const bool bRightHanded, TSharedPtr& OutGlove) +{ + FHapticGlovePtrType Glove; + const bool bReturn = FHapticGloveType::GetGlove(bRightHanded, Glove); + + if (bReturn) + { + OutGlove = MakeShared(MoveTemp(Glove)); + } + + return bReturn; +} + +FString FSGHapticGloveImpl::ToString(ESGHapticGloveCalibrationState State) +{ + const FString String{ + UTF8_TO_TCHAR(FHapticGloveType::ToString(FSGCoreEnumCast::ToEHapticGloveCalibrationState(State)).c_str()) + }; + return String; +} + +FString FSGHapticGloveImpl::ToString(ESGHapticLocation Location) +{ + const FString String{ + UTF8_TO_TCHAR(FHapticGloveType::ToString(FSGCoreEnumCast::ToEHapticLocation(Location)).c_str()) + }; + return String; +} + +FSGHapticGloveImpl::FSGHapticGloveImpl() + : FSGDeviceImpl(), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGHapticGloveImpl::FSGHapticGloveImpl(const FHapticGlovePtrType HapticGlove) + : FSGDeviceImpl(std::dynamic_pointer_cast(HapticGlove)), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGHapticGloveImpl::FSGHapticGloveImpl(const FSGHapticGloveImpl& Rhs) + : FSGDeviceImpl(Rhs), + Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGHapticGloveImpl::FSGHapticGloveImpl(FSGHapticGloveImpl&& Rhs) SG_NOEXCEPT = default; + +FSGHapticGloveImpl::~FSGHapticGloveImpl() = default; + +FSGHapticGloveImpl& FSGHapticGloveImpl::operator=(const FSGHapticGloveImpl& Rhs) +{ + FSGDeviceImpl::operator=(Rhs); + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGHapticGloveImpl& FSGHapticGloveImpl::operator=(FSGHapticGloveImpl&& Rhs) SG_NOEXCEPT = default; + +FSGHapticGloveImpl::FHapticGlovePtrType FSGHapticGloveImpl::ToHapticGlovePtr() const +{ + return std::dynamic_pointer_cast(ToSGDevicePtr()); +} + +FSGHapticGloveImpl::FHapticGlovePtrType FSGHapticGloveImpl::ToHapticGlovePtrChecked() const +{ + FHapticGlovePtrType HapticGlove = std::dynamic_pointer_cast(ToSGDevicePtr()); + ensureAlwaysMsgf(HapticGlove.get(), TEXT("Invalid HapticGlove")); + return HapticGlove; +} + +ESGDeviceType FSGHapticGloveImpl::GetDeviceType() const +{ + return FSGCoreEnumCast::ToESGDeviceType(ToHapticGlovePtrChecked()->GetDeviceType()); +} + +FString FSGHapticGloveImpl::GetDeviceId() const +{ + const FString Id{UTF8_TO_TCHAR(ToHapticGlovePtrChecked()->GetDeviceId().c_str())}; + return Id; +} + +FString FSGHapticGloveImpl::GetHardwareVersion() const +{ + const FString Version{UTF8_TO_TCHAR(ToHapticGlovePtrChecked()->GetHardwareVersion().c_str())}; + return Version; +} + +int32 FSGHapticGloveImpl::GetFirmwareVersion() const +{ + return ToHapticGlovePtrChecked()->GetFirmwareVersion(); +} + +int32 FSGHapticGloveImpl::GetSubFirmwareVersion() const +{ + return ToHapticGlovePtrChecked()->GetSubFirmwareVersion(); +} + +bool FSGHapticGloveImpl::IsRight() const +{ + return ToHapticGlovePtrChecked()->IsRight(); +} + +bool FSGHapticGloveImpl::GetImuRotation(FQuat& OutImu) +{ + FSGQuatImpl::FQuatType Imu; + const bool bResult = ToHapticGlovePtrChecked()->GetImuRotation(Imu); + OutImu = FSGQuatImpl{MoveTemp(Imu)}.ToFQuat(); + return bResult; +} + +bool FSGHapticGloveImpl::GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose) const +{ + FSGHandPoseImpl::FHandPoseType HandPose; + const bool bResult = ToHapticGlovePtrChecked()->GetHandPose(HandGeometry.ToBasicHandModel(), HandPose); + OutHandPose = FSGHandPoseImpl{MoveTemp(HandPose)}; + return bResult; +} + +bool FSGHapticGloveImpl::GetHandPose(FSGHandPoseImpl& OutHandPose) +{ + FSGHandPoseImpl::FHandPoseType HandPose; + const bool bResult = ToHapticGlovePtrChecked()->GetHandPose(HandPose); + OutHandPose = FSGHandPoseImpl{MoveTemp(HandPose)}; + return bResult; +} + +bool FSGHapticGloveImpl::GetHandAngles(TArray>& OutHandAngles) const +{ + std::vector> HandAngles; + const bool bResult = ToHapticGlovePtrChecked()->GetHandAngles(HandAngles); + OutHandAngles = FSGArrayUtils::FromSenseGloveAngles(HandAngles); + return bResult; +} + +FSGBasicHandModelImpl FSGHapticGloveImpl::GetHandGeometry() const +{ + FSGBasicHandModelImpl::FBasicHandModelType Geometry{ToHapticGlovePtrChecked()->GetHandGeometry()}; + return FSGBasicHandModelImpl{MoveTemp(Geometry)}; +} + +void FSGHapticGloveImpl::SetHandGeometry(const FSGBasicHandModelImpl& HandGeometry) +{ + ToHapticGlovePtrChecked()->SetHandGeometry(HandGeometry.ToBasicHandModel()); +} + +ESGHapticGloveCalibrationState FSGHapticGloveImpl::GetCalibrationState() const +{ + return FSGCoreEnumCast::ToESGHapticGloveCalibrationState(ToHapticGlovePtrChecked()->GetCalibrationState()); +} + +void FSGHapticGloveImpl::EndCalibration() +{ + ToHapticGlovePtrChecked()->EndCalibration(); +} + +void FSGHapticGloveImpl::ResetCalibration() +{ + ToHapticGlovePtrChecked()->ResetCalibration(); +} + +FString FSGHapticGloveImpl::GetCalibrationInstruction() const +{ + const FString Instruction{UTF8_TO_TCHAR(ToHapticGlovePtrChecked()->GetCalibrationInstruction().c_str())}; + return Instruction; +} + +void FSGHapticGloveImpl::StopHaptics() +{ + ToHapticGlovePtrChecked()->StopHaptics(); +} + +void FSGHapticGloveImpl::StopVibrations() +{ + ToHapticGlovePtrChecked()->StopVibrations(); +} + +bool FSGHapticGloveImpl::SendHaptics() +{ + return ToHapticGlovePtrChecked()->SendHaptics(); +} + +bool FSGHapticGloveImpl::SupportsCustomWaveform(const ESGHapticLocation AtLocation) const +{ + return ToHapticGlovePtrChecked()->SupportsCustomWaveform(FSGCoreEnumCast::ToEHapticLocation(AtLocation)); +} + +bool FSGHapticGloveImpl::SendCustomWaveform(FSGCustomWaveformImpl& OutWaveform, const ESGHapticLocation Location) +{ + return ToHapticGlovePtrChecked()->SendCustomWaveform( + OutWaveform.ToCustomWaveform(), FSGCoreEnumCast::ToEHapticLocation(Location)); +} + +bool FSGHapticGloveImpl::QueueForceFeedbackLevels(const TArray& Levels01) +{ + std::vector Levels01Vector{FSGArrayUtils::ToStdVector(Levels01)}; + return ToHapticGlovePtrChecked()->QueueForceFeedbackLevels(MoveTemp(Levels01Vector)); +} + +bool FSGHapticGloveImpl::QueueForceFeedbackLevel(const int32 Finger, const float Level01) +{ + return ToHapticGlovePtrChecked()->QueueForceFeedbackLevel(Finger, Level01); +} + +bool FSGHapticGloveImpl::QueueVibroLevels(const TArray& Levels01) +{ + std::vector Levels01Vector{FSGArrayUtils::ToStdVector(Levels01)}; + return ToHapticGlovePtrChecked()->QueueVibroLevels(MoveTemp(Levels01Vector)); +} + +bool FSGHapticGloveImpl::QueueVibroLevel(const ESGHapticLocation Location, const float Level01) +{ + return ToHapticGlovePtrChecked()->QueueVibroLevel(FSGCoreEnumCast::ToEHapticLocation(Location), Level01); +} + +void FSGHapticGloveImpl::GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) const +{ + FSGVect3DImpl::FVect3DType WristPosition; + FSGQuatImpl::FQuatType WristRotation; + + ToHapticGlovePtrChecked()->GetWristLocation( + FSGUnits::CentimetersToMillimeters(ReferencePosition), + FSGQuatImpl(ReferenceRotation).ToQuat(), + FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), + WristPosition, WristRotation); + + OutWristPosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(WristPosition)); + OutWristRotation = FSGQuatImpl(MoveTemp(WristRotation)).ToFQuat(); +} + +void FSGHapticGloveImpl::GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const +{ + FSGVect3DImpl::FVect3DType GlovePosition; + FSGQuatImpl::FQuatType GloveRotation; + + ToHapticGlovePtrChecked()->GetGloveLocation( + FSGUnits::CentimetersToMillimeters(ReferencePosition), + FSGQuatImpl(ReferenceRotation).ToQuat(), + FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), + GlovePosition, GloveRotation); + + OutGlovePosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(GlovePosition)); + OutGloveRotation = FSGQuatImpl(MoveTemp(GloveRotation)).ToFQuat(); +} + +FString FSGHapticGloveImpl::ToString() const +{ + const FString String{UTF8_TO_TCHAR(ToHapticGlovePtrChecked()->ToString().c_str())}; + return String; +} + +FSGHapticGloveImpl::FImpl::FImpl(FSGHapticGloveImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGHapticGloveImpl::FImpl::~FImpl() = default; + +void FSGHapticGloveImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGInterpolationSetImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGInterpolationSetImpl.cpp new file mode 100644 index 0000000..9953710 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGInterpolationSetImpl.cpp @@ -0,0 +1,228 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGInterpolationSetImpl.h" + +#include + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_InterpolationSet.h" +#include "SGUtils/SGArrayUtils.h" + +struct FSGInterpolationSetImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FInterpolationSetType InterpolationSet; + + /************************ + * Owner object + ************************/ + + FSGInterpolationSetImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGInterpolationSetImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +FSGInterpolationSetImpl FSGInterpolationSetImpl::Deserialize(const FString& SerializedString) +{ + std::string Serialized(TCHAR_TO_UTF8(*SerializedString)); + const FSGInterpolationSetImpl InterpolationSet(FInterpolationSetType::Deserialize(MoveTemp(Serialized))); + return InterpolationSet; +} + +FSGInterpolationSetImpl::FSGInterpolationSetImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGInterpolationSetImpl::FSGInterpolationSetImpl(const float From1, const float From2, const float To1, const float To2) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->InterpolationSet = FInterpolationSetType(From1, From2, To1, To2); +} + +FSGInterpolationSetImpl::FSGInterpolationSetImpl(const float From1, const float From2, const float To1, const float To2, + const float Min, const float Max) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->InterpolationSet = FInterpolationSetType(From1, From2, To1, To2, Min, Max); +} + +FSGInterpolationSetImpl::FSGInterpolationSetImpl(const FInterpolationSetType& InterpolationSet) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->InterpolationSet = InterpolationSet; +} + +FSGInterpolationSetImpl::FSGInterpolationSetImpl(const FSGInterpolationSetImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGInterpolationSetImpl::FSGInterpolationSetImpl(FSGInterpolationSetImpl&& Rhs) SG_NOEXCEPT = default; + +FSGInterpolationSetImpl::~FSGInterpolationSetImpl() = default; + +FSGInterpolationSetImpl& FSGInterpolationSetImpl::operator=(const FSGInterpolationSetImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGInterpolationSetImpl& FSGInterpolationSetImpl::operator=(FSGInterpolationSetImpl&& Rhs) SG_NOEXCEPT = default; + +const FSGInterpolationSetImpl::FInterpolationSetType& FSGInterpolationSetImpl::ToInterpolationSet() const +{ + return Pimpl->InterpolationSet; +} + +float FSGInterpolationSetImpl::GetX0() const +{ + return Pimpl->InterpolationSet.GetX0(); +} + +void FSGInterpolationSetImpl::SetX0(const float X0) +{ + Pimpl->InterpolationSet.SetX0(X0); +} + +float FSGInterpolationSetImpl::GetX1() const +{ + return Pimpl->InterpolationSet.GetX1(); +} + +void FSGInterpolationSetImpl::SetX1(const float X1) +{ + Pimpl->InterpolationSet.SetX1(X1); +} + +float FSGInterpolationSetImpl::GetY0() const +{ + return Pimpl->InterpolationSet.GetY0(); +} + +void FSGInterpolationSetImpl::SetY0(const float Y0) +{ + Pimpl->InterpolationSet.SetY0(Y0); +} + +float FSGInterpolationSetImpl::GetY1() const +{ + return Pimpl->InterpolationSet.GetY1(); +} + +void FSGInterpolationSetImpl::SetY1(const float Y1) +{ + Pimpl->InterpolationSet.SetY1(Y1); +} + +float FSGInterpolationSetImpl::GetMin() const +{ + return Pimpl->InterpolationSet.GetMin(); +} + +void FSGInterpolationSetImpl::SetMin(const float Min) +{ + Pimpl->InterpolationSet.SetMin(Min); +} + +float FSGInterpolationSetImpl::GetMax() const +{ + return Pimpl->InterpolationSet.GetMax(); +} + +void FSGInterpolationSetImpl::SetMax(const float Max) +{ + Pimpl->InterpolationSet.SetMax(Max); +} + +float FSGInterpolationSetImpl::Get(const float Value, const bool bLimit, const bool bNormalizeAngle) const +{ + return Pimpl->InterpolationSet.Get(Value, bLimit, bNormalizeAngle); +} + +bool FSGInterpolationSetImpl::Equals(const FSGInterpolationSetImpl& InterpolationSetImpl) const +{ + return Pimpl->InterpolationSet.Equals(InterpolationSetImpl.ToInterpolationSet()); +} + +FString FSGInterpolationSetImpl::ToString() const +{ + const FString String(UTF8_TO_TCHAR(Pimpl->InterpolationSet.ToString().c_str())); + return String; +} + +FString FSGInterpolationSetImpl::ToString(const bool bLimits) const +{ + const FString String(UTF8_TO_TCHAR(Pimpl->InterpolationSet.ToString(bLimits).c_str())); + return String; +} + +FString FSGInterpolationSetImpl::Serialize() const +{ + const FString Serialized(UTF8_TO_TCHAR(Pimpl->InterpolationSet.Serialize().c_str())); + return Serialized; +} + +FSGInterpolationSetImpl::FImpl::FImpl(FSGInterpolationSetImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGInterpolationSetImpl::FImpl::~FImpl() = default; + +void FSGInterpolationSetImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGJointKinematicsImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGJointKinematicsImpl.cpp new file mode 100644 index 0000000..02bd85f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGJointKinematicsImpl.cpp @@ -0,0 +1,98 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGJointKinematicsImpl.h" + +#include "SGBuildHacks/SGInclude_Core_JointKinematics.h" +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" +#include "SGCoreImpl/SGBasicHandModelImpl.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGCoreImpl/SGQuatImpl.h" +#include "SGCoreImpl/SGVect3DImpl.h" +#include "SGUtils/SGArrayUtils.h" + +bool FSGJointKinematicsImpl::ForwardKinematics(const FVector& StartPosition, const FQuat& StartRotation, + const TArray& JointLengths, const TArray& JointAngles, + TArray& OutNewPositions, TArray& OutNewRotations) +{ + FSGVect3DImpl::FVect3DType StartPositionVect3D( + FSGUnits::CentimetersToMillimeters(StartPosition)); + FSGQuatImpl::FQuatType StartRotationQuat(FSGQuatImpl(StartRotation).ToQuat()); + + std::vector JointLengthsVector{ + FSGArrayUtils::ToMillimeters(JointLengths) + }; + + std::vector JointAnglesVector{ + FSGArrayUtils::ToSenseGloveAngles(JointAngles) + }; + + std::vector NewPositions; + std::vector NewRotations; + + const bool bResults = FSGJointKinematicsImpl::FJointKinematicsType::ForwardKinematics( + MoveTemp(StartPositionVect3D), MoveTemp(StartRotationQuat), + MoveTemp(JointLengthsVector), MoveTemp(JointAnglesVector), + NewPositions, NewRotations); + + OutNewPositions = FSGArrayUtils::FromMillimeters(NewPositions);; + OutNewRotations = FSGArrayUtils::FromStdVector(NewRotations);; + + return bResults; +} + +bool FSGJointKinematicsImpl::ForwardKinematics(const FSGBasicHandModelImpl& Profile, const ESGFinger Finger, + const TArray& JointAngles, + TArray& OutNewPositions, TArray& OutNewRotations) +{ + std::vector JointAnglesVector{ + FSGArrayUtils::ToSenseGloveAngles(JointAngles) + }; + + std::vector NewPositions; + std::vector NewRotations; + + const bool bResults = FSGJointKinematicsImpl::FJointKinematicsType::ForwardKinematics( + Profile.ToBasicHandModel(), FSGCoreEnumCast::ToEFinger(Finger), MoveTemp(JointAnglesVector), + NewPositions, NewRotations); + + OutNewPositions = FSGArrayUtils::FromMillimeters(NewPositions);; + OutNewRotations = FSGArrayUtils::FromStdVector(NewRotations);; + + return bResults; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGLibraryImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGLibraryImpl.cpp new file mode 100644 index 0000000..3b2a7df --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGLibraryImpl.cpp @@ -0,0 +1,64 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGLibraryImpl.h" + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_Library.h" +#include "SGCoreImpl/SGCoreEnumCast.h" + +FString FSGLibraryImpl::Version() +{ + const FString Version(UTF8_TO_TCHAR(FLibraryType::Version().c_str())); + return Version; +} + +ESGBackendType FSGLibraryImpl::GetBackendType() +{ + return FSGCoreEnumCast::ToESGBackendType(FLibraryType::GetBackendType()); +} + +FString FSGLibraryImpl::BackendVersion() +{ + const FString Version(UTF8_TO_TCHAR(FLibraryType::BackendVersion().c_str())); + return Version; +} + +FString FSGLibraryImpl::SGConnectVersion() +{ + const FString Version(UTF8_TO_TCHAR(FLibraryType::SGConnectVersion().c_str())); + return Version; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGNova2GloveImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGNova2GloveImpl.cpp new file mode 100644 index 0000000..d991c5b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGNova2GloveImpl.cpp @@ -0,0 +1,550 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGNova2GloveImpl.h" + +#include +#include + +#include "Containers/StringConv.h" +#include "Misc/AssertionMacros.h" + +#include "SGBuildHacks/SGInclude_Core_BasicHandModel.h" +#include "SGBuildHacks/SGInclude_Core_CustomWaveform.h" +#include "SGBuildHacks/SGInclude_Core_HandInterpolator.h" +#include "SGBuildHacks/SGInclude_Core_HandPose.h" +#include "SGBuildHacks/SGInclude_Core_HapticGlove.h" +#include "SGBuildHacks/SGInclude_Core_Nova2Glove.h" +#include "SGBuildHacks/SGInclude_Core_Nova2GloveSensorData.h" +#include "SGBuildHacks/SGInclude_Core_NovaGloveInfo.h" +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_SensorNormalization.h" +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" +#include "SGCoreImpl/SGBasicHandModelImpl.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGCoreImpl/SGCustomWaveformImpl.h" +#include "SGCoreImpl/SGHandInterpolatorImpl.h" +#include "SGCoreImpl/SGHandPoseImpl.h" +#include "SGCoreImpl/SGNova2GloveSensorDataImpl.h" +#include "SGCoreImpl/SGNovaGloveInfoImpl.h" +#include "SGCoreImpl/SGQuatImpl.h" +#include "SGCoreImpl/SGSensorNormalizationImpl.h" +#include "SGCoreImpl/SGVect3DImpl.h" +#include "SGUtils/SGArrayUtils.h" + +struct FSGNova2GloveImpl::FImpl +{ + /************************ + * Owner object + ************************/ + + FSGNova2GloveImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGNova2GloveImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +TSharedRef FSGNova2GloveImpl::Parse(const FString& ConstantsString) +{ + std::string ConstantsStdString{TCHAR_TO_UTF8(*ConstantsString)}; + FSGDevicePtrType SGDevicePtr{FNova2GloveType::Parse(MoveTemp(ConstantsStdString))}; + ensureAlwaysMsgf(SGDevicePtr, TEXT("Invalid SGDevice!")); + const TSharedRef Nova2GloveImpl{ + MakeShared(std::dynamic_pointer_cast(MoveTemp(SGDevicePtr))) + }; + return Nova2GloveImpl; +} + +TArray FSGNova2GloveImpl::GetNova2Gloves() +{ + FNova2GloveVectorType Vector{FNova2GloveType::GetNova2Gloves()}; + + const TArray Array{ + FSGArrayUtils::FromStdVector(MoveTemp(Vector)) + }; + + return Array; +} + + +bool FSGNova2GloveImpl::GetNova2Glove(FSGNova2GloveImpl& OutGlove) +{ + FNova2GloveType Glove; + const bool bResult = FNova2GloveType::GetNova2Glove(Glove); + OutGlove = FSGNova2GloveImpl{MoveTemp(Glove)}; + return bResult; +} + +bool FSGNova2GloveImpl::GetNova2Glove(const bool bRightHanded, FSGNova2GloveImpl& OutGlove) +{ + FNova2GloveType Glove; + const bool bResult = FNova2GloveType::GetNova2Glove(bRightHanded, Glove); + OutGlove = FSGNova2GloveImpl{MoveTemp(Glove)}; + return bResult; +} + +void FSGNova2GloveImpl::CalculateGloveLocation( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, const FString& HardwareVersion, + FVector& OutGlovePosition, FQuat& OutGloveRotation) +{ + FSGVect3DImpl::FVect3DType GlovePosition; + FSGQuatImpl::FQuatType GloveRotation; + + FNova2GloveType::CalculateGloveLocation( + FSGUnits::CentimetersToMillimeters(ReferencePosition), + FSGQuatImpl{ReferenceRotation}.ToQuat(), + FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), bRightHanded, TCHAR_TO_UTF8(*HardwareVersion), + GlovePosition, GloveRotation); + + OutGlovePosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(GlovePosition));; + OutGloveRotation = FSGQuatImpl{MoveTemp(GloveRotation)}.ToFQuat(); +} + +void FSGNova2GloveImpl::CalculateWristLocation( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, const FString& HardwareVersion, + FVector& OutWristPosition, FQuat& OutWristRotation) +{ + FSGVect3DImpl::FVect3DType WristPosition; + FSGQuatImpl::FQuatType WristRotation; + + FNova2GloveType::CalculateWristLocation( + FSGUnits::CentimetersToMillimeters(ReferencePosition), + FSGQuatImpl{ReferenceRotation}.ToQuat(), + FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), bRightHanded, TCHAR_TO_UTF8(*HardwareVersion), + WristPosition, WristRotation); + + OutWristPosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(WristPosition)); + OutWristRotation = FSGQuatImpl{MoveTemp(WristRotation)}.ToFQuat(); +} + +ANSICHAR FSGNova2GloveImpl::GetStreamByte() +{ + static const ANSICHAR Byte = FNova2GloveType::GetStreamByte(); + return Byte; +} + +const TArray& FSGNova2GloveImpl::GetNova2SensorRanges() +{ + static const TArray Ranges{FSGArrayUtils::FromStdVector(FNova2GloveType::GetNova2SensorRanges())}; + return Ranges; +} + +TArray FSGNova2GloveImpl::ToNormalizedValues(const FSGNova2GloveSensorDataImpl& SensorData) +{ + const TArray NormalizedValues{ + FSGArrayUtils::FromStdVector( + FNova2GloveType::ToNormalizedValues(SensorData.ToNova2GloveSensorData())) + }; + return NormalizedValues; +} + +TArray> FSGNova2GloveImpl::CalculateHandAngles( + const TArray& NormalizedValues, const FSGHandInterpolatorImpl& Interpolator, const bool bInfluenceIndex) +{ + std::vector NormalizedValuesVector{FSGArrayUtils::ToStdVector(NormalizedValues)}; + + const TArray> Angles{ + FSGArrayUtils::FromSenseGloveAngles( + FNova2GloveType::CalculateHandAngles( + MoveTemp(NormalizedValuesVector), Interpolator.ToHandInterpolator(), bInfluenceIndex)) + }; + + return Angles; +} + +TArray> FSGNova2GloveImpl::ToNormalizedAngles( + const TArray& NormalizedData, const FSGNovaGloveInfoImpl& GloveInfo) +{ + std::vector NormalizedDataVector{FSGArrayUtils::ToStdVector(NormalizedData)}; + + const TArray> Angles{ + FSGArrayUtils::FromSenseGloveAngles( + FNova2GloveType::ToNormalizedAngles(MoveTemp(NormalizedDataVector), GloveInfo.ToNovaGloveInfo())) + }; + + return Angles; +} + +TArray FSGNova2GloveImpl::ToNormalizedValues(const FSGNova2GloveSensorDataImpl& SensorData, + FSGSensorNormalizationImpl& OutSensorNormalizer) +{ + const TArray NormalizedValues{ + FSGArrayUtils::FromStdVector( + FNova2GloveType::ToNormalizedValues(SensorData.ToNova2GloveSensorData(), + OutSensorNormalizer.ToSensorNormalization())) + }; + return NormalizedValues; +} + +FSGNova2GloveImpl::FSGNova2GloveImpl() + : FSGHapticGloveImpl(), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGNova2GloveImpl::FSGNova2GloveImpl(const FSGNovaGloveInfoImpl& DeviceInfo) + : FSGHapticGloveImpl(FSGNova2GloveImpl(std::make_shared((DeviceInfo.ToNovaGloveInfo())))), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGNova2GloveImpl::FSGNova2GloveImpl(const FNova2GloveType Nova2Glove) + : FSGHapticGloveImpl(std::make_shared(Nova2Glove)), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGNova2GloveImpl::FSGNova2GloveImpl(const FNova2GlovePtrType Nova2Glove) + : FSGHapticGloveImpl(Nova2Glove), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGNova2GloveImpl::FSGNova2GloveImpl(const FSGNova2GloveImpl& Rhs) + : FSGHapticGloveImpl(Rhs), + Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGNova2GloveImpl::FSGNova2GloveImpl(FSGNova2GloveImpl&& Rhs) SG_NOEXCEPT = default; + +FSGNova2GloveImpl::~FSGNova2GloveImpl() = default; + +FSGNova2GloveImpl& FSGNova2GloveImpl::operator=(const FSGNova2GloveImpl& Rhs) +{ + FSGHapticGloveImpl::operator=(Rhs); + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGNova2GloveImpl& FSGNova2GloveImpl::operator=(FSGNova2GloveImpl&& Rhs) SG_NOEXCEPT = default; + +const FSGNova2GloveImpl::FNova2GloveType& FSGNova2GloveImpl::ToNova2Glove() const +{ + return *ToNova2GlovePtrChecked(); +} + +FSGNova2GloveImpl::FNova2GlovePtrType FSGNova2GloveImpl::ToNova2GlovePtr() const +{ + return std::dynamic_pointer_cast(ToSGDevicePtr()); +} + +FSGNova2GloveImpl::FNova2GlovePtrType FSGNova2GloveImpl::ToNova2GlovePtrChecked() const +{ + FNova2GlovePtrType Nova2Glove = std::dynamic_pointer_cast(ToSGDevicePtr()); + ensureAlwaysMsgf(Nova2Glove.get(), TEXT("Invalid Nova2Glove")); + return Nova2Glove; +} + +ESGDeviceType FSGNova2GloveImpl::GetDeviceType() const +{ + return FSGCoreEnumCast::ToESGDeviceType(ToNova2GlovePtrChecked()->GetDeviceType()); +} + +FString FSGNova2GloveImpl::GetDeviceId() const +{ + const FString Id{UTF8_TO_TCHAR(ToNova2GlovePtrChecked()->GetDeviceId().c_str())}; + return Id; +} + +FString FSGNova2GloveImpl::GetHardwareVersion() const +{ + const FString Version{UTF8_TO_TCHAR(ToNova2GlovePtrChecked()->GetHardwareVersion().c_str())}; + return Version; +} + +int32 FSGNova2GloveImpl::GetFirmwareVersion() const +{ + return ToNova2GlovePtrChecked()->GetFirmwareVersion(); +} + +int32 FSGNova2GloveImpl::GetSubFirmwareVersion() const +{ + return ToNova2GlovePtrChecked()->GetSubFirmwareVersion(); +} + +bool FSGNova2GloveImpl::HasBattery() const +{ + return ToNova2GlovePtrChecked()->HasBattery(); +} + +bool FSGNova2GloveImpl::IsCharging() +{ + return ToNova2GlovePtrChecked()->IsCharging(); +} + +bool FSGNova2GloveImpl::GetBatteryLevel(float& OutBatteryLevel) +{ + return ToNova2GlovePtrChecked()->GetBatteryLevel(OutBatteryLevel); +} + +bool FSGNova2GloveImpl::IsRight() const +{ + return ToNova2GlovePtrChecked()->IsRight(); +} + +bool FSGNova2GloveImpl::GetImuRotation(FQuat& OutImu) +{ + FSGQuatImpl::FQuatType Imu; + const bool bResult = ToNova2GlovePtrChecked()->GetImuRotation(Imu); + OutImu = FSGQuatImpl{MoveTemp(Imu)}.ToFQuat(); + return bResult; +} + +bool FSGNova2GloveImpl::GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose) const +{ + FSGHandPoseImpl::FHandPoseType HandPose; + const bool bResult = ToNova2GlovePtrChecked()->GetHandPose(HandGeometry.ToBasicHandModel(), HandPose); + OutHandPose = FSGHandPoseImpl{MoveTemp(HandPose)}; + return bResult; +} + +bool FSGNova2GloveImpl::GetHandAngles(TArray>& OutHandAngles) const +{ + std::vector> HandAngles; + const bool bResult = ToNova2GlovePtrChecked()->GetHandAngles(HandAngles); + OutHandAngles = FSGArrayUtils::FromSenseGloveAngles(MoveTemp(HandAngles)); + return bResult; +} + +ESGHapticGloveCalibrationState FSGNova2GloveImpl::GetCalibrationState() const +{ + return FSGCoreEnumCast::ToESGHapticGloveCalibrationState(ToNova2GlovePtrChecked()->GetCalibrationState()); +} + +void FSGNova2GloveImpl::EndCalibration() +{ + ToNova2GlovePtrChecked()->EndCalibration(); +} + +void FSGNova2GloveImpl::ResetCalibration() +{ + ToNova2GlovePtrChecked()->ResetCalibration(); +} + +void FSGNova2GloveImpl::StopHaptics() +{ + ToNova2GlovePtrChecked()->StopHaptics(); +} + +void FSGNova2GloveImpl::StopVibrations() +{ + ToNova2GlovePtrChecked()->StopVibrations(); +} + +bool FSGNova2GloveImpl::SendHaptics() +{ + return ToNova2GlovePtrChecked()->SendHaptics(); +} + +bool FSGNova2GloveImpl::SupportsCustomWaveform(const ESGHapticLocation AtLocation) const +{ + return ToNova2GlovePtrChecked()->SupportsCustomWaveform(FSGCoreEnumCast::ToEHapticLocation(AtLocation)); +} + +bool FSGNova2GloveImpl::SendCustomWaveform(FSGCustomWaveformImpl& OutWaveform, const ESGHapticLocation Location) +{ + return ToNova2GlovePtrChecked()->SendCustomWaveform(OutWaveform.ToCustomWaveform(), + FSGCoreEnumCast::ToEHapticLocation(Location)); +} + +bool FSGNova2GloveImpl::QueueForceFeedbackLevels(const TArray& Levels01) +{ + std::vector Levels01Vector{FSGArrayUtils::ToStdVector(Levels01)}; + return ToNova2GlovePtrChecked()->QueueForceFeedbackLevels(MoveTemp(Levels01Vector)); +} + +bool FSGNova2GloveImpl::QueueForceFeedbackLevel(const int32 Finger, const float Level01) +{ + return ToNova2GlovePtrChecked()->QueueForceFeedbackLevel(Finger, Level01); +} + +bool FSGNova2GloveImpl::QueueVibroLevels(const TArray& Amplitudes) +{ + std::vector AmplitudesVector{FSGArrayUtils::ToStdVector(Amplitudes)}; + return ToNova2GlovePtrChecked()->QueueVibroLevels(MoveTemp(AmplitudesVector)); +} + +bool FSGNova2GloveImpl::QueueVibroLevel(const ESGHapticLocation Location, const float Level01) +{ + return ToNova2GlovePtrChecked()->QueueVibroLevel(FSGCoreEnumCast::ToEHapticLocation(Location), Level01); +} + +bool FSGNova2GloveImpl::QueueSqueezeLevel(const float SqueezeLevel01) +{ + return ToNova2GlovePtrChecked()->QueueSqueezeLevel(SqueezeLevel01); +} + +void FSGNova2GloveImpl::GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const +{ + FSGVect3DImpl::FVect3DType GlovePosition; + FSGQuatImpl::FQuatType GloveRotation; + + ToNova2GlovePtrChecked()->GetGloveLocation( + FSGUnits::CentimetersToMillimeters(ReferencePosition), + FSGQuatImpl{ReferenceRotation}.ToQuat(), + FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), + GlovePosition, GloveRotation); + + OutGlovePosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(GlovePosition)); + OutGloveRotation = FSGQuatImpl{MoveTemp(GloveRotation)}.ToFQuat(); +} + +void FSGNova2GloveImpl::GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) const +{ + FSGVect3DImpl::FVect3DType WristPosition; + FSGQuatImpl::FQuatType WristRotation; + + ToNova2GlovePtrChecked()->GetWristLocation( + FSGUnits::CentimetersToMillimeters(ReferencePosition), + FSGQuatImpl{ReferenceRotation}.ToQuat(), + FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), + WristPosition, WristRotation); + + OutWristPosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(WristPosition)); + OutWristRotation = FSGQuatImpl{MoveTemp(WristRotation)}.ToFQuat(); +} + +FSGNovaGloveInfoImpl FSGNova2GloveImpl::GetGloveInfo() const +{ + const FSGNovaGloveInfoImpl GloveInfo{ToNova2GlovePtrChecked()->GetGloveInfo()}; + return GloveInfo; +} + +bool FSGNova2GloveImpl::DoesIndexInfluenceOthers() const +{ + return ToNova2GlovePtrChecked()->DoesIndexInfluenceOthers(); +} + +void FSGNova2GloveImpl::SetIndexInfluencesOthers(const bool bInfluenceOthers) +{ + ToNova2GlovePtrChecked()->SetIndexInfluencesOthers(bInfluenceOthers); +} + +bool FSGNova2GloveImpl::SupportsOnBoardNormalization() const +{ + return ToNova2GlovePtrChecked()->SupportsOnBoardNormalization(); +} + +bool FSGNova2GloveImpl::GetSensorData(FSGNova2GloveSensorDataImpl& OutSensorData) const +{ + FSGNova2GloveSensorDataImpl::FNova2GloveSensorDataType SensorData; + const bool bResult = ToNova2GlovePtrChecked()->GetSensorData(SensorData); + OutSensorData = FSGNova2GloveSensorDataImpl{MoveTemp(SensorData)}; + return bResult; +} + +bool FSGNova2GloveImpl::GetNormalizedInput(TArray& OutNormalizedValues) const +{ + std::vector NormalizedValues; + const bool bResult = ToNova2GlovePtrChecked()->GetNormalizedInput(NormalizedValues); + OutNormalizedValues = FSGArrayUtils::FromStdVector(MoveTemp(NormalizedValues)); + return bResult; +} + +bool FSGNova2GloveImpl::SendRawData() +{ + return ToNova2GlovePtrChecked()->SendRawData(); +} + +bool FSGNova2GloveImpl::SendNormalizedData() +{ + return ToNova2GlovePtrChecked()->SendNormalizedData(); +} + +ESGNova2VibroMotor FSGNova2GloveImpl::ToNovaMotor(const ESGHapticLocation Location) const +{ + return FSGCoreEnumCast::ToESGNova2VibroMotor( + ToNova2GlovePtrChecked()->ToNova2Motor(FSGCoreEnumCast::ToEHapticLocation(Location))); +} + +int32 FSGNova2GloveImpl::ChannelIndex(const ESGNova2VibroMotor Motor) const +{ + return ToNova2GlovePtrChecked()->ChannelIndex(FSGCoreEnumCast::ToENova2VibroMotor(Motor)); +} + +void FSGNova2GloveImpl::ValidateWaveform(FSGCustomWaveformImpl& OutWaveform, const ESGNova2VibroMotor Motor) const +{ + return ToNova2GlovePtrChecked()->ValidateWaveform(OutWaveform.ToCustomWaveform(), + FSGCoreEnumCast::ToENova2VibroMotor(Motor)); +} + +bool FSGNova2GloveImpl::SendCustomWaveform_Nova2(FSGCustomWaveformImpl& OutWaveform, + const ESGNova2VibroMotor Motor, const bool bValidateWaveform) +{ + return ToNova2GlovePtrChecked()->SendCustomWaveform_Nova2( + OutWaveform.ToCustomWaveform(), FSGCoreEnumCast::ToENova2VibroMotor(Motor), bValidateWaveform); +} + +FString FSGNova2GloveImpl::ToString() const +{ + const FString String{UTF8_TO_TCHAR(ToNova2GlovePtrChecked()->ToString().c_str())}; + return String; +} + +FSGNova2GloveImpl::FImpl::FImpl(FSGNova2GloveImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGNova2GloveImpl::FImpl::~FImpl() = default; + +void FSGNova2GloveImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGNova2GloveSensorDataImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGNova2GloveSensorDataImpl.cpp new file mode 100644 index 0000000..172b7c2 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGNova2GloveSensorDataImpl.cpp @@ -0,0 +1,210 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGNova2GloveSensorDataImpl.h" + +#include +#include + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_Nova2GloveSensorData.h" +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGCoreImpl/SGNovaGloveInfoImpl.h" +#include "SGCoreImpl/SGQuatImpl.h" +#include "SGCoreImpl/SGVect3DImpl.h" +#include "SGUtils/SGArrayUtils.h" + +struct FSGNova2GloveSensorDataImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FNova2GloveSensorDataType Nova2GloveSensorData; + + /************************ + * Owner object + ************************/ + + FSGNova2GloveSensorDataImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGNova2GloveSensorDataImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +FSGNova2GloveSensorDataImpl FSGNova2GloveSensorDataImpl::Parse(const FString& RawData, + const FSGNovaGloveInfoImpl& GloveInfo) +{ + std::string RawDataString(TCHAR_TO_UTF8(*RawData)); + const FSGNova2GloveSensorDataImpl SensorData{ + FNova2GloveSensorDataType::Parse(MoveTemp(RawDataString), GloveInfo.ToNovaGloveInfo()) + }; + return SensorData; +} + +FSGNova2GloveSensorDataImpl::FSGNova2GloveSensorDataImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGNova2GloveSensorDataImpl::FSGNova2GloveSensorDataImpl(const ESGNormalizationState NormalizationState, + const TArray>& Values, const int32 ParsedValues, + const FQuat& ImuRotation, const bool bImuParsed, + const float BatteryLevel, const bool bCharging) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + std::vector> ValuesVector{ + FSGArrayUtils::ToStdVector( + Values) + }; + Pimpl->Nova2GloveSensorData = FNova2GloveSensorDataType( + FSGCoreEnumCast::ToENormalizationState(NormalizationState), + MoveTemp(ValuesVector), ParsedValues, FSGQuatImpl(ImuRotation).ToQuat(), bImuParsed, + BatteryLevel, bCharging); +} + +FSGNova2GloveSensorDataImpl::FSGNova2GloveSensorDataImpl(const FNova2GloveSensorDataType& Nova2GloveSensorData) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->Nova2GloveSensorData = Nova2GloveSensorData; +} + +FSGNova2GloveSensorDataImpl::FSGNova2GloveSensorDataImpl(const FSGNova2GloveSensorDataImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGNova2GloveSensorDataImpl::FSGNova2GloveSensorDataImpl(FSGNova2GloveSensorDataImpl&& Rhs) SG_NOEXCEPT = default; + +FSGNova2GloveSensorDataImpl::~FSGNova2GloveSensorDataImpl() = default; + +FSGNova2GloveSensorDataImpl& FSGNova2GloveSensorDataImpl::operator=(const FSGNova2GloveSensorDataImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGNova2GloveSensorDataImpl& FSGNova2GloveSensorDataImpl::operator=(FSGNova2GloveSensorDataImpl&& Rhs) SG_NOEXCEPT += default; + +const FSGNova2GloveSensorDataImpl::FNova2GloveSensorDataType& +FSGNova2GloveSensorDataImpl::ToNova2GloveSensorData() const +{ + return Pimpl->Nova2GloveSensorData; +} + +ESGNormalizationState FSGNova2GloveSensorDataImpl::GetSensorState() const +{ + return FSGCoreEnumCast::ToESGNormalizationState(Pimpl->Nova2GloveSensorData.GetSensorState()); +} + +TArray> FSGNova2GloveSensorDataImpl::GetSensorValues() const +{ + const TArray> SensorValues{ + FSGArrayUtils::FromStdVector( + Pimpl->Nova2GloveSensorData.GetSensorValues()) + }; + return SensorValues; +} + +float FSGNova2GloveSensorDataImpl::GetSensorValue(const ESGFinger Finger, const ESGNova2SensorLocation Location) const +{ + return Pimpl->Nova2GloveSensorData.GetSensorValue( + FSGCoreEnumCast::ToEFinger(Finger), FSGCoreEnumCast::ToESensorLocation(Location)); +} + +int32 FSGNova2GloveSensorDataImpl::GetParsedValues() const +{ + return Pimpl->Nova2GloveSensorData.GetParsedValues(); +} + +FQuat FSGNova2GloveSensorDataImpl::GetImuRotation() const +{ + return FSGQuatImpl(Pimpl->Nova2GloveSensorData.GetImuRotation()).ToFQuat(); +} + +bool FSGNova2GloveSensorDataImpl::IsImuParsed() const +{ + return Pimpl->Nova2GloveSensorData.IsImuParsed(); +} + +float FSGNova2GloveSensorDataImpl::GetBatteryLevel() const +{ + return Pimpl->Nova2GloveSensorData.GetBatteryLevel(); +} + +bool FSGNova2GloveSensorDataImpl::IsCharging() const +{ + return Pimpl->Nova2GloveSensorData.IsCharging(); +} + +bool FSGNova2GloveSensorDataImpl::Equals(const FSGNova2GloveSensorDataImpl& Nova2GloveSensorDataImpl) const +{ + return Pimpl->Nova2GloveSensorData.Equals(Nova2GloveSensorDataImpl.ToNova2GloveSensorData()); +} + +FString FSGNova2GloveSensorDataImpl::ToString() const +{ + const FString String{UTF8_TO_TCHAR(Pimpl->Nova2GloveSensorData.ToString().c_str())}; + return String; +} + +FSGNova2GloveSensorDataImpl::FImpl::FImpl(FSGNova2GloveSensorDataImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGNova2GloveSensorDataImpl::FImpl::~FImpl() = default; + +void FSGNova2GloveSensorDataImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGNovaGloveImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGNovaGloveImpl.cpp new file mode 100644 index 0000000..896083c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGNovaGloveImpl.cpp @@ -0,0 +1,585 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 NovaGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGNovaGloveImpl.h" + +#include +#include + +#include "Containers/StringConv.h" +#include "Misc/AssertionMacros.h" + +#include "SGBuildHacks/SGInclude_Core_BasicHandModel.h" +#include "SGBuildHacks/SGInclude_Core_CustomWaveform.h" +#include "SGBuildHacks/SGInclude_Core_HandInterpolator.h" +#include "SGBuildHacks/SGInclude_Core_HandPose.h" +#include "SGBuildHacks/SGInclude_Core_HapticGlove.h" +#include "SGBuildHacks/SGInclude_Core_NovaGlove.h" +#include "SGBuildHacks/SGInclude_Core_NovaGloveInfo.h" +#include "SGBuildHacks/SGInclude_Core_NovaGloveSensorData.h" +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_SensorNormalization.h" +#include "SGBuildHacks/SGInclude_Core_ThresholdCommand.h" +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" +#include "SGCoreImpl/SGBasicHandModelImpl.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGCoreImpl/SGCustomWaveformImpl.h" +#include "SGCoreImpl/SGHandInterpolatorImpl.h" +#include "SGCoreImpl/SGHandPoseImpl.h" +#include "SGCoreImpl/SGNovaGloveInfoImpl.h" +#include "SGCoreImpl/SGNovaGloveSensorDataImpl.h" +#include "SGCoreImpl/SGQuatImpl.h" +#include "SGCoreImpl/SGSensorNormalizationImpl.h" +#include "SGCoreImpl/SGThresholdCommandImpl.h" +#include "SGCoreImpl/SGVect3DImpl.h" +#include "SGUtils/SGArrayUtils.h" + +struct FSGNovaGloveImpl::FImpl +{ + /************************ + * Owner object + ************************/ + + FSGNovaGloveImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGNovaGloveImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +TSharedRef FSGNovaGloveImpl::Parse(const FString& ConstantsString) +{ + std::string ConstantsStdString{TCHAR_TO_UTF8(*ConstantsString)}; + FSGDevicePtrType SGDevicePtr{FNovaGloveType::Parse(MoveTemp(ConstantsStdString))}; + ensureAlwaysMsgf(SGDevicePtr, TEXT("Invalid SGDevice!")); + const TSharedRef NovaGloveImpl{MakeShared( + std::dynamic_pointer_cast(MoveTemp(SGDevicePtr)))}; + return NovaGloveImpl; +} + +TArray FSGNovaGloveImpl::GetNovaGloves() +{ + const TArray Gloves{ + FSGArrayUtils::FromStdVector(FNovaGloveType::GetNovaGloves()) + }; + return Gloves; +} + +bool FSGNovaGloveImpl::GetNovaGlove(FSGNovaGloveImpl& OutGlove) +{ + FNovaGloveType Glove; + const bool bResult = FNovaGloveType::GetNovaGlove(Glove); + OutGlove = FSGNovaGloveImpl{MoveTemp(Glove)}; + return bResult; +} + +bool FSGNovaGloveImpl::GetNovaGlove(const bool bRightHanded, FSGNovaGloveImpl& OutGlove) +{ + FNovaGloveType Glove; + const bool bResult = FNovaGloveType::GetNovaGlove(bRightHanded, Glove); + OutGlove = FSGNovaGloveImpl{MoveTemp(Glove)}; + return bResult; +} + +void FSGNovaGloveImpl::CalculateGloveLocation( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, + FVector& OutGlovePosition, FQuat& OutGloveRotation) +{ + FSGVect3DImpl::FVect3DType GlovePosition; + FSGQuatImpl::FQuatType GloveRotation; + + FNovaGloveType::CalculateGloveLocation( + FSGUnits::CentimetersToMillimeters(ReferencePosition), + FSGQuatImpl{ReferenceRotation}.ToQuat(), + FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), bRightHanded, + GlovePosition, GloveRotation); + + OutGlovePosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(GlovePosition));; + OutGloveRotation = FSGQuatImpl{MoveTemp(GloveRotation)}.ToFQuat(); +} + +void FSGNovaGloveImpl::CalculateWristLocation( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, + FVector& OutWristPosition, FQuat& OutWristRotation) +{ + FSGVect3DImpl::FVect3DType WristPosition; + FSGQuatImpl::FQuatType WristRotation; + + FNovaGloveType::CalculateWristLocation( + FSGUnits::CentimetersToMillimeters(ReferencePosition), + FSGQuatImpl{ReferenceRotation}.ToQuat(), + FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), bRightHanded, + WristPosition, WristRotation); + + OutWristPosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(WristPosition)); + OutWristRotation = FSGQuatImpl{MoveTemp(WristRotation)}.ToFQuat(); +} + +ANSICHAR FSGNovaGloveImpl::GetHapticsByte() +{ + static const ANSICHAR Byte = FNovaGloveType::GetHapticsByte(); + return Byte; +} + +ANSICHAR FSGNovaGloveImpl::GetThresholdsByte() +{ + static const ANSICHAR Byte = FNovaGloveType::GetThresholdsByte(); + return Byte; +} + +ANSICHAR FSGNovaGloveImpl::GetIgnoreThresholdsByte() +{ + static const ANSICHAR Byte = FNovaGloveType::GetIgnoreThresholdsByte(); + return Byte; +} + +const TArray& FSGNovaGloveImpl::GetNovaSensorRanges() +{ + static const TArray Ranges{FSGArrayUtils::FromStdVector(FNovaGloveType::GetNovaSensorRanges())}; + return Ranges; +} + +TArray FSGNovaGloveImpl::ToNormalizedValues(const FSGNovaGloveSensorDataImpl& SensorData) +{ + const TArray NormalizedValues{ + FSGArrayUtils::FromStdVector( + FNovaGloveType::ToNormalizedValues(SensorData.ToNovaGloveSensorData())) + }; + return NormalizedValues; +} + +TArray FSGNovaGloveImpl::ToNormalizedValues(const FSGNovaGloveSensorDataImpl& SensorData, + FSGSensorNormalizationImpl& OutSensorNormalizer) +{ + const TArray NormalizedValues{ + FSGArrayUtils::FromStdVector( + FNovaGloveType::ToNormalizedValues(SensorData.ToNovaGloveSensorData(), + OutSensorNormalizer.ToSensorNormalization())) + }; + return NormalizedValues; +} + +TArray> FSGNovaGloveImpl::CalculateHandAngles( + const TArray& NormalizedValues, const FSGHandInterpolatorImpl& Interpolator) +{ + std::vector NormalizedValuesVector{FSGArrayUtils::ToStdVector(NormalizedValues)}; + + const TArray> Angles{ + FSGArrayUtils::FromSenseGloveAngles( + FNovaGloveType::CalculateHandAngles(MoveTemp(NormalizedValuesVector), Interpolator.ToHandInterpolator())) + }; + + return Angles; +} + +FString FSGNovaGloveImpl::ToNovaCommandAsFlexion(const FSGThresholdCommandImpl& Thresholds) +{ + const FString Flexion{ + UTF8_TO_TCHAR(FNovaGloveType::ToNovaCommandAsFlexion(Thresholds.ToThresholdCommand()).c_str()) + }; + return Flexion; +} + +FString FSGNovaGloveImpl::ToNovaCommandAsRaw( + const FSGThresholdCommandImpl& Thresholds, const FSGSensorNormalizationImpl& Interpolator) +{ + const FString Raw{ + UTF8_TO_TCHAR(FNovaGloveType::ToNovaCommandAsRaw(Thresholds.ToThresholdCommand(), + Interpolator.ToSensorNormalization()).c_str()) + }; + return Raw; +} + +FSGNovaGloveImpl::FSGNovaGloveImpl() + : FSGHapticGloveImpl(), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGNovaGloveImpl::FSGNovaGloveImpl(const FSGNovaGloveInfoImpl& DeviceInfo) + : FSGHapticGloveImpl(FSGNovaGloveImpl(std::make_shared((DeviceInfo.ToNovaGloveInfo())))), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGNovaGloveImpl::FSGNovaGloveImpl(const FNovaGloveType NovaGlove) + : FSGHapticGloveImpl(std::make_shared(NovaGlove)), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGNovaGloveImpl::FSGNovaGloveImpl(const FNovaGlovePtrType NovaGlove) + : FSGHapticGloveImpl(NovaGlove), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGNovaGloveImpl::FSGNovaGloveImpl(const FSGNovaGloveImpl& Rhs) + : FSGHapticGloveImpl(Rhs), + Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGNovaGloveImpl::FSGNovaGloveImpl(FSGNovaGloveImpl&& Rhs) SG_NOEXCEPT = default; + +FSGNovaGloveImpl::~FSGNovaGloveImpl() = default; + +FSGNovaGloveImpl& FSGNovaGloveImpl::operator=(const FSGNovaGloveImpl& Rhs) +{ + FSGHapticGloveImpl::operator=(Rhs); + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGNovaGloveImpl& FSGNovaGloveImpl::operator=(FSGNovaGloveImpl&& Rhs) SG_NOEXCEPT = default; + +const FSGNovaGloveImpl::FNovaGloveType& FSGNovaGloveImpl::ToNovaGlove() const +{ + return *ToNovaGlovePtrChecked(); +} + +FSGNovaGloveImpl::FNovaGlovePtrType FSGNovaGloveImpl::ToNovaGlovePtr() const +{ + return std::dynamic_pointer_cast(ToSGDevicePtr()); +} + +FSGNovaGloveImpl::FNovaGlovePtrType FSGNovaGloveImpl::ToNovaGlovePtrChecked() const +{ + FNovaGlovePtrType NovaGlove{std::dynamic_pointer_cast(ToSGDevicePtr())}; + ensureAlwaysMsgf(NovaGlove.get(), TEXT("Invalid NovaGlove")); + return NovaGlove; +} + +ESGDeviceType FSGNovaGloveImpl::GetDeviceType() const +{ + return FSGCoreEnumCast::ToESGDeviceType(ToNovaGlovePtrChecked()->GetDeviceType()); +} + +FString FSGNovaGloveImpl::GetDeviceId() const +{ + const FString Id{UTF8_TO_TCHAR(ToNovaGlovePtrChecked()->GetDeviceId().c_str())}; + return Id; +} + +FString FSGNovaGloveImpl::GetHardwareVersion() const +{ + const FString Version{UTF8_TO_TCHAR(ToNovaGlovePtrChecked()->GetHardwareVersion().c_str())}; + return Version; +} + +int32 FSGNovaGloveImpl::GetFirmwareVersion() const +{ + return ToNovaGlovePtrChecked()->GetFirmwareVersion(); +} + +int32 FSGNovaGloveImpl::GetSubFirmwareVersion() const +{ + return ToNovaGlovePtrChecked()->GetSubFirmwareVersion(); +} + +void FSGNovaGloveImpl::SetDeviceIndex(const int32 NewIndex) +{ + ToNovaGlovePtrChecked()->SetDeviceIndex(NewIndex); +} + +bool FSGNovaGloveImpl::HasBattery() const +{ + return ToNovaGlovePtrChecked()->HasBattery(); +} + +bool FSGNovaGloveImpl::IsCharging() +{ + return ToNovaGlovePtrChecked()->IsCharging(); +} + +bool FSGNovaGloveImpl::GetBatteryLevel(float& OutBatteryLevel) +{ + return ToNovaGlovePtrChecked()->GetBatteryLevel(OutBatteryLevel); +} + +bool FSGNovaGloveImpl::IsRight() const +{ + return ToNovaGlovePtrChecked()->IsRight(); +} + +bool FSGNovaGloveImpl::GetImuRotation(FQuat& OutImu) +{ + FSGQuatImpl::FQuatType Imu; + const bool bResult = ToNovaGlovePtrChecked()->GetImuRotation(Imu); + OutImu = FSGQuatImpl{MoveTemp(Imu)}.ToFQuat(); + return bResult; +} + +bool FSGNovaGloveImpl::GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose) const +{ + FSGHandPoseImpl::FHandPoseType HandPose; + const bool bResult = ToNovaGlovePtrChecked()->GetHandPose(HandGeometry.ToBasicHandModel(), HandPose); + OutHandPose = FSGHandPoseImpl{MoveTemp(HandPose)}; + return bResult; +} + +bool FSGNovaGloveImpl::GetHandAngles(TArray>& OutHandAngles) const +{ + std::vector> HandAngles; + const bool bResult = ToNovaGlovePtrChecked()->GetHandAngles(HandAngles); + OutHandAngles = FSGArrayUtils::FromSenseGloveAngles(MoveTemp(HandAngles)); + return bResult; +} + +ESGHapticGloveCalibrationState FSGNovaGloveImpl::GetCalibrationState() const +{ + return FSGCoreEnumCast::ToESGHapticGloveCalibrationState(ToNovaGlovePtrChecked()->GetCalibrationState()); +} + +void FSGNovaGloveImpl::EndCalibration() +{ + ToNovaGlovePtrChecked()->EndCalibration(); +} + +void FSGNovaGloveImpl::ResetCalibration() +{ + ToNovaGlovePtrChecked()->ResetCalibration(); +} + +void FSGNovaGloveImpl::StopHaptics() +{ + ToNovaGlovePtrChecked()->StopHaptics(); +} + +void FSGNovaGloveImpl::StopVibrations() +{ + ToNovaGlovePtrChecked()->StopVibrations(); +} + +bool FSGNovaGloveImpl::SendHaptics() +{ + return ToNovaGlovePtrChecked()->SendHaptics(); +} + +bool FSGNovaGloveImpl::SupportsCustomWaveform(const ESGHapticLocation AtLocation) const +{ + return ToNovaGlovePtrChecked()->SupportsCustomWaveform(FSGCoreEnumCast::ToEHapticLocation(AtLocation)); +} + +bool FSGNovaGloveImpl::SendCustomWaveform(FSGCustomWaveformImpl& OutWaveform, ESGHapticLocation Location) +{ + return ToNovaGlovePtrChecked()->SendCustomWaveform(OutWaveform.ToCustomWaveform(), + FSGCoreEnumCast::ToEHapticLocation(Location)); +} + +bool FSGNovaGloveImpl::QueueForceFeedbackLevels(const TArray& Levels01) +{ + std::vector Levels01Vector{FSGArrayUtils::ToStdVector(Levels01)}; + return ToNovaGlovePtrChecked()->QueueForceFeedbackLevels(MoveTemp(Levels01Vector)); +} + +bool FSGNovaGloveImpl::QueueForceFeedbackLevel(const int32 Finger, const float Level01) +{ + return ToNovaGlovePtrChecked()->QueueForceFeedbackLevel(Finger, Level01); +} + +void FSGNovaGloveImpl::GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const +{ + FSGVect3DImpl::FVect3DType GlovePosition; + FSGQuatImpl::FQuatType GloveRotation; + + ToNovaGlovePtrChecked()->GetGloveLocation( + FSGUnits::CentimetersToMillimeters(ReferencePosition), + FSGQuatImpl{ReferenceRotation}.ToQuat(), + FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), + GlovePosition, GloveRotation); + + OutGlovePosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(GlovePosition)); + OutGloveRotation = FSGQuatImpl{MoveTemp(GloveRotation)}.ToFQuat(); +} + +void FSGNovaGloveImpl::GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) const +{ + FSGVect3DImpl::FVect3DType WristPosition; + FSGQuatImpl::FQuatType WristRotation; + + ToNovaGlovePtrChecked()->GetWristLocation( + FSGUnits::CentimetersToMillimeters(ReferencePosition), + FSGQuatImpl{ReferenceRotation}.ToQuat(), + FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), + WristPosition, WristRotation); + + OutWristPosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(WristPosition)); + OutWristRotation = FSGQuatImpl{MoveTemp(WristRotation)}.ToFQuat(); +} + +FSGNovaGloveInfoImpl FSGNovaGloveImpl::GetGloveInfo() const +{ + const FSGNovaGloveInfoImpl GloveInfo{ToNovaGlovePtrChecked()->GetGloveInfo()}; + return GloveInfo; +} + +bool FSGNovaGloveImpl::SupportsThresholds() const +{ + return ToNovaGlovePtrChecked()->SupportsThresholds(); +} + +bool FSGNovaGloveImpl::SupportsCustomWaveforms() const +{ + return ToNovaGlovePtrChecked()->SupportsCustomWaveforms(); +} + +bool FSGNovaGloveImpl::SupportsOnBoardNormalization() const +{ + return ToNovaGlovePtrChecked()->SupportsOnBoardNormalization(); +} + +bool FSGNovaGloveImpl::GetSensorData(FSGNovaGloveSensorDataImpl& OutSensorData) const +{ + FSGNovaGloveSensorDataImpl::FNovaGloveSensorDataType SensorData; + const bool bResult = ToNovaGlovePtrChecked()->GetSensorData(SensorData); + OutSensorData = FSGNovaGloveSensorDataImpl{MoveTemp(SensorData)}; + return bResult; +} + +bool FSGNovaGloveImpl::GetNormalizedInput(TArray& OutNormalizedValues) const +{ + std::vector NormalizedValues; + const bool bResult = ToNovaGlovePtrChecked()->GetNormalizedInput(NormalizedValues); + OutNormalizedValues = FSGArrayUtils::FromStdVector(MoveTemp(NormalizedValues)); + return bResult; +} + +FString FSGNovaGloveImpl::ToNovaCommand( + const TArray& ForceFeedbackLevels, const TArray& BuzzLevels, const float WristLevel) const +{ + std::vector ForceFeedbackLevelsVector{FSGArrayUtils::ToStdVector(ForceFeedbackLevels)}; + std::vector BuzzLevelsVector{FSGArrayUtils::ToStdVector(BuzzLevels)}; + const FString Command{ + UTF8_TO_TCHAR(ToNovaGlovePtrChecked()->ToNovaCommand( + MoveTemp(ForceFeedbackLevelsVector), MoveTemp(BuzzLevelsVector), WristLevel).c_str()) + }; + return Command; +} + +bool FSGNovaGloveImpl::QueueVibroLevels(const TArray& Amplitudes) +{ + std::vector AmplitudesVector{FSGArrayUtils::ToStdVector(Amplitudes)}; + return ToNovaGlovePtrChecked()->QueueVibroLevels(MoveTemp(AmplitudesVector)); +} + +bool FSGNovaGloveImpl::QueueVibroLevel(const ESGHapticLocation Location, const float Level01) +{ + return ToNovaGlovePtrChecked()->QueueVibroLevel(FSGCoreEnumCast::ToEHapticLocation(Location), Level01); +} + +bool FSGNovaGloveImpl::QueueVibroLevel(const int32 Finger, const float Amplitude) +{ + return ToNovaGlovePtrChecked()->QueueVibroLevel(Finger, Amplitude); +} + +bool FSGNovaGloveImpl::QueueWristLevel(const float Amplitude) +{ + return ToNovaGlovePtrChecked()->QueueWristLevel(Amplitude); +} + +ESGNovaVibroMotor FSGNovaGloveImpl::ToNovaMotor(const ESGHapticLocation Location) const +{ + return FSGCoreEnumCast::ToESGNovaVibroMotor( + ToNovaGlovePtrChecked()->ToNovaMotor(FSGCoreEnumCast::ToEHapticLocation(Location))); +} + +int32 FSGNovaGloveImpl::ChannelIndex(const ESGNovaVibroMotor Motor) const +{ + return ToNovaGlovePtrChecked()->ChannelIndex(FSGCoreEnumCast::ToENovaVibroMotor(Motor)); +} + +void FSGNovaGloveImpl::ValidateWaveform(FSGCustomWaveformImpl& OutWaveform, const ESGNovaVibroMotor Motor) const +{ + return ToNovaGlovePtrChecked()->ValidateWaveform(OutWaveform.ToCustomWaveform(), + FSGCoreEnumCast::ToENovaVibroMotor(Motor)); +} + +bool FSGNovaGloveImpl::SendCustomWaveform_Nova(FSGCustomWaveformImpl& OutWaveform, + const ESGNovaVibroMotor Motor, const bool bValidateWaveform) +{ + return ToNovaGlovePtrChecked()->SendCustomWaveform_Nova( + OutWaveform.ToCustomWaveform(), FSGCoreEnumCast::ToENovaVibroMotor(Motor), bValidateWaveform); +} + +bool FSGNovaGloveImpl::QueueThresholdCommand_Flexion(const int32 Finger, const float FlexionThreshold) +{ + return ToNovaGlovePtrChecked()->QueueThresholdCommand_Flexion(Finger, FlexionThreshold); +} + +bool FSGNovaGloveImpl::QueueClearThreshold(const int32 Finger) +{ + return ToNovaGlovePtrChecked()->QueueClearThreshold(Finger); +} + +FString FSGNovaGloveImpl::ToString() const +{ + const FString String{UTF8_TO_TCHAR(ToNovaGlovePtrChecked()->ToString().c_str())}; + return String; +} + +FSGNovaGloveImpl::FImpl::FImpl(FSGNovaGloveImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGNovaGloveImpl::FImpl::~FImpl() = default; + +void FSGNovaGloveImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGNovaGloveInfoImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGNovaGloveInfoImpl.cpp new file mode 100644 index 0000000..62e0a87 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGNovaGloveInfoImpl.cpp @@ -0,0 +1,222 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 NovaGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGNovaGloveInfoImpl.h" + +#include + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_NovaGloveInfo.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGCoreImpl/SGQuatImpl.h" +#include "SGUtils/SGArrayUtils.h" + +struct FSGNovaGloveInfoImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FNovaGloveInfoType NovaGloveInfo; + + /************************ + * Owner object + ************************/ + + FSGNovaGloveInfoImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGNovaGloveInfoImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +bool FSGNovaGloveInfoImpl::Parse(const FString& ConstantsString, FSGNovaGloveInfoImpl& OutGloveInfo) +{ + std::string Constants(TCHAR_TO_UTF8(*ConstantsString)); + FNovaGloveInfoType GloveInfo; + + const bool bResults = FNovaGloveInfoType::Parse(MoveTemp(Constants), GloveInfo); + OutGloveInfo = FSGNovaGloveInfoImpl(GloveInfo); + + return bResults; +} + +FSGNovaGloveInfoImpl FSGNovaGloveInfoImpl::Deserialize(const FString& SerializedString) +{ + std::string Serialized(TCHAR_TO_UTF8(*SerializedString)); + const FSGNovaGloveInfoImpl GloveInfo(FNovaGloveInfoType::Deserialize(MoveTemp(Serialized))); + return GloveInfo; +} + +FSGNovaGloveInfoImpl::FSGNovaGloveInfoImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGNovaGloveInfoImpl::FSGNovaGloveInfoImpl( + const FString& DeviceId, + const FString& HardwareVersion, const int32 FirmwareVersion, const int32 SubFirmwareVersion, + const bool bRightHanded, const FQuat& ImuCorrection, const int32 NumberOfSensors) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + std::string DeviceIdString(TCHAR_TO_UTF8(*DeviceId)); + std::string HardwareVersionString(TCHAR_TO_UTF8(*HardwareVersion)); + FSGQuatImpl::FQuatType ImuCorrectionQuat(FSGQuatImpl(ImuCorrection).ToQuat()); + + Pimpl->NovaGloveInfo = FNovaGloveInfoType(MoveTemp(DeviceIdString), + MoveTemp(HardwareVersionString), FirmwareVersion, SubFirmwareVersion, + bRightHanded, MoveTemp(ImuCorrectionQuat), NumberOfSensors); +} + +FSGNovaGloveInfoImpl::FSGNovaGloveInfoImpl(const FNovaGloveInfoType& GloveInfo) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->NovaGloveInfo = GloveInfo; +} + +FSGNovaGloveInfoImpl::FSGNovaGloveInfoImpl(const FSGNovaGloveInfoImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGNovaGloveInfoImpl::FSGNovaGloveInfoImpl(FSGNovaGloveInfoImpl&& Rhs) SG_NOEXCEPT = default; + +FSGNovaGloveInfoImpl::~FSGNovaGloveInfoImpl() = default; + +FSGNovaGloveInfoImpl& FSGNovaGloveInfoImpl::operator=(const FSGNovaGloveInfoImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGNovaGloveInfoImpl& FSGNovaGloveInfoImpl::operator=(FSGNovaGloveInfoImpl&& Rhs) SG_NOEXCEPT = default; + +const FSGNovaGloveInfoImpl::FNovaGloveInfoType& FSGNovaGloveInfoImpl::ToNovaGloveInfo() const +{ + return Pimpl->NovaGloveInfo; +} + +FString FSGNovaGloveInfoImpl::GetDeviceId() const +{ + const FString DeviceId(UTF8_TO_TCHAR(Pimpl->NovaGloveInfo.GetDeviceId().c_str())); + return DeviceId; +} + +FString FSGNovaGloveInfoImpl::GetHardwareVersion() const +{ + const FString HardwareVersion(UTF8_TO_TCHAR(Pimpl->NovaGloveInfo.GetHardwareVersion().c_str())); + return HardwareVersion; +} + +int32 FSGNovaGloveInfoImpl::GetFirmwareVersion() const +{ + return Pimpl->NovaGloveInfo.GetFirmwareVersion(); +} + +int32 FSGNovaGloveInfoImpl::GetSubFirmwareVersion() const +{ + return Pimpl->NovaGloveInfo.GetSubFirmwareVersion(); +} + +bool FSGNovaGloveInfoImpl::IsRight() const +{ + return Pimpl->NovaGloveInfo.IsRight(); +} + +FQuat FSGNovaGloveInfoImpl::GetImuCorrection() const +{ + const FQuat ImuCorrection(FSGQuatImpl(Pimpl->NovaGloveInfo.GetImuCorrection()).ToFQuat()); + return ImuCorrection; +} + +int32 FSGNovaGloveInfoImpl::GetNumberOfSensors() const +{ + return Pimpl->NovaGloveInfo.GetNumberOfSensors(); +} + +bool FSGNovaGloveInfoImpl::FirmwareNewerThan(const int32 FirmwareMain, const int32 FirmwareSub, + const bool bInclusive) const +{ + return Pimpl->NovaGloveInfo.FirmwareNewerThan(FirmwareMain, FirmwareSub, bInclusive); +} + +bool FSGNovaGloveInfoImpl::FirmwareOlderThan(const int32 FirmwareMain, const int32 FirmwareSub, + const bool bInclusive) const +{ + return Pimpl->NovaGloveInfo.FirmwareOlderThan(FirmwareMain, FirmwareSub, bInclusive); +} + +bool FSGNovaGloveInfoImpl::Equals(const FSGNovaGloveInfoImpl& SGNovaGloveInfo) const +{ + return Pimpl->NovaGloveInfo.Equals(SGNovaGloveInfo.ToNovaGloveInfo()); +} + +FString FSGNovaGloveInfoImpl::ToString() const +{ + FString String(UTF8_TO_TCHAR(Pimpl->NovaGloveInfo.ToString().c_str())); + return String; +} + +FString FSGNovaGloveInfoImpl::Serialize() const +{ + FString Serialized(UTF8_TO_TCHAR(Pimpl->NovaGloveInfo.Serialize().c_str())); + return Serialized; +} + +FSGNovaGloveInfoImpl::FImpl::FImpl(FSGNovaGloveInfoImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGNovaGloveInfoImpl::FImpl::~FImpl() = default; + +void FSGNovaGloveInfoImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGNovaGloveSensorDataImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGNovaGloveSensorDataImpl.cpp new file mode 100644 index 0000000..3fa39f0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGNovaGloveSensorDataImpl.cpp @@ -0,0 +1,225 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 NovaGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGNovaGloveSensorDataImpl.h" + +#include +#include + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_NovaGloveSensorData.h" +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGCoreImpl/SGNovaGloveInfoImpl.h" +#include "SGCoreImpl/SGQuatImpl.h" +#include "SGCoreImpl/SGVect3DImpl.h" +#include "SGUtils/SGArrayUtils.h" + +struct FSGNovaGloveSensorDataImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FNovaGloveSensorDataType NovaGloveSensorData; + + /************************ + * Owner object + ************************/ + + FSGNovaGloveSensorDataImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGNovaGloveSensorDataImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +const FSGNovaGloveSensorDataImpl& FSGNovaGloveSensorDataImpl::Empty() +{ + static const FSGNovaGloveSensorDataImpl EmptyData(FNovaGloveSensorDataType::Empty()); + return EmptyData; +} + +FSGNovaGloveSensorDataImpl FSGNovaGloveSensorDataImpl::Parse(const FString& RawData, + const FSGNovaGloveInfoImpl& GloveInfo) +{ + std::string RawDataString(TCHAR_TO_UTF8(*RawData)); + const FSGNovaGloveSensorDataImpl SensorData(FNovaGloveSensorDataType::Parse( + MoveTemp(RawDataString), GloveInfo.ToNovaGloveInfo())); + return SensorData; +} + +FSGNovaGloveSensorDataImpl FSGNovaGloveSensorDataImpl::Deserialize(const FString& SerializedString) +{ + std::string Serialized(TCHAR_TO_UTF8(*SerializedString)); + const FSGNovaGloveSensorDataImpl SensorData(FNovaGloveSensorDataType::Deserialize(MoveTemp(Serialized))); + return SensorData; +} + +FSGNovaGloveSensorDataImpl::FSGNovaGloveSensorDataImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGNovaGloveSensorDataImpl::FSGNovaGloveSensorDataImpl(const TArray& Values, const int32 ParsedValues, + const FQuat& ImuRotation, const bool bImuParsed, + const float BatteryLevel, const bool bCharging) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + std::vector ValuesVector{ + FSGArrayUtils::ToStdVector( + Values) + }; + Pimpl->NovaGloveSensorData = FNovaGloveSensorDataType( + MoveTemp(ValuesVector), ParsedValues, FSGQuatImpl(ImuRotation).ToQuat(), bImuParsed, + BatteryLevel, bCharging); +} + +FSGNovaGloveSensorDataImpl::FSGNovaGloveSensorDataImpl(const FNovaGloveSensorDataType& NovaGloveSensorData) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->NovaGloveSensorData = NovaGloveSensorData; +} + +FSGNovaGloveSensorDataImpl::FSGNovaGloveSensorDataImpl(const FSGNovaGloveSensorDataImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGNovaGloveSensorDataImpl::FSGNovaGloveSensorDataImpl(FSGNovaGloveSensorDataImpl&& Rhs) SG_NOEXCEPT = default; + +FSGNovaGloveSensorDataImpl::~FSGNovaGloveSensorDataImpl() = default; + +FSGNovaGloveSensorDataImpl& FSGNovaGloveSensorDataImpl::operator=(const FSGNovaGloveSensorDataImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGNovaGloveSensorDataImpl& FSGNovaGloveSensorDataImpl::operator=(FSGNovaGloveSensorDataImpl&& Rhs) SG_NOEXCEPT += default; + +const FSGNovaGloveSensorDataImpl::FNovaGloveSensorDataType& FSGNovaGloveSensorDataImpl::ToNovaGloveSensorData() const +{ + return Pimpl->NovaGloveSensorData; +} + +ESGNormalizationState FSGNovaGloveSensorDataImpl::GetSensorState() const +{ + return FSGCoreEnumCast::ToESGNormalizationState(Pimpl->NovaGloveSensorData.GetSensorState()); +} + +TArray FSGNovaGloveSensorDataImpl::GetSensorValues() const +{ + const TArray SensorValues{ + FSGArrayUtils::FromStdVector( + Pimpl->NovaGloveSensorData.GetSensorValues()) + }; + return SensorValues; +} + +float FSGNovaGloveSensorDataImpl::GetSensorValue(const ESGFinger Finger, const ESGNovaSensorLocation Location) const +{ + return Pimpl->NovaGloveSensorData.GetSensorValue( + FSGCoreEnumCast::ToEFinger(Finger), FSGCoreEnumCast::ToESensorLocation(Location)); +} + +int32 FSGNovaGloveSensorDataImpl::GetParsedValues() const +{ + return Pimpl->NovaGloveSensorData.GetParsedValues(); +} + +FQuat FSGNovaGloveSensorDataImpl::GetImuRotation() const +{ + return FSGQuatImpl(Pimpl->NovaGloveSensorData.GetImuRotation()).ToFQuat(); +} + +bool FSGNovaGloveSensorDataImpl::IsImuParsed() const +{ + return Pimpl->NovaGloveSensorData.IsImuParsed(); +} + +float FSGNovaGloveSensorDataImpl::GetBatteryLevel() const +{ + return Pimpl->NovaGloveSensorData.GetBatteryLevel(); +} + +bool FSGNovaGloveSensorDataImpl::IsCharging() const +{ + return Pimpl->NovaGloveSensorData.IsCharging(); +} + +bool FSGNovaGloveSensorDataImpl::Equals(const FSGNovaGloveSensorDataImpl& NovaGloveSensorDataImpl) const +{ + return Pimpl->NovaGloveSensorData.Equals(NovaGloveSensorDataImpl.ToNovaGloveSensorData()); +} + +FString FSGNovaGloveSensorDataImpl::ToString() const +{ + const FString String{UTF8_TO_TCHAR(Pimpl->NovaGloveSensorData.ToString().c_str())}; + return String; +} + +FString FSGNovaGloveSensorDataImpl::Serialize() const +{ + const FString Serialized{UTF8_TO_TCHAR(Pimpl->NovaGloveSensorData.Serialize().c_str())}; + return Serialized; +} + +FSGNovaGloveSensorDataImpl::FImpl::FImpl(FSGNovaGloveSensorDataImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGNovaGloveSensorDataImpl::FImpl::~FImpl() = default; + +void FSGNovaGloveSensorDataImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGQuatImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGQuatImpl.cpp new file mode 100644 index 0000000..9b96c18 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGQuatImpl.cpp @@ -0,0 +1,307 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGQuatImpl.h" + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" +#include "SGCoreImpl/SGVect3DImpl.h" + +struct FSGQuatImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FQuatType Quat; + + /************************ + * Owner object + ************************/ + + FSGQuatImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGQuatImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +const FSGQuatImpl& FSGQuatImpl::Identity() +{ + static const FSGQuatImpl I(FQuatType::Identity()); + return I; +} + +FSGQuatImpl FSGQuatImpl::FromEuler(const float XAngle, const float YAngle, const float ZAngle) +{ + return FSGQuatImpl(FQuatType::FromEuler(XAngle, YAngle, ZAngle)); +} + +FSGQuatImpl FSGQuatImpl::FromEuler(const FSGVect3DImpl& Euler) +{ + return FSGQuatImpl(FQuatType::FromEuler(Euler.ToVect3D())); +} + +FSGQuatImpl FSGQuatImpl::FromEuler(const FVector& Euler) +{ + return FSGQuatImpl(FQuatType::FromEuler(FSGVect3DImpl(Euler).ToVect3D())); +} + +FSGQuatImpl FSGQuatImpl::FromAngleAxis(const float Angle, const float XAxis, const float YAxis, const float ZAxis) +{ + return FSGQuatImpl(FQuatType::FromAngleAxis(Angle, XAxis, YAxis, ZAxis)); +} + +FSGQuatImpl FSGQuatImpl::FromAngleAxis(const float Angle, const FSGVect3DImpl& Axis) +{ + return FSGQuatImpl(FQuatType::FromAngleAxis(Angle, Axis.ToVect3D())); +} + +FSGQuatImpl FSGQuatImpl::FromAngleAxis(const float Angle, const FVector& Axis) +{ + return FSGQuatImpl(FQuatType::FromAngleAxis(Angle, FSGVect3DImpl(Axis).ToVect3D())); +} + +FSGQuatImpl FSGQuatImpl::Invert(const FSGQuatImpl& QuatImpl) +{ + return FSGQuatImpl(FQuatType::Invert(QuatImpl.ToQuat())); +} + +FSGQuatImpl FSGQuatImpl::Normalize(const FSGQuatImpl& QuatImpl) +{ + return FSGQuatImpl(FQuatType::Normalize(QuatImpl.ToQuat())); +} + +bool FSGQuatImpl::Deserialize(const FString& String, FSGQuatImpl& OutResult, const ANSICHAR Delimiter) +{ + FQuatType Quat; + const bool bReturn = FQuatType::Deserialize(TCHAR_TO_UTF8(*String), Quat, Delimiter); + OutResult = FSGQuatImpl(Quat); + return bReturn; +} + +FSGQuatImpl::FSGQuatImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGQuatImpl::FSGQuatImpl(const float X, const float Y, const float Z, const float W) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->Quat = FQuatType(X, Y, Z, W); +} + +FSGQuatImpl::FSGQuatImpl(const FQuatType& Quat) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->Quat = Quat; +} + +FSGQuatImpl::FSGQuatImpl(const FQuat& Quat) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + /// NOTE + /// Unreal Engine uses a left-handed, z-up world coordinate system, which yealds clockwise rotations: + /// Forward X + /// Right Y + /// Up Z + /// SenseGlove uses a right-handed, z-up corrdinate systenm, which yealds counter-clockwise rotations: + /// Forward X + /// Left Y + /// Up Z + Pimpl->Quat = FQuatType(-Quat.X, Quat.Y, -Quat.Z, Quat.W); +} + +FSGQuatImpl::FSGQuatImpl(const FSGQuatImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGQuatImpl::FSGQuatImpl(FSGQuatImpl&& Rhs) SG_NOEXCEPT = default; + +FSGQuatImpl::~FSGQuatImpl() = default; + +FSGQuatImpl& FSGQuatImpl::operator=(const FSGQuatImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGQuatImpl& FSGQuatImpl::operator=(FSGQuatImpl&& Rhs) SG_NOEXCEPT = default; + +const FSGQuatImpl::FQuatType& FSGQuatImpl::ToQuat() const +{ + return Pimpl->Quat; +} + +FQuat FSGQuatImpl::ToFQuat() const +{ + /// NOTE + /// Unreal Engine uses a left-handed, z-up world coordinate system, which yealds clockwise rotations: + /// Forward X + /// Right Y + /// Up Z + /// SenseGlove uses a right-handed, z-up corrdinate systenm, which yealds counter-clockwise rotations: + /// Forward X + /// Left Y + /// Up Z + return FQuat(-Pimpl->Quat.GetX(), Pimpl->Quat.GetY(), -Pimpl->Quat.GetZ(), Pimpl->Quat.GetW()); +} + +FSGQuatImpl FSGQuatImpl::operator*(const FSGQuatImpl& QuatImpl) const +{ + return FSGQuatImpl(Pimpl->Quat.operator*(QuatImpl.ToQuat())); +} + +FSGVect3DImpl FSGQuatImpl::operator*(const FSGVect3DImpl& Vect3DImpl) const +{ + return FSGVect3DImpl(Pimpl->Quat.operator*(Vect3DImpl.ToVect3D())); +} + +FVector FSGQuatImpl::operator*(const FVector& Vector) const +{ + return FSGVect3DImpl(Pimpl->Quat.operator*(FSGVect3DImpl(Vector).ToVect3D())).ToFVector(); +} + +float FSGQuatImpl::GetX() const +{ + return Pimpl->Quat.GetX(); +} + +void FSGQuatImpl::SetX(const float X) +{ + Pimpl->Quat.SetX(X); +} + +float FSGQuatImpl::GetY() const +{ + return Pimpl->Quat.GetY(); +} + +void FSGQuatImpl::SetY(const float Y) +{ + Pimpl->Quat.SetY(Y); +} + +float FSGQuatImpl::GetZ() const +{ + return Pimpl->Quat.GetZ(); +} + +void FSGQuatImpl::SetZ(const float Z) +{ + Pimpl->Quat.SetZ(Z); +} + +float FSGQuatImpl::GetW() const +{ + return Pimpl->Quat.GetW(); +} + +void FSGQuatImpl::SetW(const float W) +{ + Pimpl->Quat.SetW(W); +} + +FSGVect3DImpl FSGQuatImpl::ToEulerImpl() const +{ + return FSGVect3DImpl(Pimpl->Quat.ToEuler()); +} + +FVector FSGQuatImpl::ToEuler() const +{ + return FSGVect3DImpl(Pimpl->Quat.ToEuler()).ToFVector(); +} + +FSGVect3DImpl FSGQuatImpl::Rotate(const FSGVect3DImpl& Vect3DImpl) const +{ + return FSGVect3DImpl(Pimpl->Quat.Rotate(Vect3DImpl.ToVect3D())); +} + +FVector FSGQuatImpl::Rotate(const FVector& Vector) const +{ + return FSGVect3DImpl(Pimpl->Quat.Rotate(FSGVect3DImpl(Vector).ToVect3D())).ToFVector(); +} + +bool FSGQuatImpl::Equals(const FSGQuatImpl& QuatImpl) const +{ + return Pimpl->Quat.Equals(QuatImpl.ToQuat()); +} + +bool FSGQuatImpl::IsIdentity() const +{ + return Pimpl->Quat.IsIdentity(); +} + +float FSGQuatImpl::Magnitude() const +{ + return Pimpl->Quat.Magnitude(); +} + +FString FSGQuatImpl::ToString() const +{ + return UTF8_TO_TCHAR(Pimpl->Quat.ToString().c_str()); +} + +FString FSGQuatImpl::Serialize(const ANSICHAR Delimiter) const +{ + return UTF8_TO_TCHAR(Pimpl->Quat.Serialize(Delimiter).c_str()); +} + +FSGQuatImpl::FImpl::FImpl(FSGQuatImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGQuatImpl::FImpl::~FImpl() = default; + +void FSGQuatImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGQuatImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGQuatImpl.h new file mode 100644 index 0000000..b23f25d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGQuatImpl.h @@ -0,0 +1,174 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" + +class FSGVect3DImpl; + +namespace SGCore +{ + namespace Kinematics + { + class Quat; + } +} + +class SENSEGLOVECOREIMPL_API FSGQuatImpl +{ +public: + typedef SGCore::Kinematics::Quat FQuatType; + +public: + static const FSGQuatImpl& Identity(); + + static FSGQuatImpl FromEuler(float XAngle, float YAngle, float ZAngle); + static FSGQuatImpl FromEuler(const FSGVect3DImpl& Euler); + static FSGQuatImpl FromEuler(const FVector& Euler); + static FSGQuatImpl FromAngleAxis(float Angle, float XAxis, float YAxis, float ZAxis); + static FSGQuatImpl FromAngleAxis(float Angle, const FSGVect3DImpl& Axis); + static FSGQuatImpl FromAngleAxis(float Angle, const FVector& Axis); + + static FSGQuatImpl Invert(const FSGQuatImpl& QuatImpl); + static FSGQuatImpl Normalize(const FSGQuatImpl& QuatImpl); + + static bool Deserialize(const FString& String, FSGQuatImpl& OutResult, ANSICHAR Delimiter); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGQuatImpl(); + FSGQuatImpl(float X, float Y, float Z, float W); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGQuatImpl(const FQuatType& Quat); + + /** + * The cast from FQuat type constructor. + */ + explicit FSGQuatImpl(const FQuat& Quat); + +public: + /** + * The copy constructor. + */ + FSGQuatImpl(const FSGQuatImpl& Rhs); + + /** + * The move constructor. + */ + FSGQuatImpl(FSGQuatImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGQuatImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGQuatImpl& operator=(const FSGQuatImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGQuatImpl& operator=(FSGQuatImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FQuatType& ToQuat() const; + + /** + * The cast to FQuat type method. + */ + FQuat ToFQuat() const; + +public: + FSGQuatImpl operator*(const FSGQuatImpl& QuatImpl) const; + FSGVect3DImpl operator*(const FSGVect3DImpl& Vect3DImpl) const; + FVector operator*(const FVector& Vector) const; + +public: + float GetX() const; + void SetX(float X); + + float GetY() const; + void SetY(float Y); + + float GetZ() const; + void SetZ(float Z); + + float GetW() const; + void SetW(float W); + +public: + FSGVect3DImpl ToEulerImpl() const; + FVector ToEuler() const; + + FSGVect3DImpl Rotate(const FSGVect3DImpl& Vect3DImpl) const; + FVector Rotate(const FVector& Vector) const; + + bool Equals(const FSGQuatImpl& QuatImpl) const; + + bool IsIdentity() const; + + float Magnitude() const; + + FString ToString() const; + + FString Serialize(ANSICHAR Delimiter) const; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseComImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseComImpl.cpp new file mode 100644 index 0000000..e40c826 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseComImpl.cpp @@ -0,0 +1,76 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGSenseComImpl.h" + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_SenseCom.h" + +bool FSGSenseComImpl::RegisterExe() +{ + return FSenseComType::RegisterExe(); +} + +bool FSGSenseComImpl::RegisterExe(const FString& ExePath) +{ + return FSenseComType::RegisterExe(std::move(std::string(TCHAR_TO_UTF8(*ExePath)))); +} + +bool FSGSenseComImpl::GetExePath(FString& OutExePath) +{ + std::string Path; + const bool bResult = FSenseComType::GetExePath(Path); + OutExePath = FString(UTF8_TO_TCHAR(Path.c_str())); + return bResult; +} + +bool FSGSenseComImpl::ScanningActive() +{ + return FSenseComType::ScanningActive(); +} + +bool FSGSenseComImpl::GetCurrentExeDirectory(FString& OutDirectory) +{ + std::string Directory; + const bool bResult = FSenseComType::GetCurrentExeDirectory(Directory); + OutDirectory = FString(UTF8_TO_TCHAR(Directory.c_str())); + return bResult; +} + +bool FSGSenseComImpl::StartupSenseCom() +{ + return FSenseComType::StartupSenseCom(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGloveImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGloveImpl.cpp new file mode 100644 index 0000000..3988f0f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGloveImpl.cpp @@ -0,0 +1,586 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGSenseGloveImpl.h" + +#include +#include + +#include "Containers/StringConv.h" +#include "Misc/AssertionMacros.h" + +#include "SGBuildHacks/SGInclude_Core_BasicHandModel.h" +#include "SGBuildHacks/SGInclude_Core_HandInterpolator.h" +#include "SGBuildHacks/SGInclude_Core_HandPose.h" +#include "SGBuildHacks/SGInclude_Core_HapticGlove.h" +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_SenseGlove.h" +#include "SGBuildHacks/SGInclude_Core_SenseGloveInfo.h" +#include "SGBuildHacks/SGInclude_Core_SenseGlovePose.h" +#include "SGBuildHacks/SGInclude_Core_SenseGloveSensorData.h" +#include "SGBuildHacks/SGInclude_Core_SenseGloveSensorNormalizer.h" +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" +#include "SGCoreImpl/SGBasicHandModelImpl.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGCoreImpl/SGHandInterpolatorImpl.h" +#include "SGCoreImpl/SGHandPoseImpl.h" +#include "SGCoreImpl/SGQuatImpl.h" +#include "SGCoreImpl/SGSenseGloveInfoImpl.h" +#include "SGCoreImpl/SGSenseGlovePoseImpl.h" +#include "SGCoreImpl/SGSenseGloveSensorDataImpl.h" +#include "SGCoreImpl/SGSenseGloveSensorNormalizerImpl.h" +#include "SGCoreImpl/SGVect3DImpl.h" +#include "SGUtils/SGArrayUtils.h" + +struct FSGSenseGloveImpl::FImpl +{ + /************************ + * Owner object + ************************/ + + FSGSenseGloveImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGSenseGloveImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +TSharedRef FSGSenseGloveImpl::Parse(const FString& ConstantsString) +{ + std::string ConstantsStdString{TCHAR_TO_UTF8(*ConstantsString)}; + FSGDevicePtrType SGDevicePtr{FSenseGloveType::Parse(MoveTemp(ConstantsStdString))}; + ensureAlwaysMsgf(SGDevicePtr, TEXT("Invalid SGDevice!")); + const TSharedRef SenseGloveImpl{ + MakeShared(std::dynamic_pointer_cast(MoveTemp(SGDevicePtr))) + }; + return SenseGloveImpl; +} + +TArray FSGSenseGloveImpl::GetSenseGloves() +{ + FSenseGloveVectorType Vector{FSenseGloveType::GetSenseGloves()}; + + const TArray Array{ + FSGArrayUtils::FromStdVector(MoveTemp(Vector)) + }; + + return Array; +} + +bool FSGSenseGloveImpl::GetSenseGlove(FSGSenseGloveImpl& OutGlove) +{ + FSenseGloveType Glove; + const bool bResult = FSenseGloveType::GetSenseGlove(Glove); + OutGlove = FSGSenseGloveImpl{MoveTemp(Glove)}; + return bResult; +} + +bool FSGSenseGloveImpl::GetSenseGlove(const bool bRightHanded, FSGSenseGloveImpl& OutGlove) +{ + FSenseGloveType Glove; + const bool bResult = FSenseGloveType::GetSenseGlove(bRightHanded, Glove); + OutGlove = FSGSenseGloveImpl{MoveTemp(Glove)}; + return bResult; +} + +void FSGSenseGloveImpl::CalculateGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + const bool bRightHanded, const ESGFinger MountedOn, + FVector& OutGlovePosition, FQuat& OutGloveRotation) +{ + FSGVect3DImpl::FVect3DType GlovePosition; + FSGQuatImpl::FQuatType GloveRotation; + + FSenseGloveType::CalculateGloveLocation( + FSGUnits::CentimetersToMillimeters(ReferencePosition), + FSGQuatImpl{ReferenceRotation}.ToQuat(), + FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), + bRightHanded, FSGCoreEnumCast::ToEFinger(MountedOn), + GlovePosition, GloveRotation); + + OutGlovePosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(GlovePosition));; + OutGloveRotation = FSGQuatImpl{MoveTemp(GloveRotation)}.ToFQuat(); +} + +void FSGSenseGloveImpl::CalculateWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + const bool bRightHanded, const ESGFinger MountedOn, + const FVector& GloveWristPositionOffset, + const FQuat& GloveWristRotationOffset, + FVector& OutWristPosition, FQuat& OutWristRotation) +{ + FSGVect3DImpl::FVect3DType WristPosition; + FSGQuatImpl::FQuatType WristRotation; + + FSenseGloveType::CalculateWristLocation( + FSGUnits::CentimetersToMillimeters(ReferencePosition), + FSGQuatImpl{ReferenceRotation}.ToQuat(), + FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), + bRightHanded, FSGCoreEnumCast::ToEFinger(MountedOn), + FSGUnits::CentimetersToMillimeters(GloveWristPositionOffset), + FSGQuatImpl(GloveWristRotationOffset).ToQuat(), + WristPosition, WristRotation); + + OutWristPosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(WristPosition)); + OutWristRotation = FSGQuatImpl{MoveTemp(WristRotation)}.ToFQuat(); +} + +ANSICHAR FSGSenseGloveImpl::GetHapticsByte() +{ + static const ANSICHAR Byte = FSenseGloveType::GetHapticsByte(); + return Byte; +} + +ANSICHAR FSGSenseGloveImpl::GetThumperByte() +{ + static const ANSICHAR Byte = FSenseGloveType::GetThumperByte(); + return Byte; +} + +const FVector& FSGSenseGloveImpl::GetDefaultThimbleOffset() +{ + static const FVector Offset{FSGVect3DImpl{FSenseGloveType::GetDefaultThimbleOffset()}.ToFVector()}; + return Offset; +} + +FSGSenseGlovePoseImpl FSGSenseGloveImpl::CalculateGlovePose(const FSGSenseGloveSensorDataImpl& SensorData, + const FSGSenseGloveInfoImpl& GloveModel) +{ + const FSGSenseGlovePoseImpl Pose{ + FSenseGloveType::CalculateGlovePose(SensorData.ToSenseGloveSensorData(), GloveModel.ToSenseGloveInfo()) + }; + return Pose; +} + +FSGSenseGlovePoseImpl FSGSenseGloveImpl::CalculateGlovePose(const TArray>& GloveAngles, + const FSGSenseGloveInfoImpl& GloveModel) +{ + std::vector> GloveAnglesVector{ + FSGArrayUtils::ToSenseGloveAngles(GloveAngles) + }; + + const FSGSenseGlovePoseImpl Pose{ + FSenseGloveType::CalculateGlovePose(MoveTemp(GloveAnglesVector), GloveModel.ToSenseGloveInfo()) + }; + + return Pose; +} + +void FSGSenseGloveImpl::NormalizeValues( + const TArray& SumAngles, const FSGSenseGloveSensorNormalizerImpl& Normalizer, + TArray& OutFlexions, TArray& OutAbductions) +{ + std::vector SumAnglesVector{ + FSGArrayUtils::ToSenseGloveAngles(SumAngles) + }; + + std::vector Flexions; + std::vector Abductions; + + FSenseGloveType::NormalizeValues(MoveTemp(SumAnglesVector), Normalizer.ToSenseGloveSensorNormalizer(), + Flexions, Abductions); + + OutFlexions = FSGArrayUtils::FromStdVector(MoveTemp(Flexions)); + OutAbductions = FSGArrayUtils::FromStdVector(MoveTemp(Abductions)); +} + +void FSGSenseGloveImpl::CalculateHandAngles( + const FSGSenseGlovePoseImpl& GlovePose, + const FSGSenseGloveSensorNormalizerImpl& Normalizer, const FSGHandInterpolatorImpl& NormalizedToAngles, + TArray>& OutHandAngles) +{ + std::vector> HandAngles; + + FSenseGloveType::CalculateHandAngles( + GlovePose.ToSenseGlovePose(), + Normalizer.ToSenseGloveSensorNormalizer(), NormalizedToAngles.ToHandInterpolator(), + HandAngles); + + OutHandAngles = FSGArrayUtils::FromSenseGloveAngles(MoveTemp(HandAngles)); +} + +void FSGSenseGloveImpl::CalculateHandPose( + const FSGSenseGlovePoseImpl& GlovePose, const FSGBasicHandModelImpl& HandModel, + const FSGSenseGloveSensorNormalizerImpl& Normalizer, const FSGHandInterpolatorImpl& NormalizedToAngles, + FSGHandPoseImpl& OutHandPose) +{ + FSGHandPoseImpl::FHandPoseType HandPose; + + FSenseGloveType::CalculateHandPose( + GlovePose.ToSenseGlovePose(), HandModel.ToBasicHandModel(), + Normalizer.ToSenseGloveSensorNormalizer(), NormalizedToAngles.ToHandInterpolator(), + HandPose); + + OutHandPose = FSGHandPoseImpl{MoveTemp(HandPose)}; +} + +FSGSenseGloveImpl::FSGSenseGloveImpl() + : FSGHapticGloveImpl(), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGSenseGloveImpl::FSGSenseGloveImpl(const FSGSenseGloveInfoImpl& Model) + : FSGHapticGloveImpl(std::make_shared(Model.ToSenseGloveInfo())), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGSenseGloveImpl::FSGSenseGloveImpl(const FSenseGloveType SenseGlove) + : FSGHapticGloveImpl(std::make_shared(SenseGlove)), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGSenseGloveImpl::FSGSenseGloveImpl(const FSenseGlovePtrType SenseGlove) + : FSGHapticGloveImpl(std::dynamic_pointer_cast(SenseGlove)), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGSenseGloveImpl::FSGSenseGloveImpl(const FSGSenseGloveImpl& Rhs) + : FSGHapticGloveImpl(Rhs), + Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGSenseGloveImpl::FSGSenseGloveImpl(FSGSenseGloveImpl&& Rhs) SG_NOEXCEPT = default; + +FSGSenseGloveImpl::~FSGSenseGloveImpl() = default; + +FSGSenseGloveImpl& FSGSenseGloveImpl::operator=(const FSGSenseGloveImpl& Rhs) +{ + FSGHapticGloveImpl::operator=(Rhs); + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGSenseGloveImpl& FSGSenseGloveImpl::operator=(FSGSenseGloveImpl&& Rhs) SG_NOEXCEPT = default; + +const FSGSenseGloveImpl::FSenseGloveType& FSGSenseGloveImpl::ToSenseGlove() const +{ + return *ToSenseGlovePtrChecked(); +} + +FSGSenseGloveImpl::FSenseGlovePtrType FSGSenseGloveImpl::ToSenseGlovePtr() const +{ + return std::dynamic_pointer_cast(ToSGDevicePtr()); +} + +FSGSenseGloveImpl::FSenseGlovePtrType FSGSenseGloveImpl::ToSenseGlovePtrChecked() const +{ + FSenseGlovePtrType SenseGlove = std::dynamic_pointer_cast(ToSGDevicePtr()); + ensureAlwaysMsgf(SenseGlove.get(), TEXT("Invalid SenseGlove")); + return SenseGlove; +} + +ESGDeviceType FSGSenseGloveImpl::GetDeviceType() const +{ + return FSGCoreEnumCast::ToESGDeviceType(ToSenseGlovePtrChecked()->GetDeviceType()); +} + +FString FSGSenseGloveImpl::GetDeviceId() const +{ + const FString Id{UTF8_TO_TCHAR(ToSenseGlovePtrChecked()->GetDeviceId().c_str())}; + return Id; +} + +FString FSGSenseGloveImpl::GetHardwareVersion() const +{ + const FString Version{UTF8_TO_TCHAR(ToSenseGlovePtrChecked()->GetHardwareVersion().c_str())}; + return Version; +} + +int32 FSGSenseGloveImpl::GetFirmwareVersion() const +{ + return ToSenseGlovePtrChecked()->GetFirmwareVersion(); +} + +int32 FSGSenseGloveImpl::GetSubFirmwareVersion() const +{ + return ToSenseGlovePtrChecked()->GetSubFirmwareVersion(); +} + +bool FSGSenseGloveImpl::IsRight() const +{ + return ToSenseGlovePtr()->IsRight(); +} + +bool FSGSenseGloveImpl::GetImuRotation(FQuat& OutImu) +{ + FSGQuatImpl::FQuatType Imu; + const bool bResult = ToSenseGlovePtrChecked()->GetImuRotation(Imu); + OutImu = FSGQuatImpl{MoveTemp(Imu)}.ToFQuat(); + return bResult; +} + +bool FSGSenseGloveImpl::GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose) const +{ + FSGHandPoseImpl::FHandPoseType HandPose; + const bool bResult = ToSenseGlovePtrChecked()->GetHandPose(HandGeometry.ToBasicHandModel(), HandPose); + OutHandPose = FSGHandPoseImpl{MoveTemp(HandPose)}; + return bResult; +} + +bool FSGSenseGloveImpl::GetHandAngles(TArray>& OutHandAngles) const +{ + std::vector> HandAngles; + const bool bResult = ToSenseGlovePtrChecked()->GetHandAngles(HandAngles); + OutHandAngles = + FSGArrayUtils::FromSenseGloveAngles(MoveTemp(HandAngles)); + return bResult; +} + +ESGHapticGloveCalibrationState FSGSenseGloveImpl::GetCalibrationState() const +{ + return FSGCoreEnumCast::ToESGHapticGloveCalibrationState(ToSenseGlovePtrChecked()->GetCalibrationState()); +} + +void FSGSenseGloveImpl::EndCalibration() +{ + return ToSenseGlovePtrChecked()->EndCalibration(); +} + +void FSGSenseGloveImpl::ResetCalibration() +{ + return ToSenseGlovePtrChecked()->EndCalibration(); +} + +void FSGSenseGloveImpl::StopHaptics() +{ + ToSenseGlovePtrChecked()->StopHaptics(); +} + +void FSGSenseGloveImpl::StopVibrations() +{ + ToSenseGlovePtrChecked()->StopVibrations(); +} + +bool FSGSenseGloveImpl::SendHaptics() +{ + return ToSenseGlovePtrChecked()->SendHaptics(); +} + +bool FSGSenseGloveImpl::QueueForceFeedbackLevels(const TArray& Levels01) +{ + std::vector Levels01Vector{FSGArrayUtils::ToStdVector(Levels01)}; + return ToSenseGlovePtrChecked()->QueueForceFeedbackLevels(MoveTemp(Levels01Vector)); +} + +bool FSGSenseGloveImpl::QueueForceFeedbackLevel(const int32 Finger, const float Level01) +{ + return ToSenseGlovePtrChecked()->QueueForceFeedbackLevel(Finger, Level01); +} + +bool FSGSenseGloveImpl::QueueVibroLevels(const TArray& Amplitudes) +{ + std::vector AmplitudesVector{FSGArrayUtils::ToStdVector(Amplitudes)}; + return ToSenseGlovePtrChecked()->QueueVibroLevels(MoveTemp(AmplitudesVector)); +} + +bool FSGSenseGloveImpl::QueueVibroLevel(const ESGHapticLocation Location, const float Level01) +{ + return ToSenseGlovePtrChecked()->QueueVibroLevel(FSGCoreEnumCast::ToEHapticLocation(Location), Level01); +} + +void FSGSenseGloveImpl::GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const +{ + FSGVect3DImpl::FVect3DType GlovePosition; + FSGQuatImpl::FQuatType GloveRotation; + + ToSenseGlovePtrChecked()->GetGloveLocation( + FSGUnits::CentimetersToMillimeters(ReferencePosition), + FSGQuatImpl{ReferenceRotation}.ToQuat(), + FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), + GlovePosition, GloveRotation); + + OutGlovePosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(GlovePosition)); + OutGloveRotation = FSGQuatImpl{MoveTemp(GloveRotation)}.ToFQuat(); +} + +void FSGSenseGloveImpl::GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + const ESGFinger MountedOn, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const +{ + FSGVect3DImpl::FVect3DType GlovePosition; + FSGQuatImpl::FQuatType GloveRotation; + + ToSenseGlovePtrChecked()->GetGloveLocation( + FSGUnits::CentimetersToMillimeters(ReferencePosition), + FSGQuatImpl{ReferenceRotation}.ToQuat(), + FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), + FSGCoreEnumCast::ToEFinger(MountedOn), + GlovePosition, GloveRotation); + + OutGlovePosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(GlovePosition)); + OutGloveRotation = FSGQuatImpl{MoveTemp(GloveRotation)}.ToFQuat(); +} + +void FSGSenseGloveImpl::GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) const +{ + FSGVect3DImpl::FVect3DType WristPosition; + FSGQuatImpl::FQuatType WristRotation; + + ToSenseGlovePtrChecked()->GetWristLocation( + FSGUnits::CentimetersToMillimeters(ReferencePosition), + FSGQuatImpl{ReferenceRotation}.ToQuat(), + FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), + WristPosition, WristRotation); + + OutWristPosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(WristPosition)); + OutWristRotation = FSGQuatImpl{MoveTemp(WristRotation)}.ToFQuat(); +} + +void FSGSenseGloveImpl::GetWristLocation( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + const FVector& GloveWristPositionOffset, const FQuat& GloveWristRotationOffset, + FVector& OutWristPosition, FQuat& OutWristRotation) const +{ + FSGVect3DImpl::FVect3DType WristPosition; + FSGQuatImpl::FQuatType WristRotation; + + ToSenseGlovePtrChecked()->GetWristLocation( + FSGUnits::CentimetersToMillimeters(ReferencePosition), + FSGQuatImpl{ReferenceRotation}.ToQuat(), + FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), + FSGUnits::CentimetersToMillimeters(GloveWristPositionOffset), + FSGQuatImpl(GloveWristRotationOffset).ToQuat(), + WristPosition, WristRotation); + + OutWristPosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(WristPosition)); + OutWristRotation = FSGQuatImpl{MoveTemp(WristRotation)}.ToFQuat(); +} + +FSGSenseGloveInfoImpl FSGSenseGloveImpl::GetGloveInfo() const +{ + FSGSenseGloveInfoImpl GloveInfo{ToSenseGlovePtr()->GetGloveInfo()}; + return GloveInfo; +} + +TArray FSGSenseGloveImpl::GetFingerThimbleOffsets() const +{ + const TArray Offsets{ + FSGArrayUtils::FromStdVector( + ToSenseGlovePtrChecked()->GetFingerThimbleOffsets()) + }; + return Offsets; +} + +void FSGSenseGloveImpl::SetFingerThimbleOffset(const int32 Finger, const FVector& Offset) +{ + ToSenseGlovePtrChecked()->SetFingerThimbleOffset(Finger, FSGVect3DImpl{Offset}.ToVect3D()); +} + +bool FSGSenseGloveImpl::SupportsWristActuator() const +{ + return ToSenseGlovePtrChecked()->SupportsWristActuator(); +} + +bool FSGSenseGloveImpl::GetSensorData(FSGSenseGloveSensorDataImpl& OutSensorData) const +{ + FSGSenseGloveSensorDataImpl::FSenseGloveSensorDataType SensorData; + const bool bResult = ToSenseGlovePtrChecked()->GetSensorData(SensorData); + OutSensorData = FSGSenseGloveSensorDataImpl{MoveTemp(SensorData)}; + return bResult; +} + +bool FSGSenseGloveImpl::GetGlovePose(FSGSenseGlovePoseImpl& OutGlovePose) const +{ + FSGSenseGlovePoseImpl::FSenseGlovePoseType GlovePose; + const bool bResult = ToSenseGlovePtr()->GetGlovePose(GlovePose); + OutGlovePose = FSGSenseGlovePoseImpl{GlovePose}; + return bResult; +} + +bool FSGSenseGloveImpl::GetGlovePose(const FSGSenseGloveSensorDataImpl& SensorData, + FSGSenseGlovePoseImpl& OutGlovePose) const +{ + FSGSenseGlovePoseImpl::FSenseGlovePoseType GlovePose; + const bool bResult = ToSenseGlovePtr()->GetGlovePose(SensorData.ToSenseGloveSensorData(), GlovePose); + OutGlovePose = FSGSenseGlovePoseImpl{GlovePose}; + return bResult; +} + +bool FSGSenseGloveImpl::QueueVibroLevel(const int32 Finger, const float Amplitude) +{ + return ToSenseGlovePtrChecked()->QueueVibroLevel(Finger, Amplitude); +} + +bool FSGSenseGloveImpl::QueueThumperCommand(const ESGSenseGloveThumperCommand Command) +{ + return ToSenseGlovePtrChecked()->QueueThumperCommand(FSGCoreEnumCast::ToESenseGloveThumperCommand(Command)); +} + +FString FSGSenseGloveImpl::ToString() const +{ + const FString String{UTF8_TO_TCHAR(ToSenseGlovePtrChecked()->ToString().c_str())}; + return String; +} + +FSGSenseGloveImpl::FImpl::FImpl(FSGSenseGloveImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGSenseGloveImpl::FImpl::~FImpl() = default; + +void FSGSenseGloveImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGloveInfoImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGloveInfoImpl.cpp new file mode 100644 index 0000000..54de664 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGloveInfoImpl.cpp @@ -0,0 +1,314 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGSenseGloveInfoImpl.h" + +#include +#include + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_SenseGloveInfo.h" +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGCoreImpl/SGQuatImpl.h" +#include "SGCoreImpl/SGVect3DImpl.h" +#include "SGUtils/SGArrayUtils.h" + +struct FSGSenseGloveInfoImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FSenseGloveInfoType SenseGloveInfo; + + /************************ + * Owner object + ************************/ + + FSGSenseGloveInfoImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGSenseGloveInfoImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +bool FSGSenseGloveInfoImpl::Parse(const FString& ConstantsString, FSGSenseGloveInfoImpl& OutGloveInfo, + const bool bUpdateOldModels) +{ + std::string Constants(TCHAR_TO_UTF8(*ConstantsString)); + FSenseGloveInfoType GloveInfo; + + const bool bResults = FSenseGloveInfoType::Parse(MoveTemp(Constants), GloveInfo, bUpdateOldModels); + OutGloveInfo = FSGSenseGloveInfoImpl(GloveInfo); + + return bResults; +} + +FSGSenseGloveInfoImpl FSGSenseGloveInfoImpl::Deserialize(const FString& SerializedString) +{ + std::string Serialized(TCHAR_TO_UTF8(*SerializedString)); + const FSGSenseGloveInfoImpl GloveInfo(FSenseGloveInfoType::Deserialize(MoveTemp(Serialized))); + return GloveInfo; +} + +FSGSenseGloveInfoImpl::FSGSenseGloveInfoImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGSenseGloveInfoImpl::FSGSenseGloveInfoImpl(const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, + int32 SubFirmwareVersion, + bool bRightHanded, int32 NumberOfSensors, + const FQuat& ImuCorrection, + const TArray& StartPositions, + const TArray& StartRotations, + const TArray>& GloveLengths, + const TArray& Functions) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + std::string DeviceIdString(TCHAR_TO_UTF8(*DeviceId)); + std::string HardwareVersionString(TCHAR_TO_UTF8(*HardwareVersion)); + FSGQuatImpl::FQuatType ImuCorrectionQuat(FSGQuatImpl(ImuCorrection).ToQuat()); + + std::vector StartPositionsVector{ + FSGArrayUtils::ToMillimeters(StartPositions) + }; + + std::vector StartRotationsVector{ + FSGArrayUtils::ToStdVector(StartRotations) + }; + + std::vector> GloveLengthsVector{ + FSGArrayUtils::ToMillimeters(GloveLengths) + }; + + std::vector FunctionsVector{FSGArrayUtils::ToStdVector(Functions)}; + + Pimpl->SenseGloveInfo = FSenseGloveInfoType(MoveTemp(DeviceIdString), MoveTemp(HardwareVersionString), + FirmwareVersion, SubFirmwareVersion, + bRightHanded, NumberOfSensors, + MoveTemp(ImuCorrectionQuat), + MoveTemp(StartPositionsVector), MoveTemp(StartRotationsVector), + MoveTemp(GloveLengthsVector), MoveTemp(FunctionsVector)); +} + +FSGSenseGloveInfoImpl::FSGSenseGloveInfoImpl(const FSenseGloveInfoType& GloveInfo) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->SenseGloveInfo = GloveInfo; +} + +FSGSenseGloveInfoImpl::FSGSenseGloveInfoImpl(const FSGSenseGloveInfoImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGSenseGloveInfoImpl::FSGSenseGloveInfoImpl(FSGSenseGloveInfoImpl&& Rhs) SG_NOEXCEPT = default; + +FSGSenseGloveInfoImpl::~FSGSenseGloveInfoImpl() = default; + +FSGSenseGloveInfoImpl& FSGSenseGloveInfoImpl::operator=(const FSGSenseGloveInfoImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGSenseGloveInfoImpl& FSGSenseGloveInfoImpl::operator=(FSGSenseGloveInfoImpl&& Rhs) SG_NOEXCEPT = default; + +const FSGSenseGloveInfoImpl::FSenseGloveInfoType& FSGSenseGloveInfoImpl::ToSenseGloveInfo() const +{ + return Pimpl->SenseGloveInfo; +} + +FString FSGSenseGloveInfoImpl::GetDeviceId() const +{ + const FString DeviceId{UTF8_TO_TCHAR(Pimpl->SenseGloveInfo.GetDeviceId().c_str())}; + return DeviceId; +} + +FString FSGSenseGloveInfoImpl::GetHardwareVersion() const +{ + const FString HardwareVersion{UTF8_TO_TCHAR(Pimpl->SenseGloveInfo.GetHardwareVersion().c_str())}; + return HardwareVersion; +} + +int32 FSGSenseGloveInfoImpl::GetFirmwareVersion() const +{ + return Pimpl->SenseGloveInfo.GetFirmwareVersion(); +} + +int32 FSGSenseGloveInfoImpl::GetSubFirmwareVersion() const +{ + return Pimpl->SenseGloveInfo.GetSubFirmwareVersion(); +} + +bool FSGSenseGloveInfoImpl::IsRight() const +{ + return Pimpl->SenseGloveInfo.IsRight(); +} + +int32 FSGSenseGloveInfoImpl::GetNumberOfSensors() const +{ + return Pimpl->SenseGloveInfo.GetNumberOfSensors(); +} + +FQuat FSGSenseGloveInfoImpl::GetImuCorrection() const +{ + const FQuat ImuCorrection{FSGQuatImpl(Pimpl->SenseGloveInfo.GetImuCorrection()).ToFQuat()}; + return ImuCorrection; +} + +TArray FSGSenseGloveInfoImpl::GetStartPositions() const +{ + const TArray StartPositionsArray{ + FSGArrayUtils::FromMillimeters( + Pimpl->SenseGloveInfo.GetStartPositions())}; + return StartPositionsArray; +} + +TArray FSGSenseGloveInfoImpl::GetStartRotations() const +{ + const TArray StartRotationsArray{ + FSGArrayUtils::FromStdVector( + Pimpl->SenseGloveInfo.GetStartRotations())}; + return StartRotationsArray; +} + +TArray> FSGSenseGloveInfoImpl::GetGloveLengths() const +{ + const TArray> GloveLengths{ + FSGArrayUtils::FromMillimeters( + Pimpl->SenseGloveInfo.GetGloveLengths()) + }; + return GloveLengths; +} + +TArray FSGSenseGloveInfoImpl::GetFunctions() const +{ + const TArray FunctionsArray{FSGArrayUtils::FromStdVector(Pimpl->SenseGloveInfo.GetFunctions())}; + return FunctionsArray; +} + +FVector FSGSenseGloveInfoImpl::GetStartPosition(const ESGFinger Finger) const +{ + const FVector StartPosition{ + FSGUnits::MillimetersToCentimeters( + Pimpl->SenseGloveInfo.GetStartPosition(FSGCoreEnumCast::ToEFinger(Finger))) + }; + return StartPosition; +} + +FQuat FSGSenseGloveInfoImpl::GetStartRotation(const ESGFinger Finger) const +{ + const FQuat StartRotation( + FSGQuatImpl(Pimpl->SenseGloveInfo.GetStartRotation(FSGCoreEnumCast::ToEFinger(Finger))).ToFQuat()); + return StartRotation; +} + +TArray FSGSenseGloveInfoImpl::GetGloveLengths(const ESGFinger Finger) const +{ + std::vector GloveLengthsVector{ + Pimpl->SenseGloveInfo.GetGloveLengths(FSGCoreEnumCast::ToEFinger(Finger)) + }; + const TArray GloveLengthsArray{ + FSGArrayUtils::FromMillimeters(MoveTemp(GloveLengthsVector)) + }; + return GloveLengthsArray; +} + +TArray> FSGSenseGloveInfoImpl::ToGloveAngles(const TArray>& SensorAngles) const +{ + /// TODO + /// Does the nested float TArray requires translation? If so, how to do that without a Movement value? + std::vector> SensorAnglesVector{ + FSGArrayUtils::ToStdVector(SensorAngles) + }; + const TArray> GloveAngles{ + FSGArrayUtils::FromSenseGloveAngles( + Pimpl->SenseGloveInfo.ToGloveAngles(MoveTemp((SensorAnglesVector)))) + }; + return GloveAngles; +} + +bool FSGSenseGloveInfoImpl::Equals(const FSGSenseGloveInfoImpl& SGSenseGloveInfo, const bool bGeometryOnly) const +{ + return Pimpl->SenseGloveInfo.Equals(SGSenseGloveInfo.ToSenseGloveInfo(), bGeometryOnly); +} + +FString FSGSenseGloveInfoImpl::ToString(const bool bShortNotation) const +{ + const FString String{UTF8_TO_TCHAR(Pimpl->SenseGloveInfo.ToString(bShortNotation).c_str())}; + return String; +} + +FString FSGSenseGloveInfoImpl::ToString() const +{ + const FString String{UTF8_TO_TCHAR(Pimpl->SenseGloveInfo.ToString().c_str())}; + return String; +} + +FString FSGSenseGloveInfoImpl::Serialize() const +{ + const FString Serialized{UTF8_TO_TCHAR(Pimpl->SenseGloveInfo.Serialize().c_str())}; + return Serialized; +} + +FSGSenseGloveInfoImpl::FImpl::FImpl(FSGSenseGloveInfoImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGSenseGloveInfoImpl::FImpl::~FImpl() = default; + +void FSGSenseGloveInfoImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGlovePoseImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGlovePoseImpl.cpp new file mode 100644 index 0000000..8deb64b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGlovePoseImpl.cpp @@ -0,0 +1,248 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGSenseGlovePoseImpl.h" + +#include +#include + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_SenseGlovePose.h" +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" +#include "SGCoreImpl/SGSenseGloveInfoImpl.h" +#include "SGCoreImpl/SGQuatImpl.h" +#include "SGCoreImpl/SGVect3DImpl.h" +#include "SGUtils/SGArrayUtils.h" + +struct FSGSenseGlovePoseImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FSenseGlovePoseType SenseGlovePose; + + /************************ + * Owner object + ************************/ + + FSGSenseGlovePoseImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGSenseGlovePoseImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +FSGSenseGlovePoseImpl FSGSenseGlovePoseImpl::IdlePose(const FSGSenseGloveInfoImpl& GloveInfo) +{ + const FSGSenseGlovePoseImpl GlovePoseImpl{FSenseGlovePoseType::IdlePose(GloveInfo.ToSenseGloveInfo())}; + return GlovePoseImpl; +} + +FSGSenseGlovePoseImpl FSGSenseGlovePoseImpl::Deserialize(const FString& SerializedString) +{ + std::string Serialized{TCHAR_TO_UTF8(*SerializedString)}; + const FSGSenseGlovePoseImpl GlovePose{FSenseGlovePoseType::Deserialize(MoveTemp(Serialized))}; + return GlovePose; +} + +FSGSenseGlovePoseImpl::FSGSenseGlovePoseImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGSenseGlovePoseImpl::FSGSenseGlovePoseImpl(const bool bRightHanded, const TArray>& JointPositions, + const TArray>& JointRotations, + const TArray>& GloveAngles) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + std::vector> JointPositionsVector{ + FSGArrayUtils::ToMillimeters(JointPositions) + }; + std::vector> JointRotationsVector{ + FSGArrayUtils::ToStdVector(JointRotations) + }; + std::vector> GloveAnglesVector{ + FSGArrayUtils::ToSenseGloveAngles(GloveAngles) + }; + + Pimpl->SenseGlovePose = FSenseGlovePoseType{ + bRightHanded, + MoveTemp(JointPositionsVector), + MoveTemp(JointRotationsVector), + MoveTemp(GloveAnglesVector) + }; +} + +FSGSenseGlovePoseImpl::FSGSenseGlovePoseImpl(const FSenseGlovePoseType& SenseGlovePose) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->SenseGlovePose = SenseGlovePose; +} + +FSGSenseGlovePoseImpl::FSGSenseGlovePoseImpl(const FSGSenseGlovePoseImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGSenseGlovePoseImpl::FSGSenseGlovePoseImpl(FSGSenseGlovePoseImpl&& Rhs) SG_NOEXCEPT = default; + +FSGSenseGlovePoseImpl::~FSGSenseGlovePoseImpl() = default; + +FSGSenseGlovePoseImpl& FSGSenseGlovePoseImpl::operator=(const FSGSenseGlovePoseImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGSenseGlovePoseImpl& FSGSenseGlovePoseImpl::operator=(FSGSenseGlovePoseImpl&& Rhs) SG_NOEXCEPT = default; + +const FSGSenseGlovePoseImpl::FSenseGlovePoseType& FSGSenseGlovePoseImpl::ToSenseGlovePose() const +{ + return Pimpl->SenseGlovePose; +} + +bool FSGSenseGlovePoseImpl::IsRight() const +{ + return Pimpl->SenseGlovePose.IsRight(); +} + +TArray> FSGSenseGlovePoseImpl::GetJointPositions() const +{ + const TArray> JointPositions{ + FSGArrayUtils::FromMillimeters( + Pimpl->SenseGlovePose.GetJointPositions()) + }; + return JointPositions; +} + +TArray> FSGSenseGlovePoseImpl::GetJointRotations() const +{ + const TArray> JointRotations{ + FSGArrayUtils::FromStdVector( + Pimpl->SenseGlovePose.GetJointRotations()) + }; + return JointRotations; +} + +TArray> FSGSenseGlovePoseImpl::GetGloveAngles() const +{ + const TArray> GloveAngles{ + FSGArrayUtils::FromSenseGloveAngles( + Pimpl->SenseGlovePose.GetGloveAngles()) + }; + return GloveAngles; +} + +TArray FSGSenseGlovePoseImpl::GetThimblePositions() const +{ + const TArray ThimblePositions{ + FSGArrayUtils::FromMillimeters( + Pimpl->SenseGlovePose.GetThimblePositions()) + }; + return ThimblePositions; +} + +TArray FSGSenseGlovePoseImpl::GetThimbleRotations() const +{ + const TArray ThimbleRotations{ + FSGArrayUtils::FromStdVector( + Pimpl->SenseGlovePose.GetThimbleRotations()) + }; + return ThimbleRotations; +} + +TArray FSGSenseGlovePoseImpl::GetTotalGloveAngles() const +{ + const TArray TotalGloveAngles{ + FSGArrayUtils::FromSenseGloveAngles(Pimpl->SenseGlovePose.GetTotalGloveAngles()) + }; + return TotalGloveAngles; +} + +TArray FSGSenseGlovePoseImpl::CalculateFingertips(const TArray& FingerOffsets) const +{ + std::vector FingerOffsetsVector{ + FSGArrayUtils::ToMillimeters(FingerOffsets) + }; + const TArray Fingertips{ + FSGArrayUtils::FromMillimeters( + Pimpl->SenseGlovePose.CalculateFingertips(MoveTemp(FingerOffsetsVector))) + }; + return Fingertips; +} + +bool FSGSenseGlovePoseImpl::Equals(const FSGSenseGlovePoseImpl& SenseGlovePoseImpl) const +{ + return Pimpl->SenseGlovePose.Equals(SenseGlovePoseImpl.ToSenseGlovePose()); +} + +FString FSGSenseGlovePoseImpl::ToString(const bool bShortFormat) const +{ + const FString String(UTF8_TO_TCHAR(Pimpl->SenseGlovePose.ToString(bShortFormat).c_str())); + return String; +} + +FString FSGSenseGlovePoseImpl::Serialize() const +{ + const FString Serialized(UTF8_TO_TCHAR(Pimpl->SenseGlovePose.Serialize().c_str())); + return Serialized; +} + +FSGSenseGlovePoseImpl::FImpl::FImpl(FSGSenseGlovePoseImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGSenseGlovePoseImpl::FImpl::~FImpl() = default; + +void FSGSenseGlovePoseImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGloveSensorDataImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGloveSensorDataImpl.cpp new file mode 100644 index 0000000..b95aa6c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGloveSensorDataImpl.cpp @@ -0,0 +1,216 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGSenseGloveSensorDataImpl.h" + +#include +#include + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_SenseGloveSensorData.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGCoreImpl/SGSenseGloveInfoImpl.h" +#include "SGCoreImpl/SGQuatImpl.h" +#include "SGUtils/SGArrayUtils.h" + +struct FSGSenseGloveSensorDataImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FSenseGloveSensorDataType SenseGloveSensorData; + + /************************ + * Owner object + ************************/ + + FSGSenseGloveSensorDataImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGSenseGloveSensorDataImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +const FSGSenseGloveSensorDataImpl& FSGSenseGloveSensorDataImpl::Empty() +{ + static const FSGSenseGloveSensorDataImpl EmptyData{FSenseGloveSensorDataType::Empty()}; + return EmptyData; +} + +FSGSenseGloveSensorDataImpl FSGSenseGloveSensorDataImpl::Parse(const FString& RawData, + const FSGSenseGloveInfoImpl& GloveInfo) +{ + std::string RawDataString(TCHAR_TO_UTF8(*RawData)); + const FSGSenseGloveSensorDataImpl SensorData{ + FSenseGloveSensorDataType::Parse(MoveTemp(RawDataString), GloveInfo.ToSenseGloveInfo()) + }; + return SensorData; +} + +FSGSenseGloveSensorDataImpl FSGSenseGloveSensorDataImpl::Deserialize(const FString& SerializedString) +{ + std::string Serialized{TCHAR_TO_UTF8(*SerializedString)}; + const FSGSenseGloveSensorDataImpl SensorData{FSenseGloveSensorDataType::Deserialize(MoveTemp(Serialized))}; + return SensorData; +} + +FSGSenseGloveSensorDataImpl::FSGSenseGloveSensorDataImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGSenseGloveSensorDataImpl::FSGSenseGloveSensorDataImpl(const TArray>& SensorAngles, + const FQuat& ImuRotation, + const int32 ParsedValues, const bool bImuParsed) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + std::vector> SensorAnglesVector{FSGArrayUtils::ToStdVector(SensorAngles)}; + Pimpl->SenseGloveSensorData = FSenseGloveSensorDataType( + MoveTemp(SensorAnglesVector), FSGQuatImpl(ImuRotation).ToQuat(), ParsedValues, bImuParsed); +} + +FSGSenseGloveSensorDataImpl::FSGSenseGloveSensorDataImpl(const FSenseGloveSensorDataType& SenseGloveSensorData) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->SenseGloveSensorData = SenseGloveSensorData; +} + +FSGSenseGloveSensorDataImpl::FSGSenseGloveSensorDataImpl(const FSGSenseGloveSensorDataImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGSenseGloveSensorDataImpl::FSGSenseGloveSensorDataImpl(FSGSenseGloveSensorDataImpl&& Rhs) SG_NOEXCEPT = default; + +FSGSenseGloveSensorDataImpl::~FSGSenseGloveSensorDataImpl() = default; + +FSGSenseGloveSensorDataImpl& FSGSenseGloveSensorDataImpl::operator=(const FSGSenseGloveSensorDataImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGSenseGloveSensorDataImpl& FSGSenseGloveSensorDataImpl::operator=(FSGSenseGloveSensorDataImpl&& Rhs) SG_NOEXCEPT += default; + +const FSGSenseGloveSensorDataImpl::FSenseGloveSensorDataType& FSGSenseGloveSensorDataImpl::ToSenseGloveSensorData( + ) const +{ + return Pimpl->SenseGloveSensorData; +} + +TArray> FSGSenseGloveSensorDataImpl::GetSensorAngles() const +{ + const TArray> SensorAngles{ + FSGArrayUtils::FromSenseGloveAngles(Pimpl->SenseGloveSensorData.GetSensorAngles()) + }; + return SensorAngles; +} + +TArray FSGSenseGloveSensorDataImpl::GetSensorAngles(ESGFinger Finger) const +{ + const TArray SensorAngles{ + FSGArrayUtils::FromStdVector( + Pimpl->SenseGloveSensorData.GetSensorAngles(FSGCoreEnumCast::ToEFinger(Finger))) + }; + return SensorAngles; +} + +TArray FSGSenseGloveSensorDataImpl::GetAngleSequence() const +{ + const TArray AngleSequence{ + FSGArrayUtils::FromStdVector(Pimpl->SenseGloveSensorData.GetAngleSequence()) + }; + return AngleSequence; +} + +FQuat FSGSenseGloveSensorDataImpl::GetImuRotation() const +{ + return FSGQuatImpl(Pimpl->SenseGloveSensorData.GetImuRotation()).ToFQuat(); +} + +int32 FSGSenseGloveSensorDataImpl::GetParsedValues() const +{ + return Pimpl->SenseGloveSensorData.GetParsedValues(); +} + +bool FSGSenseGloveSensorDataImpl::IsImuParsed() const +{ + return Pimpl->SenseGloveSensorData.IsImuParsed(); +} + +bool FSGSenseGloveSensorDataImpl::Equals(const FSGSenseGloveSensorDataImpl& SenseGloveSensorDataImpl) const +{ + return Pimpl->SenseGloveSensorData.Equals(SenseGloveSensorDataImpl.ToSenseGloveSensorData()); +} + +FString FSGSenseGloveSensorDataImpl::ToString() const +{ + const FString String{UTF8_TO_TCHAR(Pimpl->SenseGloveSensorData.ToString().c_str())}; + return String; +} + +FString FSGSenseGloveSensorDataImpl::Serialize() const +{ + const FString Serialized{UTF8_TO_TCHAR(Pimpl->SenseGloveSensorData.Serialize().c_str())}; + return Serialized; +} + +FSGSenseGloveSensorDataImpl::FImpl::FImpl(FSGSenseGloveSensorDataImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGSenseGloveSensorDataImpl::FImpl::~FImpl() = default; + +void FSGSenseGloveSensorDataImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGloveSensorNormalizerImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGloveSensorNormalizerImpl.cpp new file mode 100644 index 0000000..b706b1b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGloveSensorNormalizerImpl.cpp @@ -0,0 +1,137 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGSenseGloveSensorNormalizerImpl.h" + +#include "SGBuildHacks/SGInclude_Core_SenseGloveSensorNormalizer.h" +#include "SGCoreImpl/SGSenseGloveInfoImpl.h" + +struct FSGSenseGloveSensorNormalizerImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FSenseGloveSensorNormalizerType SenseGloveSensorNormalizer; + + /************************ + * Owner object + ************************/ + + FSGSenseGloveSensorNormalizerImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGSenseGloveSensorNormalizerImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +FSGSenseGloveSensorNormalizerImpl::FSGSenseGloveSensorNormalizerImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGSenseGloveSensorNormalizerImpl::FSGSenseGloveSensorNormalizerImpl(const bool bRightHanded) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->SenseGloveSensorNormalizer = FSenseGloveSensorNormalizerType(bRightHanded); +} + +FSGSenseGloveSensorNormalizerImpl::FSGSenseGloveSensorNormalizerImpl( + const FSenseGloveSensorNormalizerType& SenseGloveSensorNormalizer) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->SenseGloveSensorNormalizer = SenseGloveSensorNormalizer; +} + +FSGSenseGloveSensorNormalizerImpl::FSGSenseGloveSensorNormalizerImpl(const FSGSenseGloveSensorNormalizerImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGSenseGloveSensorNormalizerImpl::FSGSenseGloveSensorNormalizerImpl( + FSGSenseGloveSensorNormalizerImpl&& Rhs) SG_NOEXCEPT = default; + +FSGSenseGloveSensorNormalizerImpl::~FSGSenseGloveSensorNormalizerImpl() = default; + +FSGSenseGloveSensorNormalizerImpl& FSGSenseGloveSensorNormalizerImpl::operator=( + const FSGSenseGloveSensorNormalizerImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGSenseGloveSensorNormalizerImpl& FSGSenseGloveSensorNormalizerImpl::operator=( + FSGSenseGloveSensorNormalizerImpl&& Rhs) SG_NOEXCEPT += default; + +const FSGSenseGloveSensorNormalizerImpl::FSenseGloveSensorNormalizerType& +FSGSenseGloveSensorNormalizerImpl::ToSenseGloveSensorNormalizer() const +{ + return Pimpl->SenseGloveSensorNormalizer; +} + +float FSGSenseGloveSensorNormalizerImpl::NormalizeFlexion(const int32 Finger, const float SumFlexionAngles) const +{ + return Pimpl->SenseGloveSensorNormalizer.NormalizeFlexion(Finger, SumFlexionAngles); +} + +float FSGSenseGloveSensorNormalizerImpl::NormalizeAbduction(const int32 Finger, const float SumAbductionAngles) const +{ + return Pimpl->SenseGloveSensorNormalizer.NormalizeAbduction(Finger, SumAbductionAngles); +} + +FSGSenseGloveSensorNormalizerImpl::FImpl::FImpl(FSGSenseGloveSensorNormalizerImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGSenseGloveSensorNormalizerImpl::FImpl::~FImpl() = default; + +void FSGSenseGloveSensorNormalizerImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGloveVarsImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGloveVarsImpl.cpp new file mode 100644 index 0000000..7997485 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSenseGloveVarsImpl.cpp @@ -0,0 +1,147 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGSenseGloveVarsImpl.h" + +#include + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_SenseGloveInfo.h" +#include "SGBuildHacks/SGInclude_Core_SenseGloveVars.h" +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" +#include "SGCoreImpl/SGQuatImpl.h" +#include "SGCoreImpl/SGSenseGloveInfoImpl.h" +#include "SGCoreImpl/SGVect3DImpl.h" +#include "SGUtils/SGArrayUtils.h" + +FString FSGSenseGloveVarsImpl::GetStandardConstantsString(const FString& HardwareVersion, const float FirmwareVersion, + const bool bRightHanded) +{ + std::string HardwareVersionString{TCHAR_TO_UTF8(*HardwareVersion)}; + const FString String{ + UTF8_TO_TCHAR(FSenseGloveVarsType::GetStandardConstantsString( + MoveTemp(HardwareVersionString), FirmwareVersion, bRightHanded).c_str()) + }; + return String; +} + +FString FSGSenseGloveVarsImpl::GetSensorString(const FString& HardwareVersion, const float FirmwareVersion) +{ + std::string HardwareVersionString{TCHAR_TO_UTF8(*HardwareVersion)}; + const FString String{ + UTF8_TO_TCHAR(FSenseGloveVarsType::GetSensorString(MoveTemp(HardwareVersionString),FirmwareVersion).c_str()) + }; + return String; +} + +TArray FSGSenseGloveVarsImpl::GetStartPositions(const FString& HardwareVersion, const bool bRightHanded) +{ + std::string HardwareVersionString{TCHAR_TO_UTF8(*HardwareVersion)}; + const TArray StartPositions{ + FSGArrayUtils::FromMillimeters( + FSenseGloveVarsType::GetStartPositions(MoveTemp(HardwareVersionString), bRightHanded)) + }; + return StartPositions; +} + +TArray FSGSenseGloveVarsImpl::GetStartRotations(const FString& HardwareVersion, const bool bRightHanded) +{ + std::string HardwareVersionString{TCHAR_TO_UTF8(*HardwareVersion)}; + const TArray StartRotations{ + FSGArrayUtils::FromStdVector( + FSenseGloveVarsType::GetStartRotations(MoveTemp(HardwareVersionString), bRightHanded)) + }; + return StartRotations; +} + +TArray> FSGSenseGloveVarsImpl::GetGloveLengths(const FString& HardwareVersion) +{ + std::string HardwareVersionString{TCHAR_TO_UTF8(*HardwareVersion)}; + const TArray> GloveLengths{ + FSGArrayUtils::FromMillimeters( + FSenseGloveVarsType::GetGloveLengths(MoveTemp(HardwareVersionString))) + }; + return GloveLengths; +} + +int32 FSGSenseGloveVarsImpl::GetSensors(const FString& HardwareVersion) +{ + std::string HardwareVersionString{TCHAR_TO_UTF8(*HardwareVersion)}; + return FSenseGloveVarsType::GetSensors(MoveTemp(HardwareVersionString)); +} + +FQuat FSGSenseGloveVarsImpl::GetImuCorrection(const FString& HardwareVersion, const int32 FirmwareVersion, + const int32 SubFirmwareVersion) +{ + std::string HardwareVersionString{TCHAR_TO_UTF8(*HardwareVersion)}; + return FSGQuatImpl(FSenseGloveVarsType::GetImuCorrection( + MoveTemp(HardwareVersionString), FirmwareVersion, SubFirmwareVersion)).ToFQuat(); +} + +TArray FSGSenseGloveVarsImpl::GetFunctions(const FString& HardwareVersion, const int32 FirmwareVersion, + const int32 SubFirmwareVersion) +{ + std::string HardwareVersionString{TCHAR_TO_UTF8(*HardwareVersion)}; + const TArray Functions{FSGArrayUtils::FromStdVector(FSenseGloveVarsType::GetFunctions( + MoveTemp(HardwareVersionString), FirmwareVersion, SubFirmwareVersion)) + }; + return Functions; +} + +FSGSenseGloveInfoImpl FSGSenseGloveVarsImpl::GenerateGloveModel( + const FString& HardwareVersion, const int32 FirmwareVersion, const int32 SubFirmwareVersion, + const bool bRightHanded) +{ + std::string HardwareVersionString{TCHAR_TO_UTF8(*HardwareVersion)}; + return FSGSenseGloveInfoImpl{ + FSenseGloveVarsType::GenerateGloveModel( + MoveTemp(HardwareVersionString), FirmwareVersion, SubFirmwareVersion, bRightHanded) + }; +} + +FSGSenseGloveInfoImpl FSGSenseGloveVarsImpl::GenerateGloveModel( + const FString& HardwareVersion, const int32 FirmwareVersion, const int32 SubFirmwareVersion, + const bool bRightHanded, const FString& CustomId) +{ + std::string HardwareVersionString{TCHAR_TO_UTF8(*HardwareVersion)}; + std::string CustomIdString{TCHAR_TO_UTF8(*CustomId)}; + return FSGSenseGloveInfoImpl{ + FSenseGloveVarsType::GenerateGloveModel( + MoveTemp(HardwareVersionString), FirmwareVersion, SubFirmwareVersion, + bRightHanded, MoveTemp(CustomIdString)) + }; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSensorNormalizationImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSensorNormalizationImpl.cpp new file mode 100644 index 0000000..4bba558 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGSensorNormalizationImpl.cpp @@ -0,0 +1,190 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGSensorNormalizationImpl.h" + +#include + +#include "SGBuildHacks/SGInclude_Core_SensorNormalization.h" +#include "SGUtils/SGArrayUtils.h" + +struct FSGSensorNormalizationImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FSensorNormalizationType SensorNormalization; + + /************************ + * Owner object + ************************/ + + FSGSensorNormalizationImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGSensorNormalizationImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +FSGSensorNormalizationImpl::FSGSensorNormalizationImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGSensorNormalizationImpl::FSGSensorNormalizationImpl(const TArray& MovementRanges) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + std::vector MovementRangesVector{FSGArrayUtils::ToStdVector(MovementRanges)}; + + Pimpl->SensorNormalization = FSensorNormalizationType(MoveTemp(MovementRangesVector)); +} + +FSGSensorNormalizationImpl::FSGSensorNormalizationImpl( + const FSensorNormalizationType& SensorNormalization) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->SensorNormalization = SensorNormalization; +} + +FSGSensorNormalizationImpl::FSGSensorNormalizationImpl(const FSGSensorNormalizationImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGSensorNormalizationImpl::FSGSensorNormalizationImpl(FSGSensorNormalizationImpl&& Rhs) SG_NOEXCEPT = default; + +FSGSensorNormalizationImpl::~FSGSensorNormalizationImpl() = default; + +FSGSensorNormalizationImpl& FSGSensorNormalizationImpl::operator=(const FSGSensorNormalizationImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGSensorNormalizationImpl& FSGSensorNormalizationImpl::operator=(FSGSensorNormalizationImpl&& Rhs) SG_NOEXCEPT = default; + +const FSGSensorNormalizationImpl::FSensorNormalizationType& FSGSensorNormalizationImpl::ToSensorNormalization() const +{ + return Pimpl->SensorNormalization; +} + +FSGSensorNormalizationImpl::FSensorNormalizationType& FSGSensorNormalizationImpl::ToSensorNormalization() +{ + return Pimpl->SensorNormalization; +} + +bool FSGSensorNormalizationImpl::CollectsNormalization() const +{ + return Pimpl->SensorNormalization.CollectsNormalization(); +} + +void FSGSensorNormalizationImpl::SetCollectNormalization(const bool bCollectNormalization) +{ + Pimpl->SensorNormalization.SetCollectNormalization(bCollectNormalization); +} + +int32 FSGSensorNormalizationImpl::GetLength() const +{ + return Pimpl->SensorNormalization.GetLength(); +} + +int32 FSGSensorNormalizationImpl::GetMoveCount() const +{ + return Pimpl->SensorNormalization.GetMoveCount(); +} + +bool FSGSensorNormalizationImpl::AllSensorsMoving() const +{ + return Pimpl->SensorNormalization.AllSensorsMoving(); +} + +void FSGSensorNormalizationImpl::ResetNormalization() +{ + Pimpl->SensorNormalization.ResetNormalization(); +} + +void FSGSensorNormalizationImpl::UpdateNormalization(const float Value, const int32 Index) +{ + Pimpl->SensorNormalization.UpdateNormalization(Value, Index); +} + +float FSGSensorNormalizationImpl::NormalizeValue(const float Value, const int32 Index) +{ + return Pimpl->SensorNormalization.NormalizeValue(Value, Index); +} + +TArray FSGSensorNormalizationImpl::NormalizeValues(const TArray& Values) +{ + std::vector ValuesVector{FSGArrayUtils::ToStdVector(Values)}; + const TArray NormalizedValues{ + FSGArrayUtils::FromStdVector(Pimpl->SensorNormalization.NormalizeValues(MoveTemp(ValuesVector))) + }; + return NormalizedValues; +} + +bool FSGSensorNormalizationImpl::MovedEnough(const int32 Index) const +{ + return Pimpl->SensorNormalization.MovedEnough(Index); +} + +float FSGSensorNormalizationImpl::Denormalize(const float Value01, const int32 Index, const float FallbackValue) const +{ + return Pimpl->SensorNormalization.Denormalize(Value01, Index, FallbackValue); +} + +FSGSensorNormalizationImpl::FImpl::FImpl(FSGSensorNormalizationImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGSensorNormalizationImpl::FImpl::~FImpl() = default; + +void FSGSensorNormalizationImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGThresholdCommandImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGThresholdCommandImpl.cpp new file mode 100644 index 0000000..2119154 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGThresholdCommandImpl.cpp @@ -0,0 +1,188 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGThresholdCommandImpl.h" + +#include + +#include "SGBuildHacks/SGInclude_Core_ThresholdCommand.h" +#include "SGUtils/SGArrayUtils.h" + +struct FSGThresholdCommandImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FThresholdCommandType ThresholdCommand; + + /************************ + * Owner object + ************************/ + + FSGThresholdCommandImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGThresholdCommandImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +FSGThresholdCommandImpl::FSGThresholdCommandImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGThresholdCommandImpl::FSGThresholdCommandImpl( + const TArray& AffectedFingers, const TArray& ThresholdValues) +{ + std::vector AffectedFingersVector{FSGArrayUtils::ToStdVector(AffectedFingers)}; + std::vector ThresholdValuesVector{FSGArrayUtils::ToStdVector(ThresholdValues)}; + + Pimpl->ThresholdCommand = FThresholdCommandType{MoveTemp(AffectedFingersVector), MoveTemp(ThresholdValuesVector)}; +} + +FSGThresholdCommandImpl::FSGThresholdCommandImpl( + const FThresholdCommandType& ThresholdCommand) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->ThresholdCommand = ThresholdCommand; +} + +FSGThresholdCommandImpl::FSGThresholdCommandImpl(const FSGThresholdCommandImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGThresholdCommandImpl::FSGThresholdCommandImpl(FSGThresholdCommandImpl&& Rhs) SG_NOEXCEPT = default; + +FSGThresholdCommandImpl::~FSGThresholdCommandImpl() = default; + +FSGThresholdCommandImpl& FSGThresholdCommandImpl::operator=(const FSGThresholdCommandImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGThresholdCommandImpl& FSGThresholdCommandImpl::operator=(FSGThresholdCommandImpl&& Rhs) SG_NOEXCEPT = default; + +const FSGThresholdCommandImpl::FThresholdCommandType& FSGThresholdCommandImpl::ToThresholdCommand() const +{ + return Pimpl->ThresholdCommand; +} + +FSGThresholdCommandImpl::FThresholdCommandType& FSGThresholdCommandImpl::ToThresholdCommand() +{ + return Pimpl->ThresholdCommand; +} + +float FSGThresholdCommandImpl::GetThreshold(int32 Finger) const +{ + return Pimpl->ThresholdCommand.GetThreshold(Finger); +} + +void FSGThresholdCommandImpl::SetThreshold(const int32 Finger, const float ThresholdValue) +{ + Pimpl->ThresholdCommand.SetThreshold(Finger, ThresholdValue); +} + +TArray FSGThresholdCommandImpl::GetThresholds() const +{ + const TArray Thresholds{FSGArrayUtils::FromStdVector(Pimpl->ThresholdCommand.GetThresholds())}; + return Thresholds; +} + +void FSGThresholdCommandImpl::SetThresholds(const TArray& AffectedFingers, const TArray& ThresholdValues) +{ + std::vector AffectedFingersVector{FSGArrayUtils::ToStdVector(AffectedFingers)}; + std::vector ThresholdValuesVector{FSGArrayUtils::ToStdVector(ThresholdValues)}; + + Pimpl->ThresholdCommand.SetThresholds(MoveTemp(AffectedFingersVector), MoveTemp(ThresholdValuesVector)); +} + +bool FSGThresholdCommandImpl::GetFingerActive(const int32 Finger) const +{ + return Pimpl->ThresholdCommand.GetFingerActive(Finger); +} + +TArray FSGThresholdCommandImpl::GetActiveFingers() const +{ + const TArray ActiveFingers{FSGArrayUtils::FromStdVector(Pimpl->ThresholdCommand.GetActiveFingers())}; + return ActiveFingers; +} + +void FSGThresholdCommandImpl::ClearThreshold(const int32 Finger) +{ + Pimpl->ThresholdCommand.ClearThreshold(Finger); +} + +void FSGThresholdCommandImpl::ClearThresholds() +{ + Pimpl->ThresholdCommand.ClearThresholds(); +} + +bool FSGThresholdCommandImpl::Equals(const FSGThresholdCommandImpl& ThresholdCommand) const +{ + return Pimpl->ThresholdCommand.Equals(ThresholdCommand.ToThresholdCommand()); +} + +FString FSGThresholdCommandImpl::ToString() const +{ + const FString String{UTF8_TO_TCHAR(Pimpl->ThresholdCommand.ToString().c_str())}; + return String; +} + +FSGThresholdCommandImpl::FImpl::FImpl(FSGThresholdCommandImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGThresholdCommandImpl::FImpl::~FImpl() = default; + +void FSGThresholdCommandImpl::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGTrackingImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGTrackingImpl.cpp new file mode 100644 index 0000000..992914a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGTrackingImpl.cpp @@ -0,0 +1,594 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGTrackingImpl.h" + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_Quat.h" +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" +#include "SGCoreImpl/SGCoreEnumCast.h" +#include "SGCoreImpl/SGQuatImpl.h" +#include "SGCoreImpl/SGVect3DImpl.h" +#include "SGUtils/SGArrayUtils.h" + +void FSGTrackingImpl::CalculateLocation(const FVector& TrackedPosition, const FQuat& TrackedRotation, + const FVector& PositionOffset, const FQuat& RotationOffset, + FVector& OutNewPosition, FQuat& OutNewRotation) +{ + FSGVect3DImpl::FVect3DType TrackedPositionVect3D{ + FSGUnits::CentimetersToMillimeters(TrackedPosition) + }; + FSGQuatImpl::FQuatType TrackedRotationQuat(FSGQuatImpl(TrackedRotation).ToQuat()); + FSGVect3DImpl::FVect3DType PositionOffsetVect3D{ + FSGUnits::CentimetersToMillimeters(PositionOffset) + }; + FSGQuatImpl::FQuatType RotationOffsetQuat(FSGQuatImpl(RotationOffset).ToQuat()); + FSGVect3DImpl::FVect3DType NewPosition; + FSGQuatImpl::FQuatType NewRotation; + + FTrackingType::CalculateLocation(MoveTemp(TrackedPositionVect3D), + MoveTemp(TrackedRotationQuat), + MoveTemp(PositionOffsetVect3D), + MoveTemp(RotationOffsetQuat), + NewPosition, + NewRotation); + + OutNewPosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(NewPosition)); + OutNewRotation = FSGQuatImpl(MoveTemp(NewRotation)).ToFQuat(); +} + +const TArray& FSGTrackingImpl::GetSenseGloveFingerToGlovePositionOrigin() +{ + static const TArray GlovePositionOrigin{ + FSGArrayUtils::FromMillimeters( + FTrackingType::GetSenseGloveFingerToGlovePositionOrigin()) + }; + return GlovePositionOrigin; +} + +const TArray& FSGTrackingImpl::GetSenseGloveFingerToGloveRotationOrigin() +{ + static const TArray GloveRotationOrigin{ + FSGArrayUtils::FromStdVector( + FTrackingType::GetSenseGloveFingerToGloveRotationOrigin()) + }; + return GloveRotationOrigin; +} + +const FVector& FSGTrackingImpl::GetSenseGloveWristPositionOffset() +{ + static const FVector Offset{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetSenseGloveWristPositionOffset()) + }; + return Offset; +} + +const FQuat& FSGTrackingImpl::GetSenseGloveWristRotationOffset() +{ + static FQuat Offset{FSGQuatImpl(FTrackingType::GetSenseGloveWristRotationOffset()).ToFQuat()}; + return Offset; +} + +void FSGTrackingImpl::GetSenseGloveMountOffset(const bool bRightHanded, const ESGFinger ToFinger, + FVector& OutIPosition, FQuat& OutIRotation) +{ + FSGVect3DImpl::FVect3DType IPosition; + FSGQuatImpl::FQuatType IRotation; + + FTrackingType::GetSenseGloveMountOffset(bRightHanded, FSGCoreEnumCast::ToEFinger(ToFinger), + IPosition, IRotation); + + OutIPosition = FSGUnits::MillimetersToCentimeters( + MoveTemp(IPosition)); + OutIRotation = FSGQuatImpl(MoveTemp(IRotation)).ToFQuat(); +} + +void FSGTrackingImpl::GetSenseGloveTrackerMountOffset(const ESGPositionalTrackingHardware Hardware, + const bool bRightHanded, + FVector& OutPositionOffset, FQuat& OutRotationOffset) +{ + FSGVect3DImpl::FVect3DType PositionOffset; + FSGQuatImpl::FQuatType RotationOffset; + + FTrackingType::GetSenseGloveTrackerMountOffset(FSGCoreEnumCast::ToEPositionalTrackingHardware(Hardware), + bRightHanded, PositionOffset, RotationOffset); + + OutPositionOffset = FSGUnits::MillimetersToCentimeters( + MoveTemp(PositionOffset)); + OutRotationOffset = FSGQuatImpl(MoveTemp(RotationOffset)).ToFQuat(); +} + +const FVector& FSGTrackingImpl::GetSenseGloveViveToAttachPosition() +{ + static const FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetSenseGloveViveToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetSenseGloveViveToAttachRotation() +{ + static const FQuat Rotation(FSGQuatImpl(FTrackingType::GetSenseGloveViveToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetSenseGloveOculusTouchToAttachPosition() +{ + static const FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetSenseGloveOculusTouchToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetSenseGloveOculusTouchToAttachRotation() +{ + static const FQuat Rotation(FSGQuatImpl(FTrackingType::GetSenseGloveOculusTouchToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetNovaToWristPositionOffset() +{ + static const FVector Offset{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetNovaToWristPositionOffset()) + }; + return Offset; +} + +const FQuat& FSGTrackingImpl::GetNovaToWristRotationOffset() +{ + static FQuat Offset(FSGQuatImpl(FTrackingType::GetNovaToWristRotationOffset()).ToFQuat()); + return Offset; +} + +const FVector& FSGTrackingImpl::GetRightNovaViveToAttachPosition() +{ + static const FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetRightNovaViveToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetRightNovaViveToAttachRotation() +{ + static const FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNovaViveToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetLeftNovaViveToAttachPosition() +{ + static const FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetLeftNovaViveToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetLeftNovaViveToAttachRotation() +{ + static const FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNovaViveToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetRightNovaQuest2ToAttachPosition() +{ + static const FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetRightNovaQuest2ToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetRightNovaQuest2ToAttachRotation() +{ + static const FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNovaQuest2ToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetLeftNovaQuest2ToAttachPosition() +{ + static const FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetLeftNovaQuest2ToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetLeftNovaQuest2ToAttachRotation() +{ + static const FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNovaQuest2ToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetRightNovaPico2ToAttachPosition() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetRightNovaPico2ToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetRightNovaPico2ToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNovaPico2ToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FQuat& FSGTrackingImpl::GetLeftNovaPico2ToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNovaPico2ToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetRightNovaQuestProToAttachPosition() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetRightNovaQuestProToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetRightNovaQuestProToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNovaQuestProToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetLeftNovaQuestProToAttachPosition() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetLeftNovaQuestProToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetLeftNovaQuestProToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNovaQuestProToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetRightNovaViveFocus3ToAttachPosition() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetRightNovaViveFocus3ToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetRightNovaViveFocus3ToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNovaViveFocus3ToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetLeftNovaViveFocus3ToAttachPosition() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetLeftNovaViveFocus3ToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetLeftNovaViveFocus3ToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNovaViveFocus3ToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetRightNovaQuest3ToAttachPosition() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetRightNovaQuest3ToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetRightNovaQuest3ToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNovaQuest3ToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetLeftNovaQuest3ToAttachPosition() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetLeftNovaQuest3ToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetLeftNovaQuest3ToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNovaQuest3ToAttachRotation()).ToFQuat()); + return Rotation; +} + +void FSGTrackingImpl::GetNovaGloveWristOffset(const bool bRightHanded, + FVector& OutPositionOffset, FQuat& OutRotationOffset) +{ + FSGVect3DImpl::FVect3DType PositionOffset; + FSGQuatImpl::FQuatType RotationOffset; + + FTrackingType::GetNovaGloveWristOffset(bRightHanded, PositionOffset, RotationOffset); + + OutPositionOffset = FSGUnits::MillimetersToCentimeters( + MoveTemp(PositionOffset)); + OutRotationOffset = FSGQuatImpl(MoveTemp(RotationOffset)).ToFQuat(); +} + +void FSGTrackingImpl::GetNovaGloveTrackerOffset(const ESGPositionalTrackingHardware Hardware, const bool bRightHanded, + FVector& OutPositionOffset, FQuat& OutRotationOffset) +{ + FSGVect3DImpl::FVect3DType PositionOffset; + FSGQuatImpl::FQuatType RotationOffset; + + FTrackingType::GetNovaGloveTrackerOffset(FSGCoreEnumCast::ToEPositionalTrackingHardware(Hardware), bRightHanded, + PositionOffset, RotationOffset); + + OutPositionOffset = FSGUnits::MillimetersToCentimeters( + MoveTemp(PositionOffset)); + OutRotationOffset = FSGQuatImpl(MoveTemp(RotationOffset)).ToFQuat(); +} + +const FVector& FSGTrackingImpl::GetRightNova2ToWristPositionOffset() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetRightNova2ToWristPositionOffset()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetRightNova2ToWristRotationOffset() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNova2ToWristRotationOffset()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetLeftNova2ToWristPositionOffset() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetLeftNova2ToWristPositionOffset()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetLeftNova2ToWristRotationOffset() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNova2ToWristRotationOffset()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetRightNova2Quest2ToAttachPosition() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetRightNova2Quest2ToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetRightNova2Quest2ToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNova2Quest2ToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetLeftNova2Quest2ToAttachPosition() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetLeftNova2Quest2ToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetLeftNova2Quest2ToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNova2Quest2ToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetRightNova2QuestProToAttachPosition() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetRightNova2QuestProToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetRightNova2QuestProToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNova2QuestProToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetLeftNova2QuestProToAttachPosition() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetLeftNova2QuestProToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetLeftNova2QuestProToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNova2QuestProToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetRightNova2ViveTrackerToAttachPosition() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetRightNova2ViveTrackerToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetRightNova2ViveTrackerToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNova2ViveTrackerToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetLeftNova2ViveTrackerToAttachPosition() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetLeftNova2ViveTrackerToAttachPosition()) + }; + return Position; +} + +const FVector& FSGTrackingImpl::GetRightNova2Quest3ToAttachPosition() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetRightNova2Quest3ToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetRightNova2Quest3ToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNova2Quest3ToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetLeftNova2Quest3ToAttachPosition() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetLeftNova2Quest3ToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetLeftNova2Quest3ToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNova2Quest3ToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FQuat& FSGTrackingImpl::GetLeftNova2ViveTrackerToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNova2ViveTrackerToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetRightNova2ViveWristTrackerToAttachPosition() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetRightNova2ViveWristTrackerToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetRightNova2ViveWristTrackerToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNova2ViveWristTrackerToAttachRotation()).ToFQuat()); + return Rotation; +} + +const FVector& FSGTrackingImpl::GetLeftNova2ViveWristTrackerToAttachPosition() +{ + static FVector Position{ + FSGUnits::MillimetersToCentimeters( + FTrackingType::GetLeftNova2ViveWristTrackerToAttachPosition()) + }; + return Position; +} + +const FQuat& FSGTrackingImpl::GetLeftNova2ViveWristTrackerToAttachRotation() +{ + static FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNova2ViveWristTrackerToAttachRotation()).ToFQuat()); + return Rotation; +} + +void FSGTrackingImpl::GetNova2GloveWristOffset(const bool bRightHanded, const FString& HardwareVersion, + FVector& OutPositionOffset, FQuat& OutRotationOffset) +{ + FSGVect3DImpl::FVect3DType PositionOffset; + FSGQuatImpl::FQuatType RotationOffset; + + FTrackingType::GetNova2GloveWristOffset(bRightHanded, TCHAR_TO_UTF8(*HardwareVersion), + PositionOffset, RotationOffset); + + OutPositionOffset = FSGUnits::MillimetersToCentimeters( + MoveTemp(PositionOffset)); + OutRotationOffset = FSGQuatImpl(MoveTemp(RotationOffset)).ToFQuat(); +} + +void FSGTrackingImpl::GetNova2GloveTrackerOffset(const ESGPositionalTrackingHardware Hardware, const bool bRightHanded, + const FString& HardwareVersion, + FVector& OutPositionOffset, FQuat& OutRotationOffset) +{ + FSGVect3DImpl::FVect3DType PositionOffset; + FSGQuatImpl::FQuatType RotationOffset; + + FTrackingType::GetNova2GloveTrackerOffset(FSGCoreEnumCast::ToEPositionalTrackingHardware(Hardware), bRightHanded, + TCHAR_TO_UTF8(*HardwareVersion), + PositionOffset, RotationOffset); + + OutPositionOffset = FSGUnits::MillimetersToCentimeters( + MoveTemp(PositionOffset)); + OutRotationOffset = FSGQuatImpl(MoveTemp(RotationOffset)).ToFQuat(); +} + +FString FSGTrackingImpl::ToString(const ESGPositionalTrackingHardware Hardware) +{ + FString String(UTF8_TO_TCHAR( + FTrackingType::ToString(FSGCoreEnumCast::ToEPositionalTrackingHardware(Hardware)).c_str())); + return String; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGVect3DImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGVect3DImpl.cpp new file mode 100644 index 0000000..d570083 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGVect3DImpl.cpp @@ -0,0 +1,249 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreImpl/SGVect3DImpl.h" + +#include "Containers/StringConv.h" + +#include "SGBuildHacks/SGInclude_Core_Vect3D.h" + +struct FSGVect3DImpl::FImpl +{ + /************************ + * Member variables + ************************/ + + FVect3DType Vect3D; + + /************************ + * Owner object + ************************/ + + FSGVect3DImpl* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGVect3DImpl* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +const FSGVect3DImpl& FSGVect3DImpl::Zero() +{ + static const FSGVect3DImpl Z(FVect3DType::Zero()); + return Z; +} + +bool FSGVect3DImpl::Deserialize(const FString& String, FSGVect3DImpl& OutResult, const ANSICHAR Delimiter) +{ + FVect3DType Vect3D; + const bool bReturn = FVect3DType::Deserialize(TCHAR_TO_UTF8(*String), Vect3D, Delimiter); + OutResult = FSGVect3DImpl(Vect3D); + return bReturn; +} + +FSGVect3DImpl::FSGVect3DImpl() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGVect3DImpl::FSGVect3DImpl(const float X, const float Y, const float Z) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->Vect3D = FVect3DType(X, Y, Z); +} + +FSGVect3DImpl::FSGVect3DImpl(const FVect3DType& Vect3D) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->Vect3D = Vect3D; +} + +FSGVect3DImpl::FSGVect3DImpl(const FVector& Vector) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + /// NOTE + /// Unreal Engine uses a left-handed, z-up world coordinate system, which yealds clockwise rotations: + /// Forward X + /// Right Y + /// Up Z + /// SenseGlove uses a right-handed, z-up corrdinate systenm, which yealds counter-clockwise rotations: + /// Forward X + /// Left Y + /// Up Z + + FVect3DType Vect3D(Vector.X, -Vector.Y, Vector.Z); + Pimpl->Vect3D = MoveTemp(Vect3D); +} + +FSGVect3DImpl::FSGVect3DImpl(const FSGVect3DImpl& Rhs) + : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSGVect3DImpl::FSGVect3DImpl(FSGVect3DImpl&& Rhs) SG_NOEXCEPT = default; + +FSGVect3DImpl::~FSGVect3DImpl() = default; + +FSGVect3DImpl& FSGVect3DImpl::operator=(const FSGVect3DImpl& Rhs) +{ + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSGVect3DImpl& FSGVect3DImpl::operator=(FSGVect3DImpl&& Rhs) SG_NOEXCEPT = default; + +const FSGVect3DImpl::FVect3DType& FSGVect3DImpl::ToVect3D() const +{ + return Pimpl->Vect3D; +} + +FVector FSGVect3DImpl::ToFVector() const +{ + /// NOTE + /// Unreal Engine uses a left-handed, z-up world coordinate system, which yealds clockwise rotations: + /// Forward X + /// Right Y + /// Up Z + /// SenseGlove uses a right-handed, z-up corrdinate systenm, which yealds counter-clockwise rotations: + /// Forward X + /// Left Y + /// Up Z + + FVector Vector(Pimpl->Vect3D.GetX(), -Pimpl->Vect3D.GetY(), Pimpl->Vect3D.GetZ()); + return Vector; +} + +FSGVect3DImpl FSGVect3DImpl::operator+(const FSGVect3DImpl& Vect3DImpl) const +{ + return FSGVect3DImpl(Pimpl->Vect3D.operator+(Vect3DImpl.ToVect3D())); +} + +FSGVect3DImpl FSGVect3DImpl::operator-(const FSGVect3DImpl& Vect3DImpl) const +{ + return FSGVect3DImpl(Pimpl->Vect3D.operator-(Vect3DImpl.ToVect3D())); +} + +FSGVect3DImpl FSGVect3DImpl::operator*(const float& ScaleFactor) const +{ + return FSGVect3DImpl(Pimpl->Vect3D.operator*(ScaleFactor)); +} + +float FSGVect3DImpl::GetX() const +{ + return Pimpl->Vect3D.GetX(); +} + +void FSGVect3DImpl::SetX(const float X) +{ + Pimpl->Vect3D.SetX(X); +} + +float FSGVect3DImpl::GetY() const +{ + return Pimpl->Vect3D.GetY(); +} + +void FSGVect3DImpl::SetY(const float Y) +{ + Pimpl->Vect3D.SetY(Y); +} + +float FSGVect3DImpl::GetZ() const +{ + return Pimpl->Vect3D.GetZ(); +} + +void FSGVect3DImpl::SetZ(const float Z) +{ + Pimpl->Vect3D.SetZ(Z); +} + +float FSGVect3DImpl::Magnitude() const +{ + return Pimpl->Vect3D.Magnitude(); +} + +void FSGVect3DImpl::Normalized() +{ + Pimpl->Vect3D.Normalized(); +} + +void FSGVect3DImpl::Scale(const float Factor) +{ + Pimpl->Vect3D.Scale(Factor); +} + +float FSGVect3DImpl::DistTo(const FSGVect3DImpl& Vect3DImpl) const +{ + return Pimpl->Vect3D.DistTo(Vect3DImpl.ToVect3D()); +} + +bool FSGVect3DImpl::Equals(const FSGVect3DImpl& Vect3DImpl) const +{ + return Pimpl->Vect3D.Equals(Vect3DImpl.ToVect3D()); +} + +FString FSGVect3DImpl::ToString() const +{ + return UTF8_TO_TCHAR(Pimpl->Vect3D.ToString().c_str()); +} + +FString FSGVect3DImpl::Serialize(const ANSICHAR Delimiter) const +{ + return UTF8_TO_TCHAR(Pimpl->Vect3D.Serialize(Delimiter).c_str()); +} + +FSGVect3DImpl::FImpl::FImpl(FSGVect3DImpl* InOwner) + : Owner(InOwner) +{ +} + +FSGVect3DImpl::FImpl::~FImpl() = default; + +void FSGVect3DImpl::FImplDeleter::operator()(const FSGVect3DImpl::FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGVect3DImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGVect3DImpl.h new file mode 100644 index 0000000..18ee73f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SGCoreImpl/SGVect3DImpl.h @@ -0,0 +1,223 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" + +namespace SGCore +{ + namespace Kinematics + { + class Vect3D; + } +} + +class SENSEGLOVECOREIMPL_API FSGVect3DImpl +{ +public: + typedef SGCore::Kinematics::Vect3D FVect3DType; + +public: + /** + * Represents a vector with coordinates (0, 0, 0). + */ + static const FSGVect3DImpl& Zero(); + + /** + * Serialize a FSGVect3DImpl into a string representation. + */ + static bool Deserialize(const FString& String, FSGVect3DImpl& OutResult, ANSICHAR Delimiter); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * Creates an empty vector (0, 0, 0) for internal use. + */ + FSGVect3DImpl(); + + /** + * Create a new instance of a 3D vector. + */ + FSGVect3DImpl(float X, float Y, float Z); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGVect3DImpl(const FVect3DType& Vect3D); + + /** + * The cast from FVector type constructor. + */ + explicit FSGVect3DImpl(const FVector& Vector); + +public: + /** + * The copy constructor. + */ + FSGVect3DImpl(const FSGVect3DImpl& Rhs); + + /** + * The move constructor. + */ + FSGVect3DImpl(FSGVect3DImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGVect3DImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGVect3DImpl& operator=(const FSGVect3DImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGVect3DImpl& operator=(FSGVect3DImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FVect3DType& ToVect3D() const; + + /** + * The cast to FVector type method. + */ + FVector ToFVector() const; + +public: + /** + * Overload + operator to add two SGVect3Impl objects. + */ + FSGVect3DImpl operator+(const FSGVect3DImpl& Vect3DImpl) const; + + /** + * Overload - operator to subtract two SGVect3Impl objects. + */ + FSGVect3DImpl operator-(const FSGVect3DImpl& Vect3DImpl) const; + + /** + * Overload - operator to scale a vector3 by a float. + */ + FSGVect3DImpl operator*(const float& ScaleFactor) const; + +public: + /** + * Get the x-component of the 3D vector in cm. + */ + float GetX() const; + + /** + * Set the x-component of the 3D vector in cm. + */ + void SetX(float X); + + /** + * Get the y-component of the 3D vector in cm. + */ + float GetY() const; + + /** + * Set the y-component of the 3D vector in cm. + */ + void SetY(float Y); + + /** + * Get the z-component of the 3D vector in cm. + */ + float GetZ() const; + + /** + * Set the z-component of the 3D vector in cm. + */ + void SetZ(float Z); + +public: + /** + * Calculate the magnitude or 'length' of this Vector in cm. + */ + float Magnitude() const; + + /** + * Returns this vector normalized to have a Magnitude on 1. + */ + void Normalized(); + + /** + * Scale all elements of this vector by a certain factor. + */ + void Scale(float Factor); + + /** + * Calculate the distance between this Vector and another one in cm. + */ + float DistTo(const FSGVect3DImpl& Vect3DImpl) const; + + /** + * Check if this Vector is roughly equal to another. + */ + bool Equals(const FSGVect3DImpl& Vect3DImpl) const; + + /** + * Create a string representation of this Vector. + */ + FString ToString() const; + +public: + /** + * Convert a serialized FSGVect3DImpl back into its class representation. + */ + FString Serialize(ANSICHAR Delimiter) const; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SenseGloveCoreImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SenseGloveCoreImpl.cpp new file mode 100644 index 0000000..10de9d8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SenseGloveCoreImpl.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveCoreImpl.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveCoreImplModule.h" + +IMPLEMENT_MODULE(FSenseGloveCoreImplModule, SenseGloveCoreImpl) \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SenseGloveCoreImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SenseGloveCoreImpl.h new file mode 100644 index 0000000..a30ce66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SenseGloveCoreImpl.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SenseGloveCoreImplModule.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SenseGloveCoreImplModule.cpp new file mode 100644 index 0000000..ea08923 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SenseGloveCoreImplModule.cpp @@ -0,0 +1,65 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveCoreImplModule.h" +#include "Containers/UnrealString.h" +#include "SGCoreImpl/SGLibraryImpl.h" +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveCoreImplModule" + +void FSenseGloveCoreImplModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveCoreImpl module..."); + SGLOG(FString::Printf(TEXT("The low-level implementation of '%s' has been loaded successfully!"), *FSGLibraryImpl:: + Version())); +} + +void FSenseGloveCoreImplModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveCoreImpl module..."); +} + +void FSenseGloveCoreImplModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveCoreImpl module has succeeded!"); +} + +void FSenseGloveCoreImplModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveCoreImpl module..."); +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SenseGloveCoreImplModule.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SenseGloveCoreImplModule.h new file mode 100644 index 0000000..471cb7f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Private/SenseGloveCoreImplModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveCoreImpl" + +class FSenseGloveCoreImplModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGAnatomyImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGAnatomyImpl.h new file mode 100644 index 0000000..10f8e51 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGAnatomyImpl.h @@ -0,0 +1,85 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" + +namespace SGCore +{ + namespace Kinematics + { + class Anatomy; + } +} + +class SENSEGLOVECOREIMPL_API FSGAnatomyImpl final +{ +public: + typedef SGCore::Kinematics::Anatomy FAnatomyType; + +public: + static float GetTotalFingerFlexion(); + + static float GetTotalFingerExtension(); + + static float GetTotalThumbFlexion(); + + static float GetTotalThumbExtension(); + +public: + static float GetFingerJointLimit(bool bRightHanded, int32 Joint, int32 Movement, bool bMax); + + static float GetThumbJointLimit(bool bRightHanded, int32 Joint, int32 Movement, bool bMax); + + static float ClampJointAngle(float Value, int32 Finger, bool bRightHand, int32 Joint, int32 Movement); + + static float NormalizeFingerFlexion(float FlexionInDegrees); + + static float NormalizeThumbFlexion(float FlexionInDegrees); + +public: + static TArray> GetDefaultHandAngles(bool bRightHanded); + + static TArray> GetFlatHandAngles(bool bRightHanded); + + static TArray> GetThumbsUpHandAngles(bool bRightHanded); + + static TArray> GetFistHandAngles(bool bRightHanded); + +public: + FSGAnatomyImpl() = delete; + virtual ~FSGAnatomyImpl() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGBasicHandModelImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGBasicHandModelImpl.h new file mode 100644 index 0000000..2f748de --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGBasicHandModelImpl.h @@ -0,0 +1,178 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" +#include "SGTypes/SGCoreTypes.h" + +namespace SGCore +{ + namespace Kinematics + { + class BasicHandModel; + } +} + +class SENSEGLOVECOREIMPL_API FSGBasicHandModelImpl final +{ +public: + typedef SGCore::Kinematics::BasicHandModel FBasicHandModelType; + +public: + static FSGBasicHandModelImpl Default(bool bRightHanded); + + static FSGBasicHandModelImpl Deserialize(const FString& SerializedString); + +public: + static const TArray>& GetBaseFingerLengths(); + + static const TArray& GetBaseJointPositions(); + + static const TArray& GetBaseJointAngles(); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGBasicHandModelImpl(); + + FSGBasicHandModelImpl(bool bRightHanded, const TArray>& Lengths, + const TArray& StartPositions); + + FSGBasicHandModelImpl(bool bRightHanded, const TArray>& Lengths, + const TArray& StartPositions, const TArray& StartRotations); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGBasicHandModelImpl(const FBasicHandModelType& BasicHandModel); + +public: + /** + * The copy constructor. + */ + FSGBasicHandModelImpl(const FSGBasicHandModelImpl& Rhs); + + /** + * The move constructor. + */ + FSGBasicHandModelImpl(FSGBasicHandModelImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGBasicHandModelImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGBasicHandModelImpl& operator=(const FSGBasicHandModelImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGBasicHandModelImpl& operator=(FSGBasicHandModelImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FBasicHandModelType& ToBasicHandModel() const; + +public: + bool IsRight() const; + +public: + TArray> GetFingerLengths() const; + + TArray GetFingerLengths(ESGFinger Finger) const; + + void SetFingerLengths(ESGFinger Finger, const TArray& Lengths); + void SetFingerLengths(uint8 Finger, const TArray& Lengths); + + TArray> GetFingerRatios() const; + +public: + TArray GetFingerRatios(ESGFinger Finger) const; + + TArray GetStartJointPositions() const; + + void SetStartJointPosition(ESGFinger Finger, const FVector& Position); + void SetStartJointPosition(uint8 Finger, const FVector& Position); + + TArray GetStartJointRotations() const; + + FVector GetJointPosition(ESGFinger Finger) const; + + void SetJointPosition(const FVector& NewPosition, ESGFinger Finger); + + FQuat GetJointRotation(ESGFinger Finger) const; + + void SetJointRotation(const FQuat& NewRotation, ESGFinger Finger); + + TArray GetTotalLengths() const; + + float GetTotalLength(ESGFinger Finger) const; + +public: + TArray Get3DLengths(ESGFinger Finger) const; + +public: + bool Equals(const FSGBasicHandModelImpl& BasicHandModelImpl) const; + +public: + FString ToString() const; + + FString ToString(bool bLengthsOnly) const; + + FString Serialize() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGBetaDeviceImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGBetaDeviceImpl.h new file mode 100644 index 0000000..e46092f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGBetaDeviceImpl.h @@ -0,0 +1,167 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include +#include + +#include "Containers/UnrealString.h" +#include "Runtime/Launch/Resources/Version.h" +#include "Templates/SharedPointer.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" +#include "SGCoreImpl/SGDeviceImpl.h" +#include "SGTypes/SGCoreTypes.h" + +namespace SGCore +{ + class BetaDevice; +} + +class SENSEGLOVECOREIMPL_API FSGBetaDeviceImpl final : public FSGDeviceImpl +{ +#if ENGINE_MAJOR_VERSION >= 5 + friend class SharedPointerInternals::TIntrusiveReferenceController; +#else + friend class SharedPointerInternals::TIntrusiveReferenceController; +#endif /* ENGINE_MAJOR_VERSION >= 5 */ + +public: + typedef SGCore::BetaDevice FBetaDeviceType; + + typedef std::shared_ptr FBetaDevicePtrType; + typedef std::vector FBetaDevicePtrVectorType; + +public: + static TSharedRef Parse(const FString& String); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGBetaDeviceImpl(); + + FSGBetaDeviceImpl(const FString& ConstantsString, const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGBetaDeviceImpl(const FBetaDeviceType BetaDevice); + + /** + * The cast from underlying pointer type constructor. + */ + explicit FSGBetaDeviceImpl(const FBetaDevicePtrType BetaDevice); + +public: + /** + * The copy constructor. + */ + FSGBetaDeviceImpl(const FSGBetaDeviceImpl& Rhs); + + /** + * The move constructor. + */ + FSGBetaDeviceImpl(FSGBetaDeviceImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGBetaDeviceImpl() override; + +public: + /** + * The copy assignment operator. + */ + FSGBetaDeviceImpl& operator=(const FSGBetaDeviceImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGBetaDeviceImpl& operator=(FSGBetaDeviceImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + FBetaDeviceType ToBetaDevice() const; + + /** + * The cast to underlying pointer type method. + */ + FBetaDevicePtrType ToBetaDevicePtr() const; + + /** + * The checked cast to underlying pointer type method. + */ + FBetaDevicePtrType ToBetaDevicePtrChecked() const; + +public: + virtual ESGDeviceType GetDeviceType() const override; + + virtual FString GetDeviceId() const override; + + virtual FString GetHardwareVersion() const override; + + virtual int32 GetFirmwareVersion() const override; + + virtual int32 GetSubFirmwareVersion() const override; + +public: + FString GetConstantsString() const; + + FString GetSensorData() const; + + FString GetLastCommand() const; + +public: + bool SendHaptics(const FString& Command, int32 Channel = 0) const; + +public: + virtual FString ToString() const override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGCustomWaveformImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGCustomWaveformImpl.h new file mode 100644 index 0000000..3124a4d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGCustomWaveformImpl.h @@ -0,0 +1,164 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" + +#include "SGBuildHacks/SGPlatform.h" +#include "SGTypes/SGCoreTypes.h" + +namespace SGCore +{ + class CustomWaveform; +} + +class SENSEGLOVECOREIMPL_API FSGCustomWaveformImpl final +{ +public: + typedef SGCore::CustomWaveform FCustomWaveformType; + +public: + static FString ToString(ESGWaveformType Type); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGCustomWaveformImpl(); + + FSGCustomWaveformImpl(float Amplitude, float Duration); + + FSGCustomWaveformImpl(float Amplitude, float Duration, float Frequency); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGCustomWaveformImpl(const FCustomWaveformType& CustomWaveform); + +public: + /** + * The copy constructor. + */ + FSGCustomWaveformImpl(const FSGCustomWaveformImpl& Rhs); + + /** + * The move constructor. + */ + FSGCustomWaveformImpl(FSGCustomWaveformImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGCustomWaveformImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGCustomWaveformImpl& operator=(const FSGCustomWaveformImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGCustomWaveformImpl& operator=(FSGCustomWaveformImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FCustomWaveformType& ToCustomWaveform() const; + + /** + * The cast to underlying type method. + */ + FCustomWaveformType& ToCustomWaveform(); + +public: + float GetAmplitude() const; + void SetAmplitude(float Amplitude); + + ESGWaveformType GetWaveType() const; + void SetWaveType(ESGWaveformType Type); + + bool IsInfinite() const; + void SetInfinite(bool bInfinite); + + int32 GetRepeatAmount() const; + void SetRepeatAmount(int32 Amount); + + float GetAttackTime() const; + void SetAttackTime(float Time); + + float GetSustainTime() const; + void SetSustainTime(float Time); + + float GetDecayTime() const; + void SetDecayTime(float Time); + + float GetFrequencyStart() const; + void SetFrequencyStart(float Frequency); + + float GetFrequencyEnd() const; + void SetFrequencyEnd(float Frequency); + + float GetFrequencySwitchTime() const; + void SetFrequencySwitchTime(float Time); + + float GetFrequencySwitchFactor() const; + void SetFrequencySwitchFactor(float Factor); + +public: + float GetEffectTime() const; + float GetTotalEffectTime() const; + + bool FrequencyJumps() const; + +public: + bool Equals(const FSGCustomWaveformImpl& CustomWaveformImpl) const; + +public: + FString ToString() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGDeviceImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGDeviceImpl.h new file mode 100644 index 0000000..5094b65 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGDeviceImpl.h @@ -0,0 +1,221 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + +#pragma once + +#include +#include + +#include "Containers/UnrealString.h" +#include "Templates/SharedPointer.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" +#include "SGTypes/SGCoreTypes.h" + +namespace SGCore +{ + class SGDevice; +} + +class FSGBetaDeviceImpl; +class FSGHapticChannelInfoImpl; +class FSGHapticGloveImpl; +class FSGNova2GloveImpl; +class FSGNovaGloveImpl; +class FSGSenseGloveImpl; + +class SENSEGLOVECOREIMPL_API FSGDeviceImpl : public TSharedFromThis +{ +public: + typedef SGCore::SGDevice FSGDeviceType; + + typedef std::shared_ptr FSGDevicePtrType; + typedef std::vector FSGDevicePtrVectorType; + +public: + static void ParseFirmware(const FString& RawFirmware, int32& OutMainVersion, int32& OutSubVersion); + + static bool FirmwareNewerThan(int32 MyFirmwareMain, int32 MyFirmwareSub, + int32 ReferenceMain, int32 ReferenceSub, + bool bInclusive); + static bool FirmwareOlderThan(int32 MyFirmwareMain, int32 MyFirmwareSub, + int32 ReferenceMain, int32 ReferenceSub, + bool bInclusive); + + static FString ToString(ESGDeviceType DeviceType); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGDeviceImpl(); + +public: + /** + * The cast from underlying pointer type constructor. + */ + explicit FSGDeviceImpl(const FSGDevicePtrType SGDevice); + +public: + /** + * The copy constructor. + */ + FSGDeviceImpl(const FSGDeviceImpl& Rhs); + + /** + * The move constructor. + */ + FSGDeviceImpl(FSGDeviceImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGDeviceImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGDeviceImpl& operator=(const FSGDeviceImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGDeviceImpl& operator=(FSGDeviceImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying pointer type method. + */ + FSGDevicePtrType ToSGDevicePtr() const; + + /** + * The checked cast to underlying pointer type method. + */ + FSGDevicePtrType ToSGDevicePtrChecked() const; + +public: + /** + * The cast to base TSharedRef type method. + */ + TSharedRef ToSGDeviceImplRef(); + + /** + * The cast to derived TSharedRef type method. + */ + TSharedRef ToBetaDeviceImplRef(); + + /** + * The cast to derived TSharedRef type method. + */ + TSharedRef ToHapticGloveImplRef(); + + /** + * The cast to derived TSharedRef type method. + */ + TSharedRef ToNova2GloveImplRef(); + + /** + * The cast to derived TSharedRef type method. + */ + TSharedRef ToNovaGloveImplRef(); + + /** + * The cast to derived TSharedRef type method. + */ + TSharedRef ToSenseGloveImplRef(); + +public: + bool IsABetaDevice() const; + bool IsAHapticGlove() const; + bool IsANova2Glove() const; + bool IsANovaGlove() const; + bool IsASenseGlove() const; + +public: + TSharedPtr AsBetaDevice() const; + TSharedPtr AsHapticGlove() const; + TSharedPtr AsNova2Glove() const; + TSharedPtr AsNovaGlove() const; + TSharedPtr AsSenseGlove() const; + +public: + virtual ESGDeviceType GetDeviceType() const; + + virtual FString GetDeviceId() const; + + virtual FString GetHardwareVersion() const; + virtual int32 GetFirmwareVersion() const; + virtual int32 GetSubFirmwareVersion() const; + virtual FString GetFirmwareString() const; + + bool FirmwareNewerThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const; + bool FirmwareOlderThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const; + + FString GetAddress() const; + + bool IsConnected() const; + ESGConnectionType GetConnectionType() const; + + int32 PacketsPerSecondReceived() const; + int32 PacketsPerSecondSent() const; + + int32 GetDeviceIndex() const; + virtual void SetDeviceIndex(int32 NewIndex); + + virtual bool IsWireless() const; + + virtual bool HasBattery() const; + virtual bool IsCharging(); + virtual bool GetBatteryLevel(float& OutLevel); + +public: + virtual void SetHapticChannels(const FSGHapticChannelInfoImpl& Channels); + + int32 GetHapticChannelCount() const; + int32 GetHapticChannelCount(ESGHapticChannelType ChannelType) const; + +public: + virtual FString ToString() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGDeviceListImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGDeviceListImpl.h new file mode 100644 index 0000000..c0e5ebd --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGDeviceListImpl.h @@ -0,0 +1,103 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" + +#include "SGCoreImpl/SGDeviceImpl.h" +#include "SGTypes/SGCoreTypes.h" + +namespace SGCore +{ + class DeviceList; +} + +class SENSEGLOVECOREIMPL_API FSGDeviceListImpl final +{ +public: + typedef SGCore::DeviceList FDeviceListType; + +public: + static int32 ActiveDevices(); + + static bool SenseCommRunning(); + + static void Dispose(); + + static void Reinitialize(); + + static TArray> GetDevices(); + + template + static TArray> GetDevices() + { + const std::type_info& TType = typeid(T); + const TArray> CurrentDevices = GetDevices(); + TArray> Devices; + + for (TSharedRef Device : CurrentDevices) + { + auto &d = Device.Get(); + const std::type_info& DType = typeid(d); + if (DType.hash_code() == TType.hash_code()) + { + Devices.Push(Device); + } + } + + return Devices; + } + + static bool GetSensorDataString(int32 IpcIndex, const FString& IpcAddress, FString& OutString); + + static bool SendHaptics(int32 IpcIndex, const FString& IpcAddress, int32 ChannelIndex, const FString& Commands); + + static FString GetDeviceStringAt(int32 IpcIndex, const FString& IpcAddress, int32 Index); + + static FString GetAddress(int32 IpcIndex, const FString& IpcAddress); + + static ESGConnectionType GetConnectionType(int32 IpcIndex, const FString& IpcAddress); + + static bool IsConnected(int32 IpcIndex, const FString& IpcAddress); + + static int32 PacketsPerSecondReceived(int32 IpcIndex, const FString& IpcAddress); + + static int32 PacketsPerSecondSent(int32 IpcIndex, const FString& IpcAddress); + +public: + FSGDeviceListImpl() = delete; + virtual ~FSGDeviceListImpl() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGDeviceModelImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGDeviceModelImpl.h new file mode 100644 index 0000000..5e18cb8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGDeviceModelImpl.h @@ -0,0 +1,127 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" + +namespace SGCore +{ + class DeviceModel; +} + +class SENSEGLOVECOREIMPL_API FSGDeviceModelImpl final +{ +public: + typedef SGCore::DeviceModel FDeviceModelType; + +public: + static TArray ParseFunctions(int32 Value, int32 Size); + + static void ParseFirmware(const FString& RawFirmware, int32& OutMainVersion, int32& OutSubVersion); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGDeviceModelImpl(); + + FSGDeviceModelImpl(const FString& Id, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGDeviceModelImpl(const FDeviceModelType& DeviceModel); + +public: + /** + * The copy constructor. + */ + FSGDeviceModelImpl(const FSGDeviceModelImpl& Rhs); + + /** + * The move constructor. + */ + FSGDeviceModelImpl(FSGDeviceModelImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGDeviceModelImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGDeviceModelImpl& operator=(const FSGDeviceModelImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGDeviceModelImpl& operator=(FSGDeviceModelImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FDeviceModelType& ToDeviceModel() const; + +public: + FString GetDeviceId() const; + + FString GetHardwareVersion() const; + + int32 GetFirmwareVersion() const; + + int32 GetSubFirmwareVersion() const; + +public: + bool FirmwareNewerThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const; + bool FirmwareOlderThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGExportedFunctions.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGExportedFunctions.h new file mode 100644 index 0000000..eec21d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGExportedFunctions.h @@ -0,0 +1,3151 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +/* Defines a C++ like static_assert. */ +#if ! __cplusplus +#include +#endif /* ! __cplusplus */ + +/* Contains __bool_true_false_are_defined macro that can be used in order to + check whether boolean type is supported by the compiler or not. */ +#include + +#include "CoreTypes.h" + +/* Check at compile time whether the C compiler has support for bool, true, + and false macros. */ +static_assert(__bool_true_false_are_defined, "Error: bool, true, and false are not defined!"); + +#if defined ( SENSEGLOVE_BUILDING_CORE_IMPL_MODULE ) +#define SENSEGLOVECOREIMPL_PUBLIC_API DLLEXPORT +#else +#define SENSEGLOVECOREIMPL_PUBLIC_API DLLIMPORT +#endif /* defined ( SENSEGLOVE_BUILDING_CORE_IMPL_MODULE ) */ + +/* If C++ is used, switch to C mode in order to prevent the C++ name mangling of + method names. */ +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************* + * Exceptional function calls + ******************************************************************************/ + +#if PLATFORM_ANDROID +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_Android_Initialize( + void* InEnv, + void* InClass, + void* InActiveDevicesMethodID, + void* InGetDeviceStringMethodID, + void* InGetSensorStringMethodID, + void* InWriteHapticsMethodID, + void* StoragePath); +#endif /* PLATFORM_ANDROID */ + +/******************************************************************************* + * SGAnatomyImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGAnatomyImpl_GetTotalFingerFlexion(); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGAnatomyImpl_GetTotalFingerExtension(); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGAnatomyImpl_GetTotalThumbFlexion(); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGAnatomyImpl_GetTotalThumbExtension(); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGAnatomyImpl_GetFingerJointLimit( + bool bRightHanded, + int32 Joint, + int32 Movement, + bool bMax); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGAnatomyImpl_GetThumbJointLimit( + bool bRightHanded, + int32 Joint, + int32 Movement, + bool bMax); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGAnatomyImpl_ClampJointAngle( + float Value, + int32 Finger, + bool bRightHand, + int32 Joint, + int32 Movement); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGAnatomyImpl_NormalizeFingerFlexion( + float FlexionInDegrees); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGAnatomyImpl_NormalizeThumbFlexion( + float FlexionInDegrees); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGAnatomyImpl_GetDefaultHandAngles( + void* OutAngles, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGAnatomyImpl_GetFlatHandAngles( + void* OutAngles, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGAnatomyImpl_GetThumbsUpHandAngles( + void* OutAngles, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGAnatomyImpl_GetFistHandAngles( + void* OutAngles, + bool bRightHanded); + +/******************************************************************************* + * SGBasicHandModelImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_Default( + void* OutBasicHandModelImpl, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_Deserialize( + void* OutBasicHandModelImpl, + void* SerializedString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_GetBaseFingerLengths( + void* OutLengths); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_GetBaseJointPositions( + void* OutPositions); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_GetBaseJointAngles( + void* OutRotations); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_ctor( + void* OutBasicHandModelImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_ctor_bRightHanded_Lengths_StartPosition( + void* OutBasicHandModelImpl, + bool bRightHanded, + void* Lengths, + void* StartPositions); + +SENSEGLOVECOREIMPL_PUBLIC_API void +SGCoreImpl_FSGBasicHandModelImpl_ctor_bRightHanded_Lengths_StartPositions_StartRotations( + void* OutBasicHandModelImpl, + bool bRightHanded, + void* Lengths, + void* StartPositions, + void* StartRotations); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_ctor_copy( + void* OutBasicHandModelImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_ctor_copy_assignment( + void* OutBasicHandModelImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGBasicHandModelImpl_IsRight( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_GetFingerLengths( + void* Instance, + void* OutLengths); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_GetFingerLengths_Finger( + void* Instance, + void* OutLengths, + void* Finger); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_SetFingerLengths_ESGFinger( + void* Instance, + void* Finger, + void* Lengths); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_SetFingerLengths_uint8Finger( + void* Instance, + uint8 Finger, + void* Lengths); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_GetFingerRatios( + void* Instance, + void* OutRatios); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_GetFingerRatios_Finger( + void* Instance, + void* OutRatios, + void* Finger); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_GetStartJointPositions( + void* Instance, + void* OutPositions); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_SetStartJointPosition_ESGFinger( + void* Instance, + void* Finger, + void* Position); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_SetStartJointPosition_uin8Finger( + void* Instance, + uint8 Finger, + void* Position); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_GetStartJointRotations( + void* Instance, + void* OutRotations); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_GetJointPosition( + void* Instance, + void* OutPosition, + void* Finger); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_SetJointPosition( + void* Instance, + void* NewPosition, + void* Finger); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_GetJointRotation( + void* Instance, + void* OutRotation, + void* Finger); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_SetJointRotation( + void* Instance, + void* NewRotation, + void* Finger); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_GetTotalLengths( + void* Instance, + void* OutLengths); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGBasicHandModelImpl_GetTotalLength( + void* Instance, + void* Finger); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_Get3DLengths( + void* Instance, + void* OutLengths, + void* Finger); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGBasicHandModelImpl_Equals( + void* Instance, + void* BasicHandModelImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_ToString( + void* Instance, + void* OutString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_ToString_bLengthsOnly( + void* Instance, + void* OutString, + bool bLengthsOnly); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBasicHandModelImpl_Serialize( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGBetaDeviceImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBetaDeviceImpl_Parse( + void* OutBetaDevice, + void* String); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBetaDeviceImpl_ctor( + void* OutBetaDeviceImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void +SGCoreImpl_FSGBetaDeviceImpl_ctor_ConstantsString_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion( + void* OutBetaDeviceImpl, + void* ConstantsString, + void* DeviceId, + void* HardwareVersion, + const int32 FirmwareVersion, + const int32 SubFirmwareVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API void +SGCoreImpl_FSGBetaDeviceImpl_ctor_ConstantsString_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_MakeShared( + void* OutSharedPtr, + void* ConstantsString, + void* DeviceId, + void* HardwareVersion, + const int32 FirmwareVersion, + const int32 SubFirmwareVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBetaDeviceImpl_ctor_MakeShared( + void* OutSharedPtr); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBetaDeviceImpl_ctor_copy( + void* OutBetaDeviceImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBetaDeviceImpl_ctor_copy_MakeShared( + void* OutSharedPtr, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBetaDeviceImpl_ctor_copy_assignment( + void* OutBetaDeviceImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBetaDeviceImpl_GetDeviceType( + void* Instance, + void* OutType); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBetaDeviceImpl_GetDeviceId( + void* Instance, + void* OutId); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBetaDeviceImpl_GetHardwareVersion( + void* Instance, + void* OutVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGBetaDeviceImpl_GetFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGBetaDeviceImpl_GetSubFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBetaDeviceImpl_GetConstantsString( + void* Instance, + void* OutString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBetaDeviceImpl_GetSensorData( + void* Instance, + void* OutData); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBetaDeviceImpl_GetLastCommand( + void* Instance, + void* OutCommand); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGBetaDeviceImpl_SendHaptics( + void* Instance, + void* Command); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGBetaDeviceImpl_ToString( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGCustomWaveformImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_ToString_Type( + void* OutString, + void* Type); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_ctor( + void* OutCustomWaveformImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_ctor_Amplitude_Duration( + void* OutCustomWaveformImpl, + float Amplitude, + float Duration); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_ctor_Amplitude_Duration_Frequency( + void* OutCustomWaveformImpl, + float Amplitude, + float Duration, + float Frequency); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_ctor_copy( + void* OutCustomWaveformImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_ctor_copy_assignment( + void* OutCustomWaveformImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGCustomWaveformImpl_GetAmplitude( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_SetAmplitude( + void* Instance, + float Amplitude); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_GetWaveType( + void* Instance, + void* OutType); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_SetWaveType( + void* Instance, + void* Type); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGCustomWaveformImpl_IsInfinite( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_SetInfinite( + void* Instance, + bool bInfinite); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGCustomWaveformImpl_GetRepeatAmount( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_SetRepeatAmount( + void* Instance, + int32 Amount); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGCustomWaveformImpl_GetAttackTime( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_SetAttackTime( + void* Instance, + float Time); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGCustomWaveformImpl_GetSustainTime( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_SetSustainTime( + void* Instance, + float Time); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGCustomWaveformImpl_GetDecayTime( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_SetDecayTime( + void* Instance, + float Time); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGCustomWaveformImpl_GetFrequencyStart( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_SetFrequencyStart( + void* Instance, + float Frequency); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGCustomWaveformImpl_GetFrequencyEnd( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_SetFrequencyEnd( + void* Instance, + float Frequency); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGCustomWaveformImpl_GetFrequencySwitchTime( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_SetFrequencySwitchTime( + void* Instance, + float Time); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGCustomWaveformImpl_GetFrequencySwitchFactor( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_SetFrequencySwitchFactor( + void* Instance, + float Factor); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGCustomWaveformImpl_GetEffectTime( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGCustomWaveformImpl_GetTotalEffectTime( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGCustomWaveformImpl_FrequencyJumps( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGCustomWaveformImpl_Equals( + void* Instance, + void* CustomWaveformImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGCustomWaveformImpl_ToString( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGDeviceImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_ParseFirmware( + void* RawFirmware, + int32* OutMainVersion, + int32* OutSubVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API bool +SGCoreImpl_FSGDeviceImpl_FirmwareNewerThan_MyFirmwareMain_MyFirmwareSub_ReferenceMain_ReferenceSub_bInclusive( + int32 MyFirmwareMain, + int32 MyFirmwareSub, + int32 ReferenceMain, + int32 ReferenceSub, + bool bInclusive); + +SENSEGLOVECOREIMPL_PUBLIC_API bool +SGCoreImpl_FSGDeviceImpl_FirmwareOlderThan_MyFirmwareMain_MyFirmwareSub_ReferenceMain_ReferenceSub_bInclusive( + int32 MyFirmwareMain, + int32 MyFirmwareSub, + int32 ReferenceMain, + int32 ReferenceSub, + bool bInclusive); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_ToString_DeviceType( + void* DeviceType, + void* OutString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_ctor( + void* OutSGDeviceImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_ctor_MakeShared( + void* OutSharedPtr); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_ctor_copy( + void* OutSGDeviceImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_ctor_copy_MakeShared( + void* OutSharedPtr, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_ctor_copy_assignment( + void* OutSGDeviceImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_ToSGDeviceImplRef( + void* Instance, + void* OutSharedPtr); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_ToBetaDeviceImplRef( + void* Instance, + void* OutSharedPtr); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_ToHapticGloveImplRef( + void* Instance, + void* OutSharedPtr); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_ToNova2GloveImplRef( + void* Instance, + void* OutSharedPtr); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_ToNovaGloveImplRef( + void* Instance, + void* OutSharedPtr); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_ToSenseGloveImplRef( + void* Instance, + void* OutSharedPtr); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceImpl_IsABetaDevice( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceImpl_IsAHapticGlove( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceImpl_IsANova2Glove( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceImpl_IsANovaGlove( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceImpl_IsASenseGlove( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_AsBetaDevice( + void* Instance, + void* OutSharedPtr); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_AsHapticGlove( + void* Instance, + void* OutSharedPtr); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_AsNova2Glove( + void* Instance, + void* OutSharedPtr); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_AsNovaGlove( + void* Instance, + void* OutSharedPtr); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_AsSenseGlove( + void* Instance, + void* OutSharedPtr); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_GetDeviceType( + void* Instance, + void* OutType); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_GetDeviceId( + void* Instance, + void* OutId); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_GetHardwareVersion( + void* Instance, + void* OutVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGDeviceImpl_GetFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGDeviceImpl_GetSubFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_GetFirmwareString( + void* Instance, + void* OutString); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceImpl_FirmwareNewerThan_MyFirmwareMain_MyFirmwareSub_bInclusive( + void* Instance, + int32 MyFirmwareMain, + int32 MyFirmwareSub, + bool bInclusive); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceImpl_FirmwareOlderThan_MyFirmwareMain_MyFirmwareSub_bInclusive( + void* Instance, + int32 MyFirmwareMain, + int32 MyFirmwareSub, + bool bInclusive); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_GetAddress( + void* Instance, + void* Address); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceImpl_IsConnected( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_GetConnectionType( + void* Instance, + void* OutType); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGDeviceImpl_PacketsPerSecondReceived( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGDeviceImpl_PacketsPerSecondSent( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGDeviceImpl_GetDeviceIndex( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_SetDeviceIndex( + void* Instance, + int32 NewIndex); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceImpl_IsWireless( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceImpl_HasBattery( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceImpl_IsCharging( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceImpl_GetBatteryLevel( + void* Instance, + float* OutLevel); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_SetHapticChannels( + void* Instance, + void* Channels); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGDeviceImpl_GetHapticChannelCount( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGDeviceImpl_GetHapticChannelCount_ChannelType( + void* Instance, + void* ChannelType); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceImpl_ToString( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGDeviceListImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGDeviceListImpl_ActiveDevices(); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceListImpl_SenseCommRunning(); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceListImpl_Dispose(); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceListImpl_Reinitialize(); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceListImpl_GetDevices( + void* OutDevices); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceListImpl_GetSensorDataString( + int32 IpcIndex, + void* IpcAddress, + void* OutString); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceListImpl_SendHaptics( + int32 IpcIndex, + void* IpcAddress, + int32 ChannelIndex, + void* Commands); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceListImpl_GetDeviceStringAt( + void* OutString, + int32 IpcIndex, + void* IpcAddress, + int32 Index); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceListImpl_GetAddress( + void* OutAddress, + int32 IpcIndex, + void* IpcAddress); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceListImpl_GetConnectionType( + void* OutType, + int32 IpcIndex, + void* IpcAddress); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceListImpl_IsConnected( + int32 IpcIndex, + void* IpcAddress); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGDeviceListImpl_PacketsPerSecondReceived( + int32 IpcIndex, + void* IpcAddress); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGDeviceListImpl_PacketsPerSecondSent( + int32 IpcIndex, + void* IpcAddress); + +/******************************************************************************* + * SGDeviceModelImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceModelImpl_ParseFunctions( + void* OutParseFunctions, + int32 Value, + int32 Size); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceModelImpl_ParseFirmware( + void* RawFirmware, + int32* OutMainVersion, + int32* OutSubVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceModelImpl_ctor( + void* OutDeviceModelImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void +SGCoreImpl_FSGDeviceModelImpl_ctor_Id_HardwareVersion_FirmwareVersion_SubFirmwareVersion( + void* OutDeviceModelImpl, + void* Id, + void* HardwareVersion, + int32 FirmwareVersion, + int32 SubFirmwareVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceModelImpl_ctor_copy( + void* OutDeviceModelImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceModelImpl_ctor_copy_assignment( + void* OutDeviceModelImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceModelImpl_GetDeviceId( + void* Instance, + void* OutId); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGDeviceModelImpl_GetHardwareVersion( + void* Instance, + void* OutVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGDeviceModelImpl_GetFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGDeviceModelImpl_GetSubFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceModelImpl_FirmwareNewerThan( + void* Instance, + int32 FirmwareMain, + int32 FirmwareSub, + bool bInclusive); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGDeviceModelImpl_FirmwareOlderThan( + void* Instance, + int32 FirmwareMain, + int32 FirmwareSub, + bool bInclusive); + +/******************************************************************************* + * SGHandInterpolatorImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandInterpolatorImpl_Deserialize( + void* OutHandInterpolatorImpl, + void* SerializedString, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandInterpolatorImpl_ctor( + void* OutHandInterpolatorImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandInterpolatorImpl_ctor_bRightHanded( + void* OutHandInterpolatorImpl, + const bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandInterpolatorImpl_ctor_copy( + void* OutHandInterpolatorImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandInterpolatorImpl_ctor_copy_assignment( + void* OutHandInterpolatorImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API float +SGCoreImpl_FSGHandInterpolatorImpl_CalculateAngle_ESGFingerMovement_Value_bApplyLimits( + void* Instance, + void* Movement, + float Value, + bool bApplyLimits); + +SENSEGLOVECOREIMPL_PUBLIC_API float +SGCoreImpl_FSGHandInterpolatorImpl_CalculateAngle_ESGThumbMovement_Value_bApplyLimits( + void* Instance, + void* Movement, + float Value, + bool bApplyLimits); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandInterpolatorImpl_InterpolateHandAngles( + void* Instance, + void* OutAngles, + void* Flexions, + void* Abductions, + float CmcTwist); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandInterpolatorImpl_Equals( + void* Instance, + void* HandInterpolatorImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandInterpolatorImpl_Serialize( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGHandLayerImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandLayerImpl_DeviceConnected( + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandLayerImpl_GetDeviceType( + void* OutDeviceType, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandLayerImpl_GetFirstGloveHandedness(); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGHandLayerImpl_GlovesConnected(); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandLayerImpl_GetGloveInstance( + bool bRightHanded, + void* OutGlove); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandLayerImpl_GetCalibrationState( + void* OutHapticGloveCalibrationState, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandLayerImpl_GetCalibrationInstructions( + void* OutString, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandLayerImpl_ResetCalibration( + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandLayerImpl_EndCalibration( + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandLayerImpl_GetHandPose( + bool bRightHanded, + void* OutHandPose); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandLayerImpl_GetWristLocation( + bool bRightHanded, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutWristPosition, + void* OutWristRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandLayerImpl_StopAllHaptics( + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandLayerImpl_SendHaptics( + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandLayerImpl_SupportsCustomWaveform( + bool bRightHanded, + void* AtLocation); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandLayerImpl_SendCustomWaveform( + bool bRightHanded, + void* OutWaveform, + void* Location); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandLayerImpl_QueueCommand_ForceFeedbackLevels( + bool bRightHanded, + void* Levels01, + bool bSendImmediate); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandLayerImpl_QueueCommand_ForceFeedbackLevel( + bool bRightHanded, + int32 Finger, + float Level01, + bool bSendImmediate); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandLayerImpl_QueueCommand_VibroLevels( + bool bRightHanded, + void* Levels01, + bool bSendImmediate); + +SENSEGLOVECOREIMPL_PUBLIC_API bool + SGCoreImpl_FSGHandLayerImpl_QueueCommand_VibroLevel_bRightHanded_Finger_Level0_bSendImmediate( + bool bRightHanded, + int32 Finger, + float Level01, + bool bSendImmediate); + +SENSEGLOVECOREIMPL_PUBLIC_API bool + SGCoreImpl_FSGHandLayerImpl_QueueCommand_VibroLevel_bRightHanded_AtLocation_Level01_bSendImmediate( + bool bRightHanded, + void* AtLocation, + float Level01, + bool bSendImmediate); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandLayerImpl_SupportsWristSqueeze( + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandLayerImpl_QueueCommand_WristSqueeze( + bool bRightHanded, + float SqueezeLevel01, + bool bSendImmediate); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandLayerImpl_SupportsFlexionLocks( + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandLayerImpl_QueueCommand_FlexionLock( + bool bRightHanded, + int32 Finger, + float Flexion01, + bool bSendImmediate); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandLayerImpl_QueueCommand_ClearFlexionLock( + bool bRightHanded, + int32 Finger, + bool bSendImmediate); + +/******************************************************************************* + * SGHandPoseImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_Deserialize( + void* OutHandPoseImpl, + void* SerializedString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_FromHandAngles_HandAngles_bRightHanded_HandDimensions( + void* OutHandPoseImpl, + void* HandAngles, + bool bRightHanded, + void* HandDimensions); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_FromHandAngles_HandAngles_bRightHanded( + void* OutHandPoseImpl, + void* HandAngles, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_DefaultIdle_bRightHanded_HandDimensions( + void* OutHandPoseImpl, + bool bRightHanded, + void* HandDimensions); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_DefaultIdle_bRightHanded( + void* OutHandPoseImpl, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_FlatHand_bRightHanded_HandDimensions( + void* OutHandPoseImpl, + bool bRightHanded, + void* HandDimensions); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_FlatHand_bRightHanded( + void* OutHandPoseImpl, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_ThumbsUp_bRightHanded_HandDimensions( + void* OutHandPoseImpl, + bool bRightHanded, + void* HandDimensions); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_ThumbsUp_bRightHanded( + void* OutHandPoseImpl, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_Fist_bRightHanded_HandDimensions( + void* OutHandPoseImpl, + bool bRightHanded, + void* HandDimensions); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_Fist_bRightHanded( + void* OutHandPoseImpl, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_ctor( + void* OutHandPoseImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void +SGCoreImpl_FSGHandPoseImpl_ctor_bRightHanded_JointPositions_JointRotations_HandAngles( + void* OutHandPoseImpl, + bool bRightHanded, + void* JointPositions, + void* JointRotations, + void* HandAngles); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_ctor_copy( + void* OutHandPoseImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_ctor_copy_assignment( + void* OutHandPoseImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandPoseImpl_IsRight( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_GetJointPositions( + void* Instance, + void* OutPositions); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_GetJointRotations( + void* Instance, + void* OutRotations); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_GetHandAngles( + void* Instance, + void* OutAngles); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHandPoseImpl_Equals( + void* Instance, + void* HandPoseImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGHandPoseImpl_GetNormalizedFlexion_Finger_bClamp01( + void* Instance, + void* Finger, + bool bClamp01); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_GetNormalizedFlexion_bClamp01( + void* Instance, + void* OutFlexion, + bool bClamp01); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_ToString( + void* Instance, + void* OutString, + bool bShortFormat); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHandPoseImpl_Serialize( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGHapticChannelInfoImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticChannelInfoImpl_GenerateAddress( + void* OutString, + int32 DeviceIndex, + int32 ChannelIndex); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticChannelInfoImpl_Parse( + void* OutHapticChannelInfoImpl, + void* IpcString); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGHapticChannelInfoImpl_GetStreamingType(); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGHapticChannelInfoImpl_GetFireAndForgetType(); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticChannelInfoImpl_ctor( + void* OutHapticChannelInfoImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticChannelInfoImpl_ctor_StreamIndex_FireAndForgetIndex( + void* OutHapticChannelInfoImpl, + void* StreamIndex, + void* FireAndForgetIndex); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticChannelInfoImpl_ctor_copy( + void* OutHapticChannelInfoImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticChannelInfoImpl_ctor_copy_assignment( + void* OutHapticChannelInfoImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGHapticChannelInfoImpl_GetStreamChannelCount( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGHapticChannelInfoImpl_GetFireAndForgetChannelCount( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGHapticChannelInfoImpl_GetTotalChannelCount( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticChannelInfoImpl_GetAddress_Unguarded( + void* Instance, + void* OutString, + void* Type, + int32 TypeIndex); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticChannelInfoImpl_GetIpcParams_Unguarded( + void* Instance, + void* Type, + int32 TypeIndex, + int32* OutIndex, + void* OutAddressString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticChannelInfoImpl_RegenerateAddresses( + void* Instance, + int32 ForDeviceIndex); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticChannelInfoImpl_GetAllAddresses( + void* Instance, + void* OutArray); + +/******************************************************************************* + * SGHapticGloveImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_GetHapticGloves( + void* OutGloves, + bool bConnectedOnly); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHapticGloveImpl_GetGlove_OutGlove( + void* OutGlove); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHapticGloveImpl_GetGlove_bRightHanded_OutGlove( + bool bRightHanded, + void* OutGlove); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_ToString_State( + void* OutString, + void* State); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_ToString_Location( + void* OutString, + void* Location); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_ctor( + void* OutHapticGloveImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_ctor_MakeShared( + void* OutSharedPtr); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_ctor_copy( + void* OutHapticGloveImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_ctor_copy_MakeShared( + void* OutSharedPtr, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_ctor_copy_assignment( + void* OutHapticGloveImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_GetDeviceType( + void* Instance, + void* OutType); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_GetDeviceId( + void* Instance, + void* OutId); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_GetHardwareVersion( + void* Instance, + void* OutVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGHapticGloveImpl_GetFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGHapticGloveImpl_GetSubFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHapticGloveImpl_IsRight( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHapticGloveImpl_GetImuRotation( + void* Instance, + void* OutImu); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHapticGloveImpl_GetHandPose_HandGeometry_OutHandPose( + void* Instance, + void* HandGeometry, + void* OutHandPose); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHapticGloveImpl_GetHandPose_OutHandPose( + void* Instance, + void* OutHandPose); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHapticGloveImpl_GetHandAngles_OutHandAngles( + void* Instance, + void* OutHandAngles); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_GetHandGeometry( + void* Instance, + void* OutBasicHandModel); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_SetHandGeometry( + void* Instance, + void* HandGeometry); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_GetCalibrationState( + void* Instance, + void* OutHapticGloveCalibrationState); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_EndCalibration( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_ResetCalibration( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_GetCalibrationInstruction( + void* Instance, + void* OutString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_StopHaptics( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_StopVibrations( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHapticGloveImpl_SendHaptics( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHapticGloveImpl_SupportsCustomWaveform( + void* Instance, + void* AtLocation); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHapticGloveImpl_SendCustomWaveform( + void* Instance, + void* OutWaveform, + void* Location); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHapticGloveImpl_QueueForceFeedbackLevels( + void* Instance, + void* Levels01); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHapticGloveImpl_QueueForceFeedbackLevel( + void* Instance, + int32 Finger, + float Level01); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHapticGloveImpl_QueueVibroLevels( + void* Instance, + void* Levels01); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGHapticGloveImpl_QueueVibroLevel( + void* Instance, + void* Location, + float Level01); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_GetWristLocation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutWristPosition, + void* OutWristRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_GetGloveLocation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutGlovePosition, + void* OutGloveRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGHapticGloveImpl_ToString( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGInterpolationSetImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGInterpolationSetImpl_Deserialize( + void* OutInterpolationSetImpl, + void* SerializedString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGInterpolationSetImpl_ctor( + void* OutInterpolationSetImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGInterpolationSetImpl_ctor_From1_From2_To1_To2( + void* OutInterpolationSetImpl, + float From1, + float From2, + float To1, + float To2); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGInterpolationSetImpl_ctor_From1_From2_To1_To2_Min_Max( + void* OutInterpolationSetImpl, + float From1, + float From2, + float To1, + float To2, + float Min, + float Max); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGInterpolationSetImpl_ctor_copy( + void* OutInterpolationSetImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGInterpolationSetImpl_ctor_copy_assignment( + void* OutInterpolationSetImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGInterpolationSetImpl_GetX0( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGInterpolationSetImpl_SetX0( + void* Instance, + float X0); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGInterpolationSetImpl_GetX1( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGInterpolationSetImpl_SetX1( + void* Instance, + float X1); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGInterpolationSetImpl_GetY0( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGInterpolationSetImpl_SetY0( + void* Instance, + float Y0); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGInterpolationSetImpl_GetY1( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGInterpolationSetImpl_SetY1( + void* Instance, + float Y1); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGInterpolationSetImpl_GetMin( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGInterpolationSetImpl_SetMin( + void* Instance, + float Min); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGInterpolationSetImpl_GetMax( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGInterpolationSetImpl_SetMax( + void* Instance, + float Max); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGInterpolationSetImpl_Get( + void* Instance, + float Value, + bool bLimit, + bool bNormalizeAngle); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGInterpolationSetImpl_Equals( + void* Instance, + void* InterpolationSetImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGInterpolationSetImpl_ToString( + void* Instance, + void* OutString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGInterpolationSetImpl_ToString_bLimits( + void* Instance, + void* OutString, + bool bLimits); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGInterpolationSetImpl_Serialize( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGJointKinematicsImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API bool +SGCoreImpl_FSGJointKinematicsImpl_ForwardKinematics_StartPosition_StartRotation_JointLengths_JointAngles_OutNewPositions_OutNewRotations( + void* StartPosition, + void* StartRotation, + void* JointLengths, + void* JointAngles, + void* OutNewPositions, + void* OutNewRotations); + +SENSEGLOVECOREIMPL_PUBLIC_API bool +SGCoreImpl_FSGJointKinematicsImpl_ForwardKinematics_Profile_Finger_JointAngles_OutNewPositions_OutNewRotations( + void* Profile, + void* Finger, + void* JointAngles, + void* OutNewPositions, + void* OutNewRotations); + +/******************************************************************************* + * SGLibraryImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGLibraryImpl_Version( + void* OutVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGLibraryImpl_GetBackendType( + void* OutType); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGLibraryImpl_BackendVersion( + void* OutVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGLibraryImpl_SGConnectVersion( + void* OutVersion); + +/******************************************************************************* + * SGNova2GloveImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_Parse( + void* OutNova2GloveImpl, + void* ConstantsString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_GetNova2Gloves( + void* OutGloves); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_GetNova2Glove_OutGlove( + void* OutGlove); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_GetNova2Glove_bRightHanded_OutGlove( + bool bRightHanded, + void* OutGlove); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_CalculateGloveLocation( + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + bool bRightHanded, + void* HardwareVersion, + void* OutGlovePosition, + void* OutGloveRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_CalculateWristLocation( + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + bool bRightHanded, + void* HardwareVersion, + void* OutWristPosition, + void* OutWristRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API ANSICHAR SGCoreImpl_FSGNova2GloveImpl_GetStreamByte(); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_GetNova2SensorRanges( + void* OutNova2SensorRanges); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_ToNormalizedValues_SensorData( + void* OutNormalizedValues, + void* SensorData); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_ToNormalizedValues_SensorData_OutSensorNormalizer( + void* OutNormalizedValues, + void* SensorData, + void* OutSensorNormalizer); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_CalculateHandAngles( + void* OutHandAngles, + void* NormalizedValues, + void* Interpolator, + bool bInfluenceIndex); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_ToNormalizedAngles( + void* OutNormalizedAngles, + void* NormalizedData, + void* GloveInfo); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_ctor( + void* OutNova2GloveImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_ctor_MakeShared( + void* OutSharedPtr); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_ctor_DeviceInfo( + void* OutNova2GloveImpl, + void* DeviceInfo); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_ctor_DeviceInfo_MakeShared( + void* OutSharedPtr, + void* DeviceInfo); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_ctor_copy( + void* OutNova2GloveImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_ctor_copy_MakeShared( + void* OutSharedPtr, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_ctor_copy_assignment( + void* OutNova2GloveImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_GetDeviceType( + void* Instance, + void* OutType); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_GetDeviceId( + void* Instance, + void* OutId); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_GetHardwareVersion( + void* Instance, + void* OutVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGNova2GloveImpl_GetFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGNova2GloveImpl_GetSubFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_HasBattery( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_IsCharging( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_GetBatteryLevel( + void* Instance, + float* OutBatteryLevel); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_IsRight( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_GetImuRotation( + void* Instance, + void* OutImu); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_GetHandPose( + void* Instance, + void* HandGeometry, + void* OutHandPose); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_GetHandAngles( + void* Instance, + void* OutHandAngles); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_GetCalibrationState( + void* Instance, + void* OutHapticGloveCalibrationState); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_EndCalibration( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_ResetCalibration( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_StopHaptics( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_StopVibrations( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_SendHaptics( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_SupportsCustomWaveform( + void* Instance, + void* AtLocation); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_SendCustomWaveform( + void* Instance, + void* OutWaveform, + void* Location); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_QueueForceFeedbackLevels( + void* Instance, + void* Levels01); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_QueueForceFeedbackLevel( + void* Instance, + int32 Finger, + float Level01); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_QueueVibroLevels( + void* Instance, + void* Amplitudes); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_QueueVibroLevel( + void* Instance, + void* Location, + float Level01); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_QueueSqueezeLevel( + void* Instance, + float SqueezeLevel01); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_GetGloveLocation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutGlovePosition, + void* OutGloveRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_GetWristLocation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutWristPosition, + void* OutWristRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_GetGloveInfo( + void* Instance, + void* OutGloveInfo); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_DoesIndexInfluenceOthers( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_SetIndexInfluencesOthers( + void* Instance, + bool bInfluenceOthers); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_SupportsOnBoardNormalization( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_GetSensorData( + void* Instance, + void* OutSensorData); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_GetNormalizedInput( + void* Instance, + void* OutNormalizedValues); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_SendRawData( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_SendNormalizedData( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_ToNovaMotor( + void* Instance, + void* OutNova2Motor, + void* Location); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGNova2GloveImpl_ChannelIndex( + void* Instance, + void* Motor); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_ValidateWaveform( + void* Instance, + void* OutWaveform, + void* Motor); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveImpl_SendCustomWaveform_Nova2( + void* Instance, + void* OutWaveform, + void* Motor, + bool bValidateWaveform); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveImpl_ToString( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGNova2GloveSensorDataImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveSensorDataImpl_Parse( + void* OutNova2GloveSensorDataImpl, + void* RawData, + void* GloveInfo); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor( + void* OutNova2GloveSensorDataImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void +SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor_NormalizationState_Values_ParsedValues_ImuRotation_bImuParsed_BatteryLevel_bCharging( + void* OutNova2GloveSensorDataImpl, + void* NormalizationState, + void* Values, + const int32 ParsedValues, + void* ImuRotation, + const bool bImuParsed, + const float BatteryLevel, + const bool bCharging); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor_copy( + void* OutNova2GloveSensorDataImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveSensorDataImpl_ctor_copy_assignment( + void* OutNova2GloveSensorDataImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveSensorDataImpl_GetSensorState( + void* Instance, + void* OutNormalizationState); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveSensorDataImpl_GetSensorValues( + void* Instance, + void* OutValues); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGNova2GloveSensorDataImpl_GetSensorValue( + void* Instance, + void* Finger, + void* Location); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGNova2GloveSensorDataImpl_GetParsedValues( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveSensorDataImpl_GetImuRotation( + void* Instance, + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveSensorDataImpl_IsImuParsed( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGNova2GloveSensorDataImpl_GetBatteryLevel( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveSensorDataImpl_IsCharging( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNova2GloveSensorDataImpl_Equals( + void* Instance, + void* Nova2GloveSensorDataImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNova2GloveSensorDataImpl_ToString( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGNovaGloveImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_Parse( + void* OutNovaGloveImpl, + void* ConstantsString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_GetNovaGloves( + void* OutGloves); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_GetNovaGlove_OutGlove( + void* OutGlove); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_GetNovaGlove_bRightHanded_OutGlove( + bool bRightHanded, + void* OutGlove); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_CalculateGloveLocation( + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + bool bRightHanded, + void* OutGlovePosition, + void* OutGloveRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_CalculateWristLocation( + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + bool bRightHanded, + void* OutWristPosition, + void* OutWristRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API ANSICHAR SGCoreImpl_FSGNovaGloveImpl_GetHapticsByte(); + +SENSEGLOVECOREIMPL_PUBLIC_API ANSICHAR SGCoreImpl_FSGNovaGloveImpl_GetThresholdsByte(); + +SENSEGLOVECOREIMPL_PUBLIC_API ANSICHAR SGCoreImpl_FSGNovaGloveImpl_GetIgnoreThresholdsByte(); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_GetNovaSensorRanges( + void* OutNovaSensorRanges); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_ToNormalizedValues_SensorData( + void* OutNormalizedValues, + void* SensorData); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_ToNormalizedValues_SensorData_OutSensorNormalizer( + void* OutNormalizedValues, + void* SensorData, + void* OutSensorNormalizer); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_CalculateHandAngles( + void* OutHandAngles, + void* NormalizedValues, + void* Interpolator); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_ToNovaCommandAsFlexion( + void* OutString, + void* Thresholds); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_ToNovaCommandAsRaw( + void* OutString, + void* Thresholds, + void* Interpolator); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_ctor( + void* OutNovaGloveImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_ctor_MakeShared( + void* OutSharedPtr); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_ctor_DeviceInfo( + void* OutNovaGloveImpl, + void* DeviceInfo); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_ctor_DeviceInfo_MakeShared( + void* OutSharedPtr, + void* DeviceInfo); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_ctor_copy( + void* OutNovaGloveImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_ctor_copy_MakeShared( + void* OutSharedPtr, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_ctor_copy_assignment( + void* OutNovaGloveImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_GetDeviceType( + void* Instance, + void* OutType); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_GetDeviceId( + void* Instance, + void* OutId); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_GetHardwareVersion( + void* Instance, + void* OutVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGNovaGloveImpl_GetFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGNovaGloveImpl_GetSubFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_SetDeviceIndex( + void* Instance, + int32 Index); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_HasBattery( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_IsCharging( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_GetBatteryLevel( + void* Instance, + float* OutBatteryLevel); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_IsRight( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_GetImuRotation( + void* Instance, + void* OutImu); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_GetHandPose( + void* Instance, + void* HandGeometry, + void* OutHandPose); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_GetHandAngles( + void* Instance, + void* OutHandAngles); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_GetCalibrationState( + void* Instance, + void* OutHapticGloveCalibrationState); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_EndCalibration( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_ResetCalibration( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_StopHaptics( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_StopVibrations( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_SendHaptics( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_SupportsCustomWaveform( + void* Instance, + void* AtLocation); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_SendCustomWaveform( + void* Instance, + void* OutWaveform, + void* Location); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_QueueForceFeedbackLevels( + void* Instance, + void* Levels01); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_QueueForceFeedbackLevel( + void* Instance, + int32 Finger, + float Level01); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_QueueVibroLevels( + void* Instance, + void* Amplitudes); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_QueueVibroLevel_Localtion_Level01( + void* Instance, + void* Location, + float Level01); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_GetGloveLocation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutGlovePosition, + void* OutGloveRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_GetWristLocation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutWristPosition, + void* OutWristRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_GetGloveInfo( + void* Instance, + void* OutGloveInfo); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_SupportsThresholds( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_SupportsCustomWaveforms( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_SupportsOnBoardNormalization( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_GetSensorData( + void* Instance, + void* OutSensorData); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_GetNormalizedInput( + void* Instance, + void* OutNormalizedValues); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_ToNovaCommand( + void* Instance, + void* OutString, + void* ForceFeedbackLevels, + void* BuzzLevels, + float WristLevel); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_QueueVibroLevel_Finger_Amplitude( + void* Instance, + int32 Finger, + float Amplitude); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_QueueWristLevel( + void* Instance, + float Amplitude); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_ToNovaMotor( + void* Instance, + void* OutNovaMotor, + void* Location); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGNovaGloveImpl_ChannelIndex( + void* Instance, + void* Motor); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_ValidateWaveform( + void* Instance, + void* OutWaveform, + void* Motor); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_SendCustomWaveform_Nova( + void* Instance, + void* OutWaveform, + void* Motor, + bool bValidateWaveform); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_QueueThresholdCommand_Flexion( + void* Instance, + int32 Finger, + float FlexionThreshold); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveImpl_QueueClearThreshold( + void* Instance, + int32 Finger); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveImpl_ToString( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGNovaGloveInfoImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveInfoImpl_Parse( + void* ConstantsString, + void* OutGloveInfo); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveInfoImpl_Deserialize( + void* OutNovaGloveInfoImpl, + void* SerializedString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveInfoImpl_ctor( + void* OutNovaGloveInfoImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void +SGCoreImpl_FSGNovaGloveInfoImpl_ctor_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded_ImuCorrection_NumberOfSensors( + void* OutNovaGloveInfoImpl, + void* DeviceId, + void* HardwareVersion, + int32 FirmwareVersion, + int32 SubFirmwareVersion, + bool bRightHanded, + void* ImuCorrection, + int32 NumberOfSensors); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveInfoImpl_ctor_copy( + void* OutNovaGloveInfoImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveInfoImpl_ctor_copy_assignment( + void* OutNovaGloveInfoImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveInfoImpl_GetDeviceId( + void* Instance, + void* OutId); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveInfoImpl_GetHardwareVersion( + void* Instance, + void* OutVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGNovaGloveInfoImpl_GetFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGNovaGloveInfoImpl_GetSubFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveInfoImpl_IsRight( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveInfoImpl_GetImuCorrection( + void* Instance, + void* OutCorrection); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGNovaGloveInfoImpl_GetNumberOfSensors( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveInfoImpl_FirmwareNewerThan( + void* Instance, + int32 FirmwareMain, + int32 FirmwareSub, + bool bInclusive); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveInfoImpl_FirmwareOlderThan( + void* Instance, + int32 FirmwareMain, + int32 FirmwareSub, + bool bInclusive); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveInfoImpl_Equals( + void* Instance, + void* NovaGloveInfoImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveInfoImpl_ToString( + void* Instance, + void* OutString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveInfoImpl_Serialize( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGNovaGloveSensorDataImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveSensorDataImpl_Empty( + void* OutNovaGloveSensorDataImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveSensorDataImpl_Parse( + void* OutNovaGloveSensorDataImpl, + void* RawData, + void* GloveInfo); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveSensorDataImpl_Deserialize( + void* OutNovaGloveSensorDataImpl, + void* SerializedString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveSensorDataImpl_ctor( + void* OutNovaGloveSensorDataImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void +SGCoreImpl_FSGNovaGloveSensorDataImpl_ctor_Values_ParsedValues_ImuRotation_bImuParsed_BatteryLevel_bCharging( + void* OutNovaGloveSensorDataImpl, + void* Values, + int32 ParsedValues, + void* ImuRotation, + bool bImuParsed, + float BatteryLevel, + bool bCharging); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveSensorDataImpl_ctor_copy( + void* OutNovaGloveSensorDataImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveSensorDataImpl_ctor_copy_assignment( + void* OutNovaGloveSensorDataImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveSensorDataImpl_GetSensorValues( + void* Instance, + void* OutValues); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGNovaGloveSensorDataImpl_GetSensorValue( + void* Instance, + void* Finger, + void* Location); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGNovaGloveSensorDataImpl_GetParsedValues( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveSensorDataImpl_GetImuRotation( + void* Instance, + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveSensorDataImpl_IsImuParsed( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGNovaGloveSensorDataImpl_GetBatteryLevel( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveSensorDataImpl_IsCharging( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGNovaGloveSensorDataImpl_Equals( + void* Instance, + void* NovaGloveSensorDataImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveSensorDataImpl_ToString( + void* Instance, + void* OutString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGNovaGloveSensorDataImpl_Serialize( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGSenseComImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseComImpl_RegisterExe(); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseComImpl_RegisterExe_ExePath( + void* ExePath); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseComImpl_GetExePath( + void* OutExePath); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseComImpl_ScanningActive(); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseComImpl_GetCurrentExeDirectory( + void* OutDirectory); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseComImpl_StartupSenseCom(); + +/******************************************************************************* + * SGSenseGloveImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_Parse( + void* OutSenseGloveImpl, + void* ConstantsString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_GetSenseGloves( + void* OutGloves); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_GetSenseGlove_OutGlove( + void* OutGlove); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_GetSenseGlove_bRightHanded_OutGlove( + bool bRightHanded, + void* OutGlove); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_CalculateGloveLocation( + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + bool bRightHanded, + void* MountedOn, + void* OutGlovePosition, + void* OutGloveRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_CalculateWristLocation( + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + bool bRightHanded, + void* MountedOn, + void* GloveWristPositionOffset, + void* GloveWristRotationOffset, + void* OutWristPosition, + void* OutWristRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API ANSICHAR SGCoreImpl_FSGSenseGloveImpl_GetHapticsByte(); + +SENSEGLOVECOREIMPL_PUBLIC_API ANSICHAR SGCoreImpl_FSGSenseGloveImpl_GetThumperByte(); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_GetDefaultThimbleOffset( + void* OutOffset); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_CalculateGlovePose_SensorData_GloveModel( + void* OutPose, + void* SensorData, + void* GloveModel); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_CalculateGlovePose_GloveAngles_GloveModel( + void* OutPose, + void* GloveAngles, + void* GloveModel); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_NormalizeValues( + void* SumAngles, + void* Normalizer, + void* OutFlexions, + void* OutAbductions); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_CalculateHandAngles( + void* GlovePose, + void* Normalizer, + void* NormalizedToAngles, + void* OutHandAngles); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_CalculateHandPose( + void* GlovePose, + void* HandModel, + void* Normalizer, + void* NormalizedToAngles, + void* OutHandPose); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_ctor( + void* OutSenseGloveImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_ctor_MakeShared( + void* OutSharedPtr); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_ctor_Model( + void* OutSenseGloveImpl, + void* Model); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_ctor_Model_MakeShared( + void* OutSharedPtr, + void* Model); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_ctor_copy( + void* OutSenseGloveImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_ctor_copy_MakeShared( + void* OutSharedPtr, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_ctor_copy_assignment( + void* OutSenseGloveImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_GetDeviceType( + void* Instance, + void* OutType); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_GetDeviceId( + void* Instance, + void* OutId); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_GetHardwareVersion( + void* Instance, + void* OutVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGSenseGloveImpl_GetFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGSenseGloveImpl_GetSubFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_IsRight( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_GetImuRotation( + void* Instance, + void* OutImu); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_GetHandPose( + void* Instance, + void* HandGeometry, + void* OutHandPose); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_GetHandAngles( + void* Instance, + void* OutHandAngles); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_GetHandAngles( + void* Instance, + void* OutHandAngles); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_GetCalibrationState( + void* Instance, + void* OutHapticGloveCalibrationState); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_EndCalibration( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_ResetCalibration( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_StopHaptics( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_StopVibrations( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_SendHaptics( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_QueueForceFeedbackLevels( + void* Instance, + void* Levels01); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_QueueForceFeedbackLevel( + void* Instance, + int32 Finger, + float Level01); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_QueueVibroLevels( + void* Instance, + void* Amplitudes); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_QueueVibroLevel_Location_Level01( + void* Instance, + void* Location, + float Level01); + +SENSEGLOVECOREIMPL_PUBLIC_API void +SGCoreImpl_FSGSenseGloveImpl_GetGloveLocation_ReferencePosition_ReferenceRotation_TrackingHardware_OutGlovePosition_OutGloveRotation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutGlovePosition, + void* OutGloveRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void +SGCoreImpl_FSGSenseGloveImpl_GetGloveLocation_ReferencePosition_ReferenceRotation_TrackingHardware_MountedOn_OutGlovePosition_OutGloveRotation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* MountedOn, + void* OutGlovePosition, + void* OutGloveRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void +SGCoreImpl_FSGSenseGloveImpl_GetWristLocation_ReferencePosition_ReferenceRotation_TrackingHardware_OutWristPosition_OutWristRotation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* OutWristPosition, + void* OutWristRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void +SGCoreImpl_FSGSenseGloveImpl_GetWristLocation_ReferencePosition_ReferenceRotation_TrackingHardware_GloveWristPositionOffset_GloveWristRotationOffset_OutWristPosition_OutWristRotation( + void* Instance, + void* ReferencePosition, + void* ReferenceRotation, + void* TrackingHardware, + void* GloveWristPositionOffset, + void* GloveWristRotationOffset, + void* OutWristPosition, + void* OutWristRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_GetGloveInfo( + void* Instance, + void* OutGloveInfo); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_GetFingerThimbleOffsets( + void* Instance, + void* OutFingerThimbleOffsets); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_SetFingerThimbleOffset( + void* Instance, + int32 Finger, + void* Offset); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_SupportsWristActuator( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_GetSensorData( + void* Instance, + void* OutSensorData); + + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_GetGlovePose_OutGlovePose( + void* Instance, + void* OutGlovePose); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_GetGlovePose_SensorData_OutGlovePose( + void* Instance, + void* SensorData, + void* OutGlovePose); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_QueueVibroLevel_Finger_Amplitude( + void* Instance, + int32 Finger, + float Amplitude); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveImpl_QueueThumperCommand( + void* Instance, + void* Command); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveImpl_ToString( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGSenseGloveInfoImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveInfoImpl_Parse( + void* ConstantsString, + void* OutGloveInfo, + bool bUpdateOldModels); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_Deserialize( + void* OutSenseGloveInfoImpl, + void* SerializedString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_ctor( + void* OutSenseGloveInfoImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void +SGCoreImpl_FSGSenseGloveInfoImpl_ctor_DeviceId_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded_NumberOfSensors_ImuCorrection_StartPositions_StartRotations_GloveLengths_Functions( + void* OutSenseGloveInfoImpl, + void* DeviceId, + void* HardwareVersion, + int32 FirmwareVersion, + int32 SubFirmwareVersion, + bool bRightHanded, + int32 NumberOfSensors, + void* ImuCorrection, + void* StartPositions, + void* StartRotations, + void* GloveLengths, + void* Functions); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_ctor_copy( + void* OutSenseGloveInfoImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_ctor_copy_assignment( + void* OutSenseGloveInfoImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_GetDeviceId( + void* Instance, + void* OutId); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_GetHardwareVersion( + void* Instance, + void* OutVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGSenseGloveInfoImpl_GetFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGSenseGloveInfoImpl_GetSubFirmwareVersion( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveInfoImpl_IsRight( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGSenseGloveInfoImpl_GetNumberOfSensors( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_GetImuCorrection( + void* Instance, + void* OutCorrection); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_GetStartPositions( + void* Instance, + void* OutPositions); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_GetStartRotations( + void* Instance, + void* OutRotations); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_GetGloveLengths( + void* Instance, + void* OutLengths); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_GetFunctions( + void* Instance, + void* OutFunctions); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_GetStartPosition( + void* Instance, + void* OutPosition, + void* Finger); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_GetStartRotation( + void* Instance, + void* OutRotation, + void* Finger); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_GetGloveLengths_Finger( + void* Instance, + void* OutLengths, + void* Finger); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_ToGloveAngles( + void* Instance, + void* OutAngles, + void* SensorAngles); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveInfoImpl_Equals( + void* Instance, + void* SenseGloveInfoImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_ToString_bShortNotation( + void* Instance, + void* OutString, + bool bShortNotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_ToString( + void* Instance, + void* OutString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveInfoImpl_Serialize( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGSenseGlovePoseImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGlovePoseImpl_IdlePose( + void* OutSenseGlovePoseImpl, + void* GloveInfo); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGlovePoseImpl_Deserialize( + void* OutSenseGlovePoseImpl, + void* SerializedString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGlovePoseImpl_ctor( + void* OutSenseGlovePoseImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void +SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( + void* OutSenseGlovePoseImpl, + bool bRightHanded, + void* JointPositions, + void* JointRotations, + void* GloveAngles); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGlovePoseImpl_ctor_copy( + void* OutSenseGlovePoseImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGlovePoseImpl_ctor_copy_assignment( + void* OutSenseGlovePoseImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGlovePoseImpl_IsRight( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGlovePoseImpl_GetJointPositions( + void* Instance, + void* OutPositions); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGlovePoseImpl_GetJointRotations( + void* Instance, + void* OutRotations); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGlovePoseImpl_GetGloveAngles( + void* Instance, + void* OutAngles); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGlovePoseImpl_GetThimblePositions( + void* Instance, + void* OutPositions); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGlovePoseImpl_GetThimbleRotations( + void* Instance, + void* OutRotations); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGlovePoseImpl_GetTotalGloveAngles( + void* Instance, + void* OutAngles); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGlovePoseImpl_CalculateFingertips( + void* Instance, + void* OutFingertips, + void* FingerOffsets); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGlovePoseImpl_Equals( + void* Instance, + void* SenseGlovePoseImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGlovePoseImpl_ToString( + void* Instance, + void* OutString, + bool bShortFormat); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGlovePoseImpl_Serialize( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGSenseGloveSensorDataImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveSensorDataImpl_Empty( + void* OutSenseGloveSensorDataImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveSensorDataImpl_Parse( + void* OutSenseGloveSensorDataImpl, + void* RawData, + void* GloveInfo); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveSensorDataImpl_Deserialize( + void* OutSenseGloveSensorDataImpl, + void* SerializedString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor( + void* OutSenseGloveSensorDataImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void +SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor_SensorAngles_ImuRotation_ParsedValues_bImuParsed( + void* OutSenseGloveSensorDataImpl, + void* SensorAngles, + void* ImuRotation, + int32 ParsedValues, + bool bImuParsed); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor_copy( + void* OutSenseGloveSensorDataImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveSensorDataImpl_ctor_copy_assignment( + void* OutSenseGloveSensorDataImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveSensorDataImpl_GetSensorAngles( + void* Instance, + void* OutAngles); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveSensorDataImpl_GetSensorAngles_Finger( + void* Instance, + void* OutAngles, + void* Finger); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveSensorDataImpl_GetAngleSequence( + void* Instance, + void* OutSequence); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveSensorDataImpl_GetImuRotation( + void* Instance, + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGSenseGloveSensorDataImpl_GetParsedValues( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveSensorDataImpl_IsImuParsed( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSenseGloveSensorDataImpl_Equals( + void* Instance, + void* SenseGloveSensorDataImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveSensorDataImpl_ToString( + void* Instance, + void* OutString); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveSensorDataImpl_Serialize( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGSenseGloveSensorNormalizerImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_ctor( + void* OutSenseGloveSensorNormalizerImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_ctor_bRightHanded( + void* OutSenseGloveSensorNormalizerImpl, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_ctor_copy( + void* OutSenseGloveSensorNormalizerImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_ctor_copy_assignment( + void* OutSenseGloveSensorNormalizerImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_NormalizeFlexion( + void* Instance, + int32 Finger, + float SumFlexionAngles); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGSenseGloveSensorNormalizerImpl_NormalizeAbduction( + void* Instance, + int32 Finger, + float SumAbductionAngles); + +/******************************************************************************* + * SGSenseGloveVarsImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveVarsImpl_GetStandardConstantsString( + void* OutString, + void* HardwareVersion, + float FirmwareVersion, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveVarsImpl_GetSensorString( + void* OutString, + void* HardwareVersion, + float FirmwareVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveVarsImpl_GetStartPositions( + void* OutPositions, + void* HardwareVersion, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveVarsImpl_GetStartRotations( + void* OutRotations, + void* HardwareVersion, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveVarsImpl_GetGloveLengths( + void* OutLengths, + void* HardwareVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGSenseGloveVarsImpl_GetSensors( + void* HardwareVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveVarsImpl_GetImuCorrection( + void* OutCorrection, + void* HardwareVersion, + int32 FirmwareVersion, + int32 SubFirmwareVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSenseGloveVarsImpl_GetFunctions( + void* OutFunctions, + void* HardwareVersion, + int32 FirmwareVersion, + int32 SubFirmwareVersion); + +SENSEGLOVECOREIMPL_PUBLIC_API void +SGCoreImpl_FSGSenseGloveVarsImpl_GenerateGloveModel_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded +( + void* OutModel, + void* HardwareVersion, + int32 FirmwareVersion, + int32 SubFirmwareVersion, + bool bRightHanded); + +SENSEGLOVECOREIMPL_PUBLIC_API void +SGCoreImpl_FSGSenseGloveVarsImpl_GenerateGloveModel_HardwareVersion_FirmwareVersion_SubFirmwareVersion_bRightHanded_CustomId +( + void* OutModel, + void* HardwareVersion, + int32 FirmwareVersion, + int32 SubFirmwareVersion, + bool bRightHanded, + void* CustomId); + +/******************************************************************************* + * SGSensorNormalizationImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSensorNormalizationImpl_ctor( + void* OutSensorNormalizationImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSensorNormalizationImpl_ctor_MovementRanges( + void* OutSensorNormalizationImpl, + void* MovementRanges); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSensorNormalizationImpl_ctor_copy( + void* OutSensorNormalizationImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSensorNormalizationImpl_ctor_copy_assignment( + void* OutSensorNormalizationImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSensorNormalizationImpl_CollectsNormalization( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSensorNormalizationImpl_SetCollectNormalization( + void* Instance, + bool bCollectNormalization); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGSensorNormalizationImpl_GetLength( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API int32 SGCoreImpl_FSGSensorNormalizationImpl_GetMoveCount( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSensorNormalizationImpl_AllSensorsMoving( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSensorNormalizationImpl_ResetNormalization( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSensorNormalizationImpl_UpdateNormalization( + void* Instance, + float Value, + int32 Index); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGSensorNormalizationImpl_NormalizeValue( + void* Instance, + float Value, + int32 Index); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGSensorNormalizationImpl_NormalizeValues( + void* Instance, + void* Values, + void* OutNormalizedValues); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGSensorNormalizationImpl_MovedEnough( + void* Instance, + int32 Index); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGSensorNormalizationImpl_Denormalize( + void* Instance, + float Value01, + int32 Index, + float FallbackValue); + +/******************************************************************************* + * SGThresholdCommandImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGThresholdCommandImpl_ctor( + void* OutThresholdCommandImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGThresholdCommandImpl_ctor_AffectedFingers_ThresholdValues( + void* OutThresholdCommandImpl, + void* AffectedFingers, + void* ThresholdValues); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGThresholdCommandImpl_ctor_copy( + void* OutThresholdCommandImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGThresholdCommandImpl_ctor_copy_assignment( + void* OutThresholdCommandImpl, + void* Rhs); + +SENSEGLOVECOREIMPL_PUBLIC_API float SGCoreImpl_FSGThresholdCommandImpl_GetThreshold( + void* Instance, + int32 Finger); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGThresholdCommandImpl_SetThreshold( + void* Instance, + int32 Finger, + float ThresholdValue); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGThresholdCommandImpl_GetThresholds( + void* Instance, + void* OutThresholds); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGThresholdCommandImpl_SetThresholds( + void* Instance, + void* AffectedFingers, + void* ThresholdValues); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGThresholdCommandImpl_GetFingerActive( + void* Instance, + int32 Finger); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGThresholdCommandImpl_GetActiveFingers( + void* Instance, + void* OutActiveFingers); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGThresholdCommandImpl_ClearThreshold( + void* Instance, + int32 Finger); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGThresholdCommandImpl_ClearThresholds( + void* Instance); + +SENSEGLOVECOREIMPL_PUBLIC_API bool SGCoreImpl_FSGThresholdCommandImpl_Equals( + void* Instance, + void* ThresholdCommandImpl); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGThresholdCommandImpl_ToString( + void* Instance, + void* OutString); + +/******************************************************************************* + * SGTrackingImpl.h + ******************************************************************************/ + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_CalculateLocation( + void* TrackedPosition, + void* TrackedRotation, + void* PositionOffset, + void* RotationOffset, + void* OutNewPosition, + void* OutNewRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetSenseGloveFingerToGlovePositionOrigin( + void* OutOrigin); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetSenseGloveFingerToGloveRotationOrigin( + void* OutOrigin); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetSenseGloveWristPositionOffset( + void* OutOffset); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetSenseGloveWristRotationOffset( + void* OutOffset); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetSenseGloveMountOffset( + bool bRightHanded, + void* ToFinger, + void* OutIPosition, + void* OutIRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetSenseGloveTrackerMountOffset( + void* Hardware, + bool bRightHanded, + void* OutPositionOffset, + void* OutRotationOffset); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetSenseGloveViveToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetSenseGloveViveToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetSenseGloveOculusTouchToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetSenseGloveOculusTouchToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetNovaToWristPositionOffset( + void* OutOffset); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetNovaToWristRotationOffset( + void* OutOffset); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNovaViveToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNovaViveToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNovaViveToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNovaViveToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNovaQuest2ToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNovaQuest2ToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuest2ToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuest2ToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNovaPico2ToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNovaPico2ToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNovaPico2ToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNovaQuestProToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNovaQuestProToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuestProToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuestProToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNovaViveFocus3ToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNovaViveFocus3ToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNovaViveFocus3ToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNovaViveFocus3ToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNovaQuest3ToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNovaQuest3ToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuest3ToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNovaQuest3ToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetNovaGloveWristOffset( + bool bRightHanded, + void* OutPositionOffset, + void* OutRotationOffset); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetNovaGloveTrackerOffset( + void* Hardware, + bool bRightHanded, + void* OutPositionOffset, + void* OutRotationOffset); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNova2ToWristPositionOffset( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNova2ToWristRotationOffset( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNova2ToWristPositionOffset( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNova2ToWristRotationOffset( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNova2Quest2ToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNova2Quest2ToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNova2Quest2ToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNova2Quest2ToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNova2QuestProToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNova2QuestProToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNova2QuestProToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNova2QuestProToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNova2ViveTrackerToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNova2ViveTrackerToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNova2ViveTrackerToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNova2ViveTrackerToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNova2ViveWristTrackerToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNova2ViveWristTrackerToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNova2ViveWristTrackerToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNova2ViveWristTrackerToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNova2Quest3ToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetRightNova2Quest3ToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNova2Quest3ToAttachPosition( + void* OutPosition); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetLeftNova2Quest3ToAttachRotation( + void* OutRotation); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetNova2GloveWristOffset( + bool bRightHanded, + void* HardwareVersion, + void* OutPositionOffset, + void* OutRotationOffset); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_GetNova2GloveTrackerOffset( + void* Hardware, + bool bRightHanded, + void* HardwareVersion, + void* OutPositionOffset, + void* OutRotationOffset); + +SENSEGLOVECOREIMPL_PUBLIC_API void SGCoreImpl_FSGTrackingImpl_ToString( + void* OutString, + void* Hardware); + +/******************************************************************************* + ******************************************************************************/ + +#if __cplusplus +} +#endif /* __cplusplus */ \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGHandInterpolatorImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGHandInterpolatorImpl.h new file mode 100644 index 0000000..a450b7c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGHandInterpolatorImpl.h @@ -0,0 +1,134 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" +#include "SGTypes/SGCoreTypes.h" + +class FSGInterpolationSetImpl; + +namespace SGCore +{ + namespace Kinematics + { + class HandInterpolator; + } +} + +class SENSEGLOVECOREIMPL_API FSGHandInterpolatorImpl final +{ +public: + typedef SGCore::Kinematics::HandInterpolator FHandInterpolatorType; + +public: + static FSGHandInterpolatorImpl Deserialize(const FString& SerializedString, bool bRightHanded = true); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGHandInterpolatorImpl(); + + explicit FSGHandInterpolatorImpl(bool bRightHanded); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGHandInterpolatorImpl(const FHandInterpolatorType& HandInterpolator); + +public: + /** + * The copy constructor. + */ + FSGHandInterpolatorImpl(const FSGHandInterpolatorImpl& Rhs); + + /** + * The move constructor. + */ + FSGHandInterpolatorImpl(FSGHandInterpolatorImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGHandInterpolatorImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGHandInterpolatorImpl& operator=(const FSGHandInterpolatorImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGHandInterpolatorImpl& operator=(FSGHandInterpolatorImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FHandInterpolatorType& ToHandInterpolator() const; + +public: + float CalculateAngle(ESGFingerMovement Movement, float Value, bool bApplyLimits = true) const; + + float CalculateAngle(ESGThumbMovement Movement, float Value, bool bApplyLimits = true) const; + +public: + TArray> InterpolateHandAngles( + const TArray>& Flexions, const TArray& Abductions, float CmcTwist); + +public: + bool Equals(const FSGHandInterpolatorImpl& HandInterpolatorImpl) const; + +public: + FString Serialize() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGHandLayerImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGHandLayerImpl.h new file mode 100644 index 0000000..0dbcda3 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGHandLayerImpl.h @@ -0,0 +1,121 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Templates/SharedPointer.h" + +#include "SGTypes/SGCoreTypes.h" + +namespace SGCore +{ + class HandLayer; +} + +class FSGCustomWaveformImpl; +class FSGHandPoseImpl; +class FSGHapticGloveImpl; + +class SENSEGLOVECOREIMPL_API FSGHandLayerImpl final +{ +public: + typedef SGCore::HandLayer FHandLayerType; + +public: + static bool DeviceConnected(bool bRightHanded); + + static ESGDeviceType GetDeviceType(bool bRightHanded); + + static bool GetFirstGloveHandedness(); + + static int32 GlovesConnected(); + + static bool GetGloveInstance(bool bRightHanded, TSharedPtr& OutGlove); + + static ESGHapticGloveCalibrationState GetCalibrationState(bool bRightHanded); + + static FString GetCalibrationInstructions(bool bRightHanded); + + static void ResetCalibration(bool bRightHanded); + + static void EndCalibration(bool bRightHanded); + + static bool GetHandPose(bool bRightHanded, FSGHandPoseImpl& OutHandPose); + + static void GetWristLocation( + bool bRightHanded, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation); + + static void StopAllHaptics(bool bRightHanded); + + static bool SendHaptics(bool bRightHanded); + + static bool SupportsCustomWaveform(bool bRightHanded, ESGHapticLocation AtLocation); + + static bool SendCustomWaveform(bool bRightHanded, FSGCustomWaveformImpl& OutWaveform, ESGHapticLocation Location); + + static bool QueueCommand_ForceFeedbackLevels( + bool bRightHanded, const TArray& Levels01, bool bSendImmediate); + + static bool QueueCommand_ForceFeedbackLevel(bool bRightHanded, int32 Finger, float Level01, bool bSendImmediate); + + static bool QueueCommand_VibroLevels(bool bRightHanded, const TArray& Levels01, bool bSendImmediate); + + static bool QueueCommand_VibroLevel(bool bRightHanded, int32 Finger, float Level01, bool bSendImmediate); + + static bool QueueCommand_VibroLevel( + bool bRightHanded, ESGHapticLocation AtLocation, float Level01, bool bSendImmediate); + + static bool SupportsWristSqueeze(bool bRightHanded); + + static bool QueueCommand_WristSqueeze(bool bRightHanded, float SqueezeLevel01, bool bSendImmediate); + + static bool SupportsFlexionLocks(bool bRightHanded); + + static bool QueueCommand_FlexionLock(bool bRightHanded, int32 Finger, float Flexion01, bool bSendImmediate); + + static bool QueueCommand_ClearFlexionLock(bool bRightHanded, int32 Finger, bool bSendImmediate); + +public: + FSGHandLayerImpl() = delete; + virtual ~FSGHandLayerImpl() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGHandPoseImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGHandPoseImpl.h new file mode 100644 index 0000000..e669561 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGHandPoseImpl.h @@ -0,0 +1,160 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" +#include "SGTypes/SGCoreTypes.h" + +class FSGHandInterpolatorImpl; + +namespace SGCore +{ + class HandPose; +} + +class FSGBasicHandModelImpl; + +class SENSEGLOVECOREIMPL_API FSGHandPoseImpl final +{ +public: + typedef SGCore::HandPose FHandPoseType; + +public: + static FSGHandPoseImpl Deserialize(const FString& SerializedString); + + static FSGHandPoseImpl FromHandAngles(const TArray>& HandAngles, bool bRightHanded, + const FSGBasicHandModelImpl& HandDimensions); + + static FSGHandPoseImpl FromHandAngles(const TArray>& HandAngles, bool bRightHanded); + + static FSGHandPoseImpl DefaultIdle(bool bRightHanded, const FSGBasicHandModelImpl& HandDimensions); + + static FSGHandPoseImpl DefaultIdle(bool bRightHanded); + + static FSGHandPoseImpl FlatHand(bool bRightHanded, const FSGBasicHandModelImpl& HandDimensions); + + static FSGHandPoseImpl FlatHand(bool bRightHanded); + + static FSGHandPoseImpl ThumbsUp(bool bRightHanded, const FSGBasicHandModelImpl& HandDimensions); + + static FSGHandPoseImpl ThumbsUp(bool bRightHanded); + + static FSGHandPoseImpl Fist(bool bRightHanded, const FSGBasicHandModelImpl& HandDimensions); + + static FSGHandPoseImpl Fist(bool bRightHanded); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGHandPoseImpl(); + + FSGHandPoseImpl(bool bRightHanded, const TArray>& JointPositions, + const TArray>& JointRotations, + const TArray>& HandAngles); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGHandPoseImpl(const FHandPoseType& SenseGloveHandPose); + +public: + /** + * The copy constructor. + */ + FSGHandPoseImpl(const FSGHandPoseImpl& Rhs); + + /** + * The move constructor. + */ + FSGHandPoseImpl(FSGHandPoseImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGHandPoseImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGHandPoseImpl& operator=(const FSGHandPoseImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGHandPoseImpl& operator=(FSGHandPoseImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FHandPoseType& ToHandPose() const; + +public: + bool IsRight() const; + + TArray> GetJointPositions() const; + + TArray> GetJointRotations() const; + + TArray> GetHandAngles() const; + +public: + bool Equals(const FSGHandPoseImpl& HandPoseImpl) const; + + float GetNormalizedFlexion(ESGFinger Finger, bool bClamp01 = true) const; + + TArray GetNormalizedFlexion(bool bClamp01 = true) const; + +public: + FString ToString(bool bShortFormat = false) const; + + FString Serialize() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGHapticChannelInfoImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGHapticChannelInfoImpl.h new file mode 100644 index 0000000..2f0c245 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGHapticChannelInfoImpl.h @@ -0,0 +1,133 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" + +#include "SGBuildHacks/SGPlatform.h" +#include "SGTypes/SGCoreTypes.h" + +namespace SGCore +{ + class HapticChannelInfo; +} + +class SENSEGLOVECOREIMPL_API FSGHapticChannelInfoImpl final +{ +public: + typedef SGCore::HapticChannelInfo FHapticChannelInfoType; + +public: + static FString GenerateAddress(int32 DeviceIndex, int32 ChannelIndex); + + static FSGHapticChannelInfoImpl Parse(const FString& IpcString); + +public: + static int32 GetStreamingType(); + static int32 GetFireAndForgetType(); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGHapticChannelInfoImpl(); + + FSGHapticChannelInfoImpl(const TArray& StreamIndex, const TArray& FireAndForgetIndex); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGHapticChannelInfoImpl(const FHapticChannelInfoType& HapticChannelInfo); + +public: + /** + * The copy constructor. + */ + FSGHapticChannelInfoImpl(const FSGHapticChannelInfoImpl& Rhs); + + /** + * The move constructor. + */ + FSGHapticChannelInfoImpl(FSGHapticChannelInfoImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGHapticChannelInfoImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGHapticChannelInfoImpl& operator=(const FSGHapticChannelInfoImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGHapticChannelInfoImpl& operator=(FSGHapticChannelInfoImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FHapticChannelInfoType& ToHapticChannelInfo() const; + +public: + int32 GetStreamChannelCount() const; + int32 GetFireAndForgetChannelCount() const; + int32 GetTotalChannelCount() const; + + FString GetAddress_Unguarded(ESGHapticChannelType Type, int32 TypeIndex) const; + + void GetIpcParams_Unguarded(ESGHapticChannelType Type, int32 TypeIndex, + int32& OutIndex, FString& OutAddressString) const; + + void RegenerateAddresses(int32 ForDeviceIndex); + + TArray GetAllAddresses() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGHapticGloveImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGHapticGloveImpl.h new file mode 100644 index 0000000..e15a860 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGHapticGloveImpl.h @@ -0,0 +1,209 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include +#include + +#include "Containers/Array.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Runtime/Launch/Resources/Version.h" +#include "Templates/SharedPointer.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" +#include "SGCoreImpl/SGDeviceImpl.h" +#include "SGTypes/SGCoreTypes.h" + +namespace SGCore +{ + class HapticGlove; +} + +class FSGBasicHandModelImpl; +class FSGCustomWaveformImpl; +class FSGHandPoseImpl; + +class SENSEGLOVECOREIMPL_API FSGHapticGloveImpl : public FSGDeviceImpl +{ +#if ENGINE_MAJOR_VERSION >= 5 + friend class SharedPointerInternals::TIntrusiveReferenceController; +#else + friend class SharedPointerInternals::TIntrusiveReferenceController; +#endif /* ENGINE_MAJOR_VERSION >= 5 */ + +public: + typedef SGCore::HapticGlove FHapticGloveType; + +public: + typedef std::shared_ptr FHapticGlovePtrType; + typedef std::vector FHapticGlovePtrVectorType; + +public: + static TArray> GetHapticGloves(bool bConnectedOnly = true); + + static bool GetGlove(TSharedPtr& OutGlove); + + static bool GetGlove(bool bRightHanded, TSharedPtr& OutGlove); + +public: + static FString ToString(ESGHapticGloveCalibrationState State); + + static FString ToString(ESGHapticLocation Location); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGHapticGloveImpl(); + +public: + /** + * The cast from underlying pointer type constructor. + */ + explicit FSGHapticGloveImpl(const FHapticGlovePtrType HapticGlove); + +public: + /** + * The copy constructor. + */ + FSGHapticGloveImpl(const FSGHapticGloveImpl& Rhs); + + /** + * The move constructor. + */ + FSGHapticGloveImpl(FSGHapticGloveImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGHapticGloveImpl() override; + +public: + /** + * The copy assignment operator. + */ + FSGHapticGloveImpl& operator=(const FSGHapticGloveImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGHapticGloveImpl& operator=(FSGHapticGloveImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying pointer type method. + */ + FHapticGlovePtrType ToHapticGlovePtr() const; + + /** + * The checked cast to underlying pointer type method. + */ + FHapticGlovePtrType ToHapticGlovePtrChecked() const; + +public: + virtual ESGDeviceType GetDeviceType() const override; + virtual FString GetDeviceId() const override; + + virtual FString GetHardwareVersion() const override; + virtual int32 GetFirmwareVersion() const override; + virtual int32 GetSubFirmwareVersion() const override; + +public: + virtual bool IsRight() const; + + virtual bool GetImuRotation(FQuat& OutImu); + + virtual bool GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose) const; + + virtual bool GetHandPose(FSGHandPoseImpl& OutHandPose); + + virtual bool GetHandAngles(TArray>& OutHandAngles) const; + + FSGBasicHandModelImpl GetHandGeometry() const; + void SetHandGeometry(const FSGBasicHandModelImpl& HandGeometry); + +public: + virtual ESGHapticGloveCalibrationState GetCalibrationState() const; + + virtual void EndCalibration(); + + virtual void ResetCalibration(); + + virtual FString GetCalibrationInstruction() const; + +public: + virtual void StopHaptics(); + + virtual void StopVibrations(); + + virtual bool SendHaptics(); + +public: + virtual bool SupportsCustomWaveform(ESGHapticLocation AtLocation) const; + + virtual bool SendCustomWaveform(FSGCustomWaveformImpl& OutWaveform, ESGHapticLocation Location); + + virtual bool QueueForceFeedbackLevels(const TArray& Levels01); + + virtual bool QueueForceFeedbackLevel(int32 Finger, float Level01); + + virtual bool QueueVibroLevels(const TArray& Levels01); + + virtual bool QueueVibroLevel(ESGHapticLocation Location, float Level01); + +public: + virtual void GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) const; + + virtual void GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const; + +public: + virtual FString ToString() const override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGInterpolationSetImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGInterpolationSetImpl.h new file mode 100644 index 0000000..a632e24 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGInterpolationSetImpl.h @@ -0,0 +1,154 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" + +namespace SGCore +{ + namespace Kinematics + { + class InterpolationSet; + } +} + +class SENSEGLOVECOREIMPL_API FSGInterpolationSetImpl final +{ +public: + typedef SGCore::Kinematics::InterpolationSet FInterpolationSetType; + +public: + static FSGInterpolationSetImpl Deserialize(const FString& SerializedString); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGInterpolationSetImpl(); + + FSGInterpolationSetImpl(float From1, float From2, float To1, float To2); + + FSGInterpolationSetImpl(float From1, float From2, float To1, float To2, float Min, float Max); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGInterpolationSetImpl(const FInterpolationSetType& InterpolationSet); + +public: + /** + * The copy constructor. + */ + FSGInterpolationSetImpl(const FSGInterpolationSetImpl& Rhs); + + /** + * The move constructor. + */ + FSGInterpolationSetImpl(FSGInterpolationSetImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGInterpolationSetImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGInterpolationSetImpl& operator=(const FSGInterpolationSetImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGInterpolationSetImpl& operator=(FSGInterpolationSetImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FInterpolationSetType& ToInterpolationSet() const; + +public: + float GetX0() const; + + void SetX0(float X0); + + float GetX1() const; + + void SetX1(float X1); + + float GetY0() const; + + void SetY0(float Y0); + + float GetY1() const; + + void SetY1(float Y1); + + float GetMin() const; + + void SetMin(float Min); + + float GetMax() const; + + void SetMax(float Max); + +public: + float Get(float Value, bool bLimit, bool bNormalizeAngle = false) const; + +public: + bool Equals(const FSGInterpolationSetImpl& InterpolationSetImpl) const; + +public: + FString ToString() const; + + FString ToString(bool bLimits) const; + + FString Serialize() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGJointKinematicsImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGJointKinematicsImpl.h new file mode 100644 index 0000000..b4ac26a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGJointKinematicsImpl.h @@ -0,0 +1,71 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Math/Quat.h" +#include "Math/Vector.h" + +#include "SGTypes/SGCoreTypes.h" + +class FSGBasicHandModelImpl; + +namespace SGCore +{ + namespace Kinematics + { + class JointKinematics; + } +} + +class SENSEGLOVECOREIMPL_API FSGJointKinematicsImpl final +{ +public: + typedef SGCore::Kinematics::JointKinematics FJointKinematicsType; + +public: + static bool ForwardKinematics(const FVector& StartPosition, const FQuat& StartRotation, + const TArray& JointLengths, const TArray& JointAngles, + TArray& OutNewPositions, TArray& OutNewRotations); + + static bool ForwardKinematics( + const FSGBasicHandModelImpl& Profile, ESGFinger Finger, const TArray& JointAngles, + TArray& OutNewPositions, TArray& OutNewRotations); + +public: + FSGJointKinematicsImpl() = delete; + virtual ~FSGJointKinematicsImpl() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGLibraryImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGLibraryImpl.h new file mode 100644 index 0000000..36e180d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGLibraryImpl.h @@ -0,0 +1,64 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" + +#include "SGTypes/SGCoreTypes.h" + +namespace SGCore +{ + class Library; +} + +class SENSEGLOVECOREIMPL_API FSGLibraryImpl final +{ +public: + typedef SGCore::Library FLibraryType; + +public: + static FString Version(); + + static ESGBackendType GetBackendType(); + + static FString BackendVersion(); + + static FString SGConnectVersion(); + +public: + FSGLibraryImpl() = delete; + virtual ~FSGLibraryImpl() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGNova2GloveImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGNova2GloveImpl.h new file mode 100644 index 0000000..79c38f5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGNova2GloveImpl.h @@ -0,0 +1,288 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include +#include + +#include "Containers/UnrealString.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Runtime/Launch/Resources/Version.h" +#include "Templates/SharedPointer.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" +#include "SGCoreImpl/SGHapticGloveImpl.h" + +namespace SGCore +{ + namespace Nova + { + class Nova2Glove; + } +} + +class FSGBasicHandModelImpl; +class FSGHandInterpolatorImpl; +class FSGHandPoseImpl; +class FSGNova2GloveHandProfileImpl; +class FSGNova2GloveSensorDataImpl; +class FSGNovaGloveInfoImpl; +class FSGSensorNormalizationImpl; + +class SENSEGLOVECOREIMPL_API FSGNova2GloveImpl final : public FSGHapticGloveImpl +{ +#if ENGINE_MAJOR_VERSION >= 5 + friend class SharedPointerInternals::TIntrusiveReferenceController; +#else + friend class SharedPointerInternals::TIntrusiveReferenceController; +#endif /* ENGINE_MAJOR_VERSION >= 5 */ + +public: + typedef SGCore::Nova::Nova2Glove FNova2GloveType; + + typedef std::vector FNova2GloveVectorType; + + typedef std::shared_ptr FNova2GlovePtrType; + typedef std::vector FNova2GlovePtrVectorType; + +public: + static TSharedRef Parse(const FString& ConstantsString); + + static TArray GetNova2Gloves(); + + static bool GetNova2Glove(FSGNova2GloveImpl& OutGlove); + + static bool GetNova2Glove(bool bRightHanded, FSGNova2GloveImpl& OutGlove); + +public: + static void CalculateGloveLocation( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, const FString& HardwareVersion, + FVector& OutGlovePosition, FQuat& OutGloveRotation); + + static void CalculateWristLocation( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, const FString& HardwareVersion, + FVector& OutWristPosition, FQuat& OutWristRotation); + +public: + static ANSICHAR GetStreamByte(); + + static const TArray& GetNova2SensorRanges(); + +public: + static TArray ToNormalizedValues(const FSGNova2GloveSensorDataImpl& SensorData); + + static TArray ToNormalizedValues( + const FSGNova2GloveSensorDataImpl& SensorData, FSGSensorNormalizationImpl& OutSensorNormalizer); + +public: + static TArray> CalculateHandAngles( + const TArray& NormalizedValues, const FSGHandInterpolatorImpl& Interpolator, bool bInfluenceIndex); + + static TArray> ToNormalizedAngles( + const TArray& NormalizedData, const FSGNovaGloveInfoImpl& GloveInfo); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGNova2GloveImpl(); + + explicit FSGNova2GloveImpl(const FSGNovaGloveInfoImpl& DeviceInfo); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGNova2GloveImpl(const FNova2GloveType Nova2Glove); + + /** + * The cast from underlying pointer type constructor. + */ + explicit FSGNova2GloveImpl(const FNova2GlovePtrType Nova2Glove); + +public: + /** + * The copy constructor. + */ + FSGNova2GloveImpl(const FSGNova2GloveImpl& Rhs); + + /** + * The move constructor. + */ + FSGNova2GloveImpl(FSGNova2GloveImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGNova2GloveImpl() override; + +public: + /** + * The copy assignment operator. + */ + FSGNova2GloveImpl& operator=(const FSGNova2GloveImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGNova2GloveImpl& operator=(FSGNova2GloveImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FNova2GloveType& ToNova2Glove() const; + + /** + * The cast to underlying pointer type method. + */ + FNova2GlovePtrType ToNova2GlovePtr() const; + + /** + * The checked cast to underlying pointer type method. + */ + FNova2GlovePtrType ToNova2GlovePtrChecked() const; + +public: + virtual ESGDeviceType GetDeviceType() const override; + + virtual FString GetDeviceId() const override; + + virtual FString GetHardwareVersion() const override; + + virtual int32 GetFirmwareVersion() const override; + + virtual int32 GetSubFirmwareVersion() const override; + +public: + virtual bool HasBattery() const override; + + virtual bool IsCharging() override; + + virtual bool GetBatteryLevel(float& OutBatteryLevel) override; + +public: + virtual bool IsRight() const override; + + virtual bool GetImuRotation(FQuat& OutImu) override; + + virtual bool GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose) const override; + + virtual bool GetHandAngles(TArray>& OutHandAngles) const override; + +public: + virtual ESGHapticGloveCalibrationState GetCalibrationState() const override; + + virtual void EndCalibration() override; + + virtual void ResetCalibration() override; + +public: + virtual void StopHaptics() override; + + virtual void StopVibrations() override; + + virtual bool SendHaptics() override; + +public: + virtual bool SupportsCustomWaveform(ESGHapticLocation AtLocation) const override; + + virtual bool SendCustomWaveform(FSGCustomWaveformImpl& OutWaveform, ESGHapticLocation Location) override; + +public: + virtual bool QueueForceFeedbackLevels(const TArray& Levels01) override; + + virtual bool QueueForceFeedbackLevel(int32 Finger, float Level01) override; + + virtual bool QueueVibroLevels(const TArray& Amplitudes) override; + + virtual bool QueueVibroLevel(ESGHapticLocation Location, float Level01) override; + + virtual bool QueueSqueezeLevel(float SqueezeLevel01); + +public: + virtual void GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const override; + + virtual void GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) const override; + +public: + FSGNovaGloveInfoImpl GetGloveInfo() const; + + bool DoesIndexInfluenceOthers() const; + + void SetIndexInfluencesOthers(bool bInfluenceOthers); + + bool SupportsOnBoardNormalization() const; + +public: + bool GetSensorData(FSGNova2GloveSensorDataImpl& OutSensorData) const; + + bool GetNormalizedInput(TArray& OutNormalizedValues) const; + + virtual bool SendRawData(); + + virtual bool SendNormalizedData(); + +public: + virtual ESGNova2VibroMotor ToNovaMotor(ESGHapticLocation Location) const; + + virtual int32 ChannelIndex(ESGNova2VibroMotor Motor) const; + + virtual void ValidateWaveform(FSGCustomWaveformImpl& OutWaveform, ESGNova2VibroMotor Motor) const; + + virtual bool SendCustomWaveform_Nova2(FSGCustomWaveformImpl& OutWaveform, ESGNova2VibroMotor Motor, + bool bValidateWaveform = true); + +public: + virtual FString ToString() const override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGNova2GloveSensorDataImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGNova2GloveSensorDataImpl.h new file mode 100644 index 0000000..1828f63 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGNova2GloveSensorDataImpl.h @@ -0,0 +1,143 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" +#include "SGTypes/SGCoreTypes.h" + +namespace SGCore +{ + namespace Nova + { + class Nova2GloveSensorData; + } +} + +class FSGNovaGloveInfoImpl; + +class SENSEGLOVECOREIMPL_API FSGNova2GloveSensorDataImpl final +{ +public: + typedef SGCore::Nova::Nova2GloveSensorData FNova2GloveSensorDataType; + +public: + static FSGNova2GloveSensorDataImpl Parse(const FString& RawData, const FSGNovaGloveInfoImpl& GloveInfo); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGNova2GloveSensorDataImpl(); + + FSGNova2GloveSensorDataImpl(const ESGNormalizationState NormalizationState, + const TArray>& Values, int32 ParsedValues, + const FQuat& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGNova2GloveSensorDataImpl(const FNova2GloveSensorDataType& Nova2GloveSensorData); + +public: + /** + * The copy constructor. + */ + FSGNova2GloveSensorDataImpl(const FSGNova2GloveSensorDataImpl& Rhs); + + /** + * The move constructor. + */ + FSGNova2GloveSensorDataImpl(FSGNova2GloveSensorDataImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGNova2GloveSensorDataImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGNova2GloveSensorDataImpl& operator=(const FSGNova2GloveSensorDataImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGNova2GloveSensorDataImpl& operator=(FSGNova2GloveSensorDataImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FNova2GloveSensorDataType& ToNova2GloveSensorData() const; + +public: + ESGNormalizationState GetSensorState() const; + + TArray> GetSensorValues() const; + float GetSensorValue(ESGFinger Finger, ESGNova2SensorLocation Location) const; + + int32 GetParsedValues() const; + + FQuat GetImuRotation() const; + + bool IsImuParsed() const; + +public: + float GetBatteryLevel() const; + + bool IsCharging() const; + +public: + bool Equals(const FSGNova2GloveSensorDataImpl& Nova2GloveSensorDataImpl) const; + +public: + FString ToString() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGNovaGloveImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGNovaGloveImpl.h new file mode 100644 index 0000000..31e81b0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGNovaGloveImpl.h @@ -0,0 +1,305 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 NovaGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include +#include + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Runtime/Launch/Resources/Version.h" +#include "Templates/SharedPointer.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" +#include "SGCoreImpl/SGHapticGloveImpl.h" + +namespace SGCore +{ + namespace Nova + { + class NovaGlove; + } +} + +class FSGBasicHandModelImpl; +class FSGHandInterpolatorImpl; +class FSGHandPoseImpl; +class FSGNovaGloveHandProfileImpl; +class FSGNovaGloveInfoImpl; +class FSGNovaGloveSensorDataImpl; +class FSGSensorNormalizationImpl; +class FSGThresholdCommandImpl; + +class SENSEGLOVECOREIMPL_API FSGNovaGloveImpl final : public FSGHapticGloveImpl +{ +#if ENGINE_MAJOR_VERSION >= 5 + friend class SharedPointerInternals::TIntrusiveReferenceController; +#else + friend class SharedPointerInternals::TIntrusiveReferenceController; +#endif /* ENGINE_MAJOR_VERSION >= 5 */ + +public: + typedef SGCore::Nova::NovaGlove FNovaGloveType; + + typedef std::vector FNovaGloveVectorType; + + typedef std::shared_ptr FNovaGlovePtrType; + typedef std::vector FNovaGlovePtrVectorType; + +public: + static TSharedRef Parse(const FString& ConstantsString); + + static TArray GetNovaGloves(); + + static bool GetNovaGlove(FSGNovaGloveImpl& OutGlove); + + static bool GetNovaGlove(bool bRightHanded, FSGNovaGloveImpl& OutGlove); + +public: + static void CalculateGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, + FVector& OutGlovePosition, FQuat& OutGloveRotation); + + static void CalculateWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, + FVector& OutWristPosition, FQuat& OutWristRotation); + +public: + static ANSICHAR GetHapticsByte(); + + static ANSICHAR GetThresholdsByte(); + + static ANSICHAR GetIgnoreThresholdsByte(); + + static const TArray& GetNovaSensorRanges(); + +public: + static TArray ToNormalizedValues(const FSGNovaGloveSensorDataImpl& SensorData); + + static TArray ToNormalizedValues( + const FSGNovaGloveSensorDataImpl& SensorData, FSGSensorNormalizationImpl& OutSensorNormalizer); + +public: + static TArray> CalculateHandAngles( + const TArray& NormalizedValues, const FSGHandInterpolatorImpl& Interpolator); + +public: + static FString ToNovaCommandAsFlexion(const FSGThresholdCommandImpl& Thresholds); + + static FString ToNovaCommandAsRaw( + const FSGThresholdCommandImpl& Thresholds, const FSGSensorNormalizationImpl& Interpolator); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGNovaGloveImpl(); + + explicit FSGNovaGloveImpl(const FSGNovaGloveInfoImpl& DeviceInfo); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGNovaGloveImpl(const FNovaGloveType NovaGlove); + + /** + * The cast from underlying pointer type constructor. + */ + explicit FSGNovaGloveImpl(const FNovaGlovePtrType NovaGlove); + +public: + /** + * The copy constructor. + */ + FSGNovaGloveImpl(const FSGNovaGloveImpl& Rhs); + + /** + * The move constructor. + */ + FSGNovaGloveImpl(FSGNovaGloveImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGNovaGloveImpl() override; + +public: + /** + * The copy assignment operator. + */ + FSGNovaGloveImpl& operator=(const FSGNovaGloveImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGNovaGloveImpl& operator=(FSGNovaGloveImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FNovaGloveType& ToNovaGlove() const; + + /** + * The cast to underlying pointer type method. + */ + FNovaGlovePtrType ToNovaGlovePtr() const; + + /** + * The checked cast to underlying pointer type method. + */ + FNovaGlovePtrType ToNovaGlovePtrChecked() const; + +public: + virtual ESGDeviceType GetDeviceType() const override; + + virtual FString GetDeviceId() const override; + + virtual FString GetHardwareVersion() const override; + + virtual int32 GetFirmwareVersion() const override; + + virtual int32 GetSubFirmwareVersion() const override; + +public: + virtual void SetDeviceIndex(int32 NewIndex) override; + +public: + virtual bool HasBattery() const override; + + virtual bool IsCharging() override; + + virtual bool GetBatteryLevel(float& OutBatteryLevel) override; + +public: + virtual bool IsRight() const override; + + virtual bool GetImuRotation(FQuat& OutImu) override; + + virtual bool GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose) const override; + + virtual bool GetHandAngles(TArray>& OutHandAngles) const override; + +public: + virtual ESGHapticGloveCalibrationState GetCalibrationState() const override; + + virtual void EndCalibration() override; + + virtual void ResetCalibration() override; + +public: + virtual void StopHaptics() override; + + virtual void StopVibrations() override; + + virtual bool SendHaptics() override; + +public: + virtual bool SupportsCustomWaveform(ESGHapticLocation AtLocation) const override; + + virtual bool SendCustomWaveform(FSGCustomWaveformImpl& OutWaveform, ESGHapticLocation Location) override; + +public: + virtual bool QueueForceFeedbackLevels(const TArray& Levels01) override; + + virtual bool QueueForceFeedbackLevel(int32 Finger, float Level01) override; + + virtual bool QueueVibroLevels(const TArray& Amplitudes) override; + + virtual bool QueueVibroLevel(ESGHapticLocation Location, float Level01) override; + +public: + virtual void GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const override; + + virtual void GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) const override; + +public: + FSGNovaGloveInfoImpl GetGloveInfo() const; + + bool SupportsThresholds() const; + + bool SupportsCustomWaveforms() const; + + bool SupportsOnBoardNormalization() const; + +public: + bool GetSensorData(FSGNovaGloveSensorDataImpl& OutSensorData) const; + + bool GetNormalizedInput(TArray& OutNormalizedValues) const; + +public: + virtual FString ToNovaCommand( + const TArray& ForceFeedbackLevels, const TArray& BuzzLevels, float WristLevel) const; + + virtual bool QueueVibroLevel(int32 Finger, float Amplitude); + + virtual bool QueueWristLevel(float Amplitude); + +public: + virtual ESGNovaVibroMotor ToNovaMotor(ESGHapticLocation Location) const; + + virtual int32 ChannelIndex(ESGNovaVibroMotor Motor) const; + + virtual void ValidateWaveform(FSGCustomWaveformImpl& OutWaveform, ESGNovaVibroMotor Motor) const; + + virtual bool SendCustomWaveform_Nova(FSGCustomWaveformImpl& OutWaveform, ESGNovaVibroMotor Motor, + bool bValidateWaveform = true); + +public: + bool QueueThresholdCommand_Flexion(int32 Finger, float FlexionThreshold); + + virtual bool QueueClearThreshold(int32 Finger); + +public: + virtual FString ToString() const override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGNovaGloveInfoImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGNovaGloveInfoImpl.h new file mode 100644 index 0000000..f5c82e0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGNovaGloveInfoImpl.h @@ -0,0 +1,146 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 NovaGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" + +namespace SGCore +{ + namespace Nova + { + class NovaGloveInfo; + } +} + +class SENSEGLOVECOREIMPL_API FSGNovaGloveInfoImpl final +{ +public: + typedef SGCore::Nova::NovaGloveInfo FNovaGloveInfoType; + +public: + static bool Parse(const FString& ConstantsString, FSGNovaGloveInfoImpl& OutGloveInfo); + + static FSGNovaGloveInfoImpl Deserialize(const FString& SerializedString); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGNovaGloveInfoImpl(); + + FSGNovaGloveInfoImpl(const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion, + bool bRightHanded, const FQuat& ImuCorrection, int32 NumberOfSensors); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGNovaGloveInfoImpl(const FNovaGloveInfoType& GloveInfo); + +public: + /** + * The copy constructor. + */ + FSGNovaGloveInfoImpl(const FSGNovaGloveInfoImpl& Rhs); + + /** + * The move constructor. + */ + FSGNovaGloveInfoImpl(FSGNovaGloveInfoImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGNovaGloveInfoImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGNovaGloveInfoImpl& operator=(const FSGNovaGloveInfoImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGNovaGloveInfoImpl& operator=(FSGNovaGloveInfoImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FNovaGloveInfoType& ToNovaGloveInfo() const; + +public: + FString GetDeviceId() const; + + FString GetHardwareVersion() const; + + int32 GetFirmwareVersion() const; + + int32 GetSubFirmwareVersion() const; + + bool IsRight() const; + + FQuat GetImuCorrection() const; + + int32 GetNumberOfSensors() const; + +public: + bool FirmwareNewerThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const; + + bool FirmwareOlderThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const; + +public: + bool Equals(const FSGNovaGloveInfoImpl& SGNovaGloveInfo) const; + +public: + FString ToString() const; + + FString Serialize() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGNovaGloveSensorDataImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGNovaGloveSensorDataImpl.h new file mode 100644 index 0000000..4325fea --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGNovaGloveSensorDataImpl.h @@ -0,0 +1,149 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 NovaGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" +#include "SGTypes/SGCoreTypes.h" + +namespace SGCore +{ + namespace Nova + { + class NovaGloveSensorData; + } +} + +class FSGNovaGloveInfoImpl; + +class SENSEGLOVECOREIMPL_API FSGNovaGloveSensorDataImpl final +{ +public: + typedef SGCore::Nova::NovaGloveSensorData FNovaGloveSensorDataType; + +public: + static const FSGNovaGloveSensorDataImpl& Empty(); + + static FSGNovaGloveSensorDataImpl Parse(const FString& RawData, const FSGNovaGloveInfoImpl& GloveInfo); + + static FSGNovaGloveSensorDataImpl Deserialize(const FString& SerializedString); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGNovaGloveSensorDataImpl(); + + FSGNovaGloveSensorDataImpl(const TArray& Values, int32 ParsedValues, + const FQuat& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGNovaGloveSensorDataImpl(const FNovaGloveSensorDataType& NovaGloveSensorData); + +public: + /** + * The copy constructor. + */ + FSGNovaGloveSensorDataImpl(const FSGNovaGloveSensorDataImpl& Rhs); + + /** + * The move constructor. + */ + FSGNovaGloveSensorDataImpl(FSGNovaGloveSensorDataImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGNovaGloveSensorDataImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGNovaGloveSensorDataImpl& operator=(const FSGNovaGloveSensorDataImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGNovaGloveSensorDataImpl& operator=(FSGNovaGloveSensorDataImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FNovaGloveSensorDataType& ToNovaGloveSensorData() const; + +public: + ESGNormalizationState GetSensorState() const; + + TArray GetSensorValues() const; + float GetSensorValue(ESGFinger Finger, ESGNovaSensorLocation Location) const; + + int32 GetParsedValues() const; + +public: + FQuat GetImuRotation() const; + + bool IsImuParsed() const; + +public: + float GetBatteryLevel() const; + + bool IsCharging() const; + +public: + bool Equals(const FSGNovaGloveSensorDataImpl& NovaGloveSensorDataImpl) const; + +public: + FString ToString() const; + + FString Serialize() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseComImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseComImpl.h new file mode 100644 index 0000000..f32f8a7 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseComImpl.h @@ -0,0 +1,66 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" + +namespace SGCore +{ + class SenseCom; +} + +class SENSEGLOVECOREIMPL_API FSGSenseComImpl final +{ +public: + typedef SGCore::SenseCom FSenseComType; + +public: + static bool RegisterExe(); + + static bool RegisterExe(const FString& ExePath); + + static bool GetExePath(FString& OutExePath); + + static bool ScanningActive(); + + static bool GetCurrentExeDirectory(FString& OutDirectory); + + static bool StartupSenseCom(); + +public: + FSGSenseComImpl() = delete; + virtual ~FSGSenseComImpl() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGloveImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGloveImpl.h new file mode 100644 index 0000000..f4c9fb3 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGloveImpl.h @@ -0,0 +1,290 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include +#include + +#include "Math/Quat.h" +#include "Math/Vector.h" +#include "Runtime/Launch/Resources/Version.h" +#include "Templates/SharedPointer.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" +#include "SGCoreImpl/SGHapticGloveImpl.h" +#include "SGTypes/SGCoreTypes.h" + +namespace SGCore +{ + namespace SG + { + class SenseGlove; + } +} + +class FSGBasicHandModelImpl; +class FSGHandInterpolatorImpl; +class FSGHandPoseImpl; +class FSGSenseGloveHandProfileImpl; +class FSGSenseGloveInfoImpl; +class FSGSenseGlovePoseImpl; +class FSGSenseGloveSensorDataImpl; +class FSGSenseGloveSensorNormalizerImpl; + +class SENSEGLOVECOREIMPL_API FSGSenseGloveImpl final : public FSGHapticGloveImpl +{ +#if ENGINE_MAJOR_VERSION >= 5 + friend class SharedPointerInternals::TIntrusiveReferenceController; +#else + friend class SharedPointerInternals::TIntrusiveReferenceController; +#endif /* ENGINE_MAJOR_VERSION >= 5 */ + +public: + typedef SGCore::SG::SenseGlove FSenseGloveType; + + typedef std::vector FSenseGloveVectorType; + + typedef std::shared_ptr FSenseGlovePtrType; + typedef std::vector FSenseGlovePtrVectorType; + +public: + static TSharedRef Parse(const FString& ConstantsString); + + static TArray GetSenseGloves(); + + static bool GetSenseGlove(FSGSenseGloveImpl& OutGlove); + + static bool GetSenseGlove(bool bRightHanded, FSGSenseGloveImpl& OutGlove); + +public: + static void CalculateGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + bool bRightHanded, ESGFinger MountedOn, + FVector& OutGlovePosition, FQuat& OutGloveRotation); + + static void CalculateWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + bool bRightHanded, ESGFinger MountedOn, + const FVector& GloveWristPositionOffset, + const FQuat& GloveWristRotationOffset, + FVector& OutWristPosition, FQuat& OutWristRotation); + +public: + static ANSICHAR GetHapticsByte(); + + static ANSICHAR GetThumperByte(); + + static const FVector& GetDefaultThimbleOffset(); + +public: + static FSGSenseGlovePoseImpl CalculateGlovePose(const FSGSenseGloveSensorDataImpl& SensorData, + const FSGSenseGloveInfoImpl& GloveModel); + + static FSGSenseGlovePoseImpl CalculateGlovePose(const TArray>& GloveAngles, + const FSGSenseGloveInfoImpl& GloveModel); + + static void NormalizeValues(const TArray& SumAngles, + const FSGSenseGloveSensorNormalizerImpl& Normalizer, + TArray& OutFlexions, TArray& OutAbductions); + +public: + static void CalculateHandAngles( + const FSGSenseGlovePoseImpl& GlovePose, const FSGSenseGloveSensorNormalizerImpl& Normalizer, + const FSGHandInterpolatorImpl& NormalizedToAngles, + TArray>& OutHandAngles); + + static void CalculateHandPose(const FSGSenseGlovePoseImpl& GlovePose, const FSGBasicHandModelImpl& HandModel, + const FSGSenseGloveSensorNormalizerImpl& Normalizer, + const FSGHandInterpolatorImpl& NormalizedToAngles, FSGHandPoseImpl& OutHandPose); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGSenseGloveImpl(); + + explicit FSGSenseGloveImpl(const FSGSenseGloveInfoImpl& Model); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGSenseGloveImpl(const FSenseGloveType SenseGlove); + + /** + * The cast from underlying pointer type constructor. + */ + explicit FSGSenseGloveImpl(const FSenseGlovePtrType SenseGlove); + +public: + /** + * The copy constructor. + */ + FSGSenseGloveImpl(const FSGSenseGloveImpl& Rhs); + + /** + * The move constructor. + */ + FSGSenseGloveImpl(FSGSenseGloveImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGSenseGloveImpl() override; + +public: + /** + * The copy assignment operator. + */ + FSGSenseGloveImpl& operator=(const FSGSenseGloveImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGSenseGloveImpl& operator=(FSGSenseGloveImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FSenseGloveType& ToSenseGlove() const; + + /** + * The cast to underlying pointer type method. + */ + FSenseGlovePtrType ToSenseGlovePtr() const; + + /** + * The checked cast to underlying pointer type method. + */ + FSenseGlovePtrType ToSenseGlovePtrChecked() const; + +public: + virtual ESGDeviceType GetDeviceType() const override; + + virtual FString GetDeviceId() const override; + + virtual FString GetHardwareVersion() const override; + + virtual int32 GetFirmwareVersion() const override; + + virtual int32 GetSubFirmwareVersion() const override; + +public: + virtual bool IsRight() const override; + + virtual bool GetImuRotation(FQuat& OutImu) override; + + virtual bool GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose) const override; + + virtual bool GetHandAngles(TArray>& OutHandAngles) const override; + +public: + virtual ESGHapticGloveCalibrationState GetCalibrationState() const override; + + virtual void EndCalibration() override; + + virtual void ResetCalibration() override; + +public: + virtual void StopHaptics() override; + + virtual void StopVibrations() override; + + virtual bool SendHaptics() override; + +public: + virtual bool QueueForceFeedbackLevels(const TArray& Levels01) override; + + virtual bool QueueForceFeedbackLevel(int32 Finger, float Level01) override; + + virtual bool QueueVibroLevels(const TArray& Amplitudes) override; + + virtual bool QueueVibroLevel(ESGHapticLocation Location, float Level01) override; + +public: + virtual void GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const override; + + void GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, ESGFinger MountedOn, + FVector& OutGlovePosition, FQuat& OutGloveRotation) const; + + virtual void GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) const override; + + void GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + const FVector& GloveWristPositionOffset, + const FQuat& GloveWristRotationOffset, + FVector& OutWristPosition, FQuat& OutWristRotation) const; + +public: + FSGSenseGloveInfoImpl GetGloveInfo() const; + + TArray GetFingerThimbleOffsets() const; + + void SetFingerThimbleOffset(int32 Finger, const FVector& Offset); + + bool SupportsWristActuator() const; + +public: + bool GetSensorData(FSGSenseGloveSensorDataImpl& OutSensorData) const; + + bool GetGlovePose(FSGSenseGlovePoseImpl& OutGlovePose) const; + + bool GetGlovePose(const FSGSenseGloveSensorDataImpl& SensorData, FSGSenseGlovePoseImpl& OutGlovePose) const; + +public: + virtual bool QueueVibroLevel(int32 Finger, float Amplitude); + + virtual bool QueueThumperCommand(ESGSenseGloveThumperCommand Command); + +public: + virtual FString ToString() const override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGloveInfoImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGloveInfoImpl.h new file mode 100644 index 0000000..c757059 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGloveInfoImpl.h @@ -0,0 +1,168 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" +#include "SGTypes/SGCoreTypes.h" + +namespace SGCore +{ + namespace SG + { + class SenseGloveInfo; + } +} + +class SENSEGLOVECOREIMPL_API FSGSenseGloveInfoImpl final +{ +public: + typedef SGCore::SG::SenseGloveInfo FSenseGloveInfoType; + +public: + static bool Parse(const FString& ConstantsString, FSGSenseGloveInfoImpl& OutGloveInfo, + bool bUpdateOldModels = true); + + static FSGSenseGloveInfoImpl Deserialize(const FString& SerializedString); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGSenseGloveInfoImpl(); + + FSGSenseGloveInfoImpl(const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion, + bool bRightHanded, int32 NumberOfSensors, + const FQuat& ImuCorrection, + const TArray& StartPositions, + const TArray& StartRotations, + const TArray>& GloveLengths, + const TArray& Functions); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGSenseGloveInfoImpl(const FSenseGloveInfoType& GloveInfo); + +public: + /** + * The copy constructor. + */ + FSGSenseGloveInfoImpl(const FSGSenseGloveInfoImpl& Rhs); + + /** + * The move constructor. + */ + FSGSenseGloveInfoImpl(FSGSenseGloveInfoImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGSenseGloveInfoImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGSenseGloveInfoImpl& operator=(const FSGSenseGloveInfoImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGSenseGloveInfoImpl& operator=(FSGSenseGloveInfoImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FSenseGloveInfoType& ToSenseGloveInfo() const; + +public: + FString GetDeviceId() const; + + FString GetHardwareVersion() const; + + int32 GetFirmwareVersion() const; + + int32 GetSubFirmwareVersion() const; + + bool IsRight() const; + + int32 GetNumberOfSensors() const; + + FQuat GetImuCorrection() const; + + TArray GetStartPositions() const; + + TArray GetStartRotations() const; + + TArray> GetGloveLengths() const; + + TArray GetFunctions() const; + +public: + FVector GetStartPosition(ESGFinger Finger) const; + + FQuat GetStartRotation(ESGFinger Finger) const; + + TArray GetGloveLengths(ESGFinger Finger) const; + +public: + TArray> ToGloveAngles(const TArray>& SensorAngles) const; + + bool Equals(const FSGSenseGloveInfoImpl& SGSenseGloveInfo, bool bGeometryOnly = false) const; + +public: + FString ToString(bool bShortNotation) const; + + FString ToString() const; + + FString Serialize() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGlovePoseImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGlovePoseImpl.h new file mode 100644 index 0000000..f398ba1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGlovePoseImpl.h @@ -0,0 +1,148 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "Math/Vector.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" + +namespace SGCore +{ + namespace SG + { + class SenseGlovePose; + } +} + +class FSGSenseGloveHandProfileImpl; +class FSGSenseGloveInfoImpl; + +class SENSEGLOVECOREIMPL_API FSGSenseGlovePoseImpl final +{ +public: + typedef SGCore::SG::SenseGlovePose FSenseGlovePoseType; + +public: + static FSGSenseGlovePoseImpl IdlePose(const FSGSenseGloveInfoImpl& GloveInfo); + + static FSGSenseGlovePoseImpl Deserialize(const FString& SerializedString); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGSenseGlovePoseImpl(); + + FSGSenseGlovePoseImpl(bool bRightHanded, + const TArray>& JointPositions, + const TArray>& JointRotations, + const TArray>& GloveAngles); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGSenseGlovePoseImpl(const FSenseGlovePoseType& SenseGlovePose); + +public: + /** + * The copy constructor. + */ + FSGSenseGlovePoseImpl(const FSGSenseGlovePoseImpl& Rhs); + + /** + * The move constructor. + */ + FSGSenseGlovePoseImpl(FSGSenseGlovePoseImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGSenseGlovePoseImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGSenseGlovePoseImpl& operator=(const FSGSenseGlovePoseImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGSenseGlovePoseImpl& operator=(FSGSenseGlovePoseImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FSenseGlovePoseType& ToSenseGlovePose() const; + +public: + bool IsRight() const; + + TArray> GetJointPositions() const; + + TArray> GetJointRotations() const; + + TArray> GetGloveAngles() const; + +public: + TArray GetThimblePositions() const; + + TArray GetThimbleRotations() const; + + TArray GetTotalGloveAngles() const; + + TArray CalculateFingertips(const TArray& FingerOffsets) const; + + bool Equals(const FSGSenseGlovePoseImpl& SenseGlovePoseImpl) const; + +public: + FString ToString(bool bShortFormat = true) const; + + FString Serialize() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGloveSensorDataImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGloveSensorDataImpl.h new file mode 100644 index 0000000..65727e0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGloveSensorDataImpl.h @@ -0,0 +1,144 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" +#include "SGTypes/SGCoreTypes.h" + +namespace SGCore +{ + namespace SG + { + class SenseGloveSensorData; + } +} + +class FSGSenseGloveInfoImpl; + +class SENSEGLOVECOREIMPL_API FSGSenseGloveSensorDataImpl final +{ +public: + typedef SGCore::SG::SenseGloveSensorData FSenseGloveSensorDataType; + +public: + static const FSGSenseGloveSensorDataImpl& Empty(); + + static FSGSenseGloveSensorDataImpl Parse(const FString& RawData, const FSGSenseGloveInfoImpl& GloveInfo); + + static FSGSenseGloveSensorDataImpl Deserialize(const FString& SerializedString); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGSenseGloveSensorDataImpl(); + + FSGSenseGloveSensorDataImpl(const TArray>& SensorAngles, const FQuat& ImuRotation, + int32 ParsedValues, bool bImuParsed); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGSenseGloveSensorDataImpl(const FSenseGloveSensorDataType& SenseGloveSensorData); + +public: + /** + * The copy constructor. + */ + FSGSenseGloveSensorDataImpl(const FSGSenseGloveSensorDataImpl& Rhs); + + /** + * The move constructor. + */ + FSGSenseGloveSensorDataImpl(FSGSenseGloveSensorDataImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGSenseGloveSensorDataImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGSenseGloveSensorDataImpl& operator=(const FSGSenseGloveSensorDataImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGSenseGloveSensorDataImpl& operator=(FSGSenseGloveSensorDataImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FSenseGloveSensorDataType& ToSenseGloveSensorData() const; + +public: + TArray> GetSensorAngles() const; + + TArray GetSensorAngles(ESGFinger Finger) const; + + TArray GetAngleSequence() const; + + FQuat GetImuRotation() const; + + int32 GetParsedValues() const; + +public: + bool IsImuParsed() const; + +public: + bool Equals(const FSGSenseGloveSensorDataImpl& SenseGloveSensorDataImpl) const; + +public: + FString ToString() const; + + FString Serialize() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGloveSensorNormalizerImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGloveSensorNormalizerImpl.h new file mode 100644 index 0000000..1b957e5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGloveSensorNormalizerImpl.h @@ -0,0 +1,117 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" + +namespace SGCore +{ + namespace SG + { + class SenseGloveSensorNormalizer; + } +} + +class FSGSenseGloveInfoImpl; + +class SENSEGLOVECOREIMPL_API FSGSenseGloveSensorNormalizerImpl final +{ +public: + typedef SGCore::SG::SenseGloveSensorNormalizer FSenseGloveSensorNormalizerType; + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGSenseGloveSensorNormalizerImpl(); + + explicit FSGSenseGloveSensorNormalizerImpl(bool bRightHanded); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGSenseGloveSensorNormalizerImpl(const FSenseGloveSensorNormalizerType& SenseGloveSensorNormalizer); + +public: + /** + * The copy constructor. + */ + FSGSenseGloveSensorNormalizerImpl(const FSGSenseGloveSensorNormalizerImpl& Rhs); + + /** + * The move constructor. + */ + FSGSenseGloveSensorNormalizerImpl(FSGSenseGloveSensorNormalizerImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGSenseGloveSensorNormalizerImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGSenseGloveSensorNormalizerImpl& operator=(const FSGSenseGloveSensorNormalizerImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGSenseGloveSensorNormalizerImpl& operator=(FSGSenseGloveSensorNormalizerImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FSenseGloveSensorNormalizerType& ToSenseGloveSensorNormalizer() const; + +public: + float NormalizeFlexion(int32 Finger, float SumFlexionAngles) const; + + float NormalizeAbduction(int32 Finger, float SumAbductionAngles) const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGloveVarsImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGloveVarsImpl.h new file mode 100644 index 0000000..2a4777f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSenseGloveVarsImpl.h @@ -0,0 +1,85 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "Math/Quat.h" +#include "Math/Vector.h" + +class FSGSenseGloveInfoImpl; + +namespace SGCore +{ + namespace SG + { + class SenseGloveVars; + } +} + +class SENSEGLOVECOREIMPL_API FSGSenseGloveVarsImpl final +{ +public: + typedef SGCore::SG::SenseGloveVars FSenseGloveVarsType; + +public: + static FString GetStandardConstantsString(const FString& HardwareVersion, float FirmwareVersion, bool bRightHanded); + + static FString GetSensorString(const FString& HardwareVersion, float FirmwareVersion); + + static TArray GetStartPositions(const FString& HardwareVersion, bool bRightHanded); + + static TArray GetStartRotations(const FString& HardwareVersion, bool bRightHanded); + + static TArray> GetGloveLengths(const FString& HardwareVersion); + + static int32 GetSensors(const FString& HardwareVersion); + + static FQuat GetImuCorrection(const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion); + + static TArray GetFunctions(const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion); + + static FSGSenseGloveInfoImpl GenerateGloveModel(const FString& HardwareVersion, int32 FirmwareVersion, + int32 SubFirmwareVersion, bool bRightHanded); + + static FSGSenseGloveInfoImpl GenerateGloveModel(const FString& HardwareVersion, int32 FirmwareVersion, + int32 SubFirmwareVersion, bool bRightHanded, + const FString& CustomId); + +public: + FSGSenseGloveVarsImpl() = delete; + virtual ~FSGSenseGloveVarsImpl() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSensorNormalizationImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSensorNormalizationImpl.h new file mode 100644 index 0000000..3c1840d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGSensorNormalizationImpl.h @@ -0,0 +1,142 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" + +namespace SGCore +{ + namespace Util + { + class SensorNormalization; + } +} + +class FSGSenseGloveInfoImpl; + +class SENSEGLOVECOREIMPL_API FSGSensorNormalizationImpl final +{ +public: + typedef SGCore::Util::SensorNormalization FSensorNormalizationType; + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGSensorNormalizationImpl(); + + explicit FSGSensorNormalizationImpl(const TArray& MovementRanges); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGSensorNormalizationImpl(const FSensorNormalizationType& SensorNormalization); + +public: + /** + * The copy constructor. + */ + FSGSensorNormalizationImpl(const FSGSensorNormalizationImpl& Rhs); + + /** + * The move constructor. + */ + FSGSensorNormalizationImpl(FSGSensorNormalizationImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGSensorNormalizationImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGSensorNormalizationImpl& operator=(const FSGSensorNormalizationImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGSensorNormalizationImpl& operator=(FSGSensorNormalizationImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FSensorNormalizationType& ToSensorNormalization() const; + + /** + * The cast to underlying type method. + */ + FSensorNormalizationType& ToSensorNormalization(); + +public: + bool CollectsNormalization() const; + + void SetCollectNormalization(bool bCollectNormalization); + +public: + int32 GetLength() const; + + int32 GetMoveCount() const; + + bool AllSensorsMoving() const; + + void ResetNormalization(); + + void UpdateNormalization(float Value, int32 Index); + + float NormalizeValue(float Value, int32 Index); + + TArray NormalizeValues(const TArray& Values); + + bool MovedEnough(int32 Index) const; + + float Denormalize(float Value01, int32 Index, float FallbackValue = 1.0f) const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGThresholdCommandImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGThresholdCommandImpl.h new file mode 100644 index 0000000..ebc381a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGThresholdCommandImpl.h @@ -0,0 +1,141 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" + +namespace SGCore +{ + namespace Haptics + { + class ThresholdCommand; + } +} + +class FSGSenseGloveInfoImpl; + +class SENSEGLOVECOREIMPL_API FSGThresholdCommandImpl final +{ +public: + typedef SGCore::Haptics::ThresholdCommand FThresholdCommandType; + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGThresholdCommandImpl(); + FSGThresholdCommandImpl(const TArray& AffectedFingers, const TArray& ThresholdValues); + +public: + /** + * The cast from underlying type constructor. + */ + explicit FSGThresholdCommandImpl(const FThresholdCommandType& ThresholdCommand); + +public: + /** + * The copy constructor. + */ + FSGThresholdCommandImpl(const FSGThresholdCommandImpl& Rhs); + + /** + * The move constructor. + */ + FSGThresholdCommandImpl(FSGThresholdCommandImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGThresholdCommandImpl(); + +public: + /** + * The copy assignment operator. + */ + FSGThresholdCommandImpl& operator=(const FSGThresholdCommandImpl& Rhs); + + /** + * The move assignment operator. + */ + FSGThresholdCommandImpl& operator=(FSGThresholdCommandImpl&& Rhs) SG_NOEXCEPT; + +public: + /** + * The cast to underlying type method. + */ + const FThresholdCommandType& ToThresholdCommand() const; + + /** + * The cast to underlying type method. + */ + FThresholdCommandType& ToThresholdCommand(); + +public: + float GetThreshold(int32 Finger) const; + + void SetThreshold(int32 Finger, float ThresholdValue); + + TArray GetThresholds() const; + + void SetThresholds(const TArray& AffectedFingers, const TArray& ThresholdValues); + + bool GetFingerActive(int32 Finger) const; + + TArray GetActiveFingers() const; + + void ClearThreshold(int32 Finger); + + void ClearThresholds(); + +public: + bool Equals(const FSGThresholdCommandImpl& ThresholdCommand) const; + +public: + FString ToString() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGTrackingImpl.h b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGTrackingImpl.h new file mode 100644 index 0000000..fcd0148 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/Public/SGCoreImpl/SGTrackingImpl.h @@ -0,0 +1,168 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" +#include "Math/Quat.h" +#include "Math/Vector.h" + +#include "SGBuildHacks/SGInclude_Core_Tracking.h" +#include "SGTypes/SGCoreTypes.h" + +class SENSEGLOVECOREIMPL_API FSGTrackingImpl +{ +public: + typedef SGCore::Tracking FTrackingType; + +public: + static void CalculateLocation( + const FVector& TrackedPosition, const FQuat& TrackedRotation, + const FVector& PositionOffset, const FQuat& RotationOffset, + FVector& OutNewPosition, FQuat& OutNewRotation); + + static const TArray& GetSenseGloveFingerToGlovePositionOrigin(); + + static const TArray& GetSenseGloveFingerToGloveRotationOrigin(); + + static const FVector& GetSenseGloveWristPositionOffset(); + + static const FQuat& GetSenseGloveWristRotationOffset(); + + static void GetSenseGloveMountOffset(bool bRightHanded, ESGFinger ToFinger, + FVector& OutIPosition, FQuat& OutIRotation); + + static void GetSenseGloveTrackerMountOffset(ESGPositionalTrackingHardware Hardware, bool bRightHanded, + FVector& OutPositionOffset, FQuat& OutRotationOffset); + + static const FVector& GetSenseGloveViveToAttachPosition(); + static const FQuat& GetSenseGloveViveToAttachRotation(); + + static const FVector& GetSenseGloveOculusTouchToAttachPosition(); + static const FQuat& GetSenseGloveOculusTouchToAttachRotation(); + + static const FVector& GetNovaToWristPositionOffset(); + static const FQuat& GetNovaToWristRotationOffset(); + + static const FVector& GetRightNovaViveToAttachPosition(); + static const FQuat& GetRightNovaViveToAttachRotation(); + + static const FVector& GetLeftNovaViveToAttachPosition(); + static const FQuat& GetLeftNovaViveToAttachRotation(); + + static const FVector& GetRightNovaQuest2ToAttachPosition(); + static const FQuat& GetRightNovaQuest2ToAttachRotation(); + + static const FVector& GetLeftNovaQuest2ToAttachPosition(); + static const FQuat& GetLeftNovaQuest2ToAttachRotation(); + + static const FVector& GetRightNovaPico2ToAttachPosition(); + static const FQuat& GetRightNovaPico2ToAttachRotation(); + + static const FQuat& GetLeftNovaPico2ToAttachRotation(); + + static const FVector& GetRightNovaQuestProToAttachPosition(); + static const FQuat& GetRightNovaQuestProToAttachRotation(); + + static const FVector& GetLeftNovaQuestProToAttachPosition(); + static const FQuat& GetLeftNovaQuestProToAttachRotation(); + + static const FVector& GetRightNovaViveFocus3ToAttachPosition(); + static const FQuat& GetRightNovaViveFocus3ToAttachRotation(); + + static const FVector& GetLeftNovaViveFocus3ToAttachPosition(); + static const FQuat& GetLeftNovaViveFocus3ToAttachRotation(); + + static const FVector& GetRightNovaQuest3ToAttachPosition(); + static const FQuat& GetRightNovaQuest3ToAttachRotation(); + + static const FVector& GetLeftNovaQuest3ToAttachPosition(); + static const FQuat& GetLeftNovaQuest3ToAttachRotation(); + + static void GetNovaGloveWristOffset(bool bRightHanded, FVector& OutPositionOffset, FQuat& OutRotationOffset); + + static void GetNovaGloveTrackerOffset(ESGPositionalTrackingHardware Hardware, bool bRightHanded, + FVector& OutPositionOffset, FQuat& OutRotationOffset); + + static const FVector& GetRightNova2ToWristPositionOffset(); + static const FQuat& GetRightNova2ToWristRotationOffset(); + + static const FVector& GetLeftNova2ToWristPositionOffset(); + static const FQuat& GetLeftNova2ToWristRotationOffset(); + + static const FVector& GetRightNova2Quest2ToAttachPosition(); + static const FQuat& GetRightNova2Quest2ToAttachRotation(); + + static const FVector& GetLeftNova2Quest2ToAttachPosition(); + static const FQuat& GetLeftNova2Quest2ToAttachRotation(); + + static const FVector& GetRightNova2QuestProToAttachPosition(); + static const FQuat& GetRightNova2QuestProToAttachRotation(); + + static const FVector& GetLeftNova2QuestProToAttachPosition(); + static const FQuat& GetLeftNova2QuestProToAttachRotation(); + + static const FVector& GetRightNova2ViveTrackerToAttachPosition(); + static const FQuat& GetRightNova2ViveTrackerToAttachRotation(); + + static const FVector& GetLeftNova2ViveTrackerToAttachPosition(); + static const FQuat& GetLeftNova2ViveTrackerToAttachRotation(); + + static const FVector& GetRightNova2ViveWristTrackerToAttachPosition(); + static const FQuat& GetRightNova2ViveWristTrackerToAttachRotation(); + + static const FVector& GetRightNova2Quest3ToAttachPosition(); + static const FQuat& GetRightNova2Quest3ToAttachRotation(); + + static const FVector& GetLeftNova2Quest3ToAttachPosition(); + static const FQuat& GetLeftNova2Quest3ToAttachRotation(); + + static const FVector& GetLeftNova2ViveWristTrackerToAttachPosition(); + static const FQuat& GetLeftNova2ViveWristTrackerToAttachRotation(); + + static void GetNova2GloveWristOffset(bool bRightHanded, const FString& HardwareVersion, + FVector& OutPositionOffset, FQuat& OutRotationOffset); + + static void GetNova2GloveTrackerOffset(ESGPositionalTrackingHardware Hardware, bool bRightHanded, + const FString& HardwareVersion, + FVector& OutPositionOffset, + FQuat& OutRotationOffset); + + static FString ToString(ESGPositionalTrackingHardware Hardware); + +public: + FSGTrackingImpl() = delete; + virtual ~FSGTrackingImpl() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreImpl/SenseGloveCoreImpl.Build.cs b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/SenseGloveCoreImpl.Build.cs new file mode 100644 index 0000000..ae3308c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreImpl/SenseGloveCoreImpl.Build.cs @@ -0,0 +1,206 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using UnrealBuildTool; + +public class SenseGloveCoreImpl : ModuleRules +{ + public SenseGloveCoreImpl(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + bEnableExceptions = true; + bUseRTTI = true; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveLog", + "SenseGloveTypes", + "SenseGloveUtils", + } + ); + + PrivateIncludePathModuleNames.AddRange( + new string[] + { + "SenseGloveBuildHacks", + "SenseGloveInterop", + } + ); + + AddCoreLibrary(Target); + + PublicDefinitions.Add("SENSEGLOVE_BUILDING_CORE_IMPL_MODULE"); + PublicDefinitions.Add("SENSEGLOVE_UNREAL_ENGINE_PLUGIN"); + } + + private void AddCoreLibrary(ReadOnlyTargetRules Target) + { + string PluginRootDirectory = Path.GetFullPath(Path.Combine(ModuleDirectory, "..", "..")); + string SourceDirectory = Path.GetFullPath(Path.Combine(PluginRootDirectory, "Source")); + string ThirdPartyDirectory = Path.GetFullPath(Path.Combine(SourceDirectory, "ThirdParty")); + string LibraryPath = Path.GetFullPath(Path.Combine(ThirdPartyDirectory, "lib")); + string LibraryPathAnroidArm64 = ""; + string LibraryPathAnroidx64 = ""; + string LibraryName = "sgcore"; + + bool bIsAndroid = Target.IsInPlatformGroup(UnrealPlatformGroup.Android); + bool bIsLinux = Target.Platform == UnrealTargetPlatform.Linux; + bool bIsLinuxArm64 = Target.Platform == UnrealTargetPlatform.LinuxArm64; + bool bIsWin64 = Target.IsInPlatformGroup(UnrealPlatformGroup.Windows) && + Target.WindowsPlatform.Architecture == UnrealArch.X64; + bool bIsDebugBuild = (Target.Configuration == UnrealTargetConfiguration.Debug); + + if (bIsAndroid) + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "android")); + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "r25b")); + + LibraryPathAnroidArm64 = Path.GetFullPath(Path.Combine(LibraryPath, "arm64")); + LibraryPathAnroidx64 = Path.GetFullPath(Path.Combine(LibraryPath, "x64")); + + LibraryName = string.Format("lib{0}.a", LibraryName); + } + else if (bIsLinux) + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "linux")); + LibraryName = string.Format("lib{0}.a", LibraryName); + +#if UE_5_5_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v23")); +#elif UE_5_3_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v22")); +#elif UE_5_2_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v21")); +#else + Debug.Assert(false, "Unsupported engine version or compiler!"); +#endif + + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "x86-64")); + } + else if (bIsLinuxArm64) + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "linux")); + LibraryName = string.Format("lib{0}.a", LibraryName); + +#if UE_5_5_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v23")); +#elif UE_5_3_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v22")); +#elif UE_5_2_OR_LATER + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "v21")); +#else + Debug.Assert(false, "Unsupported engine version or compiler!"); +#endif + + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "aarch64")); + } + else if (bIsWin64) + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "win64")); + switch (Target.WindowsPlatform.Compiler) + { + case WindowsCompiler.VisualStudio2022: + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "msvc143")); + break; +#if ! UE_5_4_OR_LATER + case WindowsCompiler.VisualStudio2019: + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "msvc142")); + break; +#endif + default: + Debug.Assert(false, "Unsupported engine version or compiler!"); + break; + } + + LibraryName = string.Format("{0}.lib", LibraryName); + } + else + { + Debug.Assert(false, "Unsupported platform!"); + } + + string IncludePath = Path.GetFullPath(Path.Combine(ThirdPartyDirectory, "include")); + PrivateIncludePaths.Add(IncludePath); + + if (bIsAndroid) + { + if (bIsDebugBuild) + { + LibraryPathAnroidArm64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidArm64, "debug")); + LibraryPathAnroidx64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidx64, "debug")); + } + else + { + LibraryPathAnroidArm64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidArm64, "release")); + LibraryPathAnroidx64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidx64, "release")); + } + + LibraryPathAnroidArm64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidArm64, LibraryName)); + LibraryPathAnroidx64 = Path.GetFullPath(Path.Combine(LibraryPathAnroidx64, LibraryName)); + + PublicAdditionalLibraries.Add(LibraryPathAnroidArm64); + PublicAdditionalLibraries.Add(LibraryPathAnroidx64); + } + else + { + if (bIsDebugBuild) + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "debug")); + } + else + { + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "release")); + } + + LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, LibraryName)); + PublicAdditionalLibraries.Add(LibraryPath); + } + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGAnatomyKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGAnatomyKismetLibrary.cpp new file mode 100644 index 0000000..4b824ee --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGAnatomyKismetLibrary.cpp @@ -0,0 +1,107 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGAnatomyKismetLibrary.h" + +#include "SGCore/SGAnatomy.h" +#include "SGUtils/SGArrayUtils.h" + +float USGAnatomyKismetLibrary::GetTotalFingerFlexion() +{ + return FSGAnatomy::GetTotalFingerFlexion(); +} + +float USGAnatomyKismetLibrary::GetTotalFingerExtension() +{ + return FSGAnatomy::GetTotalFingerExtension(); +} + +float USGAnatomyKismetLibrary::GetTotalThumbFlexion() +{ + return FSGAnatomy::GetTotalThumbFlexion(); +} + +float USGAnatomyKismetLibrary::GetTotalThumbExtension() +{ + return FSGAnatomy::GetTotalThumbExtension(); +} + +float USGAnatomyKismetLibrary::GetFingerJointLimit(const bool bRightHanded, const int32 Joint, const int32 Movement, + const bool bMax) +{ + return FSGAnatomy::GetFingerJointLimit(bRightHanded, Joint, Movement, bMax); +} + +float USGAnatomyKismetLibrary::GetThumbJointLimit(const bool bRightHanded, const int32 Joint, const int32 Movement, + const bool bMax) +{ + return FSGAnatomy::GetThumbJointLimit(bRightHanded, Joint, Movement, bMax); +} + +float USGAnatomyKismetLibrary::ClampJointAngle( + const float Value, const int32 Finger, const bool bRightHand, const int32 Joint, const int32 Movement) +{ + return FSGAnatomy::ClampJointAngle(Value, Finger, bRightHand, Joint, Movement); +} + +float USGAnatomyKismetLibrary::NormalizeFingerFlexion(const float FlexionInDegrees) +{ + return FSGAnatomy::NormalizeFingerFlexion(FlexionInDegrees); +} + +float USGAnatomyKismetLibrary::NormalizeThumbFlexion(const float FlexionInDegrees) +{ + return FSGAnatomy::NormalizeThumbFlexion(FlexionInDegrees); +} + +TArray USGAnatomyKismetLibrary::GetDefaultHandAngles(const bool bRightHanded) +{ + return FSGArrayUtils::ToNestedBPArray(FSGAnatomy::GetDefaultHandAngles(bRightHanded)); +} + +TArray USGAnatomyKismetLibrary::GetFlatHandAngles(const bool bRightHanded) +{ + return FSGArrayUtils::ToNestedBPArray(FSGAnatomy::GetFlatHandAngles(bRightHanded)); +} + +TArray USGAnatomyKismetLibrary::GetThumbsUpHandAngles(const bool bRightHanded) +{ + return FSGArrayUtils::ToNestedBPArray(FSGAnatomy::GetThumbsUpHandAngles(bRightHanded)); +} + +TArray USGAnatomyKismetLibrary::GetFistHandAngles(const bool bRightHanded) +{ + return FSGArrayUtils::ToNestedBPArray(FSGAnatomy::GetFistHandAngles(bRightHanded)); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGBasicHandModelKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGBasicHandModelKismetLibrary.cpp new file mode 100644 index 0000000..a415b92 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGBasicHandModelKismetLibrary.cpp @@ -0,0 +1,237 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGBasicHandModelKismetLibrary.h" + +#include "SGCore/SGBasicHandModel.h" +#include "SGUtils/SGArrayUtils.h" + +USGBasicHandModel* USGBasicHandModelKismetLibrary::MakeBasicHandModel(UObject* WorldContextObject) +{ + return USGBasicHandModel::NewBasicHandModel(WorldContextObject); +} + +USGBasicHandModel* USGBasicHandModelKismetLibrary::MakeBasicHandModel_bRH_L_SP( + UObject* WorldContextObject, + const bool bRightHanded, const TArray& Lengths, const TArray& StartPositions) +{ + return USGBasicHandModel::NewBasicHandModel(WorldContextObject, bRightHanded, Lengths, StartPositions); +} + +USGBasicHandModel* USGBasicHandModelKismetLibrary::MakeBasicHandModel_bRH_L_SP_TArrayFQuat_SR( + UObject* WorldContextObject, + const bool bRightHanded, const TArray& Lengths, + const TArray& StartPositions, const TArray& StartRotations) +{ + return USGBasicHandModel::NewBasicHandModel(WorldContextObject, bRightHanded, Lengths, + StartPositions, StartRotations); +} + +USGBasicHandModel* USGBasicHandModelKismetLibrary::MakeBasicHandModel_bRH_L_SP_TArrayFRotator_SR( + UObject* WorldContextObject, + const bool bRightHanded, const TArray& Lengths, + const TArray& StartPositions, const TArray& StartRotations) +{ + return USGBasicHandModel::NewBasicHandModel(WorldContextObject, bRightHanded, Lengths, + StartPositions, StartRotations); +} + +USGBasicHandModel* USGBasicHandModelKismetLibrary::Default(UObject* WorldContextObject, const bool bRightHanded) +{ + return USGBasicHandModel::Default(WorldContextObject, bRightHanded); +} + +USGBasicHandModel* USGBasicHandModelKismetLibrary::Deserialize(UObject* WorldContextObject, + const FString& SerializedString) +{ + return USGBasicHandModel::Deserialize(WorldContextObject, SerializedString); +} + +TArray USGBasicHandModelKismetLibrary::GetBaseFingerLengths() +{ + return FSGArrayUtils::ToNestedBPArray(USGBasicHandModel::GetBaseFingerLengths()); +} + +TArray USGBasicHandModelKismetLibrary::GetBaseJointPositions() +{ + return USGBasicHandModel::GetBaseJointPositions(); +} + +TArray USGBasicHandModelKismetLibrary::GetBaseJointAngles() +{ + return USGBasicHandModel::GetBaseJointAngles(); +} + +bool USGBasicHandModelKismetLibrary::IsRight(const USGBasicHandModel* BasicHandModel) +{ + return BasicHandModel->IsRight(); +} + +TArray USGBasicHandModelKismetLibrary::GetFingerLengths(const USGBasicHandModel* BasicHandModel) +{ + return FSGArrayUtils::ToNestedBPArray(BasicHandModel->GetFingerLengths()); +} + +TArray USGBasicHandModelKismetLibrary::GetFingerLengths_F(const USGBasicHandModel* BasicHandModel, + const ESGFinger Finger) +{ + return BasicHandModel->GetFingerLengths(Finger); +} + +void USGBasicHandModelKismetLibrary::SetFingerLengths_ESGFinger_F_L(USGBasicHandModel* BasicHandModel, + const ESGFinger Finger, + const TArray& Lengths) +{ + BasicHandModel->SetFingerLengths(Finger, Lengths); +} + +void USGBasicHandModelKismetLibrary::SetFingerLengths_uint8_F_L(USGBasicHandModel* BasicHandModel, + const uint8 Finger, const TArray& Lengths) +{ + BasicHandModel->SetFingerLengths(Finger, Lengths); +} + +TArray USGBasicHandModelKismetLibrary::GetFingerRatios(const USGBasicHandModel* BasicHandModel) const +{ + return FSGArrayUtils::ToNestedBPArray(BasicHandModel->GetFingerRatios()); +} + +TArray USGBasicHandModelKismetLibrary::GetFingerRatios_F(const USGBasicHandModel* BasicHandModel, + const ESGFinger Finger) +{ + return BasicHandModel->GetFingerRatios(Finger); +} + +TArray USGBasicHandModelKismetLibrary::GetStartJointPositions(const USGBasicHandModel* BasicHandModel) +{ + return BasicHandModel->GetStartJointPositions(); +} + +void USGBasicHandModelKismetLibrary::SetStartJointPosition_ESGFinger_F_P(USGBasicHandModel* BasicHandModel, + const ESGFinger Finger, + const FVector& Position) +{ + BasicHandModel->SetStartJointPosition(Finger, Position); +} + +void USGBasicHandModelKismetLibrary::SetStartJointPosition_uint8_F_P(USGBasicHandModel* BasicHandModel, + const uint8 Finger, const FVector& Position) +{ + BasicHandModel->SetStartJointPosition(Finger, Position); +} + +TArray USGBasicHandModelKismetLibrary::GetStartJointRotations_TArrayFQuat( + const USGBasicHandModel* BasicHandModel) +{ + return BasicHandModel->GetStartJointRotationsQ(); +} + +TArray USGBasicHandModelKismetLibrary::GetStartJointRotations_TArrayFRotator( + const USGBasicHandModel* BasicHandModel) +{ + return BasicHandModel->GetStartJointRotations(); +} + +FVector USGBasicHandModelKismetLibrary::GetJointPosition(const USGBasicHandModel* BasicHandModel, + const ESGFinger Finger) +{ + return BasicHandModel->GetJointPosition(Finger); +} + +void USGBasicHandModelKismetLibrary::SetJointPosition(USGBasicHandModel* BasicHandModel, const FVector& NewPosition, + const ESGFinger Finger) +{ + return BasicHandModel->SetJointPosition(NewPosition, Finger); +} + +FQuat USGBasicHandModelKismetLibrary::GetJointRotation_FQuat(const USGBasicHandModel* BasicHandModel, + const ESGFinger Finger) +{ + return BasicHandModel->GetJointRotationQ(Finger); +} + +FRotator USGBasicHandModelKismetLibrary::GetJointRotation_FRotator(const USGBasicHandModel* BasicHandModel, + const ESGFinger Finger) +{ + return BasicHandModel->GetJointRotation(Finger); +} + +void USGBasicHandModelKismetLibrary::SetJointRotation_FQuat_NR_F(USGBasicHandModel* BasicHandModel, + const FQuat& NewRotation, const ESGFinger Finger) +{ + return BasicHandModel->SetJointRotation(NewRotation, Finger); +} + +void USGBasicHandModelKismetLibrary::SetJointRotation_FRotator_NR_F(USGBasicHandModel* BasicHandModel, + const FRotator& NewRotation, const ESGFinger Finger) +{ + return BasicHandModel->SetJointRotation(NewRotation, Finger); +} + +TArray USGBasicHandModelKismetLibrary::GetTotalLengths(const USGBasicHandModel* BasicHandModel) +{ + return BasicHandModel->GetTotalLengths(); +} + +float USGBasicHandModelKismetLibrary::GetTotalLength(const USGBasicHandModel* BasicHandModel, const ESGFinger Finger) +{ + return BasicHandModel->GetTotalLength(Finger); +} + +TArray USGBasicHandModelKismetLibrary::Get3DLengths(const USGBasicHandModel* BasicHandModel, + const ESGFinger Finger) +{ + return BasicHandModel->Get3DLengths(Finger); +} + +bool USGBasicHandModelKismetLibrary::Equals(const USGBasicHandModel* A, const USGBasicHandModel* B) +{ + return A->Equals(B); +} + +FString USGBasicHandModelKismetLibrary::ToString(const USGBasicHandModel* BasicHandModel) +{ + return BasicHandModel->ToString(); +} + +FString USGBasicHandModelKismetLibrary::ToString_bLO(const USGBasicHandModel* BasicHandModel, const bool bLengthsOnly) +{ + return BasicHandModel->ToString(bLengthsOnly); +} + +FString USGBasicHandModelKismetLibrary::SGSerialize(const USGBasicHandModel* BasicHandModel) +{ + return BasicHandModel->SGSerialize(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGBetaDeviceKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGBetaDeviceKismetLibrary.cpp new file mode 100644 index 0000000..c14992f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGBetaDeviceKismetLibrary.cpp @@ -0,0 +1,93 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGBetaDeviceKismetLibrary.h" + +#include "SGCore/SGBetaDevice.h" + +USGBetaDevice* USGBetaDeviceKismetLibrary::Parse(UObject* WorldContextObject, const FString& String) +{ + return USGBetaDevice::Parse(WorldContextObject, String); +} + +ESGDeviceType USGBetaDeviceKismetLibrary::GetDeviceType(const USGBetaDevice* BetaDevice) +{ + return BetaDevice->GetDeviceType(); +} + +FString USGBetaDeviceKismetLibrary::GetDeviceId(const USGBetaDevice* BetaDevice) +{ + return BetaDevice->GetDeviceId(); +} + +FString USGBetaDeviceKismetLibrary::GetHardwareVersion(const USGBetaDevice* BetaDevice) +{ + return BetaDevice->GetHardwareVersion(); +} + +int32 USGBetaDeviceKismetLibrary::GetFirmwareVersion(const USGBetaDevice* BetaDevice) +{ + return BetaDevice->GetFirmwareVersion(); +} + +int32 USGBetaDeviceKismetLibrary::GetSubFirmwareVersion(const USGBetaDevice* BetaDevice) +{ + return BetaDevice->GetSubFirmwareVersion(); +} + +FString USGBetaDeviceKismetLibrary::GetConstantsString(const USGBetaDevice* BetaDevice) +{ + return BetaDevice->GetConstantsString(); +} + +FString USGBetaDeviceKismetLibrary::GetSensorData(const USGBetaDevice* BetaDevice) +{ + return BetaDevice->GetSensorData(); +} + +FString USGBetaDeviceKismetLibrary::GetLastCommand(const USGBetaDevice* BetaDevice) +{ + return BetaDevice->GetLastCommand(); +} + +bool USGBetaDeviceKismetLibrary::SendHaptics(const USGBetaDevice* BetaDevice, const FString& Command) +{ + return BetaDevice->SendHaptics(Command); +} + +FString USGBetaDeviceKismetLibrary::ToString(const USGBetaDevice* BetaDevice) +{ + return BetaDevice->ToString(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGCustomWaveformKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGCustomWaveformKismetLibrary.cpp new file mode 100644 index 0000000..31ae72c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGCustomWaveformKismetLibrary.cpp @@ -0,0 +1,195 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGCustomWaveformKismetLibrary.h" + +#include "SGCore/SGCustomWaveform.h" + +USGCustomWaveform* USGCustomWaveformKismetLibrary::MakeCustomWaveform(UObject* WorldContextObject) +{ + return USGCustomWaveform::NewCustomWaveform(WorldContextObject); +} + +USGCustomWaveform* USGCustomWaveformKismetLibrary::MakeCustomWaveform_A_D( + UObject* WorldContextObject, const float Amplitude, const float Duration) +{ + return USGCustomWaveform::NewCustomWaveform(WorldContextObject, Amplitude, Duration); +} + +USGCustomWaveform* USGCustomWaveformKismetLibrary::MakeCustomWaveform_A_D_F( + UObject* WorldContextObject, const float Amplitude, const float Duration, const float Frequency) +{ + return USGCustomWaveform::NewCustomWaveform(WorldContextObject, Amplitude, Duration, Frequency); +} + +FString USGCustomWaveformKismetLibrary::ToString_T(const ESGWaveformType Type) +{ + return USGCustomWaveform::ToString(Type); +} + +float USGCustomWaveformKismetLibrary::GetAmplitude(const USGCustomWaveform* CustomWaveform) +{ + return CustomWaveform->GetAmplitude(); +} + +void USGCustomWaveformKismetLibrary::SetAmplitude(USGCustomWaveform* CustomWaveform, const float Amplitude) +{ + CustomWaveform->SetAmplitude(Amplitude); +} + +ESGWaveformType USGCustomWaveformKismetLibrary::GetWaveType(const USGCustomWaveform* CustomWaveform) +{ + return CustomWaveform->GetWaveType(); +} + +void USGCustomWaveformKismetLibrary::SetWaveType(USGCustomWaveform* CustomWaveform, const ESGWaveformType Type) +{ + CustomWaveform->SetWaveType(Type); +} + +bool USGCustomWaveformKismetLibrary::IsInfinite(const USGCustomWaveform* CustomWaveform) +{ + return CustomWaveform->IsInfinite(); +} + +void USGCustomWaveformKismetLibrary::SetInfinite(USGCustomWaveform* CustomWaveform, const bool bInfinite) +{ + CustomWaveform->SetInfinite(bInfinite); +} + +int32 USGCustomWaveformKismetLibrary::GetRepeatAmount(const USGCustomWaveform* CustomWaveform) +{ + return CustomWaveform->GetRepeatAmount(); +} + +void USGCustomWaveformKismetLibrary::SetRepeatAmount(USGCustomWaveform* CustomWaveform, const int32 Amount) +{ + CustomWaveform->SetRepeatAmount(Amount); +} + +float USGCustomWaveformKismetLibrary::GetAttackTime(const USGCustomWaveform* CustomWaveform) +{ + return CustomWaveform->GetAttackTime(); +} + +void USGCustomWaveformKismetLibrary::SetAttackTime(USGCustomWaveform* CustomWaveform, const float Time) +{ + CustomWaveform->SetAttackTime(Time); +} + +float USGCustomWaveformKismetLibrary::GetSustainTime(const USGCustomWaveform* CustomWaveform) +{ + return CustomWaveform->GetSustainTime(); +} + +void USGCustomWaveformKismetLibrary::SetSustainTime(USGCustomWaveform* CustomWaveform, const float Time) +{ + CustomWaveform->SetSustainTime(Time); +} + +float USGCustomWaveformKismetLibrary::GetDecayTime(const USGCustomWaveform* CustomWaveform) +{ + return CustomWaveform->GetDecayTime(); +} + +void USGCustomWaveformKismetLibrary::SetDecayTime(USGCustomWaveform* CustomWaveform, const float Time) +{ + CustomWaveform->SetDecayTime(Time); +} + +float USGCustomWaveformKismetLibrary::GetFrequencyStart(const USGCustomWaveform* CustomWaveform) +{ + return CustomWaveform->GetFrequencyStart(); +} + +void USGCustomWaveformKismetLibrary::SetFrequencyStart(USGCustomWaveform* CustomWaveform, const float Frequency) +{ + CustomWaveform->SetFrequencyStart(Frequency); +} + +float USGCustomWaveformKismetLibrary::GetFrequencyEnd(const USGCustomWaveform* CustomWaveform) +{ + return CustomWaveform->GetFrequencyEnd(); +} + +void USGCustomWaveformKismetLibrary::SetFrequencyEnd(USGCustomWaveform* CustomWaveform, const float Frequency) +{ + CustomWaveform->SetFrequencyEnd(Frequency); +} + +float USGCustomWaveformKismetLibrary::GetFrequencySwitchTime(const USGCustomWaveform* CustomWaveform) +{ + return CustomWaveform->GetFrequencySwitchTime(); +} + +void USGCustomWaveformKismetLibrary::SetFrequencySwitchTime(USGCustomWaveform* CustomWaveform, const float Time) +{ + CustomWaveform->SetFrequencySwitchTime(Time); +} + +float USGCustomWaveformKismetLibrary::GetFrequencySwitchFactor(const USGCustomWaveform* CustomWaveform) +{ + return CustomWaveform->GetFrequencySwitchFactor(); +} + +void USGCustomWaveformKismetLibrary::SetFrequencySwitchFactor(USGCustomWaveform* CustomWaveform, const float Time) +{ + CustomWaveform->SetFrequencySwitchFactor(Time); +} + +float USGCustomWaveformKismetLibrary::GetEffectTime(const USGCustomWaveform* CustomWaveform) +{ + return CustomWaveform->GetEffectTime(); +} + +float USGCustomWaveformKismetLibrary::GetTotalEffectTime(const USGCustomWaveform* CustomWaveform) +{ + return CustomWaveform->GetTotalEffectTime(); +} + +bool USGCustomWaveformKismetLibrary::FrequencyJumps(const USGCustomWaveform* CustomWaveform) +{ + return CustomWaveform->FrequencyJumps(); +} + +bool USGCustomWaveformKismetLibrary::Equals(const USGCustomWaveform* A, const USGCustomWaveform* B) +{ + return A->Equals(B); +} + +FString USGCustomWaveformKismetLibrary::ToString(const USGCustomWaveform* CustomWaveform) +{ + return CustomWaveform->ToString(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGDeviceKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGDeviceKismetLibrary.cpp new file mode 100644 index 0000000..2cc02bd --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGDeviceKismetLibrary.cpp @@ -0,0 +1,182 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGDeviceKismetLibrary.h" + +#include "SGCore/SGDevice.h" +#include "SGCore/SGHapticChannelInfo.h" + +void USGDeviceKismetLibrary::ParseFirmware(const FString& RawFirmware, int32& OutMainVersion, int32& OutSubVersion) +{ + return USGDevice::ParseFirmware(RawFirmware, OutMainVersion, OutSubVersion); +} + +bool USGDeviceKismetLibrary::FirmwareNewerThan_MF_MF_RM_RS_bI(const int32 MyFirmwareMain, const int32 MyFirmwareSub, + const int32 ReferenceMain, const int32 ReferenceSub, + const bool bInclusive) +{ + return USGDevice::FirmwareNewerThan(MyFirmwareMain, MyFirmwareSub, ReferenceMain, ReferenceSub, bInclusive); +} + +bool USGDeviceKismetLibrary::FirmwareOlderThan_MF_MF_RM_RS_bI(const int32 MyFirmwareMain, const int32 MyFirmwareSub, + const int32 ReferenceMain, const int32 ReferenceSub, + const bool bInclusive) +{ + return USGDevice::FirmwareOlderThan(MyFirmwareMain, MyFirmwareSub, ReferenceMain, ReferenceSub, bInclusive); +} + +FString USGDeviceKismetLibrary::ToString_DT(const ESGDeviceType DeviceType) +{ + return USGDevice::ToString(DeviceType); +} + +ESGDeviceType USGDeviceKismetLibrary::GetDeviceType(const USGDevice* SGDevice) +{ + return SGDevice->GetDeviceType(); +} + +FString USGDeviceKismetLibrary::GetDeviceId(const USGDevice* SGDevice) +{ + return SGDevice->GetDeviceId(); +} + +FString USGDeviceKismetLibrary::GetHardwareVersion(const USGDevice* SGDevice) +{ + return SGDevice->GetHardwareVersion(); +} + +int32 USGDeviceKismetLibrary::GetFirmwareVersion(const USGDevice* SGDevice) +{ + return SGDevice->GetFirmwareVersion(); +} + +int32 USGDeviceKismetLibrary::GetSubFirmwareVersion(const USGDevice* SGDevice) +{ + return SGDevice->GetSubFirmwareVersion(); +} + +FString USGDeviceKismetLibrary::GetFirmwareString(const USGDevice* SGDevice) +{ + return SGDevice->GetFirmwareString(); +} + +bool USGDeviceKismetLibrary::FirmwareNewerThan_FM_FS_bI(const USGDevice* SGDevice, + const int32 FirmwareMain, const int32 FirmwareSub, + const bool bInclusive) +{ + return SGDevice->FirmwareNewerThan(FirmwareMain, FirmwareSub, bInclusive); +} + +bool USGDeviceKismetLibrary::FirmwareOlderThan_FM_FS_bI(const USGDevice* SGDevice, + const int32 FirmwareMain, const int32 FirmwareSub, + const bool bInclusive) +{ + return SGDevice->FirmwareOlderThan(FirmwareMain, FirmwareSub, bInclusive); +} + +FString USGDeviceKismetLibrary::GetAddress(const USGDevice* SGDevice) +{ + return SGDevice->GetAddress(); +} + +bool USGDeviceKismetLibrary::IsConnected(const USGDevice* SGDevice) +{ + return SGDevice->IsConnected(); +} + +ESGConnectionType USGDeviceKismetLibrary::GetConnectionType(const USGDevice* SGDevice) +{ + return SGDevice->GetConnectionType(); +} + +int32 USGDeviceKismetLibrary::PacketsPerSecondReceived(const USGDevice* SGDevice) +{ + return SGDevice->PacketsPerSecondReceived(); +} + +int32 USGDeviceKismetLibrary::PacketsPerSecondSent(const USGDevice* SGDevice) +{ + return SGDevice->PacketsPerSecondSent(); +} + +int32 USGDeviceKismetLibrary::GetDeviceIndex(const USGDevice* SGDevice) +{ + return SGDevice->GetDeviceIndex(); +} + +void USGDeviceKismetLibrary::SetDeviceIndex(USGDevice* SGDevice, const int32 NewIndex) +{ + SGDevice->SetDeviceIndex(NewIndex); +} + +bool USGDeviceKismetLibrary::IsWireless(const USGDevice* SGDevice) +{ + return SGDevice->IsWireless(); +} + +bool USGDeviceKismetLibrary::HasBattery(const USGDevice* SGDevice) +{ + return SGDevice->HasBattery(); +} + +bool USGDeviceKismetLibrary::IsCharging(USGDevice* SGDevice) +{ + return SGDevice->IsCharging(); +} + +bool USGDeviceKismetLibrary::GetBatteryLevel(USGDevice* SGDevice, float& OutLevel) +{ + return SGDevice->GetBatteryLevel(OutLevel); +} + +void USGDeviceKismetLibrary::SetHapticChannels(USGDevice* SGDevice, const USGHapticChannelInfo* Channels) +{ + SGDevice->SetHapticChannels(Channels); +} + +int32 USGDeviceKismetLibrary::GetHapticChannelCount(const USGDevice* SGDevice) +{ + return SGDevice->GetHapticChannelCount(); +} + +int32 USGDeviceKismetLibrary::GetHapticChannelCount_CT(const USGDevice* SGDevice, ESGHapticChannelType ChannelType) +{ + return SGDevice->GetHapticChannelCount(ChannelType); +} + +FString USGDeviceKismetLibrary::ToString(const USGDevice* SGDevice) +{ + return SGDevice->ToString(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGDeviceListKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGDeviceListKismetLibrary.cpp new file mode 100644 index 0000000..1475a1c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGDeviceListKismetLibrary.cpp @@ -0,0 +1,119 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGDeviceListKismetLibrary.h" + +#include "SGCore/SGDevice.h" +#include "SGCore/SGDeviceList.h" + +int32 USGDeviceListKismetLibrary::ActiveDevices() +{ + return FSGDeviceList::ActiveDevices(); +} + +bool USGDeviceListKismetLibrary::SenseCommRunning() +{ + return FSGDeviceList::SenseCommRunning(); +} + +void USGDeviceListKismetLibrary::Dispose() +{ + FSGDeviceList::Dispose(); +} + +void USGDeviceListKismetLibrary::Reinitialize() +{ + FSGDeviceList::Reinitialize(); +} + +TArray USGDeviceListKismetLibrary::GetDevices(UObject* WorldContextObject) +{ + return FSGDeviceList::GetDevices(WorldContextObject); +} + +TArray USGDeviceListKismetLibrary::GetDevices_TSubclassOfUSGDevice_DT( + UObject* WorldContextObject, const TSubclassOf& DeviceType) +{ + return FSGDeviceList::GetDevices(WorldContextObject, DeviceType); +} + +TArray USGDeviceListKismetLibrary::GetDevices_ESGDeviceType_DT( + UObject* WorldContextObject, const ESGDeviceType DeviceType) +{ + return FSGDeviceList::GetDevices(WorldContextObject, DeviceType); +} + +bool USGDeviceListKismetLibrary::GetSensorDataString(const int32 IpcIndex, const FString& IpcAddress, + FString& OutString) +{ + return FSGDeviceList::GetSensorDataString(IpcIndex, IpcAddress, OutString); +} + +bool USGDeviceListKismetLibrary::SendHaptics( + const int32 IpcIndex, const FString& IpcAddress, const int32 ChannelIndex, const FString& Commands) +{ + return FSGDeviceList::SendHaptics(IpcIndex, IpcAddress, ChannelIndex, Commands); +} + +FString USGDeviceListKismetLibrary::GetDeviceStringAt(const int32 IpcIndex, const FString& IpcAddress, + const int32 Index) +{ + return FSGDeviceList::GetDeviceStringAt(IpcIndex, IpcAddress, Index); +} + +FString USGDeviceListKismetLibrary::GetAddress(const int32 IpcIndex, const FString& IpcAddress) +{ + return FSGDeviceList::GetAddress(IpcIndex, IpcAddress); +} + +ESGConnectionType USGDeviceListKismetLibrary::GetConnectionType(const int32 IpcIndex, const FString& IpcAddress) +{ + return FSGDeviceList::GetConnectionType(IpcIndex, IpcAddress); +} + +bool USGDeviceListKismetLibrary::IsConnected(const int32 IpcIndex, const FString& IpcAddress) +{ + return FSGDeviceList::IsConnected(IpcIndex, IpcAddress); +} + +int32 USGDeviceListKismetLibrary::PacketsPerSecondReceived(const int32 IpcIndex, const FString& IpcAddress) +{ + return FSGDeviceList::PacketsPerSecondReceived(IpcIndex, IpcAddress); +} + +int32 USGDeviceListKismetLibrary::PacketsPerSecondSent(const int32 IpcIndex, const FString& IpcAddress) +{ + return FSGDeviceList::PacketsPerSecondSent(IpcIndex, IpcAddress); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGDeviceModelKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGDeviceModelKismetLibrary.cpp new file mode 100644 index 0000000..0aac9d3 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGDeviceModelKismetLibrary.cpp @@ -0,0 +1,94 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGDeviceModelKismetLibrary.h" + +#include "SGCore/SGDeviceModel.h" + +USGDeviceModel* USGDeviceModelKismetLibrary::MakeDeviceModel(UObject* WorldContextObject) +{ + return USGDeviceModel::NewDeviceModel(WorldContextObject); +} + +USGDeviceModel* USGDeviceModelKismetLibrary::MakeDeviceModel_I_HV_FV_SFV( + UObject* WorldContextObject, + const FString& Id, const FString& HardwareVersion, const int32 FirmwareVersion, const int32 SubFirmwareVersion) +{ + return USGDeviceModel::NewDeviceModel(WorldContextObject, Id, HardwareVersion, FirmwareVersion, SubFirmwareVersion); +} + +TArray USGDeviceModelKismetLibrary::ParseFunctions(const int32 Value, const int32 Size) +{ + return USGDeviceModel::ParseFunctions(Value, Size); +} + +void USGDeviceModelKismetLibrary::ParseFirmware(const FString& RawFirmware, int32& OutMainVersion, int32& OutSubVersion) +{ + USGDeviceModel::ParseFirmware(RawFirmware, OutMainVersion, OutSubVersion); +} + +FString USGDeviceModelKismetLibrary::GetDeviceId(const USGDeviceModel* DeviceModel) +{ + return DeviceModel->GetDeviceId(); +} + +FString USGDeviceModelKismetLibrary::GetHardwareVersion(const USGDeviceModel* DeviceModel) +{ + return DeviceModel->GetHardwareVersion(); +} + +int32 USGDeviceModelKismetLibrary::GetFirmwareVersion(const USGDeviceModel* DeviceModel) +{ + return DeviceModel->GetFirmwareVersion(); +} + +int32 USGDeviceModelKismetLibrary::GetSubFirmwareVersion(const USGDeviceModel* DeviceModel) +{ + return DeviceModel->GetSubFirmwareVersion(); +} + +bool USGDeviceModelKismetLibrary::FirmwareNewerThan(const USGDeviceModel* DeviceModel, + const int32 FirmwareMain, const int32 FirmwareSub, + const bool bInclusive) +{ + return DeviceModel->FirmwareNewerThan(FirmwareMain, FirmwareSub, bInclusive); +} + +bool USGDeviceModelKismetLibrary::FirmwareOlderThan(const USGDeviceModel* DeviceModel, + const int32 FirmwareMain, const int32 FirmwareSub, + const bool bInclusive) +{ + return DeviceModel->FirmwareOlderThan(FirmwareMain, FirmwareSub, bInclusive); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGHandInterpolatorKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGHandInterpolatorKismetLibrary.cpp new file mode 100644 index 0000000..711b11d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGHandInterpolatorKismetLibrary.cpp @@ -0,0 +1,97 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGHandInterpolatorKismetLibrary.h" + +#include "SGCore/SGHandInterpolator.h" +#include "SGUtils/SGArrayUtils.h" + +USGHandInterpolator* USGHandInterpolatorKismetLibrary::MakeHandInterpolator(UObject* WorldContextObject) +{ + return USGHandInterpolator::NewHandInterpolator(WorldContextObject); +} + +USGHandInterpolator* USGHandInterpolatorKismetLibrary::MakeHandInterpolator_bRH( + UObject* WorldContextObject, const bool bRightHanded) +{ + return USGHandInterpolator::NewHandInterpolator(WorldContextObject, bRightHanded); +} + +USGHandInterpolator* USGHandInterpolatorKismetLibrary::Deserialize( + UObject* WorldContextObject, const FString& SerializedString, const bool bRightHanded) +{ + return USGHandInterpolator::Deserialize(WorldContextObject, SerializedString, bRightHanded); +} + +float USGHandInterpolatorKismetLibrary::CalculateAngle_M_ESGFingerMovement_V_bAL( + const USGHandInterpolator* HandInterpolator, + const ESGFingerMovement Movement, const float Value, const bool bApplyLimits) +{ + return HandInterpolator->CalculateAngle(Movement, Value, bApplyLimits); +} + +float USGHandInterpolatorKismetLibrary::CalculateAngle_M_ESGFingerMovement_V_bAL( + const USGHandInterpolator* HandInterpolator, + const ESGThumbMovement Movement, const float Value, const bool bApplyLimits) +{ + return HandInterpolator->CalculateAngle(Movement, Value, bApplyLimits); +} + +TArray USGHandInterpolatorKismetLibrary::InterpolateHandAngles( + const USGHandInterpolator* HandInterpolator, + const TArray& Flexions, const TArray& Abductions, const float CmcTwist) const +{ + TArray> FlexionsNestedArray{ + FSGArrayUtils::FromNestedBPArray< + float, FSGFloatArray, &FSGFloatArray::FloatArray>(Flexions) + }; + + const TArray Angles{ + FSGArrayUtils::ToNestedBPArray( + HandInterpolator->InterpolateHandAngles(MoveTemp(FlexionsNestedArray), Abductions, CmcTwist)) + }; + + return Angles; +} + +bool USGHandInterpolatorKismetLibrary::Equals(const USGHandInterpolator* A, const USGHandInterpolator* B) +{ + return A->Equals(B); +} + +FString USGHandInterpolatorKismetLibrary::SGSerialize(const USGHandInterpolator* HandInterpolator) +{ + return HandInterpolator->SGSerialize(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGHandLayerKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGHandLayerKismetLibrary.cpp new file mode 100644 index 0000000..2a58133 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGHandLayerKismetLibrary.cpp @@ -0,0 +1,180 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGHandLayerKismetLibrary.h" + +#include "SGCore/SGCustomWaveform.h" +#include "SGCore/SGHandLayer.h" +#include "SGCore/SGHandPose.h" + +bool USGHandLayerKismetLibrary::DeviceConnected(const bool bRightHanded) +{ + return FSGHandLayer::DeviceConnected(bRightHanded); +} + +ESGDeviceType USGHandLayerKismetLibrary::GetDeviceType(const bool bRightHanded) +{ + return FSGHandLayer::GetDeviceType(bRightHanded); +} + +bool USGHandLayerKismetLibrary::GetFirstGloveHandedness() +{ + return FSGHandLayer::GetFirstGloveHandedness(); +} + +int32 USGHandLayerKismetLibrary::GlovesConnected() +{ + return FSGHandLayer::GlovesConnected(); +} + +bool USGHandLayerKismetLibrary::GetGloveInstance(UObject* WorldContextObject, + const bool bRightHanded, USGHapticGlove*& OutGlove) +{ + return FSGHandLayer::GetGloveInstance(WorldContextObject, bRightHanded, OutGlove); +} + +ESGHapticGloveCalibrationState USGHandLayerKismetLibrary::GetCalibrationState(const bool bRightHanded) +{ + return FSGHandLayer::GetCalibrationState(bRightHanded); +} + +FString USGHandLayerKismetLibrary::GetCalibrationInstructions(const bool bRightHanded) +{ + return FSGHandLayer::GetCalibrationInstructions(bRightHanded); +} + +void USGHandLayerKismetLibrary::ResetCalibration(const bool bRightHanded) +{ + FSGHandLayer::ResetCalibration(bRightHanded); +} + +void USGHandLayerKismetLibrary::EndCalibration(const bool bRightHanded) +{ + FSGHandLayer::EndCalibration(bRightHanded); +} + +bool USGHandLayerKismetLibrary::GetHandPose(UObject* WorldContextObject, + const bool bRightHanded, USGHandPose*& OutHandPose) +{ + return FSGHandLayer::GetHandPose(WorldContextObject, bRightHanded, OutHandPose); +} + +void USGHandLayerKismetLibrary::GetWristLocation(const bool bRightHanded, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) +{ + FSGHandLayer::GetWristLocation(bRightHanded, ReferencePosition, ReferenceRotation, TrackingHardware, + OutWristPosition, OutWristRotation); +} + +void USGHandLayerKismetLibrary::StopAllHaptics(const bool bRightHanded) +{ + FSGHandLayer::StopAllHaptics(bRightHanded); +} + +bool USGHandLayerKismetLibrary::SendHaptics(const bool bRightHanded) +{ + return FSGHandLayer::SendHaptics(bRightHanded); +} + +bool USGHandLayerKismetLibrary::SupportsCustomWaveform(const bool bRightHanded, const ESGHapticLocation AtLocation) +{ + return FSGHandLayer::SupportsCustomWaveform(bRightHanded, AtLocation); +} + +bool USGHandLayerKismetLibrary::SendCustomWaveform( + const bool bRightHanded, USGCustomWaveform* OutWaveform, const ESGHapticLocation Location) +{ + return FSGHandLayer::SendCustomWaveform(bRightHanded, OutWaveform, Location); +} + +bool USGHandLayerKismetLibrary::QueueCommand_ForceFeedbackLevels( + const bool bRightHanded, const TArray& Levels01, const bool bSendImmediate) +{ + return FSGHandLayer::QueueCommand_ForceFeedbackLevels(bRightHanded, Levels01, bSendImmediate); +} + +bool USGHandLayerKismetLibrary::QueueCommand_ForceFeedbackLevel( + const bool bRightHanded, const int32 Finger, const float Level01, const bool bSendImmediate) +{ + return FSGHandLayer::QueueCommand_ForceFeedbackLevel(bRightHanded, Finger, Level01, bSendImmediate); +} + +bool USGHandLayerKismetLibrary::QueueCommand_VibroLevels( + const bool bRightHanded, const TArray& Levels01, const bool bSendImmediate) +{ + return FSGHandLayer::QueueCommand_VibroLevels(bRightHanded, Levels01, bSendImmediate); +} + +bool USGHandLayerKismetLibrary::QueueCommand_VibroLevel_bRH_F_L01_bSI( + const bool bRightHanded, const int32 Finger, const float Level01, const bool bSendImmediate) +{ + return FSGHandLayer::QueueCommand_VibroLevel(bRightHanded, Finger, Level01, bSendImmediate); +} + +bool USGHandLayerKismetLibrary::QueueCommand_VibroLevel_bRH_AL_L01_bSI( + const bool bRightHanded, const ESGHapticLocation AtLocation, const float Level01, const bool bSendImmediate) +{ + return FSGHandLayer::QueueCommand_VibroLevel(bRightHanded, AtLocation, Level01, bSendImmediate); +} + +bool USGHandLayerKismetLibrary::SupportsWristSqueeze(const bool bRightHanded) +{ + return FSGHandLayer::SupportsWristSqueeze(bRightHanded); +} + +bool USGHandLayerKismetLibrary::QueueCommand_WristSqueeze( + const bool bRightHanded, const float SqueezeLevel01, const bool bSendImmediate) +{ + return FSGHandLayer::QueueCommand_WristSqueeze(bRightHanded, SqueezeLevel01, bSendImmediate); +} + +bool USGHandLayerKismetLibrary::SupportsFlexionLocks(const bool bRightHanded) +{ + return FSGHandLayer::SupportsFlexionLocks(bRightHanded); +} + +bool USGHandLayerKismetLibrary::QueueCommand_FlexionLock( + const bool bRightHanded, const int32 Finger, const float Flexion01, const bool bSendImmediate) +{ + return FSGHandLayer::QueueCommand_FlexionLock(bRightHanded, Finger, Flexion01, bSendImmediate); +} + +bool USGHandLayerKismetLibrary::QueueCommand_ClearFlexionLock( + const bool bRightHanded, const int32 Finger, const bool bSendImmediate) +{ + return FSGHandLayer::QueueCommand_ClearFlexionLock(bRightHanded, Finger, bSendImmediate); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGHandPoseKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGHandPoseKismetLibrary.cpp new file mode 100644 index 0000000..983849f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGHandPoseKismetLibrary.cpp @@ -0,0 +1,183 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGHandPoseKismetLibrary.h" + +#include "SGCore/SGBasicHandModel.h" +#include "SGCore/SGHandPose.h" +#include "SGUtils/SGArrayUtils.h" + +USGHandPose* USGHandPoseKismetLibrary::MakeHandPose(UObject* WorldContextObject) +{ + return USGHandPose::NewHandPose(WorldContextObject); +} + +USGHandPose* USGHandPoseKismetLibrary::MakeHandPose_bRH_JP_FSGQuatArray_JR_HA( + UObject* WorldContextObject, + const bool bRightHanded, const TArray& JointPositions, const TArray& JointRotations, + const TArray& HandAngles) +{ + return USGHandPose::NewHandPose(WorldContextObject, bRightHanded, JointPositions, JointRotations, HandAngles); +} + +USGHandPose* USGHandPoseKismetLibrary::MakeHandPose_bRH_JP_FSGRotatorArray_JR_HA( + UObject* WorldContextObject, + const bool bRightHanded, + const TArray& JointPositions, const TArray& JointRotations, + const TArray& HandAngles) +{ + return USGHandPose::NewHandPose(WorldContextObject, bRightHanded, JointPositions, JointRotations, HandAngles); +} + +USGHandPose* USGHandPoseKismetLibrary::Deserialize(UObject* WorldContextObject, const FString& SerializedString) +{ + return USGHandPose::Deserialize(WorldContextObject, SerializedString); +} + +USGHandPose* USGHandPoseKismetLibrary::FromHandAngles_HA_bRH_HD( + UObject* WorldContextObject, + const TArray& HandAngles, const bool bRightHanded, const USGBasicHandModel* HandDimensions) +{ + TArray> HandAnglesNestedArray{ + FSGArrayUtils::FromNestedBPArray(HandAngles) + }; + return USGHandPose::FromHandAngles(WorldContextObject, MoveTemp(HandAnglesNestedArray), bRightHanded, + HandDimensions); +} + +USGHandPose* USGHandPoseKismetLibrary::FromHandAngles_HA_bRH( + UObject* WorldContextObject, const TArray& HandAngles, const bool bRightHanded) +{ + TArray> HandAnglesNestedArray{ + FSGArrayUtils::FromNestedBPArray(HandAngles) + }; + return USGHandPose::FromHandAngles(WorldContextObject, MoveTemp(HandAnglesNestedArray), bRightHanded); +} + +USGHandPose* USGHandPoseKismetLibrary::DefaultIdle_bRH_HD( + UObject* WorldContextObject, const bool bRightHanded, const USGBasicHandModel* HandDimensions) +{ + return USGHandPose::DefaultIdle(WorldContextObject, bRightHanded, HandDimensions); +} + +USGHandPose* USGHandPoseKismetLibrary::DefaultIdle_bRH(UObject* WorldContextObject, const bool bRightHanded) +{ + return USGHandPose::DefaultIdle(WorldContextObject, bRightHanded); +} + +USGHandPose* USGHandPoseKismetLibrary::FlatHand_bRH_HD( + UObject* WorldContextObject, const bool bRightHanded, const USGBasicHandModel* HandDimensions) +{ + return USGHandPose::FlatHand(WorldContextObject, bRightHanded, HandDimensions); +} + +USGHandPose* USGHandPoseKismetLibrary::FlatHand_bRH(UObject* WorldContextObject, const bool bRightHanded) +{ + return USGHandPose::FlatHand(WorldContextObject, bRightHanded); +} + +USGHandPose* USGHandPoseKismetLibrary::ThumbsUp_bRH_HD( + UObject* WorldContextObject, const bool bRightHanded, const USGBasicHandModel* HandDimensions) +{ + return USGHandPose::ThumbsUp(WorldContextObject, bRightHanded, HandDimensions); +} + +USGHandPose* USGHandPoseKismetLibrary::ThumbsUp_bRH(UObject* WorldContextObject, const bool bRightHanded) +{ + return USGHandPose::ThumbsUp(WorldContextObject, bRightHanded); +} + +USGHandPose* USGHandPoseKismetLibrary::Fist_bRH_HD( + UObject* WorldContextObject, const bool bRightHanded, const USGBasicHandModel* HandDimensions) +{ + return USGHandPose::Fist(WorldContextObject, bRightHanded, HandDimensions); +} + +USGHandPose* USGHandPoseKismetLibrary::Fist_bRH(UObject* WorldContextObject, const bool bRightHanded) +{ + return USGHandPose::Fist(WorldContextObject, bRightHanded); +} + +bool USGHandPoseKismetLibrary::IsRight(const USGHandPose* HandPose) +{ + return HandPose->IsRight(); +} + +TArray USGHandPoseKismetLibrary::GetJointPositions(const USGHandPose* HandPose) +{ + return FSGArrayUtils::ToNestedBPArray(HandPose->GetJointPositions()); +} + +TArray USGHandPoseKismetLibrary::GetJointRotationsQ(const USGHandPose* HandPose) +{ + return FSGArrayUtils::ToNestedBPArray(HandPose->GetJointRotationsQ()); +} + +TArray USGHandPoseKismetLibrary::GetJointRotations(const USGHandPose* HandPose) +{ + return FSGArrayUtils::ToNestedBPArray(HandPose->GetJointRotations()); +} + +TArray USGHandPoseKismetLibrary::GetHandAngles(const USGHandPose* HandPose) +{ + return FSGArrayUtils::ToNestedBPArray(HandPose->GetHandAngles()); +} + +bool USGHandPoseKismetLibrary::Equals(const USGHandPose* A, const USGHandPose* B) +{ + return A->Equals(B); +} + +float USGHandPoseKismetLibrary::GetNormalizedFlexion_F_bC01( + const USGHandPose* HandPose, const ESGFinger Finger, const bool bClamp01) +{ + return HandPose->GetNormalizedFlexion(Finger, bClamp01); +} + +TArray USGHandPoseKismetLibrary::GetNormalizedFlexion_bC01( + const USGHandPose* HandPose, const bool bClamp01) +{ + return HandPose->GetNormalizedFlexion(bClamp01); +} + +FString USGHandPoseKismetLibrary::ToString(const USGHandPose* HandPose, const bool bShortFormat) +{ + return HandPose->ToString(bShortFormat); +} + +FString USGHandPoseKismetLibrary::SGSerialize(const USGHandPose* HandPose) +{ + return HandPose->SGSerialize(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGHapticChannelInfoKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGHapticChannelInfoKismetLibrary.cpp new file mode 100644 index 0000000..11ce486 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGHapticChannelInfoKismetLibrary.cpp @@ -0,0 +1,109 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGHapticChannelInfoKismetLibrary.h" + +#include "SGCore/SGHapticChannelInfo.h" + +USGHapticChannelInfo* USGHapticChannelInfoKismetLibrary::MakeHapticChannelInfo(UObject* WorldContextObject) +{ + return USGHapticChannelInfo::NewHapticChannelInfo(WorldContextObject); +} + +USGHapticChannelInfo* USGHapticChannelInfoKismetLibrary::MakeHapticChannelInfo_SI_FAFI( + UObject* WorldContextObject, + const TArray& StreamIndex, const TArray& FireAndForgetIndex) +{ + return USGHapticChannelInfo::NewHapticChannelInfo(WorldContextObject, StreamIndex, FireAndForgetIndex); +} + +FString USGHapticChannelInfoKismetLibrary::GenerateAddress(const int32 DeviceIndex, const int32 ChannelIndex) +{ + return USGHapticChannelInfo::GenerateAddress(DeviceIndex, ChannelIndex); +} + +USGHapticChannelInfo* USGHapticChannelInfoKismetLibrary::Parse(UObject* WorldContextObject, const FString& IpcString) +{ + return USGHapticChannelInfo::Parse(WorldContextObject, IpcString); +} + +int32 USGHapticChannelInfoKismetLibrary::GetStreamingType() +{ + return USGHapticChannelInfo::GetStreamingType(); +} + +int32 USGHapticChannelInfoKismetLibrary::GetFireAndForgetType() +{ + return USGHapticChannelInfo::GetFireAndForgetType(); +} + +int32 USGHapticChannelInfoKismetLibrary::GetStreamChannelCount(const USGHapticChannelInfo* HapticChannelInfo) +{ + return HapticChannelInfo->GetStreamChannelCount(); +} + +int32 USGHapticChannelInfoKismetLibrary::GetFireAndForgetChannelCount(const USGHapticChannelInfo* HapticChannelInfo) +{ + return HapticChannelInfo->GetFireAndForgetChannelCount(); +} + +int32 USGHapticChannelInfoKismetLibrary::GetTotalChannelCount(const USGHapticChannelInfo* HapticChannelInfo) +{ + return HapticChannelInfo->GetTotalChannelCount(); +} + +FString USGHapticChannelInfoKismetLibrary::GetAddress_Unguarded(const USGHapticChannelInfo* HapticChannelInfo, + const ESGHapticChannelType Type, const int32 TypeIndex) +{ + return HapticChannelInfo->GetAddress_Unguarded(Type, TypeIndex); +} + +void USGHapticChannelInfoKismetLibrary::GetIpcParams_Unguarded(USGHapticChannelInfo* HapticChannelInfo, + const ESGHapticChannelType Type, const int32 TypeIndex, + int32& OutIndex, FString& OutAddressString) +{ + HapticChannelInfo->GetIpcParams_Unguarded(Type, TypeIndex, OutIndex, OutAddressString); +} + +void USGHapticChannelInfoKismetLibrary::RegenerateAddresses(USGHapticChannelInfo* HapticChannelInfo, + const int32 ForDeviceIndex) +{ + HapticChannelInfo->RegenerateAddresses(ForDeviceIndex); +} + +TArray USGHapticChannelInfoKismetLibrary::GetAllAddresses(const USGHapticChannelInfo* HapticChannelInfo) +{ + return HapticChannelInfo->GetAllAddresses(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGHapticGloveKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGHapticGloveKismetLibrary.cpp new file mode 100644 index 0000000..d777e01 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGHapticGloveKismetLibrary.cpp @@ -0,0 +1,259 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGHapticGloveKismetLibrary.h" + +#include "SGCore/SGBasicHandModel.h" +#include "SGCore/SGHandPose.h" +#include "SGCore/SGHapticGlove.h" +#include "SGUtils/SGArrayUtils.h" + +TArray USGHapticGloveKismetLibrary::GetHapticGloves(UObject* WorldContextObject, + const bool bConnectedOnly) +{ + return USGHapticGlove::GetHapticGloves(WorldContextObject, bConnectedOnly); +} + +bool USGHapticGloveKismetLibrary::GetGlove_OutG(UObject* WorldContextObject, USGHapticGlove*& OutGlove) +{ + return USGHapticGlove::GetGlove(WorldContextObject, OutGlove); +} + +bool USGHapticGloveKismetLibrary::GetGlove_bRH_OutG(UObject* WorldContextObject, + const bool bRightHanded, USGHapticGlove*& OutGlove) +{ + return USGHapticGlove::GetGlove(WorldContextObject, bRightHanded, OutGlove); +} + +FString USGHapticGloveKismetLibrary::ToString_S(const ESGHapticGloveCalibrationState State) +{ + return USGHapticGlove::ToString(State); +} + +FString USGHapticGloveKismetLibrary::ToString_L(const ESGHapticLocation Location) +{ + return USGHapticGlove::ToString(Location); +} + +ESGDeviceType USGHapticGloveKismetLibrary::GetDeviceType(const USGHapticGlove* HapticGlove) +{ + return HapticGlove->GetDeviceType(); +} + +FString USGHapticGloveKismetLibrary::GetDeviceId(const USGHapticGlove* HapticGlove) +{ + return HapticGlove->GetDeviceId(); +} + +FString USGHapticGloveKismetLibrary::GetHardwareVersion(const USGHapticGlove* HapticGlove) +{ + return HapticGlove->GetHardwareVersion(); +} + +int32 USGHapticGloveKismetLibrary::GetFirmwareVersion(const USGHapticGlove* HapticGlove) +{ + return HapticGlove->GetFirmwareVersion(); +} + +int32 USGHapticGloveKismetLibrary::GetSubFirmwareVersion(const USGHapticGlove* HapticGlove) +{ + return HapticGlove->GetSubFirmwareVersion(); +} + +bool USGHapticGloveKismetLibrary::IsRight(const USGHapticGlove* HapticGlove) +{ + return HapticGlove->IsRight(); +} + +bool USGHapticGloveKismetLibrary::GetImuRotation_FQuat_OutI(USGHapticGlove* HapticGlove, FQuat& OutImu) +{ + return HapticGlove->GetImuRotation(OutImu); +} + +bool USGHapticGloveKismetLibrary::GetImuRotation_FRotator_OutI(USGHapticGlove* HapticGlove, FRotator& OutImu) +{ + return HapticGlove->GetImuRotation(OutImu); +} + +bool USGHapticGloveKismetLibrary::GetHandPose_HG_OutHP( + UObject* WorldContextObject, + const USGHapticGlove* HapticGlove, const USGBasicHandModel* HandGeometry, USGHandPose*& OutHandPose) +{ + return HapticGlove->GetHandPose(WorldContextObject, HandGeometry, OutHandPose); +} + +bool USGHapticGloveKismetLibrary::GetHandPose_OutHP( + UObject* WorldContextObject, USGHapticGlove* HapticGlove, USGHandPose*& OutHandPose) +{ + return HapticGlove->GetHandPose(WorldContextObject, OutHandPose); +} + +bool USGHapticGloveKismetLibrary::GetHandAngles(const USGHapticGlove* HapticGlove, + TArray& OutHandAngles) +{ + TArray> HandAnglesNestedArray; + const bool bResult = HapticGlove->GetHandAngles(HandAnglesNestedArray); + OutHandAngles = FSGArrayUtils::ToNestedBPArray(MoveTemp(HandAnglesNestedArray)); + return bResult; +} + +USGBasicHandModel* USGHapticGloveKismetLibrary::GetHandGeometry(UObject* WorldContextObject, + const USGHapticGlove* HapticGlove) +{ + return HapticGlove->GetHandGeometry(WorldContextObject); +} + +void USGHapticGloveKismetLibrary::SetHandGeometry(USGHapticGlove* HapticGlove, const USGBasicHandModel* HandGeometry) +{ + HapticGlove->SetHandGeometry(HandGeometry); +} + +ESGHapticGloveCalibrationState USGHapticGloveKismetLibrary::GetCalibrationState(const USGHapticGlove* HapticGlove) +{ + return HapticGlove->GetCalibrationState(); +} + +void USGHapticGloveKismetLibrary::EndCalibration(USGHapticGlove* HapticGlove) +{ + HapticGlove->EndCalibration(); +} + +void USGHapticGloveKismetLibrary::ResetCalibration(USGHapticGlove* HapticGlove) +{ + HapticGlove->ResetCalibration(); +} + +FString USGHapticGloveKismetLibrary::GetCalibrationInstruction(const USGHapticGlove* HapticGlove) +{ + return HapticGlove->GetCalibrationInstruction(); +} + +void USGHapticGloveKismetLibrary::StopHaptics(USGHapticGlove* HapticGlove) +{ + return HapticGlove->StopHaptics(); +} + +void USGHapticGloveKismetLibrary::StopVibrations(USGHapticGlove* HapticGlove) +{ + return HapticGlove->StopVibrations(); +} + +bool USGHapticGloveKismetLibrary::SendHaptics(USGHapticGlove* HapticGlove) +{ + return HapticGlove->SendHaptics(); +} + +bool USGHapticGloveKismetLibrary::SupportsCustomWaveform(const USGHapticGlove* HapticGlove, + const ESGHapticLocation AtLocation) +{ + return HapticGlove->SupportsCustomWaveform(AtLocation); +} + +bool USGHapticGloveKismetLibrary::SendCustomWaveform(USGHapticGlove* HapticGlove, + USGCustomWaveform* OutWaveform, const ESGHapticLocation Location) +{ + return HapticGlove->SendCustomWaveform(OutWaveform, Location); +} + +bool USGHapticGloveKismetLibrary::QueueForceFeedbackLevels(USGHapticGlove* HapticGlove, const TArray& Levels01) +{ + return HapticGlove->QueueForceFeedbackLevels(Levels01); +} + +bool USGHapticGloveKismetLibrary::QueueForceFeedbackLevel(USGHapticGlove* HapticGlove, + const int32 Finger, const float Level01) +{ + return HapticGlove->QueueForceFeedbackLevel(Finger, Level01); +} + +bool USGHapticGloveKismetLibrary::QueueVibroLevels(USGHapticGlove* HapticGlove, const TArray& Levels01) +{ + return HapticGlove->QueueVibroLevels(Levels01); +} + +bool USGHapticGloveKismetLibrary::QueueVibroLevel(USGHapticGlove* HapticGlove, + const ESGHapticLocation Location, const float Level01) +{ + return HapticGlove->QueueVibroLevel(Location, Level01); +} + +void USGHapticGloveKismetLibrary::GetWristLocation_RP_FQuat_RR_TH_OutWP_OutWR( + const USGHapticGlove* HapticGlove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) +{ + HapticGlove->GetWristLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + OutWristPosition, OutWristRotation); +} + +void USGHapticGloveKismetLibrary::GetWristLocation_RP_FRotator_RR_TH_OutWP_OutWR( + const USGHapticGlove* HapticGlove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FRotator& OutWristRotation) +{ + HapticGlove->GetWristLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + OutWristPosition, OutWristRotation); +} + +void USGHapticGloveKismetLibrary::GetGloveLocation_RP_FQuat_RR_TH_OutGP_OutGR( + const USGHapticGlove* HapticGlove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) +{ + HapticGlove->GetGloveLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + OutGlovePosition, OutGloveRotation); +} + +void USGHapticGloveKismetLibrary::GetGloveLocation_RP_FRotator_RR_TH_OutGP_OutGR( + const USGHapticGlove* HapticGlove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FRotator& OutGloveRotation) +{ + HapticGlove->GetGloveLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + OutGlovePosition, OutGloveRotation); +} + +FString USGHapticGloveKismetLibrary::ToString(const USGHapticGlove* HapticGlove) +{ + return HapticGlove->ToString(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGInterpolationSetKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGInterpolationSetKismetLibrary.cpp new file mode 100644 index 0000000..ad8d779 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGInterpolationSetKismetLibrary.cpp @@ -0,0 +1,148 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGInterpolationSetKismetLibrary.h" + +#include "SGCore/SGInterpolationSet.h" + +USGInterpolationSet* USGInterpolationSetKismetLibrary::MakeInterpolationSet(UObject* WorldContextObject) +{ + return USGInterpolationSet::NewInterpolationSet(WorldContextObject); +} + +USGInterpolationSet* USGInterpolationSetKismetLibrary::MakeInterpolationSet_F1_F2_T1_T2( + UObject* WorldContextObject, const float From1, const float From2, const float To1, const float To2) +{ + return USGInterpolationSet::NewInterpolationSet(WorldContextObject, From1, From2, To1, To2); +} + +USGInterpolationSet* USGInterpolationSetKismetLibrary::MakeInterpolationSet_F1_F2_T1_T2_M_M( + UObject* WorldContextObject, + const float From1, const float From2, const float To1, const float To2, const float Min, const float Max) +{ + return USGInterpolationSet::NewInterpolationSet(WorldContextObject, From1, From2, To1, To2, Min, Max); +} + +USGInterpolationSet* USGInterpolationSetKismetLibrary::Deserialize(UObject* WorldContextObject, + const FString& SerializedString) +{ + return USGInterpolationSet::Deserialize(WorldContextObject, SerializedString); +} + +float USGInterpolationSetKismetLibrary::GetX0(const USGInterpolationSet* InterpolationSet) +{ + return InterpolationSet->GetX0(); +} + +void USGInterpolationSetKismetLibrary::SetX0(USGInterpolationSet* InterpolationSet, const float X0) +{ + InterpolationSet->SetX0(X0); +} + +float USGInterpolationSetKismetLibrary::GetX1(const USGInterpolationSet* InterpolationSet) +{ + return InterpolationSet->GetX1(); +} + +void USGInterpolationSetKismetLibrary::SetX1(USGInterpolationSet* InterpolationSet, const float X1) +{ + InterpolationSet->SetX1(X1); +} + +float USGInterpolationSetKismetLibrary::GetY0(const USGInterpolationSet* InterpolationSet) +{ + return InterpolationSet->GetY0(); +} + +void USGInterpolationSetKismetLibrary::SetY0(USGInterpolationSet* InterpolationSet, const float Y0) +{ + InterpolationSet->SetY0(Y0); +} + +float USGInterpolationSetKismetLibrary::GetY1(const USGInterpolationSet* InterpolationSet) +{ + return InterpolationSet->GetY1(); +} + +void USGInterpolationSetKismetLibrary::SetY1(USGInterpolationSet* InterpolationSet, const float Y1) +{ + InterpolationSet->SetY1(Y1); +} + +float USGInterpolationSetKismetLibrary::GetMin(const USGInterpolationSet* InterpolationSet) +{ + return InterpolationSet->GetMin(); +} + +void USGInterpolationSetKismetLibrary::SetMin(USGInterpolationSet* InterpolationSet, const float Min) +{ + InterpolationSet->SetMin(Min); +} + +float USGInterpolationSetKismetLibrary::GetMax(const USGInterpolationSet* InterpolationSet) +{ + return InterpolationSet->GetMax(); +} + +void USGInterpolationSetKismetLibrary::SetMax(USGInterpolationSet* InterpolationSet, const float Max) +{ + InterpolationSet->SetMax(Max); +} + +int32 USGInterpolationSetKismetLibrary::Get(const USGInterpolationSet* InterpolationSet, const float Value, + const bool bLimit, const bool bNormalizeAngle) +{ + return InterpolationSet->Get(Value, bLimit, bNormalizeAngle); +} + +bool USGInterpolationSetKismetLibrary::Equals(const USGInterpolationSet* A, const USGInterpolationSet* B) +{ + return A->Equals(B); +} + +FString USGInterpolationSetKismetLibrary::ToString(const USGInterpolationSet* InterpolationSet) +{ + return InterpolationSet->ToString(); +} + +FString USGInterpolationSetKismetLibrary::ToString_bL(const USGInterpolationSet* InterpolationSet, const bool bLimits) +{ + return InterpolationSet->ToString(bLimits); +} + +FString USGInterpolationSetKismetLibrary::SGSerialize(const USGInterpolationSet* InterpolationSet) +{ + return InterpolationSet->SGSerialize(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGJointKinematicsKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGJointKinematicsKismetLibrary.cpp new file mode 100644 index 0000000..f9a9e66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGJointKinematicsKismetLibrary.cpp @@ -0,0 +1,70 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGJointKinematicsKismetLibrary.h" + +#include "SGCore/SGJointKinematics.h" + +bool USGJointKinematicsKismetLibrary::ForwardKinematics_SP_FQuat_SR_JL_JA_OutNP_TArrayFQuat_OutNR( + const FVector& StartPosition, const FQuat& StartRotation, const TArray& JointLengths, + const TArray& JointAngles, TArray& OutNewPositions, TArray& OutNewRotations) +{ + return FSGJointKinematics::ForwardKinematics(StartPosition, StartRotation, JointLengths, JointAngles, + OutNewPositions, OutNewRotations); +} + +bool USGJointKinematicsKismetLibrary::ForwardKinematics_SP_FRotator_SR_JL_JA_OutNP_TArrayFRotator_OutNR( + const FVector& StartPosition, const FRotator& StartRotation, const TArray& JointLengths, + const TArray& JointAngles, TArray& OutNewPositions, TArray& OutNewRotations) +{ + return FSGJointKinematics::ForwardKinematics(StartPosition, StartRotation, JointLengths, JointAngles, + OutNewPositions, OutNewRotations); +} + +bool +USGJointKinematicsKismetLibrary::ForwardKinematics_P_F_JA_OutNP_TArrayFQuat_OutNR( + const USGBasicHandModel* Profile, const ESGFinger Finger, const TArray& JointAngles, + TArray& OutNewPositions, TArray& OutNewRotations) +{ + return FSGJointKinematics::ForwardKinematics(Profile, Finger, JointAngles, OutNewPositions, OutNewRotations); +} + +bool +USGJointKinematicsKismetLibrary::ForwardKinematics_P_F_JA_OutNP_TArrayFRotator_OutNR( + const USGBasicHandModel* Profile, const ESGFinger Finger, const TArray& JointAngles, + TArray& OutNewPositions, TArray& OutNewRotations) +{ + return FSGJointKinematics::ForwardKinematics(Profile, Finger, JointAngles, OutNewPositions, OutNewRotations); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGLibraryKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGLibraryKismetLibrary.cpp new file mode 100644 index 0000000..4847361 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGLibraryKismetLibrary.cpp @@ -0,0 +1,53 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGLibraryKismetLibrary.h" + +#include "SGCore/SGLibrary.h" + +FString USGLibraryKismetLibrary::GetVersion() +{ + return FSGLibrary::GetVersion(); +} + +FString USGLibraryKismetLibrary::GetBackendVersion() +{ + return FSGLibrary::GetBackendVersion(); +} + +FString USGLibraryKismetLibrary::GetSGConnectVersion() +{ + return FSGLibrary::GetSGConnectVersion(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGNova2GloveKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGNova2GloveKismetLibrary.cpp new file mode 100644 index 0000000..bb2f7ed --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGNova2GloveKismetLibrary.cpp @@ -0,0 +1,389 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGNova2GloveKismetLibrary.h" + +#include "SGCore/SGHandPose.h" +#include "SGCore/SGNova2Glove.h" +#include "SGCore/SGNova2GloveSensorData.h" +#include "SGUtils/SGArrayUtils.h" + +USGDevice* USGNova2GloveKismetLibrary::Parse(UObject* WorldContextObject, const FString& ConstantsString) +{ + return USGNova2Glove::Parse(WorldContextObject, ConstantsString); +} + +TArray USGNova2GloveKismetLibrary::GetNova2Gloves(UObject* WorldContextObject) +{ + return USGNova2Glove::GetNova2Gloves(WorldContextObject); +} + +bool USGNova2GloveKismetLibrary::GetNova2Glove_OutG(UObject* WorldContextObject, USGNova2Glove*& OutGlove) +{ + return USGNova2Glove::GetNova2Glove(WorldContextObject, OutGlove); +} + +bool USGNova2GloveKismetLibrary::GetNova2Glove_bRH_OutG(UObject* WorldContextObject, + const bool bRightHanded, USGNova2Glove*& OutGlove) +{ + return USGNova2Glove::GetNova2Glove(WorldContextObject, bRightHanded, OutGlove); +} + +void USGNova2GloveKismetLibrary::CalculateGloveLocation_RP_FQuat_RR_TH_bRH_HW_OutGP_OutGR( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, const FString& HardwareVersion, + FVector& OutGlovePosition, FQuat& OutGloveRotation) +{ + USGNova2Glove::CalculateGloveLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, bRightHanded, HardwareVersion, + OutGlovePosition, OutGloveRotation); +} + +void USGNova2GloveKismetLibrary::CalculateGloveLocation_RP_FRotator_RR_TH_bRH_HW_OutGP_OutGR( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, const FString& HardwareVersion, + FVector& OutGlovePosition, FRotator& OutGloveRotation) +{ + USGNova2Glove::CalculateGloveLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, bRightHanded, HardwareVersion, + OutGlovePosition, OutGloveRotation); +} + +void USGNova2GloveKismetLibrary::CalculateWristLocation_RP_FQuat_RR_TH_bRH_HW_OutWP_OutWR( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, const FString& HardwareVersion, + FVector& OutWristPosition, FQuat& OutWristRotation) +{ + USGNova2Glove::CalculateWristLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, bRightHanded, HardwareVersion, + OutWristPosition, OutWristRotation); +} + +void USGNova2GloveKismetLibrary::CalculateWristLocation_RP_FRotator_RR_TH_bRH_HW_OutWP_OutWR( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, const FString& HardwareVersion, + FVector& OutWristPosition, FRotator& OutWristRotation) +{ + USGNova2Glove::CalculateWristLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, bRightHanded, HardwareVersion, + OutWristPosition, OutWristRotation); +} + +FString USGNova2GloveKismetLibrary::GetStreamByte() +{ + return FString::Printf(TEXT("%c"), USGNova2Glove::GetStreamByte()); +} + +TArray USGNova2GloveKismetLibrary::GetNova2SensorRanges() +{ + return USGNova2Glove::GetNova2SensorRanges(); +} + +TArray USGNova2GloveKismetLibrary::ToNormalizedValues_SD(const USGNova2GloveSensorData* SensorData) +{ + return USGNova2Glove::ToNormalizedValues(SensorData); +} + +TArray USGNova2GloveKismetLibrary::ToNormalizedValues_SD_OutSN( + UObject* WorldContextObject, + const USGNova2GloveSensorData* SensorData, USGSensorNormalization*& OutSensorNormalizer) +{ + return USGNova2Glove::ToNormalizedValues(WorldContextObject, SensorData, OutSensorNormalizer); +} + +TArray USGNova2GloveKismetLibrary::CalculateHandAngles( + const TArray& NormalizedValues, const USGHandInterpolator* Interpolator, const bool bInfluenceIndex) +{ + const TArray HandAngles{ + FSGArrayUtils::ToNestedBPArray( + USGNova2Glove::CalculateHandAngles(NormalizedValues, Interpolator, bInfluenceIndex)) + }; + return HandAngles; +} + +TArray USGNova2GloveKismetLibrary::ToNormalizedAngles( + const TArray& NormalizedData, const USGNovaGloveInfo* GloveInfo) +{ + return FSGArrayUtils::ToNestedBPArray( + USGNova2Glove::ToNormalizedAngles(NormalizedData, GloveInfo)); +} + +ESGDeviceType USGNova2GloveKismetLibrary::GetDeviceType(const USGNova2Glove* Nova2Glove) +{ + return Nova2Glove->GetDeviceType(); +} + +FString USGNova2GloveKismetLibrary::GetDeviceId(const USGNova2Glove* Nova2Glove) +{ + return Nova2Glove->GetDeviceId(); +} + +FString USGNova2GloveKismetLibrary::GetHardwareVersion(const USGNova2Glove* Nova2Glove) +{ + return Nova2Glove->GetHardwareVersion(); +} + +int32 USGNova2GloveKismetLibrary::GetFirmwareVersion(const USGNova2Glove* Nova2Glove) +{ + return Nova2Glove->GetFirmwareVersion(); +} + +int32 USGNova2GloveKismetLibrary::GetSubFirmwareVersion(const USGNova2Glove* Nova2Glove) +{ + return Nova2Glove->GetSubFirmwareVersion(); +} + +bool USGNova2GloveKismetLibrary::HasBattery(const USGNova2Glove* Nova2Glove) +{ + return Nova2Glove->HasBattery(); +} + +bool USGNova2GloveKismetLibrary::IsCharging(USGNova2Glove* Nova2Glove) +{ + return Nova2Glove->IsCharging(); +} + +bool USGNova2GloveKismetLibrary::GetBatteryLevel(USGNova2Glove* Nova2Glove, float& OutBatteryLevel) +{ + return Nova2Glove->GetBatteryLevel(OutBatteryLevel); +} + +bool USGNova2GloveKismetLibrary::IsRight(const USGNova2Glove* Nova2Glove) +{ + return Nova2Glove->IsRight(); +} + +bool USGNova2GloveKismetLibrary::GetImuRotation_FQuat_OutI(USGNova2Glove* Nova2Glove, FQuat& OutImu) +{ + return Nova2Glove->GetImuRotation(OutImu); +} + +bool USGNova2GloveKismetLibrary::GetImuRotation_FRotator_OutI(USGNova2Glove* Nova2Glove, FRotator& OutImu) +{ + return Nova2Glove->GetImuRotation(OutImu); +} + +bool USGNova2GloveKismetLibrary::GetHandPose( + UObject* WorldContextObject, + USGNova2Glove* Nova2Glove, const USGBasicHandModel* HandModel, USGHandPose*& OutHandPose) +{ + return Nova2Glove->GetHandPose(WorldContextObject, HandModel, OutHandPose); +} + +bool USGNova2GloveKismetLibrary::GetHandAngles(const USGNova2Glove* Nova2Glove, TArray& OutHandAngles) +{ + TArray> HandAnglesNestedArray; + const bool bResult = Nova2Glove->GetHandAngles(HandAnglesNestedArray); + OutHandAngles = FSGArrayUtils::ToNestedBPArray(MoveTemp(HandAnglesNestedArray)); + return bResult; +} + +ESGHapticGloveCalibrationState USGNova2GloveKismetLibrary::GetCalibrationState(const USGNova2Glove* Nova2Glove) +{ + return Nova2Glove->GetCalibrationState(); +} + +void USGNova2GloveKismetLibrary::EndCalibration(USGNova2Glove* Nova2Glove) +{ + Nova2Glove->EndCalibration(); +} + +void USGNova2GloveKismetLibrary::ResetCalibration(USGNova2Glove* Nova2Glove) +{ + Nova2Glove->ResetCalibration(); +} + +void USGNova2GloveKismetLibrary::StopHaptics(USGNova2Glove* Nova2Glove) +{ + Nova2Glove->StopHaptics(); +} + +void USGNova2GloveKismetLibrary::StopVibrations(USGNova2Glove* Nova2Glove) +{ + Nova2Glove->StopVibrations(); +} + +bool USGNova2GloveKismetLibrary::SendHaptics(USGNova2Glove* Nova2Glove) +{ + return Nova2Glove->SendHaptics(); +} + +bool USGNova2GloveKismetLibrary::SupportsCustomWaveform(const USGNova2Glove* Nova2Glove, + const ESGHapticLocation AtLocation) +{ + return Nova2Glove->SupportsCustomWaveform(AtLocation); +} + +bool USGNova2GloveKismetLibrary::SendCustomWaveform(USGNova2Glove* Nova2Glove, + USGCustomWaveform* OutWaveform, const ESGHapticLocation Location) +{ + return Nova2Glove->SendCustomWaveform(OutWaveform, Location); +} + +bool USGNova2GloveKismetLibrary::QueueForceFeedbackLevels(USGNova2Glove* Nova2Glove, const TArray& Levels01) +{ + return Nova2Glove->QueueForceFeedbackLevels(Levels01); +} + +bool USGNova2GloveKismetLibrary::QueueForceFeedbackLevel( + USGNova2Glove* Nova2Glove, const int32 Finger, const float Level01) +{ + return Nova2Glove->QueueForceFeedbackLevel(Finger, Level01); +} + +bool USGNova2GloveKismetLibrary::QueueVibroLevels(USGNova2Glove* Nova2Glove, const TArray& Amplitudes) +{ + return Nova2Glove->QueueVibroLevels(Amplitudes); +} + +bool USGNova2GloveKismetLibrary::QueueVibroLevel(USGNova2Glove* Nova2Glove, + const ESGHapticLocation Location, const float Level01) +{ + return Nova2Glove->QueueVibroLevel(Location, Level01); +} + +void USGNova2GloveKismetLibrary::GetGloveLocation_RP_FQuat_RR_TH_OutGP_FQuat_OutGR( + const USGNova2Glove* Nova2Glove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) +{ + Nova2Glove->GetGloveLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + OutGlovePosition, OutGloveRotation); +} + +void USGNova2GloveKismetLibrary::GetGloveLocation_RP_FRotator_RR_TH_OutGP_FRotator_OutGR( + const USGNova2Glove* Nova2Glove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FRotator& OutGloveRotation) +{ + Nova2Glove->GetGloveLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + OutGlovePosition, OutGloveRotation); +} + +void USGNova2GloveKismetLibrary::GetWristLocation_RP_FQuat_RR_TH_OutWP_FQuat_OutWR( + const USGNova2Glove* Nova2Glove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) +{ + Nova2Glove->GetWristLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + OutWristPosition, OutWristRotation); +} + +void USGNova2GloveKismetLibrary::GetWristLocation_RP_FRotator_RR_TH_OutWP_FRotator_OutWR( + const USGNova2Glove* Nova2Glove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FRotator& OutWristRotation) +{ + Nova2Glove->GetWristLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + OutWristPosition, OutWristRotation); +} + +USGNovaGloveInfo* USGNova2GloveKismetLibrary::GetGloveInfo(UObject* WorldContextObject, const USGNova2Glove* Nova2Glove) +{ + return Nova2Glove->GetGloveInfo(WorldContextObject); +} + +bool USGNova2GloveKismetLibrary::DoesIndexInfluenceOthers(const USGNova2Glove* Nova2Glove) +{ + return Nova2Glove->DoesIndexInfluenceOthers(); +} + +void USGNova2GloveKismetLibrary::SetIndexInfluencesOthers(USGNova2Glove* Nova2Glove, const bool bInfluenceOthers) +{ + Nova2Glove->SetIndexInfluencesOthers(bInfluenceOthers); +} + +bool USGNova2GloveKismetLibrary::SupportsOnBoardNormalization(const USGNova2Glove* Nova2Glove) +{ + return Nova2Glove->SupportsOnBoardNormalization(); +} + +bool USGNova2GloveKismetLibrary::GetSensorData( + UObject* WorldContextObject, USGNova2Glove* Nova2Glove, USGNova2GloveSensorData*& OutSensorData) +{ + return Nova2Glove->GetSensorData(WorldContextObject, OutSensorData); +} + +bool USGNova2GloveKismetLibrary::GetNormalizedInput(const USGNova2Glove* Nova2Glove, TArray& OutNormalizedValues) +{ + return Nova2Glove->GetNormalizedInput(OutNormalizedValues); +} + +bool USGNova2GloveKismetLibrary::SendRawData(USGNova2Glove* Nova2Glove) +{ + return Nova2Glove->SendRawData(); +} + +bool USGNova2GloveKismetLibrary::SendNormalizedData(USGNova2Glove* Nova2Glove) +{ + return Nova2Glove->SendNormalizedData(); +} + +ESGNova2VibroMotor USGNova2GloveKismetLibrary::ToNovaMotor(const USGNova2Glove* Nova2Glove, + const ESGHapticLocation Location) +{ + return Nova2Glove->ToNovaMotor(Location); +} + +int32 USGNova2GloveKismetLibrary::ChannelIndex(const USGNova2Glove* Nova2Glove, const ESGNova2VibroMotor Motor) +{ + return Nova2Glove->ChannelIndex(Motor); +} + +void USGNova2GloveKismetLibrary::ValidateWaveform(const USGNova2Glove* Nova2Glove, + USGCustomWaveform* OutWaveform, const ESGNova2VibroMotor Motor) +{ + Nova2Glove->ValidateWaveform(OutWaveform, Motor); +} + +bool USGNova2GloveKismetLibrary::SendCustomWaveform_Nova2( + USGNova2Glove* Nova2Glove, + USGCustomWaveform* OutWaveform, const ESGNova2VibroMotor Motor, const bool bValidateWaveform) +{ + return Nova2Glove->SendCustomWaveform_Nova2(OutWaveform, Motor, bValidateWaveform); +} + +FString USGNova2GloveKismetLibrary::ToString(const USGNova2Glove* Nova2Glove) +{ + return Nova2Glove->ToString(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGNova2GloveSensorDataKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGNova2GloveSensorDataKismetLibrary.cpp new file mode 100644 index 0000000..ea317d7 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGNova2GloveSensorDataKismetLibrary.cpp @@ -0,0 +1,131 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGNova2GloveSensorDataKismetLibrary.h" + +#include "SGCore/SGNovaGloveInfo.h" +#include "SGCore/SGNova2GloveSensorData.h" +#include "SGUtils/SGArrayUtils.h" + +USGNova2GloveSensorData* USGNova2GloveSensorDataKismetLibrary::MakeNova2GloveSensorData(UObject* WorldContextObject) +{ + return USGNova2GloveSensorData::NewNova2GloveSensorData(WorldContextObject); +} + +USGNova2GloveSensorData* USGNova2GloveSensorDataKismetLibrary::MakeNova2GloveSensorData_NS_V_PV_FQuat_IR_bIP_BL_bC( + UObject* WorldContextObject, const ESGNormalizationState NormalizationState, + const TArray& Values, const int32 ParsedValues, + const FQuat& ImuRotation, const bool bImuParsed, const float BatteryLevel, const bool bCharging) +{ + return USGNova2GloveSensorData::NewNova2GloveSensorData( + WorldContextObject, + NormalizationState, Values, ParsedValues, ImuRotation, bImuParsed, BatteryLevel, bCharging); +} + +USGNova2GloveSensorData* USGNova2GloveSensorDataKismetLibrary::MakeNova2GloveSensorData_NS_V_PV_FRotator_IR_bIP_BL_b( + UObject* WorldContextObject, const ESGNormalizationState NormalizationState, + const TArray& Values, const int32 ParsedValues, + const FRotator& ImuRotation, const bool bImuParsed, const float BatteryLevel, const bool bCharging) +{ + return USGNova2GloveSensorData::NewNova2GloveSensorData( + WorldContextObject, + NormalizationState, Values, ParsedValues, ImuRotation, bImuParsed, BatteryLevel, bCharging); +} + +USGNova2GloveSensorData* USGNova2GloveSensorDataKismetLibrary::Parse( + UObject* WorldContextObject, const FString& RawData, const USGNovaGloveInfo* GloveInfo) +{ + return USGNova2GloveSensorData::Parse(WorldContextObject, RawData, GloveInfo); +} + +ESGNormalizationState USGNova2GloveSensorDataKismetLibrary::GetSensorState( + const USGNova2GloveSensorData* Nova2GloveSensorData) +{ + return Nova2GloveSensorData->GetSensorState(); +} + +TArray USGNova2GloveSensorDataKismetLibrary::GetSensorValues( + const USGNova2GloveSensorData* Nova2GloveSensorData) +{ + return FSGArrayUtils::ToNestedBPArray(Nova2GloveSensorData->GetSensorValues()); +} + +float USGNova2GloveSensorDataKismetLibrary::GetSensorValue( + const USGNova2GloveSensorData* Nova2GloveSensorData, + const ESGFinger Finger, const ESGNova2SensorLocation Location) +{ + return Nova2GloveSensorData->GetSensorValue(Finger, Location); +} + +int32 USGNova2GloveSensorDataKismetLibrary::GetParsedValues(const USGNova2GloveSensorData* Nova2GloveSensorData) +{ + return Nova2GloveSensorData->GetParsedValues(); +} + +FQuat USGNova2GloveSensorDataKismetLibrary::GetImuRotation_FQuat(const USGNova2GloveSensorData* Nova2GloveSensorData) +{ + return Nova2GloveSensorData->GetImuRotationQ(); +} + +FRotator USGNova2GloveSensorDataKismetLibrary::GetImuRotation_FRotator( + const USGNova2GloveSensorData* Nova2GloveSensorData) +{ + return Nova2GloveSensorData->GetImuRotation(); +} + +bool USGNova2GloveSensorDataKismetLibrary::IsImuParsed(const USGNova2GloveSensorData* Nova2GloveSensorData) +{ + return Nova2GloveSensorData->IsImuParsed(); +} + +float USGNova2GloveSensorDataKismetLibrary::GetBatteryLevel(const USGNova2GloveSensorData* Nova2GloveSensorData) +{ + return Nova2GloveSensorData->GetBatteryLevel(); +} + +bool USGNova2GloveSensorDataKismetLibrary::IsCharging(const USGNova2GloveSensorData* Nova2GloveSensorData) +{ + return Nova2GloveSensorData->IsCharging(); +} + +bool USGNova2GloveSensorDataKismetLibrary::Equals(const USGNova2GloveSensorData* A, const USGNova2GloveSensorData* B) +{ + return A->Equals(B); +} + +FString USGNova2GloveSensorDataKismetLibrary::ToString(const USGNova2GloveSensorData* Nova2GloveSensorData) +{ + return Nova2GloveSensorData->ToString(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGNovaGloveInfoKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGNovaGloveInfoKismetLibrary.cpp new file mode 100644 index 0000000..6dc4c4f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGNovaGloveInfoKismetLibrary.cpp @@ -0,0 +1,135 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGNovaGloveInfoKismetLibrary.h" + +#include "SGCore/SGNovaGloveInfo.h" + +USGNovaGloveInfo* USGNovaGloveInfoKismetLibrary::MakeNovaGloveInfo(UObject* WorldContextObject) +{ + return USGNovaGloveInfo::NewNovaGloveInfo(WorldContextObject); +} + +USGNovaGloveInfo* USGNovaGloveInfoKismetLibrary::MakeNovaGloveInfo_DI_HV_FV_SFV_bRH_IC_NOS( + UObject* WorldContextObject, + const FString& DeviceId, + const FString& HardwareVersion, const int32 FirmwareVersion, const int32 SubFirmwareVersion, + const bool bRightHanded, const FQuat& ImuCorrection, const int32 NumberOfSensors) +{ + return USGNovaGloveInfo::NewNovaGloveInfo(WorldContextObject, + DeviceId, HardwareVersion, FirmwareVersion, SubFirmwareVersion, + bRightHanded, ImuCorrection, NumberOfSensors); +} + +bool USGNovaGloveInfoKismetLibrary::Parse(UObject* WorldContextObject, + const FString& ConstantsString, USGNovaGloveInfo*& OutGloveInfo) +{ + return USGNovaGloveInfo::Parse(WorldContextObject, ConstantsString, OutGloveInfo); +} + +USGNovaGloveInfo* USGNovaGloveInfoKismetLibrary::Deserialize(UObject* WorldContextObject, + const FString& SerializedString) +{ + return USGNovaGloveInfo::Deserialize(WorldContextObject, SerializedString); +} + +FString USGNovaGloveInfoKismetLibrary::GetDeviceId(const USGNovaGloveInfo* NovaGloveInfo) +{ + return NovaGloveInfo->GetDeviceId(); +} + +FString USGNovaGloveInfoKismetLibrary::GetHardwareVersion(const USGNovaGloveInfo* NovaGloveInfo) +{ + return NovaGloveInfo->GetHardwareVersion(); +} + +int32 USGNovaGloveInfoKismetLibrary::GetFirmwareVersion(const USGNovaGloveInfo* NovaGloveInfo) +{ + return NovaGloveInfo->GetFirmwareVersion(); +} + +int32 USGNovaGloveInfoKismetLibrary::GetSubFirmwareVersion(const USGNovaGloveInfo* NovaGloveInfo) +{ + return NovaGloveInfo->GetSubFirmwareVersion(); +} + +bool USGNovaGloveInfoKismetLibrary::IsRight(const USGNovaGloveInfo* NovaGloveInfo) +{ + return NovaGloveInfo->IsRight(); +} + +FQuat USGNovaGloveInfoKismetLibrary::GetImuCorrection_FQuat(const USGNovaGloveInfo* NovaGloveInfo) +{ + return NovaGloveInfo->GetImuCorrectionQ(); +} + +FRotator USGNovaGloveInfoKismetLibrary::GetImuCorrection_FRotator(const USGNovaGloveInfo* NovaGloveInfo) +{ + return NovaGloveInfo->GetImuCorrection(); +} + +int32 USGNovaGloveInfoKismetLibrary::GetNumberOfSensors(const USGNovaGloveInfo* NovaGloveInfo) +{ + return NovaGloveInfo->GetNumberOfSensors(); +} + +bool USGNovaGloveInfoKismetLibrary::FirmwareNewerThan( + const USGNovaGloveInfo* NovaGloveInfo, + const int32 FirmwareMain, const int32 FirmwareSub, const bool bInclusive) const +{ + return NovaGloveInfo->FirmwareNewerThan(FirmwareMain, FirmwareSub, bInclusive); +} + +bool USGNovaGloveInfoKismetLibrary::FirmwareOlderThan( + const USGNovaGloveInfo* NovaGloveInfo, + const int32 FirmwareMain, const int32 FirmwareSub, const bool bInclusive) const +{ + return NovaGloveInfo->FirmwareOlderThan(FirmwareMain, FirmwareSub, bInclusive); +} + +bool USGNovaGloveInfoKismetLibrary::Equals(const USGNovaGloveInfo* A, const USGNovaGloveInfo* B) +{ + return A->Equals(B); +} + +FString USGNovaGloveInfoKismetLibrary::ToString(const USGNovaGloveInfo* NovaGloveInfo) +{ + return NovaGloveInfo->ToString(); +} + +FString USGNovaGloveInfoKismetLibrary::SGSerialize(const USGNovaGloveInfo* NovaGloveInfo) +{ + return NovaGloveInfo->SGSerialize(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGNovaGloveKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGNovaGloveKismetLibrary.cpp new file mode 100644 index 0000000..2a4fc59 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGNovaGloveKismetLibrary.cpp @@ -0,0 +1,421 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 NovaGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGNovaGloveKismetLibrary.h" + +#include "SGCore/SGHandPose.h" +#include "SGCore/SGNovaGlove.h" +#include "SGCore/SGNovaGloveSensorData.h" +#include "SGUtils/SGArrayUtils.h" + +USGDevice* USGNovaGloveKismetLibrary::Parse(UObject* WorldContextObject, const FString& ConstantsString) +{ + return USGNovaGlove::Parse(WorldContextObject, ConstantsString); +} + +TArray USGNovaGloveKismetLibrary::GetNovaGloves(UObject* WorldContextObject) +{ + return USGNovaGlove::GetNovaGloves(WorldContextObject); +} + +bool USGNovaGloveKismetLibrary::GetNovaGlove_OutG(UObject* WorldContextObject, USGNovaGlove*& OutGlove) +{ + return USGNovaGlove::GetNovaGlove(WorldContextObject, OutGlove); +} + +bool USGNovaGloveKismetLibrary::GetNovaGlove_bRH_OutG(UObject* WorldContextObject, + const bool bRightHanded, USGNovaGlove*& OutGlove) +{ + return USGNovaGlove::GetNovaGlove(WorldContextObject, bRightHanded, OutGlove); +} + +void USGNovaGloveKismetLibrary::CalculateGloveLocation_RP_FQuat_RR_TH_bRH_OutGP_OutGR( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, + FVector& OutGlovePosition, FQuat& OutGloveRotation) +{ + USGNovaGlove::CalculateGloveLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, bRightHanded, + OutGlovePosition, OutGloveRotation); +} + +void USGNovaGloveKismetLibrary::CalculateGloveLocation_RP_FRotator_RR_TH_bRH_OutGP_OutGR( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, + FVector& OutGlovePosition, FRotator& OutGloveRotation) +{ + USGNovaGlove::CalculateGloveLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, bRightHanded, + OutGlovePosition, OutGloveRotation); +} + +void USGNovaGloveKismetLibrary::CalculateWristLocation_RP_FQuat_RR_TH_bRH_OutWP_OutWR( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, + FVector& OutWristPosition, FQuat& OutWristRotation) +{ + USGNovaGlove::CalculateWristLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, bRightHanded, + OutWristPosition, OutWristRotation); +} + +void USGNovaGloveKismetLibrary::CalculateWristLocation_RP_FRotator_RR_TH_bRH_OutWP_OutWR( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, + FVector& OutWristPosition, FRotator& OutWristRotation) +{ + USGNovaGlove::CalculateWristLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, bRightHanded, + OutWristPosition, OutWristRotation); +} + +FString USGNovaGloveKismetLibrary::GetHapticsByte() +{ + return FString::Printf(TEXT("%c"), USGNovaGlove::GetHapticsByte()); +} + +FString USGNovaGloveKismetLibrary::GetThresholdsByte() +{ + return FString::Printf(TEXT("%c"), USGNovaGlove::GetThresholdsByte()); +} + +FString USGNovaGloveKismetLibrary::GetIgnoreThresholdsByte() +{ + return FString::Printf(TEXT("%c"), USGNovaGlove::GetIgnoreThresholdsByte()); +} + +TArray USGNovaGloveKismetLibrary::GetNovaSensorRanges() +{ + return USGNovaGlove::GetNovaSensorRanges(); +} + +TArray USGNovaGloveKismetLibrary::ToNormalizedValues_SD(const USGNovaGloveSensorData* SensorData) +{ + return USGNovaGlove::ToNormalizedValues(SensorData); +} + +TArray USGNovaGloveKismetLibrary::ToNormalizedValues_SD_OutSN( + UObject* WorldContextObject, + const USGNovaGloveSensorData* SensorData, USGSensorNormalization*& OutSensorNormalizer) +{ + return USGNovaGlove::ToNormalizedValues(WorldContextObject, SensorData, OutSensorNormalizer); +} + +TArray USGNovaGloveKismetLibrary::CalculateHandAngles( + const TArray& NormalizedValues, const USGHandInterpolator* Interpolator) +{ + const TArray HandAngles{ + FSGArrayUtils::ToNestedBPArray( + USGNovaGlove::CalculateHandAngles(NormalizedValues, Interpolator)) + }; + return HandAngles; +} + +FString USGNovaGloveKismetLibrary::ToNovaCommandAsFlexion(const USGThresholdCommand* Thresholds) +{ + return USGNovaGlove::ToNovaCommandAsFlexion(Thresholds); +} + +FString USGNovaGloveKismetLibrary::ToNovaCommandAsRaw( + const USGThresholdCommand* Thresholds, const USGSensorNormalization* Interpolator) +{ + return USGNovaGlove::ToNovaCommandAsRaw(Thresholds, Interpolator); +} + +ESGDeviceType USGNovaGloveKismetLibrary::GetDeviceType(const USGNovaGlove* NovaGlove) +{ + return NovaGlove->GetDeviceType(); +} + +FString USGNovaGloveKismetLibrary::GetDeviceId(const USGNovaGlove* NovaGlove) +{ + return NovaGlove->GetDeviceId(); +} + +FString USGNovaGloveKismetLibrary::GetHardwareVersion(const USGNovaGlove* NovaGlove) +{ + return NovaGlove->GetHardwareVersion(); +} + +int32 USGNovaGloveKismetLibrary::GetFirmwareVersion(const USGNovaGlove* NovaGlove) +{ + return NovaGlove->GetFirmwareVersion(); +} + +int32 USGNovaGloveKismetLibrary::GetSubFirmwareVersion(const USGNovaGlove* NovaGlove) +{ + return NovaGlove->GetSubFirmwareVersion(); +} + +void USGNovaGloveKismetLibrary::SetDeviceIndex(USGNovaGlove* NovaGlove, const int32 NewIndex) +{ + NovaGlove->SetDeviceIndex(NewIndex); +} + +bool USGNovaGloveKismetLibrary::HasBattery(const USGNovaGlove* NovaGlove) +{ + return NovaGlove->HasBattery(); +} + +bool USGNovaGloveKismetLibrary::IsCharging(USGNovaGlove* NovaGlove) +{ + return NovaGlove->IsCharging(); +} + +bool USGNovaGloveKismetLibrary::GetBatteryLevel(USGNovaGlove* NovaGlove, float& OutBatteryLevel) +{ + return NovaGlove->GetBatteryLevel(OutBatteryLevel); +} + +bool USGNovaGloveKismetLibrary::IsRight(const USGNovaGlove* NovaGlove) +{ + return NovaGlove->IsRight(); +} + +bool USGNovaGloveKismetLibrary::GetImuRotation_FQuat_OutI(USGNovaGlove* NovaGlove, FQuat& OutImu) +{ + return NovaGlove->GetImuRotation(OutImu); +} + +bool USGNovaGloveKismetLibrary::GetImuRotation_FRotator_OutI(USGNovaGlove* NovaGlove, FRotator& OutImu) +{ + return NovaGlove->GetImuRotation(OutImu); +} + +bool USGNovaGloveKismetLibrary::GetHandPose( + UObject* WorldContextObject, + USGNovaGlove* NovaGlove, const USGBasicHandModel* HandModel, USGHandPose*& OutHandPose) +{ + return NovaGlove->GetHandPose(WorldContextObject, HandModel, OutHandPose); +} + +bool USGNovaGloveKismetLibrary::GetHandAngles(const USGNovaGlove* NovaGlove, TArray& OutHandAngles) +{ + TArray> HandAnglesNestedArray; + const bool bResult = NovaGlove->GetHandAngles(HandAnglesNestedArray); + OutHandAngles = FSGArrayUtils::ToNestedBPArray(MoveTemp(HandAnglesNestedArray)); + return bResult; +} + +ESGHapticGloveCalibrationState USGNovaGloveKismetLibrary::GetCalibrationState(const USGNovaGlove* NovaGlove) +{ + return NovaGlove->GetCalibrationState(); +} + +void USGNovaGloveKismetLibrary::EndCalibration(USGNovaGlove* NovaGlove) +{ + NovaGlove->EndCalibration(); +} + +void USGNovaGloveKismetLibrary::ResetCalibration(USGNovaGlove* NovaGlove) +{ + NovaGlove->ResetCalibration(); +} + +void USGNovaGloveKismetLibrary::StopHaptics(USGNovaGlove* NovaGlove) +{ + NovaGlove->StopHaptics(); +} + +void USGNovaGloveKismetLibrary::StopVibrations(USGNovaGlove* NovaGlove) +{ + NovaGlove->StopVibrations(); +} + +bool USGNovaGloveKismetLibrary::SendHaptics(USGNovaGlove* NovaGlove) +{ + return NovaGlove->SendHaptics(); +} + +bool USGNovaGloveKismetLibrary::SupportsCustomWaveform(const USGNovaGlove* NovaGlove, + const ESGHapticLocation AtLocation) +{ + return NovaGlove->SupportsCustomWaveform(AtLocation); +} + +bool USGNovaGloveKismetLibrary::SendCustomWaveform(USGNovaGlove* NovaGlove, + USGCustomWaveform* OutWaveform, const ESGHapticLocation Location) +{ + return NovaGlove->SendCustomWaveform(OutWaveform, Location); +} + +bool USGNovaGloveKismetLibrary::QueueForceFeedbackLevels(USGNovaGlove* NovaGlove, const TArray& Levels01) +{ + return NovaGlove->QueueForceFeedbackLevels(Levels01); +} + +bool USGNovaGloveKismetLibrary::QueueForceFeedbackLevel( + USGNovaGlove* NovaGlove, const int32 Finger, const float Level01) +{ + return NovaGlove->QueueForceFeedbackLevel(Finger, Level01); +} + +bool USGNovaGloveKismetLibrary::QueueVibroLevels(USGNovaGlove* NovaGlove, const TArray& Amplitudes) +{ + return NovaGlove->QueueVibroLevels(Amplitudes); +} + +bool USGNovaGloveKismetLibrary::QueueVibroLevel_L_L(USGNovaGlove* NovaGlove, + const ESGHapticLocation Location, const float Level01) +{ + return NovaGlove->QueueVibroLevel(Location, Level01); +} + +void USGNovaGloveKismetLibrary::GetGloveLocation_RP_FQuat_RR_TH_OutGP_FQuat_OutGR( + const USGNovaGlove* NovaGlove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) +{ + NovaGlove->GetGloveLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + OutGlovePosition, OutGloveRotation); +} + +void USGNovaGloveKismetLibrary::GetGloveLocation_RP_FRotator_RR_TH_OutGP_FRotator_OutGR( + const USGNovaGlove* NovaGlove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FRotator& OutGloveRotation) +{ + NovaGlove->GetGloveLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + OutGlovePosition, OutGloveRotation); +} + +void USGNovaGloveKismetLibrary::GetWristLocation_RP_FQuat_RR_TH_OutWP_FQuat_OutWR( + const USGNovaGlove* NovaGlove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) +{ + NovaGlove->GetWristLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + OutWristPosition, OutWristRotation); +} + +void USGNovaGloveKismetLibrary::GetWristLocation_RP_FRotator_RR_TH_OutWP_FRotator_OutWR( + const USGNovaGlove* NovaGlove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FRotator& OutWristRotation) +{ + NovaGlove->GetWristLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + OutWristPosition, OutWristRotation); +} + +USGNovaGloveInfo* USGNovaGloveKismetLibrary::GetGloveInfo(UObject* WorldContextObject, const USGNovaGlove* NovaGlove) +{ + return NovaGlove->GetGloveInfo(WorldContextObject); +} + +bool USGNovaGloveKismetLibrary::SupportsThresholds(const USGNovaGlove* NovaGlove) +{ + return NovaGlove->SupportsThresholds(); +} + +bool USGNovaGloveKismetLibrary::SupportsCustomWaveforms(const USGNovaGlove* NovaGlove) +{ + return NovaGlove->SupportsCustomWaveforms(); +} + +bool USGNovaGloveKismetLibrary::SupportsOnBoardNormalization(const USGNovaGlove* NovaGlove) +{ + return NovaGlove->SupportsOnBoardNormalization(); +} + +bool USGNovaGloveKismetLibrary::GetSensorData( + UObject* WorldContextObject, USGNovaGlove* NovaGlove, USGNovaGloveSensorData*& OutSensorData) +{ + return NovaGlove->GetSensorData(WorldContextObject, OutSensorData); +} + +FString USGNovaGloveKismetLibrary::ToNovaCommand( + const USGNovaGlove* NovaGlove, + const TArray& ForceFeedbackLevels, const TArray& BuzzLevels, const float WristLevel) +{ + return NovaGlove->ToNovaCommand(ForceFeedbackLevels, BuzzLevels, WristLevel); +} + +bool USGNovaGloveKismetLibrary::QueueVibroLevel_F_A(USGNovaGlove* NovaGlove, const int32 Finger, const float Amplitude) +{ + return NovaGlove->QueueVibroLevel(Finger, Amplitude); +} + +bool USGNovaGloveKismetLibrary::QueueWristLevel(USGNovaGlove* NovaGlove, const float Amplitude) +{ + return NovaGlove->QueueWristLevel(Amplitude); +} + +ESGNovaVibroMotor USGNovaGloveKismetLibrary::ToNovaMotor(const USGNovaGlove* NovaGlove, + const ESGHapticLocation Location) +{ + return NovaGlove->ToNovaMotor(Location); +} + +int32 USGNovaGloveKismetLibrary::ChannelIndex(const USGNovaGlove* NovaGlove, const ESGNovaVibroMotor Motor) +{ + return NovaGlove->ChannelIndex(Motor); +} + +void USGNovaGloveKismetLibrary::ValidateWaveform(const USGNovaGlove* NovaGlove, + USGCustomWaveform* OutWaveform, const ESGNovaVibroMotor Motor) +{ + NovaGlove->ValidateWaveform(OutWaveform, Motor); +} + +bool USGNovaGloveKismetLibrary::SendCustomWaveform_Nova( + USGNovaGlove* NovaGlove, + USGCustomWaveform* OutWaveform, const ESGNovaVibroMotor Motor, const bool bValidateWaveform) +{ + return NovaGlove->SendCustomWaveform_Nova(OutWaveform, Motor, bValidateWaveform); +} + +bool USGNovaGloveKismetLibrary::QueueThresholdCommand_Flexion(USGNovaGlove* NovaGlove, + const int32 Finger, const float FlexionThreshold) +{ + return NovaGlove->QueueThresholdCommand_Flexion(Finger, FlexionThreshold); +} + +bool USGNovaGloveKismetLibrary::QueueClearThreshold(USGNovaGlove* NovaGlove, const int32 Finger) +{ + return NovaGlove->QueueClearThreshold(Finger); +} + +FString USGNovaGloveKismetLibrary::ToString(const USGNovaGlove* NovaGlove) +{ + return NovaGlove->ToString(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGNovaGloveSensorDataKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGNovaGloveSensorDataKismetLibrary.cpp new file mode 100644 index 0000000..3dd3647 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGNovaGloveSensorDataKismetLibrary.cpp @@ -0,0 +1,134 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGNovaGloveSensorDataKismetLibrary.h" + +#include "SGCore/SGNovaGloveInfo.h" +#include "SGCore/SGNovaGloveSensorData.h" + +USGNovaGloveSensorData* USGNovaGloveSensorDataKismetLibrary::MakeNovaGloveSensorData(UObject* WorldContextObject) +{ + return USGNovaGloveSensorData::NewNovaGloveSensorData(WorldContextObject); +} + +USGNovaGloveSensorData* USGNovaGloveSensorDataKismetLibrary::MakeNovaGloveSensorData_V_PV_FQuat_IR_bIP_BL_bC( + UObject* WorldContextObject, const TArray& Values, const int32 ParsedValues, + const FQuat& ImuRotation, const bool bImuParsed, const float BatteryLevel, const bool bCharging) +{ + return USGNovaGloveSensorData::NewNovaGloveSensorData( + WorldContextObject, Values, ParsedValues, ImuRotation, bImuParsed, BatteryLevel, bCharging); +} + +USGNovaGloveSensorData* USGNovaGloveSensorDataKismetLibrary::MakeNovaGloveSensorData_V_PV_FRotator_IR_bIP_BL_b( + UObject* WorldContextObject, const TArray& Values, const int32 ParsedValues, + const FRotator& ImuRotation, const bool bImuParsed, const float BatteryLevel, const bool bCharging) +{ + return USGNovaGloveSensorData::NewNovaGloveSensorData( + WorldContextObject, Values, ParsedValues, ImuRotation, bImuParsed, BatteryLevel, bCharging); +} + +USGNovaGloveSensorData* USGNovaGloveSensorDataKismetLibrary::Empty(UObject* WorldContextObject) +{ + return USGNovaGloveSensorData::Empty(WorldContextObject); +} + +USGNovaGloveSensorData* USGNovaGloveSensorDataKismetLibrary::Parse( + UObject* WorldContextObject, const FString& RawData, const USGNovaGloveInfo* GloveInfo) +{ + return USGNovaGloveSensorData::Parse(WorldContextObject, RawData, GloveInfo); +} + +USGNovaGloveSensorData* USGNovaGloveSensorDataKismetLibrary::Deserialize(UObject* WorldContextObject, + const FString& SerializedString) +{ + return USGNovaGloveSensorData::Deserialize(WorldContextObject, SerializedString); +} + +TArray USGNovaGloveSensorDataKismetLibrary::GetSensorValues( + const USGNovaGloveSensorData* NovaGloveSensorData) +{ + return NovaGloveSensorData->GetSensorValues(); +} + +float USGNovaGloveSensorDataKismetLibrary::GetSensorValue(const USGNovaGloveSensorData* NovaGloveSensorData, + const ESGFinger Finger, const ESGNovaSensorLocation Location) +{ + return NovaGloveSensorData->GetSensorValue(Finger, Location); +} + +int32 USGNovaGloveSensorDataKismetLibrary::GetParsedValues(const USGNovaGloveSensorData* NovaGloveSensorData) +{ + return NovaGloveSensorData->GetParsedValues(); +} + +FQuat USGNovaGloveSensorDataKismetLibrary::GetImuRotation_FQuat(const USGNovaGloveSensorData* NovaGloveSensorData) +{ + return NovaGloveSensorData->GetImuRotationQ(); +} + +FRotator USGNovaGloveSensorDataKismetLibrary::GetImuRotation_FRotator(const USGNovaGloveSensorData* NovaGloveSensorData) +{ + return NovaGloveSensorData->GetImuRotation(); +} + +bool USGNovaGloveSensorDataKismetLibrary::IsImuParsed(const USGNovaGloveSensorData* NovaGloveSensorData) +{ + return NovaGloveSensorData->IsImuParsed(); +} + +float USGNovaGloveSensorDataKismetLibrary::GetBatteryLevel(const USGNovaGloveSensorData* NovaGloveSensorData) +{ + return NovaGloveSensorData->GetBatteryLevel(); +} + +bool USGNovaGloveSensorDataKismetLibrary::IsCharging(const USGNovaGloveSensorData* NovaGloveSensorData) +{ + return NovaGloveSensorData->IsCharging(); +} + +bool USGNovaGloveSensorDataKismetLibrary::Equals(const USGNovaGloveSensorData* A, const USGNovaGloveSensorData* B) +{ + return A->Equals(B); +} + +FString USGNovaGloveSensorDataKismetLibrary::ToString(const USGNovaGloveSensorData* NovaGloveSensorData) +{ + return NovaGloveSensorData->ToString(); +} + +FString USGNovaGloveSensorDataKismetLibrary::SGSerialize(const USGNovaGloveSensorData* NovaGloveSensorData) +{ + return NovaGloveSensorData->SGSerialize(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseComKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseComKismetLibrary.cpp new file mode 100644 index 0000000..ec0bfd6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseComKismetLibrary.cpp @@ -0,0 +1,68 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGSenseComKismetLibrary.h" + +#include "SGCore/SGSenseCom.h" + +bool USGSenseComKismetLibrary::RegisterExe() +{ + return FSGSenseCom::RegisterExe(); +} + +bool USGSenseComKismetLibrary::RegisterExe_EP(const FString& ExePath) +{ + return FSGSenseCom::RegisterExe(ExePath); +} + +bool USGSenseComKismetLibrary::GetExePath(FString& OutExePath) +{ + return FSGSenseCom::GetExePath(OutExePath); +} + +bool USGSenseComKismetLibrary::ScanningActive() +{ + return FSGSenseCom::ScanningActive(); +} + +bool USGSenseComKismetLibrary::GetCurrentExeDirectory(FString& OutDirectory) +{ + return FSGSenseCom::GetCurrentExeDirectory(OutDirectory); +} + +bool USGSenseComKismetLibrary::StartupSenseCom() +{ + return FSGSenseCom::StartupSenseCom(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGloveInfoKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGloveInfoKismetLibrary.cpp new file mode 100644 index 0000000..e86e36b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGloveInfoKismetLibrary.cpp @@ -0,0 +1,211 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGSenseGloveInfoKismetLibrary.h" + +#include "SGCore/SGSenseGloveInfo.h" +#include "SGUtils/SGArrayUtils.h" + +USGSenseGloveInfo* USGSenseGloveInfoKismetLibrary::MakeSenseGloveInfo(UObject* WorldContextObject) +{ + return USGSenseGloveInfo::NewSenseGloveInfo(WorldContextObject); +} + +USGSenseGloveInfo* +USGSenseGloveInfoKismetLibrary::MakeSenseGloveInfo_DI_HV_FV_SFV_bRH_NOS_FQuat_IC_SP_TArrayFQuat_SR_GL_F( + UObject* WorldContextObject, const FString& DeviceId, + const FString& HardwareVersion, const int32 FirmwareVersion, const int32 SubFirmwareVersion, + const bool bRightHanded, const int32 NumberOfSensors, const FQuat& ImuCorrection, + const TArray& StartPositions, const TArray& StartRotations, + const TArray& GloveLengths, const TArray& Functions) +{ + return USGSenseGloveInfo::NewSenseGloveInfo(WorldContextObject, DeviceId, + HardwareVersion, FirmwareVersion, SubFirmwareVersion, + bRightHanded, NumberOfSensors, ImuCorrection, + StartPositions, StartRotations, + GloveLengths, Functions); +} + +USGSenseGloveInfo* +USGSenseGloveInfoKismetLibrary::MakeSenseGloveInfo_DI_HV_FV_SFV_bRH_NOS_FRotator_IC_SP_TArrayFRotator_SR_GL_F( + UObject* WorldContextObject, const FString& DeviceId, + const FString& HardwareVersion, const int32 FirmwareVersion, const int32 SubFirmwareVersion, + const bool bRightHanded, const int32 NumberOfSensors, const FRotator& ImuCorrection, + const TArray& StartPositions, const TArray& StartRotations, + const TArray& GloveLengths, const TArray& Functions) +{ + return USGSenseGloveInfo::NewSenseGloveInfo(WorldContextObject, DeviceId, + HardwareVersion, FirmwareVersion, SubFirmwareVersion, + bRightHanded, NumberOfSensors, ImuCorrection, + StartPositions, StartRotations, + GloveLengths, Functions); +} + +bool USGSenseGloveInfoKismetLibrary::Parse(UObject* WorldContextObject, + const FString& ConstantsString, USGSenseGloveInfo*& OutGloveInfo, + const bool bUpdateOldModels) +{ + return USGSenseGloveInfo::Parse(WorldContextObject, ConstantsString, OutGloveInfo, bUpdateOldModels); +} + +USGSenseGloveInfo* USGSenseGloveInfoKismetLibrary::Deserialize(UObject* WorldContextObject, + const FString& SerializedString) +{ + return USGSenseGloveInfo::Deserialize(WorldContextObject, SerializedString); +} + +FString USGSenseGloveInfoKismetLibrary::GetDeviceId(const USGSenseGloveInfo* SenseGloveInfo) +{ + return SenseGloveInfo->GetDeviceId(); +} + +FString USGSenseGloveInfoKismetLibrary::GetHardwareVersion(const USGSenseGloveInfo* SenseGloveInfo) +{ + return SenseGloveInfo->GetHardwareVersion(); +} + +int32 USGSenseGloveInfoKismetLibrary::GetFirmwareVersion(const USGSenseGloveInfo* SenseGloveInfo) +{ + return SenseGloveInfo->GetFirmwareVersion(); +} + +int32 USGSenseGloveInfoKismetLibrary::GetSubFirmwareVersion(const USGSenseGloveInfo* SenseGloveInfo) +{ + return SenseGloveInfo->GetSubFirmwareVersion(); +} + +bool USGSenseGloveInfoKismetLibrary::IsRight(const USGSenseGloveInfo* SenseGloveInfo) +{ + return SenseGloveInfo->IsRight(); +} + +int32 USGSenseGloveInfoKismetLibrary::GetNumberOfSensors(const USGSenseGloveInfo* SenseGloveInfo) +{ + return SenseGloveInfo->GetNumberOfSensors(); +} + +FQuat USGSenseGloveInfoKismetLibrary::GetImuCorrection_FQuat(const USGSenseGloveInfo* SenseGloveInfo) +{ + return SenseGloveInfo->GetImuCorrectionQ(); +} + +FRotator USGSenseGloveInfoKismetLibrary::GetImuCorrection_FRotator(const USGSenseGloveInfo* SenseGloveInfo) +{ + return SenseGloveInfo->GetImuCorrection(); +} + +TArray USGSenseGloveInfoKismetLibrary::GetStartPositions(const USGSenseGloveInfo* SenseGloveInfo) +{ + return SenseGloveInfo->GetStartPositions(); +} + +TArray USGSenseGloveInfoKismetLibrary::GetStartRotations_TArrayFQuat(const USGSenseGloveInfo* SenseGloveInfo) +{ + return SenseGloveInfo->GetStartRotationsQ(); +} + +TArray USGSenseGloveInfoKismetLibrary::GetStartRotations_TArrayFRotator( + const USGSenseGloveInfo* SenseGloveInfo) +{ + return SenseGloveInfo->GetStartRotations(); +} + +TArray USGSenseGloveInfoKismetLibrary::GetGloveLengths(const USGSenseGloveInfo* SenseGloveInfo) +{ + return FSGArrayUtils::ToNestedBPArray(SenseGloveInfo->GetGloveLengths()); +} + +TArray USGSenseGloveInfoKismetLibrary::GetFunctions(const USGSenseGloveInfo* SenseGloveInfo) +{ + return SenseGloveInfo->GetFunctions(); +} + +FVector USGSenseGloveInfoKismetLibrary::GetStartPosition(const USGSenseGloveInfo* SenseGloveInfo, + const ESGFinger Finger) +{ + return SenseGloveInfo->GetStartPosition(Finger); +} + +FQuat USGSenseGloveInfoKismetLibrary::GetStartRotation_FQuat(const USGSenseGloveInfo* SenseGloveInfo, + const ESGFinger Finger) +{ + return SenseGloveInfo->GetStartRotationQ(Finger); +} + +FRotator USGSenseGloveInfoKismetLibrary::GetStartRotation_FRotator(const USGSenseGloveInfo* SenseGloveInfo, + const ESGFinger Finger) +{ + return SenseGloveInfo->GetStartRotation(Finger); +} + +TArray USGSenseGloveInfoKismetLibrary::GetGloveLengths_F(const USGSenseGloveInfo* SenseGloveInfo, + const ESGFinger Finger) +{ + return SenseGloveInfo->GetGloveLengths(Finger); +} + +TArray USGSenseGloveInfoKismetLibrary::ToGloveAngles(const USGSenseGloveInfo* SenseGloveInfo, + const TArray& SensorAngles) +{ + TArray> SensorAnglesNestedArray{ + FSGArrayUtils::FromNestedBPArray< + float, FSGFloatArray, &FSGFloatArray::FloatArray>(SensorAngles) + }; + const TArray GloveAngles{ + FSGArrayUtils::ToNestedBPArray( + SenseGloveInfo->ToGloveAngles(MoveTemp(SensorAnglesNestedArray))) + }; + return GloveAngles; +} + +bool USGSenseGloveInfoKismetLibrary::Equals(const USGSenseGloveInfo* A, const USGSenseGloveInfo* B) +{ + return A->Equals(B); +} + +FString USGSenseGloveInfoKismetLibrary::ToString_bSN(const USGSenseGloveInfo* SenseGloveInfo, const bool bShortNotation) +{ + return SenseGloveInfo->ToString(bShortNotation); +} + +FString USGSenseGloveInfoKismetLibrary::ToString(const USGSenseGloveInfo* SenseGloveInfo) +{ + return SenseGloveInfo->ToString(); +} + +FString USGSenseGloveInfoKismetLibrary::SGSerialize(const USGSenseGloveInfo* SenseGloveInfo) +{ + return SenseGloveInfo->SGSerialize(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGloveKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGloveKismetLibrary.cpp new file mode 100644 index 0000000..11892d9 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGloveKismetLibrary.cpp @@ -0,0 +1,430 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGSenseGloveKismetLibrary.h" + +#include "SGCore/SGDevice.h" +#include "SGCore/SGHandInterpolator.h" +#include "SGCore/SGHandPose.h" +#include "SGCore/SGSenseGlove.h" +#include "SGCore/SGSenseGloveSensorNormalizer.h" +#include "SGUtils/SGArrayUtils.h" + +USGDevice* USGSenseGloveKismetLibrary::Parse(UObject* WorldContextObject, const FString& ConstantsString) +{ + return USGSenseGlove::Parse(WorldContextObject, ConstantsString); +} + +TArray USGSenseGloveKismetLibrary::GetSenseGloves(UObject* WorldContextObject) +{ + return USGSenseGlove::GetSenseGloves(WorldContextObject); +} + +bool USGSenseGloveKismetLibrary::GetSenseGlove_OutG(UObject* WorldContextObject, USGSenseGlove*& OutGlove) +{ + return USGSenseGlove::GetSenseGlove(WorldContextObject, OutGlove); +} + +bool USGSenseGloveKismetLibrary::GetSenseGlove_bRH_OutG(UObject* WorldContextObject, + const bool bRightHanded, USGSenseGlove*& OutGlove) +{ + return USGSenseGlove::GetSenseGlove(WorldContextObject, bRightHanded, OutGlove); +} + +void USGSenseGloveKismetLibrary::CalculateGloveLocation_RP_FQuat_RR_TH_bRH_MO_OutGP_FQuat_OutGR( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, const ESGFinger MountedOn, + FVector& OutGlovePosition, FQuat& OutGloveRotation) +{ + USGSenseGlove::CalculateGloveLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, bRightHanded, MountedOn, + OutGlovePosition, OutGloveRotation); +} + +void USGSenseGloveKismetLibrary::CalculateGloveLocation_RP_FRotator_RR_TH_bRH_MO_OutGP_FRotator_OutGR( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, const ESGFinger MountedOn, + FVector& OutGlovePosition, FRotator& OutGloveRotation) +{ + USGSenseGlove::CalculateGloveLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, bRightHanded, MountedOn, + OutGlovePosition, OutGloveRotation); +} + +void USGSenseGloveKismetLibrary::CalculateWristLocation_RP_FQuat_RR_TH_bRH_MO_GWPOffset_FQuat_GWRO_OutWP_FQuat_OutWR( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, const ESGFinger MountedOn, + const FVector& GloveWristPositionOffset, const FQuat& GloveWristRotationOffset, + FVector& OutWristPosition, FQuat& OutWristRotation) +{ + USGSenseGlove::CalculateWristLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, bRightHanded, MountedOn, + GloveWristPositionOffset, GloveWristRotationOffset, + OutWristPosition, OutWristRotation); +} + +void +USGSenseGloveKismetLibrary::CalculateWristLocation_RP_FRotator_RR_TH_bRH_MO_GWPOffset_FRotator_GWRO_OutWP_FRotator_OutWR( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, const ESGFinger MountedOn, + const FVector& GloveWristPositionOffset, const FRotator& GloveWristRotationOffset, + FVector& OutWristPosition, FRotator& OutWristRotation) +{ + USGSenseGlove::CalculateWristLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, bRightHanded, MountedOn, + GloveWristPositionOffset, GloveWristRotationOffset, + OutWristPosition, OutWristRotation); +} + +FString USGSenseGloveKismetLibrary::GetHapticsByte() +{ + return FString::Printf(TEXT("%c"), USGSenseGlove::GetHapticsByte()); +} + +FString USGSenseGloveKismetLibrary::GetThumperByte() +{ + return FString::Printf(TEXT("%c"), USGSenseGlove::GetThumperByte()); +} + +FVector USGSenseGloveKismetLibrary::GetDefaultThimbleOffset() +{ + return USGSenseGlove::GetDefaultThimbleOffset(); +} + +USGSenseGlovePose* USGSenseGloveKismetLibrary::CalculateGlovePose_SD_GM( + UObject* WorldContextObject, + const USGSenseGloveSensorData* SensorData, const USGSenseGloveInfo* GloveModel) +{ + return USGSenseGlove::CalculateGlovePose(WorldContextObject, SensorData, GloveModel); +} + +USGSenseGlovePose* USGSenseGloveKismetLibrary::CalculateGlovePose_GA_GM( + UObject* WorldContextObject, + const TArray& GloveAngles, const USGSenseGloveInfo* GloveModel) +{ + TArray> GloveAnglesNestedArray{ + FSGArrayUtils::FromNestedBPArray(GloveAngles) + }; + return USGSenseGlove::CalculateGlovePose(WorldContextObject, MoveTemp(GloveAnglesNestedArray), GloveModel); +} + +void USGSenseGloveKismetLibrary::NormalizeValues( + const TArray& SumAngles, const USGSenseGloveSensorNormalizer* Normalizer, + TArray& OutFlexions, TArray& OutAbductions) +{ + USGSenseGlove::NormalizeValues(SumAngles, Normalizer, OutFlexions, OutAbductions); +} + +void USGSenseGloveKismetLibrary::CalculateHandAngles( + const USGSenseGlovePose* GlovePose, + const USGSenseGloveSensorNormalizer* Normalizer, const USGHandInterpolator* NormalizedToAngles, + TArray& OutHandAngles) +{ + TArray> OutHandAnglesArray; + USGSenseGlove::CalculateHandAngles(GlovePose, Normalizer, NormalizedToAngles, OutHandAnglesArray); + + TArray OutHandHandAnglesNestedArray{ + FSGArrayUtils::ToNestedBPArray(OutHandAnglesArray) + }; + OutHandAngles = MoveTemp(OutHandHandAnglesNestedArray); +} + +void USGSenseGloveKismetLibrary::CalculateHandPose( + UObject* WorldContextObject, + const USGSenseGlovePose* GlovePose, const USGBasicHandModel* HandModel, + const USGSenseGloveSensorNormalizer* Normalizer, const USGHandInterpolator* NormalizedToAngles, + USGHandPose*& OutHandPose) +{ + USGSenseGlove::CalculateHandPose( + WorldContextObject, + GlovePose, HandModel, Normalizer, NormalizedToAngles, OutHandPose); +} + +ESGDeviceType USGSenseGloveKismetLibrary::GetDeviceType(const USGSenseGlove* SenseGlove) +{ + return SenseGlove->GetDeviceType(); +} + +FString USGSenseGloveKismetLibrary::GetDeviceId(const USGSenseGlove* SenseGlove) +{ + return SenseGlove->GetDeviceId(); +} + +FString USGSenseGloveKismetLibrary::GetHardwareVersion(const USGSenseGlove* SenseGlove) +{ + return SenseGlove->GetHardwareVersion(); +} + +int32 USGSenseGloveKismetLibrary::GetFirmwareVersion(const USGSenseGlove* SenseGlove) +{ + return SenseGlove->GetFirmwareVersion(); +} + +int32 USGSenseGloveKismetLibrary::GetSubFirmwareVersion(const USGSenseGlove* SenseGlove) +{ + return SenseGlove->GetSubFirmwareVersion(); +} + +bool USGSenseGloveKismetLibrary::IsRight(const USGSenseGlove* SenseGlove) +{ + return SenseGlove->IsRight(); +} + +bool USGSenseGloveKismetLibrary::GetImuRotation_FQuat_OutI(USGSenseGlove* SenseGlove, FQuat& OutImu) +{ + return SenseGlove->GetImuRotation(OutImu); +} + +bool USGSenseGloveKismetLibrary::GetImuRotation_FRotator_OutI(USGSenseGlove* SenseGlove, FRotator& OutImu) +{ + return SenseGlove->GetImuRotation(OutImu); +} + +bool USGSenseGloveKismetLibrary::GetHandPose( + UObject* WorldContextObject, USGSenseGlove* SenseGlove, const USGBasicHandModel* HandModel, + USGHandPose*& OutHandPose) +{ + return SenseGlove->GetHandPose(WorldContextObject, HandModel, OutHandPose); +} + +bool USGSenseGloveKismetLibrary::GetHandAngles(const USGSenseGlove* SenseGlove, TArray& OutHandAngles) +{ + TArray> HandAnglesNestedArray; + const bool bResult = SenseGlove->GetHandAngles(HandAnglesNestedArray); + OutHandAngles = FSGArrayUtils::ToNestedBPArray(MoveTemp(HandAnglesNestedArray)); + return bResult; +} + +ESGHapticGloveCalibrationState USGSenseGloveKismetLibrary::GetCalibrationState(const USGSenseGlove* SenseGlove) +{ + return SenseGlove->GetCalibrationState(); +} + +void USGSenseGloveKismetLibrary::EndCalibration(USGSenseGlove* SenseGlove) +{ + SenseGlove->EndCalibration(); +} + +void USGSenseGloveKismetLibrary::ResetCalibration(USGSenseGlove* SenseGlove) +{ + SenseGlove->ResetCalibration(); +} + +void USGSenseGloveKismetLibrary::StopHaptics(USGSenseGlove* SenseGlove) +{ + SenseGlove->StopHaptics(); +} + +void USGSenseGloveKismetLibrary::StopVibrations(USGSenseGlove* SenseGlove) +{ + SenseGlove->StopVibrations(); +} + +bool USGSenseGloveKismetLibrary::SendHaptics(USGSenseGlove* SenseGlove) +{ + return SenseGlove->SendHaptics(); +} + +bool USGSenseGloveKismetLibrary::QueueForceFeedbackLevels(USGSenseGlove* SenseGlove, const TArray& Levels01) +{ + return SenseGlove->QueueForceFeedbackLevels(Levels01); +} + +bool USGSenseGloveKismetLibrary::QueueForceFeedbackLevel(USGSenseGlove* SenseGlove, + const int32 Finger, const float Level01) +{ + return SenseGlove->QueueForceFeedbackLevel(Finger, Level01); +} + +bool USGSenseGloveKismetLibrary::QueueVibroLevels(USGSenseGlove* SenseGlove, const TArray& Amplitudes) +{ + return SenseGlove->QueueVibroLevels(Amplitudes); +} + +bool USGSenseGloveKismetLibrary::QueueVibroLevel_L_L(USGSenseGlove* SenseGlove, + const ESGHapticLocation Location, const float Level01) +{ + return SenseGlove->QueueVibroLevel(Location, Level01); +} + +void USGSenseGloveKismetLibrary::GetGloveLocation_RP_FQuat_RR_TH_OutGP_FQuat_OutGR( + const USGSenseGlove* SenseGlove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation) +{ + SenseGlove->GetGloveLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + OutGlovePosition, OutGloveRotation); +} + +void USGSenseGloveKismetLibrary::GetGloveLocation_RP_FRotator_RR_TH_OutGP_FRotator_OutGR( + const USGSenseGlove* SenseGlove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FRotator& OutGloveRotation) +{ + SenseGlove->GetGloveLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + OutGlovePosition, OutGloveRotation); +} + +void USGSenseGloveKismetLibrary::GetGloveLocation_RP_FQuat_RR_TH_MO_OutGP_FQuat_OutGR( + const USGSenseGlove* SenseGlove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const ESGFinger MountedOn, + FVector& OutGlovePosition, FQuat& OutGloveRotation) +{ + SenseGlove->GetGloveLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, MountedOn, + OutGlovePosition, OutGloveRotation); +} + +void USGSenseGloveKismetLibrary::GetGloveLocation_RP_FRotator_RR_TH_MO_OutGP_FRotator_OutGR( + const USGSenseGlove* SenseGlove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, const ESGFinger MountedOn, FVector& OutGlovePosition, + FRotator& OutGloveRotation) +{ + SenseGlove->GetGloveLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, MountedOn, + OutGlovePosition, OutGloveRotation); +} + +void USGSenseGloveKismetLibrary::GetWristLocation_RP_FQuat_RR_TH_OutWP_FQuat_OutWR( + const USGSenseGlove* SenseGlove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation) +{ + SenseGlove->GetWristLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + OutWristPosition, OutWristRotation); +} + +void USGSenseGloveKismetLibrary::GetWristLocation_RP_FRotator_RR_TH_OutWP_FRotator_OutWR( + const USGSenseGlove* SenseGlove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FRotator& OutWristRotation) +{ + SenseGlove->GetWristLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + OutWristPosition, OutWristRotation); +} + +void USGSenseGloveKismetLibrary::GetWristLocation_RP_FQuat_RR_TH_GWPO_FQuat_GWRO_OutWP_FQuat_OutWR( + const USGSenseGlove* SenseGlove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + const FVector& GloveWristPositionOffset, const FQuat& GloveWristRotationOffset, + FVector& OutWristPosition, FQuat& OutWristRotation) +{ + SenseGlove->GetWristLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + GloveWristPositionOffset, GloveWristRotationOffset, + OutWristPosition, OutWristRotation); +} + +void USGSenseGloveKismetLibrary::GetWristLocation_RP_FRotator_RR_TH_GWPO_FRotator_GWRO_OutWP_FRotator_OutWR( + const USGSenseGlove* SenseGlove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + const ESGPositionalTrackingHardware TrackingHardware, + const FVector& GloveWristPositionOffset, const FRotator& GloveWristRotationOffset, + FVector& OutWristPosition, FRotator& OutWristRotation) +{ + SenseGlove->GetWristLocation(ReferencePosition, ReferenceRotation, + TrackingHardware, + GloveWristPositionOffset, GloveWristRotationOffset, + OutWristPosition, OutWristRotation); +} + +USGSenseGloveInfo* USGSenseGloveKismetLibrary::GetGloveInfo( + UObject* WorldContextObject, const USGSenseGlove* SenseGlove) +{ + return SenseGlove->GetGloveInfo(WorldContextObject); +} + +TArray USGSenseGloveKismetLibrary::GetFingerThimbleOffsets(const USGSenseGlove* SenseGlove) +{ + return SenseGlove->GetFingerThimbleOffsets(); +} + +void USGSenseGloveKismetLibrary::SetFingerThimbleOffset(USGSenseGlove* SenseGlove, + const int32 Finger, const FVector& Offset) +{ + SenseGlove->SetFingerThimbleOffset(Finger, Offset); +} + +bool USGSenseGloveKismetLibrary::SupportsWristActuator(const USGSenseGlove* SenseGlove) +{ + return SenseGlove->SupportsWristActuator(); +} + +bool USGSenseGloveKismetLibrary::GetSensorData(UObject* WorldContextObject, const USGSenseGlove* SenseGlove, + USGSenseGloveSensorData*& OutSensorData) +{ + return SenseGlove->GetSensorData(WorldContextObject, OutSensorData); +} + +bool USGSenseGloveKismetLibrary::GetGlovePose_OutGP(UObject* WorldContextObject, USGSenseGlove* SenseGlove, + USGSenseGlovePose*& OutGlovePose) +{ + return SenseGlove->GetGlovePose(WorldContextObject, OutGlovePose); +} + +bool USGSenseGloveKismetLibrary::GetGlovePose_SD_OutGP( + UObject* WorldContextObject, USGSenseGlove* SenseGlove, + const USGSenseGloveSensorData* SensorData, USGSenseGlovePose*& OutGlovePose) +{ + return SenseGlove->GetGlovePose(WorldContextObject, SensorData, OutGlovePose); +} + +bool USGSenseGloveKismetLibrary::QueueVibroLevel_F_A(USGSenseGlove* SenseGlove, const int32 Finger, + const float Amplitude) +{ + return SenseGlove->QueueVibroLevel(Finger, Amplitude); +} + +bool USGSenseGloveKismetLibrary::QueueThumperCommand(USGSenseGlove* SenseGlove, + const ESGSenseGloveThumperCommand Command) +{ + return SenseGlove->QueueThumperCommand(Command); +} + +FString USGSenseGloveKismetLibrary::ToString(const USGSenseGlove* SenseGlove) +{ + return SenseGlove->ToString(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGlovePoseKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGlovePoseKismetLibrary.cpp new file mode 100644 index 0000000..6505520 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGlovePoseKismetLibrary.cpp @@ -0,0 +1,142 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGSenseGlovePoseKismetLibrary.h" + +#include "SGCore/SGSenseGlovePose.h" +#include "SGUtils/SGArrayUtils.h" + +USGSenseGlovePose* USGSenseGlovePoseKismetLibrary::MakeSenseGlovePose(UObject* WorldContextObject) +{ + return USGSenseGlovePose::NewSenseGlovePose(WorldContextObject); +} + +USGSenseGlovePose* USGSenseGlovePoseKismetLibrary::MakeSenseGlovePose_bRH_JP_TArrayFSGQuatArray_JR_GA( + UObject* WorldContextObject, const bool bRightHanded, + const TArray& JointPositions, const TArray& JointRotations, + const TArray& GloveAngles) +{ + return USGSenseGlovePose::NewSenseGlovePose(WorldContextObject, bRightHanded, + JointPositions, JointRotations, GloveAngles); +} + +USGSenseGlovePose* USGSenseGlovePoseKismetLibrary::MakeSenseGlovePose_bRH_JP_TArrayFSGRotatorArray_JR_GA( + UObject* WorldContextObject, const bool bRightHanded, + const TArray& JointPositions, const TArray& JointRotations, + const TArray& GloveAngles) +{ + return USGSenseGlovePose::NewSenseGlovePose(WorldContextObject, bRightHanded, + JointPositions, JointRotations, GloveAngles); +} + +USGSenseGlovePose* USGSenseGlovePoseKismetLibrary::IdlePose(UObject* WorldContextObject, + const USGSenseGloveInfo* GloveInfo) +{ + return USGSenseGlovePose::IdlePose(WorldContextObject, GloveInfo); +} + +USGSenseGlovePose* USGSenseGlovePoseKismetLibrary::Deserialize(UObject* WorldContextObject, + const FString& SerializedString) +{ + return USGSenseGlovePose::Deserialize(WorldContextObject, SerializedString); +} + +bool USGSenseGlovePoseKismetLibrary::IsRight(const USGSenseGlovePose* SenseGlovePose) +{ + return SenseGlovePose->IsRight(); +} + +TArray USGSenseGlovePoseKismetLibrary::GetJointPositions(const USGSenseGlovePose* SenseGlovePose) +{ + return FSGArrayUtils::ToNestedBPArray(SenseGlovePose->GetJointPositions()); +} + +TArray USGSenseGlovePoseKismetLibrary::GetJointRotations_TArrayFSGQuatArray( + const USGSenseGlovePose* SenseGlovePose) +{ + return FSGArrayUtils::ToNestedBPArray(SenseGlovePose->GetJointRotationsQ()); +} + +TArray USGSenseGlovePoseKismetLibrary::GetJointRotations_TArrayFSGRotatorArray( + const USGSenseGlovePose* SenseGlovePose) +{ + return FSGArrayUtils::ToNestedBPArray(SenseGlovePose->GetJointRotations()); +} + +TArray USGSenseGlovePoseKismetLibrary::GetGloveAngles(const USGSenseGlovePose* SenseGlovePose) +{ + return FSGArrayUtils::ToNestedBPArray(SenseGlovePose->GetGloveAngles()); +} + +TArray USGSenseGlovePoseKismetLibrary::GetThimblePositions(const USGSenseGlovePose* SenseGlovePose) +{ + return SenseGlovePose->GetThimblePositions(); +} + +TArray USGSenseGlovePoseKismetLibrary::GetThimbleRotations_FQuat(const USGSenseGlovePose* SenseGlovePose) +{ + return SenseGlovePose->GetThimbleRotationsQ(); +} + +TArray USGSenseGlovePoseKismetLibrary::GetThimbleRotations_FRotator(const USGSenseGlovePose* SenseGlovePose) +{ + return SenseGlovePose->GetThimbleRotations(); +} + +TArray USGSenseGlovePoseKismetLibrary::GetTotalGloveAngles(const USGSenseGlovePose* SenseGlovePose) +{ + return SenseGlovePose->GetTotalGloveAngles(); +} + +TArray USGSenseGlovePoseKismetLibrary::CalculateFingertips( + const USGSenseGlovePose* SenseGlovePose, const TArray& FingerOffsets) +{ + return SenseGlovePose->CalculateFingertips(FingerOffsets); +} + +bool USGSenseGlovePoseKismetLibrary::Equals(const USGSenseGlovePose* A, const USGSenseGlovePose* B) +{ + return A->Equals(B); +} + +FString USGSenseGlovePoseKismetLibrary::ToString(const USGSenseGlovePose* SenseGlovePose, const bool bShortFormat) +{ + return SenseGlovePose->ToString(bShortFormat); +} + +FString USGSenseGlovePoseKismetLibrary::SGSerialize(const USGSenseGlovePose* SenseGlovePose) +{ + return SenseGlovePose->SGSerialize(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGloveSensorDataKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGloveSensorDataKismetLibrary.cpp new file mode 100644 index 0000000..19d1359 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGloveSensorDataKismetLibrary.cpp @@ -0,0 +1,134 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGSenseGloveSensorDataKismetLibrary.h" + +#include "SGCore/SGSenseGloveSensorData.h" +#include "SGUtils/SGArrayUtils.h" + +USGSenseGloveSensorData* USGSenseGloveSensorDataKismetLibrary::MakeSenseGloveSensorData(UObject* WorldContextObject) +{ + return USGSenseGloveSensorData::NewSenseGloveSensorData(WorldContextObject); +} + +USGSenseGloveSensorData* USGSenseGloveSensorDataKismetLibrary::MakeSenseGloveSensorData_SA_FQuatImuRotation_PV_bIP( + UObject* WorldContextObject, + const TArray& SensorAngles, + const FQuat& ImuRotation, const int32 ParsedValues, const bool bImuParsed) +{ + return USGSenseGloveSensorData::NewSenseGloveSensorData(WorldContextObject, SensorAngles, + ImuRotation, ParsedValues, bImuParsed); +} + +USGSenseGloveSensorData* USGSenseGloveSensorDataKismetLibrary::MakeSenseGloveSensorData_SA_FRotatorImuRotation_PV_bIP( + UObject* WorldContextObject, + const TArray& SensorAngles, + const FRotator& ImuRotation, const int32 ParsedValues, const bool bImuParsed) +{ + return USGSenseGloveSensorData::NewSenseGloveSensorData(WorldContextObject, SensorAngles, + ImuRotation, ParsedValues, bImuParsed); +} + +USGSenseGloveSensorData* USGSenseGloveSensorDataKismetLibrary::Empty(UObject* WorldContextObject) +{ + return USGSenseGloveSensorData::Empty(WorldContextObject); +} + +USGSenseGloveSensorData* USGSenseGloveSensorDataKismetLibrary::Parse( + UObject* WorldContextObject, + const FString& RawData, const USGSenseGloveInfo* GloveInfo) +{ + return USGSenseGloveSensorData::Parse(WorldContextObject, RawData, GloveInfo); +} + +USGSenseGloveSensorData* USGSenseGloveSensorDataKismetLibrary::Deserialize(UObject* WorldContextObject, + const FString& SerializedString) +{ + return USGSenseGloveSensorData::Deserialize(WorldContextObject, SerializedString); +} + +TArray USGSenseGloveSensorDataKismetLibrary::GetSensorAngles( + const USGSenseGloveSensorData* SenseGloveSensorData) +{ + return FSGArrayUtils::ToNestedBPArray(SenseGloveSensorData->GetSensorAngles()); +} + +TArray USGSenseGloveSensorDataKismetLibrary::GetSensorAngles_F( + const USGSenseGloveSensorData* SenseGloveSensorData, const ESGFinger Finger) +{ + return SenseGloveSensorData->GetSensorAngles(Finger); +} + +TArray USGSenseGloveSensorDataKismetLibrary::GetAngleSequence( + const USGSenseGloveSensorData* SenseGloveSensorData) +{ + return SenseGloveSensorData->GetAngleSequence(); +} + +FQuat USGSenseGloveSensorDataKismetLibrary::GetImuRotation_FQuat(const USGSenseGloveSensorData* SenseGloveSensorData) +{ + return SenseGloveSensorData->GetImuRotationQ(); +} + +FRotator USGSenseGloveSensorDataKismetLibrary::GetImuRotation_FRotator( + const USGSenseGloveSensorData* SenseGloveSensorData) +{ + return SenseGloveSensorData->GetImuRotation(); +} + +int32 USGSenseGloveSensorDataKismetLibrary::GetParsedValues(const USGSenseGloveSensorData* SenseGloveSensorData) +{ + return SenseGloveSensorData->GetParsedValues(); +} + +bool USGSenseGloveSensorDataKismetLibrary::IsImuParsed(const USGSenseGloveSensorData* SenseGloveSensorData) +{ + return SenseGloveSensorData->IsImuParsed(); +} + +bool USGSenseGloveSensorDataKismetLibrary::Equals(const USGSenseGloveSensorData* A, const USGSenseGloveSensorData* B) +{ + return A->Equals(B); +} + +FString USGSenseGloveSensorDataKismetLibrary::ToString(const USGSenseGloveSensorData* SenseGloveSensorData) +{ + return SenseGloveSensorData->ToString(); +} + +FString USGSenseGloveSensorDataKismetLibrary::SGSerialize(const USGSenseGloveSensorData* SenseGloveSensorData) +{ + return SenseGloveSensorData->SGSerialize(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGloveSensorNormalizerKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGloveSensorNormalizerKismetLibrary.cpp new file mode 100644 index 0000000..ac5132c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGloveSensorNormalizerKismetLibrary.cpp @@ -0,0 +1,62 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGSenseGloveSensorNormalizerKismetLibrary.h" + +#include "SGCore/SGSenseGloveSensorNormalizer.h" + +USGSenseGloveSensorNormalizer* USGSenseGloveSensorNormalizerKismetLibrary::MakeSenseGloveSensorNormalizer( + UObject* WorldContextObject) +{ + return USGSenseGloveSensorNormalizer::NewSenseGloveSensorNormalizer(WorldContextObject); +} + +USGSenseGloveSensorNormalizer* USGSenseGloveSensorNormalizerKismetLibrary::MakeSenseGloveSensorNormalizer_bRH( + UObject* WorldContextObject, const bool bRightHanded) +{ + return USGSenseGloveSensorNormalizer::NewSenseGloveSensorNormalizer(WorldContextObject, bRightHanded); +} + +float USGSenseGloveSensorNormalizerKismetLibrary::NormalizeFlexion( + const USGSenseGloveSensorNormalizer* SenseGloveSensorNormalizer, const int32 Finger, const float SumFlexionAngles) +{ + return SenseGloveSensorNormalizer->NormalizeFlexion(Finger, SumFlexionAngles); +} + +float USGSenseGloveSensorNormalizerKismetLibrary::NormalizeAbduction( + const USGSenseGloveSensorNormalizer* SenseGloveSensorNormalizer, const int32 Finger, const float SumAbductionAngles) +{ + return SenseGloveSensorNormalizer->NormalizeFlexion(Finger, SumAbductionAngles); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGloveVarsKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGloveVarsKismetLibrary.cpp new file mode 100644 index 0000000..59a0982 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSenseGloveVarsKismetLibrary.cpp @@ -0,0 +1,117 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGSenseGloveVarsKismetLibrary.h" + +#include "SGCore/SGSenseGloveInfo.h" +#include "SGCore/SGSenseGloveVars.h" +#include "SGUtils/SGArrayUtils.h" + +FString USGSenseGloveVarsKismetLibrary::GetStandardConstantsString(const FString& HardwareVersion, + const float FirmwareVersion, const bool bRightHanded) +{ + return FSGSenseGloveVars::GetStandardConstantsString(HardwareVersion, FirmwareVersion, bRightHanded); +} + +FString USGSenseGloveVarsKismetLibrary::GetSensorString(const FString& HardwareVersion, const float FirmwareVersion) +{ + return FSGSenseGloveVars::GetSensorString(HardwareVersion, FirmwareVersion); +} + +TArray USGSenseGloveVarsKismetLibrary::GetStartPositions(const FString& HardwareVersion, + const bool bRightHanded) +{ + return FSGSenseGloveVars::GetStartPositions(HardwareVersion, bRightHanded); +} + +TArray USGSenseGloveVarsKismetLibrary::GetStartRotations_TArrayFQuat( + const FString& HardwareVersion, const bool bRightHanded) +{ + return FSGSenseGloveVars::GetStartRotationsQ(HardwareVersion, bRightHanded); +} + +TArray USGSenseGloveVarsKismetLibrary::GetStartRotations_TArrayFRotator( + const FString& HardwareVersion, const bool bRightHanded) +{ + return FSGSenseGloveVars::GetStartRotations(HardwareVersion, bRightHanded); +} + +TArray USGSenseGloveVarsKismetLibrary::GetGloveLengths(const FString& HardwareVersion) +{ + return FSGArrayUtils::ToNestedBPArray(FSGSenseGloveVars::GetGloveLengths(HardwareVersion)); +} + +int32 USGSenseGloveVarsKismetLibrary::GetSensors(const FString& HardwareVersion) +{ + return FSGSenseGloveVars::GetSensors(HardwareVersion); +} + +FQuat USGSenseGloveVarsKismetLibrary::GetImuCorrection_FQuat(const FString& HardwareVersion, + const int32 FirmwareVersion, + const int32 SubFirmwareVersion) +{ + return FSGSenseGloveVars::GetImuCorrectionQ(HardwareVersion, FirmwareVersion, SubFirmwareVersion); +} + +FRotator USGSenseGloveVarsKismetLibrary::GetImuCorrection_FRotator(const FString& HardwareVersion, + const int32 FirmwareVersion, + const int32 SubFirmwareVersion) +{ + return FSGSenseGloveVars::GetImuCorrection(HardwareVersion, FirmwareVersion, SubFirmwareVersion); +} + +TArray USGSenseGloveVarsKismetLibrary::GetFunctions(const FString& HardwareVersion, + const int32 FirmwareVersion, const int32 SubFirmwareVersion) +{ + return FSGSenseGloveVars::GetFunctions(HardwareVersion, FirmwareVersion, SubFirmwareVersion); +} + +USGSenseGloveInfo* USGSenseGloveVarsKismetLibrary::GenerateGloveModel_HV_FV_SFV_bRH( + UObject* WorldContextObject, + const FString& HardwareVersion, const int32 FirmwareVersion, const int32 SubFirmwareVersion, + const bool bRightHanded) +{ + return FSGSenseGloveVars::GenerateGloveModel(WorldContextObject, + HardwareVersion, FirmwareVersion, SubFirmwareVersion, bRightHanded); +} + +USGSenseGloveInfo* USGSenseGloveVarsKismetLibrary::GenerateGloveModel_HV_FV_SFV_bRH_CI( + UObject* WorldContextObject, + const FString& HardwareVersion, const int32 FirmwareVersion, const int32 SubFirmwareVersion, + const bool bRightHanded, const FString& CustomId) +{ + return FSGSenseGloveVars::GenerateGloveModel( + WorldContextObject, HardwareVersion, FirmwareVersion, SubFirmwareVersion, bRightHanded, CustomId); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSensorNormalizationKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSensorNormalizationKismetLibrary.cpp new file mode 100644 index 0000000..79a0cda --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGSensorNormalizationKismetLibrary.cpp @@ -0,0 +1,111 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGSensorNormalizationKismetLibrary.h" + +#include "SGCore/SGSensorNormalization.h" + +USGSensorNormalization* USGSensorNormalizationKismetLibrary::MakeSensorNormalization(UObject* WorldContextObject) +{ + return USGSensorNormalization::NewSensorNormalization(WorldContextObject); +} + +USGSensorNormalization* USGSensorNormalizationKismetLibrary::MakeSensorNormalization_MR( + UObject* WorldContextObject, const TArray& MovementRanges) +{ + return USGSensorNormalization::NewSensorNormalization(WorldContextObject, MovementRanges); +} + +bool USGSensorNormalizationKismetLibrary::CollectsNormalization(const USGSensorNormalization* SensorNormalization) +{ + return SensorNormalization->CollectsNormalization(); +} + +void USGSensorNormalizationKismetLibrary::SetCollectNormalization(USGSensorNormalization* SensorNormalization, + const bool bCollectNormalization) +{ + SensorNormalization->SetCollectNormalization(bCollectNormalization); +} + +int32 USGSensorNormalizationKismetLibrary::GetLength(const USGSensorNormalization* SensorNormalization) +{ + return SensorNormalization->GetLength(); +} + +int32 USGSensorNormalizationKismetLibrary::GetMoveCount(const USGSensorNormalization* SensorNormalization) +{ + return SensorNormalization->GetMoveCount(); +} + +bool USGSensorNormalizationKismetLibrary::AllSensorsMoving(const USGSensorNormalization* SensorNormalization) +{ + return SensorNormalization->AllSensorsMoving(); +} + +void USGSensorNormalizationKismetLibrary::ResetNormalization(USGSensorNormalization* SensorNormalization) +{ + SensorNormalization->ResetNormalization(); +} + +void USGSensorNormalizationKismetLibrary::UpdateNormalization(USGSensorNormalization* SensorNormalization, + const float Value, const int32 Index) +{ + SensorNormalization->UpdateNormalization(Value, Index); +} + +float USGSensorNormalizationKismetLibrary::NormalizeValue(USGSensorNormalization* SensorNormalization, + const float Value, const int32 Index) +{ + return SensorNormalization->NormalizeValue(Value, Index); +} + +TArray USGSensorNormalizationKismetLibrary::NormalizeValues(USGSensorNormalization* SensorNormalization, + const TArray& Values) +{ + return SensorNormalization->NormalizeValues(Values); +} + +bool USGSensorNormalizationKismetLibrary::MovedEnough(const USGSensorNormalization* SensorNormalization, + const int32 Index) +{ + return SensorNormalization->MovedEnough(Index); +} + +float USGSensorNormalizationKismetLibrary::Denormalize( + const USGSensorNormalization* SensorNormalization, + const float Value01, const int32 Index, const float FallbackValue) +{ + return SensorNormalization->Denormalize(Value01, Index, FallbackValue); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGThresholdCommandKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGThresholdCommandKismetLibrary.cpp new file mode 100644 index 0000000..a264414 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGThresholdCommandKismetLibrary.cpp @@ -0,0 +1,103 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGThresholdCommandKismetLibrary.h" + +#include "SGCore/SGThresholdCommand.h" + +USGThresholdCommand* USGThresholdCommandKismetLibrary::MakeThresholdCommand(UObject* WorldContextObject) +{ + return USGThresholdCommand::NewThresholdCommand(WorldContextObject); +} + +USGThresholdCommand* USGThresholdCommandKismetLibrary::MakeThresholdCommand_AF_TV( + UObject* WorldContextObject, + const TArray& AffectedFingers, const TArray& ThresholdValues) +{ + return USGThresholdCommand::NewThresholdCommand(WorldContextObject, AffectedFingers, ThresholdValues); +} + +float USGThresholdCommandKismetLibrary::GetThreshold(const USGThresholdCommand* ThresholdCommand, const int32 Finger) +{ + return ThresholdCommand->GetThreshold(Finger); +} + +void USGThresholdCommandKismetLibrary::SetThreshold(USGThresholdCommand* ThresholdCommand, + const int32 Finger, const float ThresholdValue) +{ + ThresholdCommand->SetThreshold(Finger, ThresholdValue); +} + +TArray USGThresholdCommandKismetLibrary::GetThresholds(const USGThresholdCommand* ThresholdCommand) +{ + return ThresholdCommand->GetThresholds(); +} + +void USGThresholdCommandKismetLibrary::SetThresholds( + USGThresholdCommand* ThresholdCommand, + const TArray& AffectedFingers, const TArray& ThresholdValues) +{ + ThresholdCommand->SetThresholds(AffectedFingers, ThresholdValues); +} + +bool USGThresholdCommandKismetLibrary::GetFingerActive(const USGThresholdCommand* ThresholdCommand, const int32 Finger) +{ + return ThresholdCommand->GetFingerActive(Finger); +} + +TArray USGThresholdCommandKismetLibrary::GetActiveFingers(const USGThresholdCommand* ThresholdCommand) +{ + return ThresholdCommand->GetActiveFingers(); +} + +void USGThresholdCommandKismetLibrary::ClearThreshold(USGThresholdCommand* ThresholdCommand, const int32 Finger) +{ + ThresholdCommand->ClearThreshold(Finger); +} + +void USGThresholdCommandKismetLibrary::ClearThresholds(USGThresholdCommand* ThresholdCommand) +{ + ThresholdCommand->ClearThresholds(); +} + +bool USGThresholdCommandKismetLibrary::Equals(const USGThresholdCommand* A, const USGThresholdCommand* B) +{ + return A->Equals(B); +} + +FString USGThresholdCommandKismetLibrary::ToString(const USGThresholdCommand* ThresholdCommand) +{ + return ThresholdCommand->ToString(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGTrackingKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGTrackingKismetLibrary.cpp new file mode 100644 index 0000000..ac758a8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SGCoreKismet/SGTrackingKismetLibrary.cpp @@ -0,0 +1,580 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGCoreKismet/SGTrackingKismetLibrary.h" + +#include "SGCore/SGTracking.h" + +void USGTrackingKismetLibrary::CalculateLocation_TP_FQuat_TR_PO_FQuat_RO_OutNP_FQuat_OutNR( + const FVector& TrackedPosition, const FQuat& TrackedRotation, + const FVector& PositionOffset, const FQuat& RotationOffset, + FVector& OutNewPosition, FQuat& OutNewRotation) +{ + return FSGTracking::CalculateLocation(TrackedPosition, TrackedRotation, PositionOffset, RotationOffset, + OutNewPosition, OutNewRotation); +} + +void USGTrackingKismetLibrary::CalculateLocation_TP_FRotator_TR_PO_FRotator_RO_OutNP_FRotator_OutNR( + const FVector& TrackedPosition, const FRotator& TrackedRotation, + const FVector& PositionOffset, const FRotator& RotationOffset, + FVector& OutNewPosition, FRotator& OutNewRotation) +{ + return FSGTracking::CalculateLocation(TrackedPosition, TrackedRotation, PositionOffset, RotationOffset, + OutNewPosition, OutNewRotation); +} + +TArray USGTrackingKismetLibrary::GetSenseGloveFingerToGlovePositionOrigin() +{ + return FSGTracking::GetSenseGloveFingerToGlovePositionOrigin(); +} + +TArray USGTrackingKismetLibrary::GetSenseGloveFingerToGloveRotationOrigin_TArrayFQuat() +{ + return FSGTracking::GetSenseGloveFingerToGloveRotationOriginQ(); +} + +TArray USGTrackingKismetLibrary::GetSenseGloveFingerToGloveRotationOrigin_TArrayFRotator() +{ + return FSGTracking::GetSenseGloveFingerToGloveRotationOrigin(); +} + +FVector USGTrackingKismetLibrary::GetSenseGloveWristPositionOffset() +{ + return FSGTracking::GetSenseGloveWristPositionOffset(); +} + +FQuat USGTrackingKismetLibrary::GetSenseGloveWristRotationOffset_FQuat() +{ + return FSGTracking::GetSenseGloveWristRotationOffsetQ(); +} + +FRotator USGTrackingKismetLibrary::GetSenseGloveWristRotationOffset_FRotator() +{ + return FSGTracking::GetSenseGloveWristRotationOffset(); +} + +void USGTrackingKismetLibrary::GetSenseGloveMountOffset_bRH_TF_OutIP_FQuat_OutIR( + const bool bRightHanded, const ESGFinger ToFinger, + FVector& OutIPosition, FQuat& OutIRotation) +{ + return FSGTracking::GetSenseGloveMountOffset(bRightHanded, ToFinger, OutIPosition, OutIRotation); +} + +void USGTrackingKismetLibrary::GetSenseGloveMountOffset_bRH_TF_OutIP_FRotator_OutIR( + const bool bRightHanded, const ESGFinger ToFinger, + FVector& OutIPosition, FRotator& OutIRotation) +{ + return FSGTracking::GetSenseGloveMountOffset(bRightHanded, ToFinger, OutIPosition, OutIRotation); +} + +void USGTrackingKismetLibrary::GetSenseGloveTrackerMountOffset_H_bRH_OutPO_FQuat_OutRO( + const ESGPositionalTrackingHardware Hardware, const bool bRightHanded, + FVector& OutPositionOffset, FQuat& OutRotationOffset) +{ + return FSGTracking::GetSenseGloveTrackerMountOffset(Hardware, bRightHanded, + OutPositionOffset, OutRotationOffset); +} + +void USGTrackingKismetLibrary::GetSenseGloveTrackerMountOffset_H_bRH_OutPO_FRotator_OutRO( + const ESGPositionalTrackingHardware Hardware, const bool bRightHanded, + FVector& OutPositionOffset, FRotator& OutRotationOffset) +{ + return FSGTracking::GetSenseGloveTrackerMountOffset(Hardware, bRightHanded, + OutPositionOffset, OutRotationOffset); +} + +FVector USGTrackingKismetLibrary::GetSenseGloveViveToAttachPosition() +{ + return FSGTracking::GetSenseGloveViveToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetSenseGloveViveToAttachRotation_FQuat() +{ + return FSGTracking::GetSenseGloveViveToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetSenseGloveViveToAttachRotation_FRotator() +{ + return FSGTracking::GetSenseGloveViveToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetSenseGloveOculusTouchToAttachPosition() +{ + return FSGTracking::GetSenseGloveOculusTouchToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetSenseGloveOculusTouchToAttachRotation_FQuat() +{ + return FSGTracking::GetSenseGloveOculusTouchToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetSenseGloveOculusTouchToAttachRotation_FRotator() +{ + return FSGTracking::GetSenseGloveOculusTouchToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetNovaToWristPositionOffset() +{ + return FSGTracking::GetNovaToWristPositionOffset(); +} + +FQuat USGTrackingKismetLibrary::GetNovaToWristRotationOffset_FQuat() +{ + return FSGTracking::GetNovaToWristRotationOffsetQ(); +} + +FRotator USGTrackingKismetLibrary::GetNovaToWristRotationOffset_FRotator() +{ + return FSGTracking::GetNovaToWristRotationOffset(); +} + +FVector USGTrackingKismetLibrary::GetRightNovaViveToAttachPosition() +{ + return FSGTracking::GetRightNovaViveToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetRightNovaViveToAttachRotation_FQuat() +{ + return FSGTracking::GetRightNovaViveToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetRightNovaViveToAttachRotation_FRotator() +{ + return FSGTracking::GetRightNovaViveToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetLeftNovaViveToAttachPosition() +{ + return FSGTracking::GetLeftNovaViveToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetLeftNovaViveToAttachRotation_FQuat() +{ + return FSGTracking::GetLeftNovaViveToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetLeftNovaViveToAttachRotation_FRotator() +{ + return FSGTracking::GetLeftNovaViveToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetRightNovaQuest2ToAttachPosition() +{ + return FSGTracking::GetRightNovaQuest2ToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetRightNovaQuest2ToAttachRotation_FQuat() +{ + return FSGTracking::GetRightNovaQuest2ToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetRightNovaQuest2ToAttachRotation_FRotator() +{ + return FSGTracking::GetRightNovaQuest2ToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetLeftNovaQuest2ToAttachPosition() +{ + return FSGTracking::GetLeftNovaQuest2ToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetLeftNovaQuest2ToAttachRotation_FQuat() +{ + return FSGTracking::GetLeftNovaQuest2ToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetLeftNovaQuest2ToAttachRotation_FRotator() +{ + return FSGTracking::GetLeftNovaQuest2ToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetRightNovaPico2ToAttachPosition() +{ + return FSGTracking::GetRightNovaPico2ToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetRightNovaPico2ToAttachRotation_FQuat() +{ + return FSGTracking::GetRightNovaPico2ToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetRightNovaPico2ToAttachRotation_FRotator() +{ + return FSGTracking::GetRightNovaPico2ToAttachRotation(); +} + +FQuat USGTrackingKismetLibrary::GetLeftNovaPico2ToAttachRotation_FQuat() +{ + return FSGTracking::GetLeftNovaPico2ToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetLeftNovaPico2ToAttachRotation_FRotator() +{ + return FSGTracking::GetLeftNovaPico2ToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetRightNovaQuestProToAttachPosition() +{ + return FSGTracking::GetRightNovaQuestProToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetRightNovaQuestProToAttachRotation_FQuat() +{ + return FSGTracking::GetRightNovaQuestProToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetRightNovaQuestProToAttachRotation_FRotator() +{ + return FSGTracking::GetRightNovaQuestProToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetLeftNovaQuestProToAttachPosition() +{ + return FSGTracking::GetLeftNovaQuestProToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetLeftNovaQuestProToAttachRotation_FQuat() +{ + return FSGTracking::GetLeftNovaQuestProToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetLeftNovaQuestProToAttachRotation_FRotator() +{ + return FSGTracking::GetLeftNovaQuestProToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetRightNovaViveFocus3ToAttachPosition() +{ + return FSGTracking::GetRightNovaViveFocus3ToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetRightNovaViveFocus3ToAttachRotation_FQuat() +{ + return FSGTracking::GetRightNovaViveFocus3ToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetRightNovaViveFocus3ToAttachRotation_FRotator() +{ + return FSGTracking::GetRightNovaViveFocus3ToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetLeftNovaViveFocus3ToAttachPosition() +{ + return FSGTracking::GetLeftNovaViveFocus3ToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetLeftNovaViveFocus3ToAttachRotation_FQuat() +{ + return FSGTracking::GetLeftNovaViveFocus3ToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetLeftNovaViveFocus3ToAttachRotation_FRotator() +{ + return FSGTracking::GetLeftNovaViveFocus3ToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetRightNovaQuest3ToAttachPosition() +{ + return FSGTracking::GetRightNovaQuest3ToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetRightNovaQuest3ToAttachRotation_FQuat() +{ + return FSGTracking::GetRightNovaQuest3ToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetRightNovaQuest3ToAttachRotation_FRotator() +{ + return FSGTracking::GetRightNovaQuest3ToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetLeftNovaQuest3ToAttachPosition() +{ + return FSGTracking::GetLeftNovaQuest3ToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetLeftNovaQuest3ToAttachRotation_FQuat() +{ + return FSGTracking::GetLeftNovaQuest3ToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetLeftNovaQuest3ToAttachRotation_FRotator() +{ + return FSGTracking::GetLeftNovaQuest3ToAttachRotation(); +} + +void USGTrackingKismetLibrary::GetNovaGloveWristOffset_bRH_OutPO_FQuat_OutRO( + const bool bRightHanded, FVector& OutPositionOffset, FQuat& OutRotationOffset) +{ + return FSGTracking::GetNovaGloveWristOffset(bRightHanded, OutPositionOffset, OutRotationOffset); +} + +void USGTrackingKismetLibrary::GetNovaGloveWristOffset_bRH_OutPO_FRotator_OutRO( + const bool bRightHanded, FVector& OutPositionOffset, FRotator& OutRotationOffset) +{ + return FSGTracking::GetNovaGloveWristOffset(bRightHanded, OutPositionOffset, OutRotationOffset); +} + +void USGTrackingKismetLibrary::GetNovaGloveTrackerOffset_H_bRH_OutPO_FQuat_OutRO( + const ESGPositionalTrackingHardware Hardware, const bool bRightHanded, + FVector& OutPositionOffset, FQuat& OutRotationOffset) +{ + return FSGTracking::GetNovaGloveTrackerOffset(Hardware, bRightHanded, OutPositionOffset, OutRotationOffset); +} + +void +USGTrackingKismetLibrary::GetNovaGloveTrackerOffset_H_bRH_OutPO_FRotator_OutRO( + const ESGPositionalTrackingHardware Hardware, const bool bRightHanded, + FVector& OutPositionOffset, FRotator& OutRotationOffset) +{ + return FSGTracking::GetNovaGloveTrackerOffset(Hardware, bRightHanded, OutPositionOffset, OutRotationOffset); +} + +FVector USGTrackingKismetLibrary::GetRightNova2ToWristPositionOffset() +{ + return FSGTracking::GetRightNova2ToWristPositionOffset(); +} + +FQuat USGTrackingKismetLibrary::GetRightNova2ToWristRotationOffset_FQuat() +{ + return FSGTracking::GetRightNova2ToWristRotationOffsetQ(); +} + +FRotator USGTrackingKismetLibrary::GetRightNova2ToWristRotationOffset_FRotator() +{ + return FSGTracking::GetRightNova2ToWristRotationOffset(); +} + +FVector USGTrackingKismetLibrary::GetLeftNova2ToWristPositionOffset() +{ + return FSGTracking::GetLeftNova2ToWristPositionOffset(); +} + +FQuat USGTrackingKismetLibrary::GetLeftNova2ToWristRotationOffset_FQuat() +{ + return FSGTracking::GetLeftNova2ToWristRotationOffsetQ(); +} + +FRotator USGTrackingKismetLibrary::GetLeftNova2ToWristRotationOffset_FRotator() +{ + return FSGTracking::GetLeftNova2ToWristRotationOffset(); +} + +FVector USGTrackingKismetLibrary::GetRightNova2Quest2ToAttachPosition() +{ + return FSGTracking::GetRightNova2Quest2ToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetRightNova2Quest2ToAttachRotation_FQuat() +{ + return FSGTracking::GetRightNova2Quest2ToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetRightNova2Quest2ToAttachRotation_FRotator() +{ + return FSGTracking::GetRightNova2Quest2ToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetLeftNova2Quest2ToAttachPosition() +{ + return FSGTracking::GetLeftNova2Quest2ToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetLeftNova2Quest2ToAttachRotation_FQuat() +{ + return FSGTracking::GetLeftNova2Quest2ToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetLeftNova2Quest2ToAttachRotation_FRotator() +{ + return FSGTracking::GetLeftNova2Quest2ToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetRightNova2QuestProToAttachPosition() +{ + return FSGTracking::GetRightNova2QuestProToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetRightNova2QuestProToAttachRotation_FQuat() +{ + return FSGTracking::GetRightNova2QuestProToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetRightNova2QuestProToAttachRotation_FRotator() +{ + return FSGTracking::GetRightNova2QuestProToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetLeftNova2QuestProToAttachPosition() +{ + return FSGTracking::GetLeftNova2QuestProToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetLeftNova2QuestProToAttachRotation_FQuat() +{ + return FSGTracking::GetLeftNova2QuestProToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetLeftNova2QuestProToAttachRotation_FRotator() +{ + return FSGTracking::GetLeftNova2QuestProToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetRightNova2ViveTrackerToAttachPosition() +{ + return FSGTracking::GetRightNova2ViveTrackerToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetRightNova2ViveTrackerToAttachRotation_FQuat() +{ + return FSGTracking::GetRightNova2ViveTrackerToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetRightNova2ViveTrackerToAttachRotation_FRotator() +{ + return FSGTracking::GetRightNova2ViveTrackerToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetLeftNova2ViveTrackerToAttachPosition() +{ + return FSGTracking::GetLeftNova2ViveTrackerToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetLeftNova2ViveTrackerToAttachRotation_FQuat() +{ + return FSGTracking::GetLeftNova2ViveTrackerToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetLeftNova2ViveTrackerToAttachRotation_FRotator() +{ + return FSGTracking::GetLeftNova2ViveTrackerToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetRightNova2ViveWristTrackerToAttachPosition() +{ + return FSGTracking::GetRightNova2ViveWristTrackerToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetRightNova2ViveWristTrackerToAttachRotation_FQuat() +{ + return FSGTracking::GetRightNova2ViveWristTrackerToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetRightNova2ViveWristTrackerToAttachRotation_FRotator() +{ + return FSGTracking::GetRightNova2ViveWristTrackerToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetLeftNova2ViveWristTrackerToAttachPosition() +{ + return FSGTracking::GetLeftNova2ViveWristTrackerToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetLeftNova2ViveWristTrackerToAttachRotation_FQuat() +{ + return FSGTracking::GetLeftNova2ViveWristTrackerToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetLeftNova2ViveWristTrackerToAttachRotation_FRotator() +{ + return FSGTracking::GetLeftNova2ViveWristTrackerToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetRightNova2Quest3ToAttachPosition() +{ + return FSGTracking::GetRightNova2Quest3ToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetRightNova2Quest3ToAttachRotation_FQuat() +{ + return FSGTracking::GetRightNova2Quest3ToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetRightNova2Quest3ToAttachRotation_FRotator() +{ + return FSGTracking::GetRightNova2Quest3ToAttachRotation(); +} + +FVector USGTrackingKismetLibrary::GetLeftNova2Quest3ToAttachPosition() +{ + return FSGTracking::GetLeftNova2Quest3ToAttachPosition(); +} + +FQuat USGTrackingKismetLibrary::GetLeftNova2Quest3ToAttachRotation_FQuat() +{ + return FSGTracking::GetLeftNova2Quest3ToAttachRotationQ(); +} + +FRotator USGTrackingKismetLibrary::GetLeftNova2Quest3ToAttachRotation_FRotator() +{ + return FSGTracking::GetLeftNova2Quest3ToAttachRotation(); +} + +void USGTrackingKismetLibrary::GetNova2GloveWristOffset_bRH_HW_OutPO_FQuat_OutRO( + const bool bRightHanded, const FString& HardwareVersion, + FVector& OutPositionOffset, FQuat& OutRotationOffset) +{ + return FSGTracking::GetNova2GloveWristOffset(bRightHanded, HardwareVersion, + OutPositionOffset, OutRotationOffset); +} + +void USGTrackingKismetLibrary::GetNova2GloveWristOffset_bRH_HW_OutPO_FRotator_OutRO( + const bool bRightHanded, const FString& HardwareVersion, + FVector& OutPositionOffset, FRotator& OutRotationOffset) +{ + return FSGTracking::GetNova2GloveWristOffset(bRightHanded, HardwareVersion, + OutPositionOffset, OutRotationOffset); +} + +void USGTrackingKismetLibrary::GetNova2GloveTrackerOffset_H_bRH_HW_OutPO_FQuat_OutRO( + const ESGPositionalTrackingHardware Hardware, const bool bRightHanded, const FString& HardwareVersion, + FVector& OutPositionOffset, FQuat& OutRotationOffset) +{ + return FSGTracking::GetNova2GloveTrackerOffset(Hardware, bRightHanded, HardwareVersion, + OutPositionOffset, OutRotationOffset); +} + +void USGTrackingKismetLibrary::GetNova2GloveTrackerOffset_H_bRH_HW_OutPO_FRotator_OutRO( + const ESGPositionalTrackingHardware Hardware, const bool bRightHanded, const FString& HardwareVersion, + FVector& OutPositionOffset, FRotator& OutRotationOffset) +{ + return FSGTracking::GetNova2GloveTrackerOffset(Hardware, bRightHanded, HardwareVersion, + OutPositionOffset, OutRotationOffset); +} + +FString USGTrackingKismetLibrary::ToString(const ESGPositionalTrackingHardware Hardware) +{ + return FSGTracking::ToString(Hardware); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SenseGloveCoreKismet.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SenseGloveCoreKismet.cpp new file mode 100644 index 0000000..6317233 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SenseGloveCoreKismet.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveCoreKismet.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveCoreKismetModule.h" + +IMPLEMENT_MODULE(FSenseGloveCoreKismetModule, SenseGloveCoreKismet) diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SenseGloveCoreKismet.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SenseGloveCoreKismet.h new file mode 100644 index 0000000..ab121d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SenseGloveCoreKismet.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SenseGloveCoreKismetModule.cpp b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SenseGloveCoreKismetModule.cpp new file mode 100644 index 0000000..d0523b5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SenseGloveCoreKismetModule.cpp @@ -0,0 +1,61 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveCoreKismetModule.h" +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveCoreKismetModule" + +void FSenseGloveCoreKismetModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveCoreKismet module..."); +} + +void FSenseGloveCoreKismetModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveCoreKismet module..."); +} + +void FSenseGloveCoreKismetModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveCoreKismet module has succeeded!"); +} + +void FSenseGloveCoreKismetModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveCoreKismet module..."); +} + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SenseGloveCoreKismetModule.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SenseGloveCoreKismetModule.h new file mode 100644 index 0000000..fef1146 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Private/SenseGloveCoreKismetModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveCoreKismet" + +class FSenseGloveCoreKismetModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGAnatomyKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGAnatomyKismetLibrary.h new file mode 100644 index 0000000..92bbc06 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGAnatomyKismetLibrary.h @@ -0,0 +1,133 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Hard-Coded Database that is used in calibration and in solving. + * Values herein are used to limit outputs within 'natural' ranges. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "HAL/Platform.h" + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGVectorArray.h" + +#include "SGAnatomyKismetLibrary.generated.h" + +/** + * "Database" of anatomical values, such as joint limits. + */ +UCLASS(meta=(ScriptName = "SenseGloveAnatomyKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGAnatomyKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Total sum of all finger flexion that would be considered "total flexion". + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Anatomy") + static float GetTotalFingerFlexion(); + + /** + * Total sum of all finger flexion that would be considered "total extension". + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Anatomy") + static float GetTotalFingerExtension(); + + /** + * Total sum of all thumb flexion that would be considered "total flexion". + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Anatomy") + static float GetTotalThumbFlexion(); + + /** + * Total sum of all thumb flexion that would be considered "total extension". + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Anatomy") + static float GetTotalThumbExtension(); + + /** + * Retrieve one of the limits of a finger joint's movement. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Anatomy") + static float GetFingerJointLimit(bool bRightHanded, int32 Joint, int32 Movement, bool bMax); + + /** + * Retrieve one of the limits of a thumb joint's movement. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Anatomy") + static float GetThumbJointLimit(bool bRightHanded, int32 Joint, int32 Movement, bool bMax); + + /* + * Limit a value between specific joint angles. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Anatomy") + static float ClampJointAngle(float Value, int32 Finger, bool bRightHand, int32 Joint, int32 Movement); + + /** + * Convert a total finger flexion in degrees. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Anatomy") + static float NormalizeFingerFlexion(float FlexionInDegrees); + + /** + * Convert a total thumb flexion in degrees. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Anatomy") + static float NormalizeThumbFlexion(float FlexionInDegrees); + + /** + * Get Hand Angles that would make a Default (Idle) Pose. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Anatomy") + static TArray GetDefaultHandAngles(bool bRightHanded); + + /** + * Get Hand Angles that would make a flat hand. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Anatomy") + static TArray GetFlatHandAngles(bool bRightHanded); + + /** + * Get hand angles that would make a thumbs up. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Anatomy") + static TArray GetThumbsUpHandAngles(bool bRightHanded); + + /** + * Get Hand Angles that would make a fist. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Anatomy") + static TArray GetFistHandAngles(bool bRightHanded); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGBasicHandModelKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGBasicHandModelKismetLibrary.h new file mode 100644 index 0000000..6f25354 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGBasicHandModelKismetLibrary.h @@ -0,0 +1,304 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * A data class containing the minimum required data for a hand's forward + * kinematics. + * Used in both kinematics and calibration. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" +#include "SGTypes/SGFloatArray.h" + +#include "SGBasicHandModelKismetLibrary.generated.h" + +class USGBasicHandModel; + +/** + * Represents data of a user's hand required for forward kinematics. + */ +UCLASS(meta=(ScriptName = "SenseGloveBasicHandModelKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGBasicHandModelKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * The basic class constructor. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Basic Hand Model", + meta=(WorldContext="WorldContextObject")) + static USGBasicHandModel* MakeBasicHandModel(UObject* WorldContextObject); + + /** + * Create a new BasicHandModel with no starting rotations. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Basic Hand Model", + Category="SenseGlove | Core | Kinematics | Basic Hand Model", + meta=(WorldContext="WorldContextObject")) + static USGBasicHandModel* MakeBasicHandModel_bRH_L_SP( + UObject* WorldContextObject, + bool bRightHanded, const TArray& Lengths, const TArray& StartPositions); + + /** + * Create a new BasicHandModel. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Basic Hand Model", + Category="SenseGlove | Core | Kinematics | Basic Hand Model", + meta=(WorldContext="WorldContextObject")) + static USGBasicHandModel* MakeBasicHandModel_bRH_L_SP_TArrayFQuat_SR( + UObject* WorldContextObject, + bool bRightHanded, const TArray& Lengths, + const TArray& StartPositions, const TArray& StartRotations); + + /** + * Create a new BasicHandModel. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Basic Hand Model", + Category="SenseGlove | Core | Kinematics | Basic Hand Model", + meta=(WorldContext="WorldContextObject")) + static USGBasicHandModel* MakeBasicHandModel_bRH_L_SP_TArrayFRotator_SR( + UObject* WorldContextObject, + bool bRightHanded, const TArray& Lengths, + const TArray& StartPositions, const TArray& StartRotations); + + /** + * Retrieve a default left or right hand model. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Basic Hand Model", + meta=(WorldContext="WorldContextObject")) + static USGBasicHandModel* Default(UObject* WorldContextObject, bool bRightHanded); + + /** + * Convert a serialized HandModel back into its class representation. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Basic Hand Model", + meta=(WorldContext="WorldContextObject")) + static USGBasicHandModel* Deserialize(UObject* WorldContextObject, const FString& SerializedString); + + /** + * Default finger lengths (based on right hand). + * + * @remarks Any missing fingers are replaced with their respective value. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static TArray GetBaseFingerLengths(); + + /** + * Default joint positions (based on right hand). + * + * @remarks Any missing positions are replaced with their respective value. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static TArray GetBaseJointPositions(); + + /** + * Default joint angles (based on right hand). + * + * @remarks Any missing angles are replaced with their respective value. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static TArray GetBaseJointAngles(); + + /** + * Whether or not this BasicHandModel was created for a left- or right hand. Used for validation. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static bool IsRight(const USGBasicHandModel* BasicHandModel); + + /** + * The length of individual finger phalangers in mm, sorted per finger. Generally 5x3. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static TArray GetFingerLengths(const USGBasicHandModel* BasicHandModel); + + /** + * Retrieve the finger lengths of a specific finger in cm. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Finger Lengths", + Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static TArray GetFingerLengths_F(const USGBasicHandModel* BasicHandModel, ESGFinger Finger); + + /** + * Set the finger lengths of a specific finger in cm. + */ + UFUNCTION(BlueprintCallable, DisplayName="Set Finger Lengths", + Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static void SetFingerLengths_ESGFinger_F_L(UPARAM(ref) USGBasicHandModel* BasicHandModel, ESGFinger Finger, + const TArray& Lengths); + + /** + * Set the finger lengths of a specific finger in cm. + */ + UFUNCTION(BlueprintCallable, DisplayName="Set Finger Lengths", + Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static void SetFingerLengths_uint8_F_L(UPARAM(ref) USGBasicHandModel* BasicHandModel, uint8 Finger, + const TArray& Lengths); + + /** + * Get the finger ratios of all fingers. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Basic Hand Model") + TArray GetFingerRatios(const USGBasicHandModel* BasicHandModel) const; + + /** + * Get the finger ratios of a specific finger. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Finger Ratios", + Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static TArray GetFingerRatios_F(const USGBasicHandModel* BasicHandModel, ESGFinger Finger); + + /** + * Starting joint positions relative to the device Origin. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static TArray GetStartJointPositions(const USGBasicHandModel* BasicHandModel); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Set Start Joint Position", + Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static void SetStartJointPosition_ESGFinger_F_P(UPARAM(ref) USGBasicHandModel* BasicHandModel, ESGFinger Finger, + const FVector& Position); + + /** + * + */ + UFUNCTION(BlueprintPure, DisplayName="Set Start Joint Position", + Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static void SetStartJointPosition_uint8_F_P(UPARAM(ref) USGBasicHandModel* BasicHandModel, uint8 Finger, + const FVector& Position); + + /** + * Starting joint rotations relative to the device Origin. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Start Joint Rotations", + Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static TArray GetStartJointRotations_TArrayFQuat(const USGBasicHandModel* BasicHandModel); + + /** + * Starting joint rotations relative to the device Origin. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Start Joint Rotations", + Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static TArray GetStartJointRotations_TArrayFRotator(const USGBasicHandModel* BasicHandModel); + + /** + * Retrieve the start position of a specific finger. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static FVector GetJointPosition(const USGBasicHandModel* BasicHandModel, ESGFinger Finger); + + /** + * Set the start position of a specific finger. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static void SetJointPosition(UPARAM(ref) USGBasicHandModel* BasicHandModel, const FVector& NewPosition, + ESGFinger Finger); + + /** + * Retrieve the start rotation of a specific finger. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Joint Rotation", + Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static FQuat GetJointRotation_FQuat(const USGBasicHandModel* BasicHandModel, ESGFinger Finger); + + /** + * Retrieve the start rotation of a specific finger. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Joint Rotation", + Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static FRotator GetJointRotation_FRotator(const USGBasicHandModel* BasicHandModel, ESGFinger Finger); + + /** + * Set the start rotation of a specific finger. + */ + UFUNCTION(BlueprintCallable, DisplayName="Set Joint Rotation", + Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static void SetJointRotation_FQuat_NR_F( + UPARAM(ref) USGBasicHandModel* BasicHandModel, const FQuat& NewRotation, ESGFinger Finger); + + /** + * Set the start rotation of a specific finger. + */ + UFUNCTION(BlueprintCallable, DisplayName="Set Joint Rotation", + Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static void SetJointRotation_FRotator_NR_F( + UPARAM(ref) USGBasicHandModel* BasicHandModel, const FRotator& NewRotation, ESGFinger Finger); + + /** + * Get the total lengths of fingers, in cm. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static TArray GetTotalLengths(const USGBasicHandModel* BasicHandModel); + + /** + * Get the total length of a specific finger, in mm. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static float GetTotalLength(const USGBasicHandModel* BasicHandModel, ESGFinger Finger); + + /** + * Retrieve the lengths of a specific finger, as BasicHandModel representation (L, 0, 0). + * + * @remarks Used for forwards kinematics. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static TArray Get3DLengths(const USGBasicHandModel* BasicHandModel, ESGFinger Finger); + + /** + * Check if this BasicHandModel has the same values as another BasicHandModel. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static bool Equals(const USGBasicHandModel* A, const USGBasicHandModel* B); + + /** + * Convert this handModel into a string notation, readable for humans. Does not include starting positions / rotations. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static FString ToString(const USGBasicHandModel* BasicHandModel); + + /** + * Convert this handModel into a string notation, readable for humans. Optionally includes starting positions / rotations. + */ + UFUNCTION(BlueprintPure, DisplayName="To String", Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static FString ToString_bLO(const USGBasicHandModel* BasicHandModel, bool bLengthsOnly); + + /** + * Serialize this HandModel into a string representation. + */ + UFUNCTION(BlueprintPure, DisplayName="Serialize", Category="SenseGlove | Core | Kinematics | Basic Hand Model") + static FString SGSerialize(const USGBasicHandModel* BasicHandModel); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGBetaDeviceKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGBetaDeviceKismetLibrary.h new file mode 100644 index 0000000..63cf460 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGBetaDeviceKismetLibrary.h @@ -0,0 +1,122 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Represents a Sense Glove Device that has no specific class within the API. + * Used to test different iterations of the same product before integrating it + * into the Core API. + * Allows access to raw sensor values and commands of such a device. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" + +#include "SGBetaDeviceKismetLibrary.generated.h" + +class USGBetaDevice; + +/** + * A Device that adheres to the SenseGlove communications protocol, but which has no implementation in this API. + */ +UCLASS(meta=(ScriptName = "SenseGloveBetaDeviceKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGBetaDeviceKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Deserialize a beta device from its basic constants string. Returns nullptr is unsuccessful. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Beta Device", meta=(WorldContext="WorldContextObject")) + static USGBetaDevice* Parse(UObject* WorldContextObject, const FString& String); + + /** + * Get the DeviceType enumerator of this SenseGlove, used in DeviceList enumeration. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Beta Device") + static ESGDeviceType GetDeviceType(const USGBetaDevice* BetaDevice); + + /** + * Get the unique identifier of this device. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Beta Device") + static FString GetDeviceId(const USGBetaDevice* BetaDevice); + + /** + * Retrieve this device's hardware version. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Beta Device") + static FString GetHardwareVersion(const USGBetaDevice* BetaDevice); + + /** + * Retrieve this device's firmware version. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Beta Device") + static int32 GetFirmwareVersion(const USGBetaDevice* BetaDevice); + + /** + * Retrieve this device's sub-firmware version. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Beta Device") + static int32 GetSubFirmwareVersion(const USGBetaDevice* BetaDevice); + + /** + * Retrieve the constants string for additional processing. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Beta Device") + static FString GetConstantsString(const USGBetaDevice* BetaDevice); + + /** + * Retrieve a raw sensor string from this Beta Device. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Beta Device") + static FString GetSensorData(const USGBetaDevice* BetaDevice); + + /** + * Retrieve the last command retrieved from this Beta Device. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Beta Device") + static FString GetLastCommand(const USGBetaDevice* BetaDevice); + + /** + * Send a raw string command to this device. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Beta Device") + static bool SendHaptics(const USGBetaDevice* BetaDevice, const FString& Command); + + /** + * Create a string representation of this device for reporting purposes. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Beta Device") + static FString ToString(const USGBetaDevice* BetaDevice); +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGCustomWaveformKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGCustomWaveformKismetLibrary.h new file mode 100644 index 0000000..44c7f58 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGCustomWaveformKismetLibrary.h @@ -0,0 +1,267 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Describes a vibration based on a number of parameters. Is sent to Nova Gloves + * to be generated on the hardware and played. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" + +#include "SGCustomWaveformKismetLibrary.generated.h" + +class USGBasicHandModel; +class USGCustomWaveform; + +/** + * A single vibration pulse for Nova Gloves. + */ +UCLASS(meta=(ScriptName = "SenseGloveCustomWaveformKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGCustomWaveformKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * The default constructor. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | CV | Custom Waveform", + meta=(WorldContext="WorldContextObject")) + static USGCustomWaveform* MakeCustomWaveform(UObject* WorldContextObject); + + /** + * Create a new instance of CustomWaveform. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Custom Waveform", Category="SenseGlove | Core | CV | Custom Waveform", + meta=(WorldContext="WorldContextObject")) + static USGCustomWaveform* MakeCustomWaveform_A_D( + UObject* WorldContextObject, + float Amplitude, float Duration); + + /** + * Create a new instance of CustomWaveform. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Custom Waveform", Category="SenseGlove | Core | CV | Custom Waveform", + meta=(WorldContext="WorldContextObject")) + static USGCustomWaveform* MakeCustomWaveform_A_D_F( + UObject* WorldContextObject, + float Amplitude, float Duration, float Frequency); + + /** + * Creates a string representation of the ESGWaveformType. + */ + UFUNCTION(BlueprintCallable, DisplayName="ToString", Category="SenseGlove | Core | CV | Custom Waveform") + static FString ToString_T(ESGWaveformType Type); + + /** + * Get the total amplitude of the wave-from, represented by 0 (off) or 1 (maximum value). + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | CV | Custom Waveform") + static float GetAmplitude(const USGCustomWaveform* CustomWaveform); + + /** + * Set the total amplitude of the wave-from, represented by 0 (off) or 1 (maximum value). + * @param Amplitude + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | CV | Custom Waveform") + static void SetAmplitude(UPARAM(ref) USGCustomWaveform* CustomWaveform, float Amplitude); + + /** + * Get the Type of waveform pattern that is used. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | CV | Custom Waveform") + ESGWaveformType GetWaveType(const USGCustomWaveform* CustomWaveform); + + /** + * Set the Type of waveform pattern that is used. + * @param Type + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | CV | Custom Waveform") + static void SetWaveType(UPARAM(ref) USGCustomWaveform* CustomWaveform, ESGWaveformType Type); + + /** + * Get whether or not this Waveform is infinitely repeating. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | CV | Custom Waveform") + static bool IsInfinite(const USGCustomWaveform* CustomWaveform); + + /** + * Set whether or not this Waveform is infinitely repeating. + * @param bInfinite + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | CV | Custom Waveform") + static void SetInfinite(UPARAM(ref) USGCustomWaveform* CustomWaveform, bool bInfinite); + + /** + * Get the amount of times to repeat this waveform. 1 is the default. If set to 0, repeats indefinitely. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | CV | Custom Waveform", meta=(WorldContext="WorldContextObject")) + int32 GetRepeatAmount(const USGCustomWaveform* CustomWaveform); + + /** + * Set the amount of times to repeat this waveform. 1 is the default. If set to 0, repeats indefinitely. + * @param Amount + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | CV | Custom Waveform") + static void SetRepeatAmount(UPARAM(ref) USGCustomWaveform* CustomWaveform, int32 Amount); + + /** + * Get time, in seconds, before the signal reaches its maximum amplitude. Limited to 0.01 - 1s. Set to 0 for an + * instant start. Linear only. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | CV | Custom Waveform") + static float GetAttackTime(const USGCustomWaveform* CustomWaveform); + + /** + * Set time, in seconds, before the signal reaches its maximum amplitude. Limited to 0.01 - 1s. Set to 0 for an + * instant start. Linear only. + * @param Time + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | CV | Custom Waveform") + static void SetAttackTime(UPARAM(ref) USGCustomWaveform* CustomWaveform, float Time); + + /** + * Get time, in seconds, to keep the signal at one Amplitude. Limited to 0.01 - 1s. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | CV | Custom Waveform") + static float GetSustainTime(const USGCustomWaveform* CustomWaveform); + + /** + * Set time, in seconds, to keep the signal at one Amplitude. Limited to 0.01 - 1s. + * @param Time + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | CV | Custom Waveform") + static void SetSustainTime(UPARAM(ref) USGCustomWaveform* CustomWaveform, float Time); + + /** + * Get time it takes for the effect to fade out after AttackTime+SustainTime has passed. Limited to 0.01 - 1s. Set + * to 0 for instant stop. Linear only. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | CV | Custom Waveform") + static float GetDecayTime(const USGCustomWaveform* CustomWaveform); + + /** + * Set time it takes for the effect to fade out after AttackTime+SustainTime has passed. Limited to 0.01 - 1s. Set + * to 0 for instant stop. Linear only. + * @param Time + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | CV | Custom Waveform") + static void SetDecayTime(UPARAM(ref) USGCustomWaveform* CustomWaveform, float Time); + + /** + * Get the Wave-from Frequency at the start of the wave-from. Limited between [10 - 500Hz] for Nova Gloves. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | CV | Custom Waveform") + static float GetFrequencyStart(const USGCustomWaveform* CustomWaveform); + + /** + * Set the Wave-from Frequency at the start of the wave-from. Limited between [10 - 500Hz] for Nova Gloves. + * @param Frequency + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | CV | Custom Waveform") + static void SetFrequencyStart(UPARAM(ref) USGCustomWaveform* CustomWaveform, float Frequency); + + /** + * Get the Wave-from Frequency at the end of the wave-from. Limited between [10 - 500Hz] for Nova Gloves. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | CV | Custom Waveform", + meta=(WorldContext="WorldContextObject")) + static float GetFrequencyEnd(const USGCustomWaveform* CustomWaveform); + + /** + * Set the Wave-from Frequency at the end of the wave-from. Limited between [10 - 500Hz] for Nova Gloves. + * @param Frequency + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | CV | Custom Waveform", + meta=(WorldContext="WorldContextObject")) + static void SetFrequencyEnd(UPARAM(ref) USGCustomWaveform* CustomWaveform, float Frequency); + + /** + * Get value of [0..1], representing a percentage of total time (attack+sustain+decay). After that moment passes, + * we increase the frequency by FrequencySwitch factor. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | CV | Custom Waveform") + static float GetFrequencySwitchTime(const USGCustomWaveform* CustomWaveform); + + /** + * Set value of [0..1], representing a percentage of total time (attack+sustain+decay). After that moment passes, + * we increase the frequency by FrequencySwitch factor. + * @param Time + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | CV | Custom Waveform") + static void SetFrequencySwitchTime(UPARAM(ref) USGCustomWaveform* CustomWaveform, float Time); + + /** + * After a certain % of the waveform (FrequencySwitchTime) plays, multiply the frequency by this factor [1x .. 3x]. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | CV | Custom Waveform") + static float GetFrequencySwitchFactor(const USGCustomWaveform* CustomWaveform); + + /** + * After a certain % of the waveform (FrequencySwitchTime) plays, multiply the frequency by this factor [1x .. 3x]. + * param Time + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | CV | Custom Waveform") + static void SetFrequencySwitchFactor(UPARAM(ref) USGCustomWaveform* CustomWaveform, float Time); + + /** + * The total command time of a single play of this pattern (not taking into account the RepeatAmount). + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | CV | Custom Waveform") + static float GetEffectTime(const USGCustomWaveform* CustomWaveform); + + /** + * Total time for the entire effect (effect time multiplied by the repeat amount). + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | CV | Custom Waveform") + static float GetTotalEffectTime(const USGCustomWaveform* CustomWaveform); + + /** + * If true, the frequency of this waveform jumps at any time during its playtime by FrequencySwitchFactor. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | CV | Custom Waveform") + static bool FrequencyJumps(const USGCustomWaveform* CustomWaveform); + + /** + * Check if this CustomWaveform is roughly equal to another. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | CV | Custom Waveform") + static bool Equals(const USGCustomWaveform* A, const USGCustomWaveform* B); + + /** + * Create a string representation of this CustomWaveform. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | CV | Custom Waveform") + static FString ToString(const USGCustomWaveform* CustomWaveform); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGDeviceKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGDeviceKismetLibrary.h new file mode 100644 index 0000000..f9baac9 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGDeviceKismetLibrary.h @@ -0,0 +1,239 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Represents a Device built by the Sense Glove company that is compatible with + * our Communications Protocol. All such devices derive from this abstract + * class. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" + +#include "SGDeviceKismetLibrary.generated.h" + +class USGDevice; +class USGHapticChannelInfo; + +UCLASS(meta=(ScriptName = "SenseGloveSGDeviceKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGDeviceKismetLibrary : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Parse a main and sub firmware version from its raw (v4.12) notation + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SGDevice") + static void ParseFirmware(const FString& RawFirmware, int32& OutMainVersion, int32& OutSubVersion); + + /** + * If true, my firmware is newer than the reference firmware. + * @param MyFirmwareMain + * @param MyFirmwareSub + * @param ReferenceMain + * @param ReferenceSub + * @param bInclusive + */ + UFUNCTION(BlueprintCallable, DisplayName="Firmware Newer Than", Category="SenseGlove | Core | SGDevice") + static bool FirmwareNewerThan_MF_MF_RM_RS_bI(int32 MyFirmwareMain, int32 MyFirmwareSub, + int32 ReferenceMain, int32 ReferenceSub, + bool bInclusive); + + /** + * If true, my firmware is older than the reference firmware. + * @param MyFirmwareMain + * @param MyFirmwareSub + * @param ReferenceMain + * @param ReferenceSub + * @param bInclusive + */ + UFUNCTION(BlueprintCallable, DisplayName="Firmware Older Than", Category="SenseGlove | Core | SGDevice") + static bool FirmwareOlderThan_MF_MF_RM_RS_bI(int32 MyFirmwareMain, int32 MyFirmwareSub, + int32 ReferenceMain, int32 ReferenceSub, + bool bInclusive); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="To String", Category="SenseGlove | Core | SGDevice") + static FString ToString_DT(ESGDeviceType DeviceType); + + /** + * Check which DeviceType this class belongs to. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SGDevice") + static ESGDeviceType GetDeviceType(const USGDevice* SGDevice); + + /** + * Retrieve this device's unique identifier. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SGDevice") + static FString GetDeviceId(const USGDevice* SGDevice); + + /** + * Retrieve this device's hardware version. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SGDevice") + static FString GetHardwareVersion(const USGDevice* SGDevice); + + /** + * Retrieve this device's main firmware version. v4.12 returns 4. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SGDevice") + static int32 GetFirmwareVersion(const USGDevice* SGDevice); + + /** + * Retrieve this device's sub firmware version. v4.12 returns 12. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SGDevice") + static int32 GetSubFirmwareVersion(const USGDevice* SGDevice); + + /** + * + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SGDevice") + static FString GetFirmwareString(const USGDevice* SGDevice); + + /** + * Returns true if this glove's firmware is newer than certain version. + * @param FirmwareMain + * @param FirmwareSub + * @param bInclusive + */ + UFUNCTION(BlueprintPure, DisplayName="Firmware Newer Than", Category="SenseGlove | Core | SGDevice") + bool FirmwareNewerThan_FM_FS_bI(const USGDevice* SGDevice, + int32 FirmwareMain, int32 FirmwareSub, bool bInclusive); + + /** + * Returns true if this glove's firmware is older than certain version. + * @param FirmwareMain + * @param FirmwareSub + * @param bInclusive + */ + UFUNCTION(BlueprintPure, DisplayName="Firmware Older Than", Category="SenseGlove | Core | SGDevice") + static bool FirmwareOlderThan_FM_FS_bI(const USGDevice* SGDevice, + int32 FirmwareMain, int32 FirmwareSub, bool bInclusive); + + /** + * Retrieve this Device's Serial/Bluetooth address. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SGDevice") + static FString GetAddress(const USGDevice* SGDevice); + + /** + * Check if this device is currently connected to the system. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SGDevice") + static bool IsConnected(const USGDevice* SGDevice); + + /** + * Retrieve the connection type of this Sense Glove. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SGDevice") + static ESGConnectionType GetConnectionType(const USGDevice* SGDevice); + + /** + * Retrieve the device's Packets per Second Variable. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SGDevice") + static int32 PacketsPerSecondReceived(const USGDevice* SGDevice); + + /** + * Retrieve the device's Packets per Second Variable. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SGDevice") + static int32 PacketsPerSecondSent(const USGDevice* SGDevice); + + /** + * Retrieve the index of this device within SenseCom. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SGDevice") + static int32 GetDeviceIndex(const USGDevice* SGDevice); + + /** + * Change this device's index within the SenseCom. Warning: Can cause errors. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SGDevice") + static void SetDeviceIndex(UPARAM(ref) USGDevice* SGDevice, int32 NewIndex); + + /** + * Returns true if this device is connected over a connection other than usb cable. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SGDevice") + static bool IsWireless(const USGDevice* SGDevice); + + /** + * Returns true if this device operates on a battery. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SGDevice") + static bool HasBattery(const USGDevice* SGDevice); + + /** + * Returns true if this device is currently charging. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SGDevice") + static bool IsCharging(UPARAM(ref) USGDevice* SGDevice); + + /** + * Returns the device's battery level, as a value between 0 (empty) and 1 (full). + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SGDevice") + static bool GetBatteryLevel(UPARAM(ref) USGDevice* SGDevice, float& OutLevel); + + /** + * Assign this Device's Haptic Channels. Should not be done outside the API unless you know what you're doing. + * @param Channels + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SGDevice") + static void SetHapticChannels(UPARAM(ref) USGDevice* SGDevice, const USGHapticChannelInfo* Channels); + + /** + * The number of haptic channels this device can support. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Haptic Channel Index", Category="SenseGlove | Core | SGDevice") + static int32 GetHapticChannelCount(const USGDevice* SGDevice); + + /** + * How many channels of a specific type this SGDevice possesses. + * @param ChannelType + */ + UFUNCTION(BlueprintPure, DisplayName="Get Haptic Channel Index", Category="SenseGlove | Core | SGDevice") + static int32 GetHapticChannelCount_CT(const USGDevice* SGDevice, ESGHapticChannelType ChannelType); + + /** + * Get a string representation of this SGDevice, used for debugging. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SGDevice") + static FString ToString(const USGDevice* SGDevice); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGDeviceListKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGDeviceListKismetLibrary.h new file mode 100644 index 0000000..7821e54 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGDeviceListKismetLibrary.h @@ -0,0 +1,151 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Interface for SenseCom, allows the retrieval of Devices and Data, but only + * as. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "HAL/Platform.h" +#include "Templates/SubclassOf.h" + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" + +#include "SGDeviceListKismetLibrary.generated.h" + +class USGDevice; + +/** + * Interface for SenseCom, allows the retrieval of Devices and Data. + */ +UCLASS(meta=(ScriptName = "SenseGloveDeviceListKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGDeviceListKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Retrieve the number of devices that have been detected by the SenseCom executable. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Device List") + static int32 ActiveDevices(); + + /** + * Returns true if the SenseCom program is running. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Device List") + static bool SenseCommRunning(); + + /** + * Clear the device list, and block any further attempt to add to it until ReInitialize is called. + * + * @remarks Useful if your IDE has troubles unloading dlls (cough, Unity, Cough). + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Device List") + static void Dispose(); + + /** + * When you've accidentally disposed of the list before you meant to. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Device List") + static void Reinitialize(); + + /** + * Retrieve all Sense Glove Devices connected to this system. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Device List", meta=(WorldContext="WorldContextObject")) + static TArray GetDevices(UObject* WorldContextObject); + + /** + * Retrieve a list of SGDevices of a specific class. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Devices", Category="SenseGlove | Core | Device List", + meta=(WorldContext="WorldContextObject")) + static TArray GetDevices_TSubclassOfUSGDevice_DT(UObject* WorldContextObject, + const TSubclassOf& DeviceType); + + /** + * Retrieve a list of SGDevices of a specific type. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Devices", Category="SenseGlove | Core | Device List", + meta=(WorldContext="WorldContextObject")) + static TArray GetDevices_ESGDeviceType_DT(UObject* WorldContextObject, ESGDeviceType DeviceType); + + /** + * Retrieve the latest (raw) sensor data from a specific device in our list. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Device List") + static bool GetSensorDataString(int32 IpcIndex, const FString& IpcAddress, FString& OutString); + + /** + * Send a (raw) command to a specific device in the list. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Device List") + static bool SendHaptics( + const int32 IpcIndex, const FString& IpcAddress, const int32 ChannelIndex, const FString& Commands); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Device List") + static FString GetDeviceStringAt(int32 IpcIndex, const FString& IpcAddress, int32 Index); + + /** + * Retrieve Device Address. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Device List") + static FString GetAddress(int32 IpcIndex, const FString& IpcAddress); + + /** + * Retieve this device's connectionType. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Device List") + static ESGConnectionType GetConnectionType(int32 IpcIndex, const FString& IpcAddress); + + /** + * Returns true if the device at this connection side is properly connected. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Device List") + static bool IsConnected(int32 IpcIndex, const FString& IpcAddress); + + /** + * Retrieve the device's Packets per Second Variable. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Device List") + static int32 PacketsPerSecondReceived(int32 IpcIndex, const FString& IpcAddress); + + /** + * Retrieve the device's Packets per Second sent Variable. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Device List") + static int32 PacketsPerSecondSent(int32 IpcIndex, const FString& IpcAddress); +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGDeviceModelKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGDeviceModelKismetLibrary.h new file mode 100644 index 0000000..d8bd497 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGDeviceModelKismetLibrary.h @@ -0,0 +1,119 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Base class for Device Models containing the minimum amount of data gathered + * through Communications Protocol. Used for shared functionality. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" + +#include "SGKismet/SGBlueprintFunctionLibrary.h" + +#include "SGDeviceModelKismetLibrary.generated.h" + +class USGDeviceModel; + +/** + * Base class containing the minimum amount of data for device models. + */ +UCLASS(meta=(ScriptName = "SenseGloveDeviceModelKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGDeviceModelKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Empty constructor to be used by child classes. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Device Model", meta=(WorldContext="WorldContextObject")) + static USGDeviceModel* MakeDeviceModel(UObject* WorldContextObject); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Device Model", Category="SenseGlove | Core | Device Model", + meta=(WorldContext="WorldContextObject")) + static USGDeviceModel* MakeDeviceModel_I_HV_FV_SFV( + UObject* WorldContextObject, + const FString& Id, const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion); + + /** + * Parse a 32-bit integer value into a set of booleans (010010011) that indicate which (optional) functions this device has. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Device Model") + static TArray ParseFunctions(int32 Value, int32 Size); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Device Model") + static void ParseFirmware(const FString& RawFirmware, int32& OutMainVersion, int32& OutSubVersion); + + /** + * Retrieve the Unique identifier of this device. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Device Model") + static FString GetDeviceId(const USGDeviceModel* DeviceModel); + + /** + * Retrieve the Hardware (sub) version of this Sense Glove Device. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Device Model") + static FString GetHardwareVersion(const USGDeviceModel* DeviceModel); + + /** + * Firmware version running on the device's MicroController. (as v4.12, this is the 4). + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Device Model") + static int32 GetFirmwareVersion(const USGDeviceModel* DeviceModel); + + /** + * Sub firmware version running on the device's microcontroller (as v4.12, this is the 12). + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Device Model") + static int32 GetSubFirmwareVersion(const USGDeviceModel* DeviceModel); + + /** + * Returns true if this glove's firmware is newer than certain version. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Device Model") + static bool FirmwareNewerThan(const USGDeviceModel* DeviceModel, + int32 FirmwareMain, int32 FirmwareSub, bool bInclusive); + + /** + * Returns true if this glove's firmware is older than certain version. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Device Model") + static bool FirmwareOlderThan(const USGDeviceModel* DeviceModel, + int32 FirmwareMain, int32 FirmwareSub, bool bInclusive); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGHandInterpolatorKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGHandInterpolatorKismetLibrary.h new file mode 100644 index 0000000..67dbc12 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGHandInterpolatorKismetLibrary.h @@ -0,0 +1,117 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Contains interpolation sets for all hand joint movements that can be + * calculated using the Sense Glove. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" +#include "SGTypes/SGFloatArray.h" +#include "SGTypes/SGVectorArray.h" + +#include "SGHandInterpolatorKismetLibrary.generated.h" + +class USGHandInterpolator; + +/** + * Contains interpolation sets of all joint movements that can be calculated into a HandPose. + */ +UCLASS(meta=(ScriptName = "SenseGloveHandInterpolatorKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGHandInterpolatorKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * The basic constructor. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Hand Interpolator", + Category="SenseGlove | Core | Kinematics | Hand Interpolator", meta=(WorldContext="WorldContextObject")) + static USGHandInterpolator* MakeHandInterpolator(UObject* WorldContextObject); + + /** + * Create a new basic HandInterpolator. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Hand Interpolator", + Category="SenseGlove | Core | Kinematics | Hand Interpolator", meta=(WorldContext="WorldContextObject")) + static USGHandInterpolator* MakeHandInterpolator_bRH(UObject* WorldContextObject, bool bRightHanded); + + /** + * Convert a serialized HandInterpolator back into a class representation. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Hand Interpolator", + meta=(WorldContext="WorldContextObject")) + static USGHandInterpolator* Deserialize(UObject* WorldContextObject, + const FString& SerializedString, bool bRightHanded = true); + + /** + * Calculate a finger movement's rotation, using an input value. + * + * WARNING: This method is for internal use only. Avoid using it! + */ + static float CalculateAngle_M_ESGFingerMovement_V_bAL(const USGHandInterpolator* HandInterpolator, + ESGFingerMovement Movement, float Value, + bool bApplyLimits = true); + + /** + * Calculate a thumb movement's rotation, using an input value. + * + * WARNING: This method is for internal use only. Avoid using it! + */ + static float CalculateAngle_M_ESGFingerMovement_V_bAL(const USGHandInterpolator* HandInterpolator, + ESGThumbMovement Movement, float Value, + bool bApplyLimits = true); + + /** + * Calculate all hand angles based on an interpolator and normalized input. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Hand Interpolator", + meta=(WorldContext="WorldContextObject")) + TArray InterpolateHandAngles(const USGHandInterpolator* HandInterpolator, + const TArray& Flexions, const TArray& Abductions, + float CmcTwist) const; + + /** + * Check if this handInterpolator matches another. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Hand Interpolator") + static bool Equals(const USGHandInterpolator* A, const USGHandInterpolator* B); + + /** + * Serialize this HandInterpolator into a string representation. + */ + UFUNCTION(BlueprintPure, DisplayName="Serialize", Category="SenseGlove | Core | Kinematics | Hand Interpolator") + static FString SGSerialize(const USGHandInterpolator* HandInterpolator); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGHandLayerKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGHandLayerKismetLibrary.h new file mode 100644 index 0000000..a6707f3 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGHandLayerKismetLibrary.h @@ -0,0 +1,227 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * A way to access all sorts of Hand Tracking and -Haptics without needing to + * cache any device instances. + * Use this layer if you don't care where a HandPose is coming from, and are + * fine with calling generic haptic functions. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" + +#include "SGHandLayerKismetLibrary.generated.h" + +class USGCustomWaveform; +class USGHandPose; + +/** + * A way to access all sorts of Hand Tracking and -Haptics without needing to cache any device instances. + */ +UCLASS(meta=(ScriptName = "SenseGloveHandLayerKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGHandLayerKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Returns true if there is a HapticGlove Device connected that corresponds to the chosen hand. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static bool DeviceConnected(bool bRightHanded); + + /** + * Returns the Device Type of the right / left hand. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static ESGDeviceType GetDeviceType(bool bRightHanded); + + /** + * Returns the handedness of the first device you can find; true for right, false for left. Use this for testing a + * single glove. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static bool GetFirstGloveHandedness(); + + /** + * Returns the number of Haptic Gloves connected to the system. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static int32 GlovesConnected(); + + /** + * Retrieve a Glove Instance for the right- or left hand to do more complicated, device-specific stuff. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer", + meta=(WorldContext="WorldContextObject")) + static bool GetGloveInstance(UObject* WorldContextObject, bool bRightHanded, USGHapticGlove*& OutGlove); + + /** + * Returns the calibration state of the chosen hand. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static ESGHapticGloveCalibrationState GetCalibrationState(bool bRightHanded); + + /** + * Returns the Calibration Instructions for the chosen hand. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static FString GetCalibrationInstructions(bool bRightHanded); + + /** + * Reset the calibration of the left/right hand. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static void ResetCalibration(bool bRightHanded); + + /** + * Reset the calibration of the left/right hand. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static void EndCalibration(bool bRightHanded); + + /** + * Attempt to get the HandPose through any of our gloves. You don't care which one is on the other side, as long as + * you get one. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer", + meta=(WorldContext="WorldContextObject")) + static bool GetHandPose(UObject* WorldContextObject, bool bRightHanded, USGHandPose*& OutHandPose); + + /** + * Calculate the Wrist Location of the chosen hand, based on a reference location and tracking hardware. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static void GetWristLocation( + bool bRightHanded, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation); + + /** + * Stop all haptics on the chosen hand. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static void StopAllHaptics(bool bRightHanded); + + /** + * Sends all haptics in the queue for the Left / Right hand. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static bool SendHaptics(bool bRightHanded); + + /** + * Returns true if the glove for this hand supports a custom waveform vibration on said location. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static bool SupportsCustomWaveform(bool bRightHanded, ESGHapticLocation AtLocation); + + /** + * Send a Custom Waveform to a glove at a specific location. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static bool SendCustomWaveform(bool bRightHanded, USGCustomWaveform* OutWaveform, ESGHapticLocation Location); + + /** + * Queue Force Feedback for multiple fingers. Up to 5. Make sure the value is not NULL. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static bool QueueCommand_ForceFeedbackLevels( + bool bRightHanded, const TArray& Levels01, bool bSendImmediate); + + /** + * Tell a specific hand to hold the force-feedback at a certain level. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static bool QueueCommand_ForceFeedbackLevel(bool bRightHanded, int32 Finger, float Level01, bool bSendImmediate); + + /** + * Queue a command to set the vibration level(s) of a Haptic Glove's finger. Note: This is only for Nova 1.0 and + * DK1.0. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static bool QueueCommand_VibroLevels(bool bRightHanded, const TArray& Levels01, bool bSendImmediate); + + /** + * Queue a command to set the vibration level(s) of a Haptic Glove's finger. Note: This is only for Nova 1.0 and + * DK1.0. + */ + UFUNCTION(BlueprintCallable, DisplayName="Queue Command Vibro Level", Category="SenseGlove | Core | Hand Layer") + static bool QueueCommand_VibroLevel_bRH_F_L01_bSI( + bool bRightHanded, int32 Finger, float Level01, bool bSendImmediate); + + /** + * Queue a vibration level command for a specific HapticLocation. If the gloves has this vibration motor installed. + * Cross-compatible with Nova 2.0. + * + * @param bRightHanded + * @param AtLocation + * @param Level01 + * @param bSendImmediate + */ + UFUNCTION(BlueprintCallable, DisplayName="Queue Command Vibro Level", Category="SenseGlove | Core | Hand Layer") + static bool QueueCommand_VibroLevel_bRH_AL_L01_bSI( + bool bRightHanded, ESGHapticLocation AtLocation, float Level01, bool bSendImmediate); + + /** + * Returns true if the chosen glove supports active contact feedback on the Wrist. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static bool SupportsWristSqueeze(bool bRightHanded); + + /** + * Queue a command to set a squeeze level on the wrist, and optionally send it right away. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static bool QueueCommand_WristSqueeze(bool bRightHanded, float SqueezeLevel01, bool bSendImmediate); + + /** + * Returns true is the chosen hand supports flexion locking; automatic locking of FFB when flexed beyond a specific + * point. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static bool SupportsFlexionLocks(bool bRightHanded); + + /** + * If the flexion exceeds a particular value, turn on the Force-Feedback. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static bool QueueCommand_FlexionLock(bool bRightHanded, int32 Finger, float Flexion01, bool bSendImmediate); + + /** + * Stop any Flexion Threshold active on the chosen finger. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Layer") + static bool QueueCommand_ClearFlexionLock(bool bRightHanded, int32 Finger, bool bSendImmediate); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGHandPoseKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGHandPoseKismetLibrary.h new file mode 100644 index 0000000..6e1d3c9 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGHandPoseKismetLibrary.h @@ -0,0 +1,231 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Data class containing all variables to draw or analyze a virtual hand in + * different formats. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" +#include "SGTypes/SGQuatArray.h" +#include "SGTypes/SGRotatorArray.h" +#include "SGTypes/SGVectorArray.h" + +#include "SGHandPoseKismetLibrary.generated.h" + +class USGBasicHandModel; +class USGHandPose; + +/** + * Contains all variables required to draw or analyze a virtual hand. + */ +UCLASS(meta=(ScriptName = "SenseGloveHandPoseKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGHandPoseKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * The default constructor. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Pose", meta=(WorldContext="WorldContextObject")) + static USGHandPose* MakeHandPose(UObject* WorldContextObject); + + /** + * Create a new instance of HandPose. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Hand Pose", Category="SenseGlove | Core | Hand Pose", + meta=(WorldContext="WorldContextObject")) + static USGHandPose* MakeHandPose_bRH_JP_FSGQuatArray_JR_HA( + UObject* WorldContextObject, + bool bRightHanded, const TArray& JointPositions, const TArray& JointRotations, + const TArray& HandAngles); + + /** + * Create a new instance of HandPose. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Hand Pose", Category="SenseGlove | Core | Hand Pose", + meta=(WorldContext="WorldContextObject")) + static USGHandPose* MakeHandPose_bRH_JP_FSGRotatorArray_JR_HA( + UObject* WorldContextObject, + bool bRightHanded, const TArray& JointPositions, const TArray& JointRotations, + const TArray& HandAngles); + + /** + * Deserialize a HandPose back into usable values. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Hand Pose", meta=(WorldContext="WorldContextObject")) + static USGHandPose* Deserialize(UObject* WorldContextObject, const FString& SerializedString); + + /** + * Generate a HandPose based on articulation angles (handAngles). + */ + UFUNCTION(BlueprintCallable, DisplayName="From Hand Angles", Category="SenseGlove | Core | Hand Pose", + meta=(WorldContext="WorldContextObject")) + static USGHandPose* FromHandAngles_HA_bRH_HD( + UObject* WorldContextObject, + const TArray& HandAngles, bool bRightHanded, const USGBasicHandModel* HandDimensions); + + /** + * Generate a HandPose based on articulation angles (handAngles), with a default HandModel. + */ + UFUNCTION(BlueprintCallable, DisplayName="From Hand Angles", Category="SenseGlove | Core | Hand Pose", + meta=(WorldContext="WorldContextObject")) + static USGHandPose* FromHandAngles_HA_bRH(UObject* WorldContextObject, + const TArray& HandAngles, bool bRightHanded); + + /** + * Create a new instance of a left or right handed Pose that is "idle"; in a neutral position. + */ + UFUNCTION(BlueprintCallable, DisplayName="Default Idle", Category="SenseGlove | Core | Hand Pose", + meta=(WorldContext="WorldContextObject")) + static USGHandPose* DefaultIdle_bRH_HD(UObject* WorldContextObject, + bool bRightHanded, const USGBasicHandModel* HandDimensions); + + /** + * Create a new instance of a left or right handed Pose that is "idle"; in a neutral position. + */ + UFUNCTION(BlueprintCallable, DisplayName="Default Idle", Category="SenseGlove | Core | Hand Pose", + meta=(WorldContext="WorldContextObject")) + static USGHandPose* DefaultIdle_bRH(UObject* WorldContextObject, bool bRightHanded); + + /** + * Generates a HandPose representing an 'open hand', used in calibration to determine finger extension. + */ + UFUNCTION(BlueprintCallable, DisplayName="Flat Hand", Category="SenseGlove | Core | Hand Pose", + meta=(WorldContext="WorldContextObject")) + static USGHandPose* FlatHand_bRH_HD(UObject* WorldContextObject, + bool bRightHanded, const USGBasicHandModel* HandDimensions); + + /** + * Generates a HandPose representing an 'open hand', used in calibration to determine finger extension. + */ + UFUNCTION(BlueprintCallable, DisplayName="Flat Hand", Category="SenseGlove | Core | Hand Pose", + meta=(WorldContext="WorldContextObject")) + static USGHandPose* FlatHand_bRH(UObject* WorldContextObject, bool bRightHanded); + + /** + * Generates a HandPose representing a 'thumbs up', used in calibration to determine finger flexion, thumb extension and adduction. + */ + UFUNCTION(BlueprintCallable, DisplayName="Thumbs Up", Category="SenseGlove | Core | Hand Pose", + meta=(WorldContext="WorldContextObject")) + static USGHandPose* ThumbsUp_bRH_HD(UObject* WorldContextObject, bool bRightHanded, + const USGBasicHandModel* HandDimensions); + + /** + * Generates a HandPose representing a 'thumbs up', used in calibration to determine finger flexion, thumb extension and adduction. + */ + UFUNCTION(BlueprintCallable, DisplayName="Thumbs Up", Category="SenseGlove | Core | Hand Pose", + meta=(WorldContext="WorldContextObject")) + static USGHandPose* ThumbsUp_bRH(UObject* WorldContextObject, bool bRightHanded); + + /** + * Generates a HandPose representing a 'fist', used in calibration to determine, thumb flexion and abduction. + */ + UFUNCTION(BlueprintCallable, DisplayName="Fist", Category="SenseGlove | Core | Hand Pose", + meta=(WorldContext="WorldContextObject")) + static USGHandPose* Fist_bRH_HD(UObject* WorldContextObject, + bool bRightHanded, const USGBasicHandModel* HandDimensions); + + /** + * Generates a HandPose representing a 'fist', used in calibration to determine, thumb flexion and abduction. + */ + UFUNCTION(BlueprintCallable, DisplayName="Fist", Category="SenseGlove | Core | Hand Pose", + meta=(WorldContext="WorldContextObject")) + static USGHandPose* Fist_bRH(UObject* WorldContextObject, bool bRightHanded); + + /** + * Whether this HandPose was created to be a right- or left hand. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Hand Pose") + static bool IsRight(const USGHandPose* HandPose); + + /** + * Positions of all hand joints relative to the Sense Glove origin. From thumb to pinky, proximal to distal. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Hand Pose") + static TArray GetJointPositions(const USGHandPose* HandPose); + + /** + * Quaternion rotations of all hand joints. From thumb to pinky, proximal to distal. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Joint Rotations", Category="SenseGlove | Core | Hand Pose") + static TArray GetJointRotationsQ(const USGHandPose* HandPose); + + /** + * Rotations of all hand joints. From thumb to pinky, proximal to distal. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Joint Rotations", Category="SenseGlove | Core | Hand Pose") + static TArray GetJointRotations(const USGHandPose* HandPose); + + /** + * Euler representations of all possible hand angles. From thumb to pinky, proximal to distal. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Hand Pose") + static TArray GetHandAngles(const USGHandPose* HandPose); + + /** + * Returns true of these two hand poses are roughly equal. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Hand Pose") + static bool Equals(const USGHandPose* A, const USGHandPose* B); + + /** + * Returns the total flexion of a specific finger as a value between 0 (fully extended) and 1 (fully flexed). + * + * @remarks Useful for animation or for detecting gestures. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Normalized Flexion", Category="SenseGlove | Core | Hand Pose") + static float GetNormalizedFlexion_F_bC01(const USGHandPose* HandPose, ESGFinger Finger, bool bClamp01 = true); + + /** + * Returns the total flexion of a specific finger as a value between 0 (fully extended) and 1 (fully flexed). + * + * @remarks Useful for animation or for detecting gestures. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Normalized Flexion", Category="SenseGlove | Core | Hand Pose") + static TArray GetNormalizedFlexion_bC01(const USGHandPose* HandPose, bool bClamp01 = true); + + /** + * + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Hand Pose") + static FString ToString(const USGHandPose* HandPose, bool bShortFormat = false); + + /** + * Serialize this HandPose into a string representation. + */ + UFUNCTION(BlueprintPure, DisplayName="Serialize", Category="SenseGlove | Core | Hand Pose") + static FString SGSerialize(const USGHandPose* HandPose); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGHapticChannelInfoKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGHapticChannelInfoKismetLibrary.h new file mode 100644 index 0000000..6550ef4 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGHapticChannelInfoKismetLibrary.h @@ -0,0 +1,152 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Contains information on Haptic channels available to this device for IPC. + * Some devices have different "Haptic Channels". This info is exposed via IPC + * to SGCore. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" +#include "UObject/ObjectMacros.h" + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" + +#include "SGHapticChannelInfoKismetLibrary.generated.h" + +class USGBasicHandModel; +class USGHapticChannelInfo; + +/** + * Contains information on Haptic channels available to this device for IPC. + */ +UCLASS(meta=(ScriptName = "SenseGloveHapticChannelInfoKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGHapticChannelInfoKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Creates a default HapticChannelInfo, with solely a single streaming haptic Channel. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptic Channel Info", + meta=(WorldContext="WorldContextObject")) + static USGHapticChannelInfo* MakeHapticChannelInfo(UObject* WorldContextObject); + + /** + * Create a new instance of HapticChannelInfo. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Haptic Channel Info", + Category="SenseGlove | Core | Haptic Channel Info", meta=(WorldContext="WorldContextObject")) + static USGHapticChannelInfo* MakeHapticChannelInfo_SI_FAFI( + UObject* WorldContextObject, + const TArray& StreamIndex, const TArray& FireAndForgetIndex); + + /** + * Generate a single IPCAddress for an address. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptic Channel Info") + static FString GenerateAddress(int32 DeviceIndex, int32 ChannelIndex); + + /** + * Parse HapticChannelInfo received through IPC into usable data. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptic Channel Info", + meta=(WorldContext="WorldContextObject")) + static USGHapticChannelInfo* Parse(UObject* WorldContextObject, const FString& IpcString); + + /** + * Byte used to identify streaming channels. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptic Channel Info") + static int32 GetStreamingType(); + + /** + * Byte used to indicate fire-and-forget channels. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptic Channel Info") + static int32 GetFireAndForgetType(); + + /** + * Returns the amount of streaming channels available for haptics. Will indicate if a device can support the + * haptics you're trying to send through it. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptic Channel Info") + static int32 GetStreamChannelCount(const USGHapticChannelInfo* HapticChannelInfo); + + /** + * Returns the amount of fire-and-forget channels available for haptics. Will indicate if a device can support the + * haptics you're trying to send through it. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptic Channel Info") + static int32 GetFireAndForgetChannelCount(const USGHapticChannelInfo* HapticChannelInfo); + + /** + * Retrieve the total amount of channels for this device. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptic Channel Info") + static int32 GetTotalChannelCount(const USGHapticChannelInfo* HapticChannelInfo); + + /** + * Returns the address that corresponds to the nth channel of a specific type. It's unguarded, which means I don't + * check the validity of index - could result in an exception. Optimized piece of code for for loops. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptic Channel Info") + static FString GetAddress_Unguarded(const USGHapticChannelInfo* HapticChannelInfo, + ESGHapticChannelType Type, int32 TypeIndex); + + /** + * Returns the address that corresponds to the nth channel of a specific type. It's unguarded, which means I don't + * check the validity of index - could result in an exception. Optimized piece of code for for loops. + * Used for Internals. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptic Channel Info") + static void GetIpcParams_Unguarded(UPARAM(ref) USGHapticChannelInfo* HapticChannelInfo, + ESGHapticChannelType Type, int32 TypeIndex, + int32& OutIndex, FString& OutAddressString); + + /** + * Regenerate the channel names for a specific device Index in shared memory. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptic Channel Info") + static void RegenerateAddresses(USGHapticChannelInfo* HapticChannelInfo, int32 ForDeviceIndex); + + /** + * Returns an array of all the haptic addresses stored for this info channel. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptic Channel Info") + static TArray GetAllAddresses(const USGHapticChannelInfo* HapticChannelInfo); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGHapticGloveKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGHapticGloveKismetLibrary.h new file mode 100644 index 0000000..f8b7fb2 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGHapticGloveKismetLibrary.h @@ -0,0 +1,321 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * An interface for any of our gloves that can track hand motion and/or send + * force / vibrotactile feedback. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" +#include "SGTypes/SGVectorArray.h" + +#include "SGHapticGloveKismetLibrary.generated.h" + +class USGBasicHandModel; +class USGHandPose; +class USGHandProfile; +class USGHapticGlove; + +/** + * A glove developed by SenseGlove, that has hand tracking and/or haptic feedback functionality. + */ +UCLASS(meta=(ScriptName = "SenseGloveHapticGloveKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGHapticGloveKismetLibrary : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Get all Haptic Gloves detected on this system. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptic Glove", meta=(WorldContext="WorldContextObject")) + static TArray GetHapticGloves(UObject* WorldContextObject, bool bConnectedOnly = true); + + /** + * Get the first Haptic Glove detected on this system. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Glove", Category="SenseGlove | Core | Haptic Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetGlove_OutG(UObject* WorldContextObject, USGHapticGlove*& OutGlove); + + /** + * Get the first left/right Haptic Glove detected on this system. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Glove", Category="SenseGlove | Core | Haptic Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetGlove_bRH_OutG(UObject* WorldContextObject, bool bRightHanded, + USGHapticGlove*& OutGlove); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="To String", Category="SenseGlove | Core | Haptic Glove") + static FString ToString_S(ESGHapticGloveCalibrationState State); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="To String", Category="SenseGlove | Core | Haptic Glove") + static FString ToString_L(ESGHapticLocation Location); + + + /** + * Get the DeviceType enumerator of this device; used to check if its a SenseGlove/Nova/etc. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptic Glove") + static ESGDeviceType GetDeviceType(const USGHapticGlove* HapticGlove); + + /** + * Retrieve this glove's unique identifier. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptic Glove") + static FString GetDeviceId(const USGHapticGlove* HapticGlove); + + /** + * Retrieve this glove's hardware (sub) version. "DK1", "DK2", etc. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptic Glove") + static FString GetHardwareVersion(const USGHapticGlove* HapticGlove); + + /** + * Retrieve this device's main firmware version. v4.12 returns 4. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptic Glove") + static int32 GetFirmwareVersion(const USGHapticGlove* HapticGlove); + + /** + * Retrieve this device's sub firmware version. v4.12 returns 12. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptic Glove") + static int32 GetSubFirmwareVersion(const USGHapticGlove* HapticGlove); + + /** + * Returns true if this glove is made for a right hand. If false, it's a left hand. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptic Glove") + static bool IsRight(const USGHapticGlove* HapticGlove); + + /** + * Retrieve this glove's IMU rotation, if if has any. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Imu Rotation", Category="SenseGlove | Core | Haptic Glove") + static bool GetImuRotation_FQuat_OutI(UPARAM(ref) USGHapticGlove* HapticGlove, FQuat& OutImu); + + /** + * Retrieve this glove's IMU rotation, if if has any. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Imu Rotation", Category="SenseGlove | Core | Haptic Glove") + static bool GetImuRotation_FRotator_OutI(UPARAM(ref) USGHapticGlove* HapticGlove, FRotator& OutImu); + + /** + * Retrieve a HandPose based on the latest profile, but with a specific hand geometry. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Hand Pose", Category="SenseGlove | Core | Haptic Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetHandPose_HG_OutHP(UObject* WorldContextObject, + const USGHapticGlove* HapticGlove, + const USGBasicHandModel* HandGeometry, + USGHandPose*& OutHandPose); + + /** + * Retrieve a HandPose based on the latest profile and default hand Geometry. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Hand Pose", Category="SenseGlove | Core | Haptic Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetHandPose_OutHP(UObject* WorldContextObject, + UPARAM(ref) USGHapticGlove* HapticGlove, + USGHandPose*& OutHandPose); + + /** + * Returns the Hand Angles calculated by this Nova 2 Glove. Used for input for HandPoses, but can be used in and of + * itself. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Imu Rotation", Category="SenseGlove | Core | Haptic Glove") + static bool GetHandAngles(const USGHapticGlove* HapticGlove, TArray& OutHandAngles); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptic Glove", meta=(WorldContext="WorldContextObject")) + static USGBasicHandModel* GetHandGeometry(UObject* WorldContextObject, const USGHapticGlove* HapticGlove); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Imu Rotation", Category="SenseGlove | Core | Haptic Glove") + static void SetHandGeometry(UPARAM(ref) USGHapticGlove* HapticGlove, const USGBasicHandModel* HandGeometry); + + /** + * Returns the HapticGlove's state of calibration for its on-board sensors. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Imu Rotation", Category="SenseGlove | Core | Haptic Glove") + static ESGHapticGloveCalibrationState GetCalibrationState(const USGHapticGlove* HapticGlove); + + /** + * Resets internal calibration of the Haptic Glove. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Imu Rotation", Category="SenseGlove | Core | Haptic Glove") + static void EndCalibration(UPARAM(ref) USGHapticGlove* HapticGlove); + + /** + * Force-End any form of calibration manually, if any is still running. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Imu Rotation", Category="SenseGlove | Core | Haptic Glove") + static void ResetCalibration(UPARAM(ref) USGHapticGlove* HapticGlove); + + /** + * Retrieve the current calibration instruction. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Imu Rotation", Category="SenseGlove | Core | Haptic Glove") + static FString GetCalibrationInstruction(const USGHapticGlove* HapticGlove); + + /** + * Stops all Haptic effects if any are currently playing. Useful at the end of simulations or when resetting. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptic Glove") + static void StopHaptics(UPARAM(ref) USGHapticGlove* HapticGlove); + + /** + * Stops only vibrations. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptic Glove") + static void StopVibrations(UPARAM(ref) USGHapticGlove* HapticGlove); + + /** + * Take all active commands in the device queue, compile them into one and send them to the device. + * + * @return Returns true if the message was successfully sent to SenseCom. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptic Glove") + static bool SendHaptics(UPARAM(ref) USGHapticGlove* HapticGlove); + + /** + * Returns true if the HapticGlove supports vibration feedback on the specified location. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptic Glove") + static bool SupportsCustomWaveform(const USGHapticGlove* HapticGlove, ESGHapticLocation AtLocation); + + /** + * Sends a custom waveform to the location specified, provided that the glove has a motor there, and can support + * custom waveforms. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptic Glove") + static bool SendCustomWaveform(UPARAM(ref) USGHapticGlove* HapticGlove, + USGCustomWaveform* OutWaveform, ESGHapticLocation Location); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + * + * @remarks The simplest interface, using default offsets. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Wrist Location", Category="SenseGlove | Core | Haptic Glove") + static void GetWristLocation_RP_FQuat_RR_TH_OutWP_OutWR( + const USGHapticGlove* HapticGlove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation); + + /** + * Queue a list of force-feedback levels, between 0.0f and 1.0f. Your list should be sorted from thumb to pinky. + * + * @remarks Devices that 'only' have on/off FFB will treat any value > 0.0 as 1.0. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptic Glove") + static bool QueueForceFeedbackLevels(UPARAM(ref) USGHapticGlove* HapticGlove, const TArray& Levels01); + + /** + * Set the Force-Feedback value of a particular finger to a specific level. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptic Glove") + static bool QueueForceFeedbackLevel(UPARAM(ref) USGHapticGlove* HapticGlove, int32 Finger, float Level01); + + /** + * Queue a list of vibration levels, between 0.0 and 1.0. Your list should be sorted from thumb to pinky. + * + * @param Levels01 Array containing the vibration levels, from 0.0 (no vibration) to 1.0. A value < 0.0f will be + * ignored. + * + * @remarks Devices that 'only' have on/off FFB will treat any value > 0.0 as 1.0. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptic Glove") + static bool QueueVibroLevels(UPARAM(ref) USGHapticGlove* HapticGlove, const TArray& Levels01); + + /** + * Queue a command to set the (continuous) vibration level at a specific location to a set amplitude. + * + * @param Location + * @param Level01 Value will be clamped between [0...1], where 0.0f means no vibration, and 1.0 means full + * vibration. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptic Glove") + static bool QueueVibroLevel(UPARAM(ref) USGHapticGlove* HapticGlove, ESGHapticLocation Location, float Level01); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + * + * @remarks The simplest interface, using default offsets. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Wrist Location", Category="SenseGlove | Core | Haptic Glove") + static void GetWristLocation_RP_FRotator_RR_TH_OutWP_OutWR( + const USGHapticGlove* HapticGlove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FRotator& OutWristRotation); + + /** + * Retrieve the location of the glove origin, based on a reference location. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Glove Location", Category="SenseGlove | Core | Haptic Glove") + static void GetGloveLocation_RP_FQuat_RR_TH_OutGP_OutGR( + const USGHapticGlove* HapticGlove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation); + + /** + * Retrieve the location of the glove origin, based on a reference location. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Glove Location", Category="SenseGlove | Core | Haptic Glove") + static void GetGloveLocation_RP_FRotator_RR_TH_OutGP_OutGR( + const USGHapticGlove* HapticGlove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FRotator& OutGloveRotation); + + /** + * Create a String Representation of this Haptic Glove. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptic Glove") + static FString ToString(const USGHapticGlove* HapticGlove); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGInterpolationSetKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGInterpolationSetKismetLibrary.h new file mode 100644 index 0000000..329bad5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGInterpolationSetKismetLibrary.h @@ -0,0 +1,186 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Data class containing all variables to map an input value from one range to + * another. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" + +#include "SGInterpolationSetKismetLibrary.generated.h" + +class USGInterpolationSet; + +/** + * Set of variables to map a value from one range to the next. + */ +UCLASS(meta=(ScriptName = "SenseGloveInterpolationSetKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGInterpolationSetKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Creates a basic interpolation set, without limits. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Interpolation Set", + meta=(WorldContext="WorldContextObject")) + static USGInterpolationSet* MakeInterpolationSet(UObject* WorldContextObject); + + /** + * Create a new interpolation set without limits. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Interpolation Set", + Category="SenseGlove | Core | Kinematics | Interpolation Set", meta=(WorldContext="WorldContextObject")) + static USGInterpolationSet* MakeInterpolationSet_F1_F2_T1_T2( + UObject* WorldContextObject, float From1, float From2, float To1, float To2); + + /** + * Create a new interpolation set with limits. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Interpolation Set", + Category="SenseGlove | Core | Kinematics | Interpolation Set", meta=(WorldContext="WorldContextObject")) + static USGInterpolationSet* MakeInterpolationSet_F1_F2_T1_T2_M_M( + UObject* WorldContextObject, float From1, float From2, float To1, float To2, float Min, float Max); + + /** + * Convert a string notation of an InterpolationSet into a new class instance. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Kinematics | Interpolation Set", + meta=(WorldContext="WorldContextObject")) + static USGInterpolationSet* Deserialize(UObject* WorldContextObject, const FString& SerializedString); + + /** + * First value of input range. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Interpolation Set") + static float GetX0(const USGInterpolationSet* InterpolationSet); + + /** + * + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Interpolation Set") + static void SetX0(UPARAM(ref) USGInterpolationSet* InterpolationSet, float X0); + + /** + * Second value of input range. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Interpolation Set") + float GetX1(const USGInterpolationSet* InterpolationSet); + + /** + * + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Interpolation Set") + static void SetX1(UPARAM(ref) USGInterpolationSet* InterpolationSet, float X1); + + /** + * First value of output range. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Interpolation Set") + static float GetY0(const USGInterpolationSet* InterpolationSet); + + /** + * + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Interpolation Set") + static void SetY0(UPARAM(ref) USGInterpolationSet* InterpolationSet, float Y0); + + /** + * Second value of output range. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Interpolation Set") + static float GetY1(const USGInterpolationSet* InterpolationSet); + + /** + * + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Interpolation Set") + static void SetY1(UPARAM(ref) USGInterpolationSet* InterpolationSet, float Y1); + + /** + * Minimum range of the output value. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Interpolation Set") + static float GetMin(const USGInterpolationSet* InterpolationSet); + + /** + * + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Interpolation Set") + static void SetMin(UPARAM(ref) USGInterpolationSet* InterpolationSet, float Min); + + /** + * Maximum range of the output value. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Interpolation Set") + static float GetMax(const USGInterpolationSet* InterpolationSet); + + /** + * + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Interpolation Set") + static void SetMax(UPARAM(ref) USGInterpolationSet* InterpolationSet, float Max); + + /** + * Calculate an output value in range [x0...x1] to [y0..y1] + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Interpolation Set") + static int32 Get(const USGInterpolationSet* InterpolationSet, float Value, bool bLimit, + bool bNormalizeAngle = false); + + /** + * Returns true if this InterpolationSet has the same values as another set. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Interpolation Set") + static bool Equals(const USGInterpolationSet* A, const USGInterpolationSet* B); + + /** + * + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Kinematics | Interpolation Set") + static FString ToString(const USGInterpolationSet* InterpolationSet); + + /** + * + */ + UFUNCTION(BlueprintPure, DisplayName="To String", Category="SenseGlove | Core | Kinematics | Interpolation Set") + static FString ToString_bL(const USGInterpolationSet* InterpolationSet, bool bLimits); + + /** + * Convert this InterpolationSet into a string notation so it can be stored on disk. + */ + UFUNCTION(BlueprintPure, DisplayName="Serialize", Category="SenseGlove | Core | Kinematics | Interpolation Set") + static FString SGSerialize(const USGInterpolationSet* InterpolationSet); +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGJointKinematicsKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGJointKinematicsKismetLibrary.h new file mode 100644 index 0000000..cbf7382 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGJointKinematicsKismetLibrary.h @@ -0,0 +1,97 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Contains kinematic formulae and wrappers for Sense Glove mathematics. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Math/Quat.h" +#include "Math/Vector.h" + +#include "SGCore/SGBasicHandModel.h" +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" + +#include "SGJointKinematicsKismetLibrary.generated.h" + +/** + * + */ +UCLASS(meta=(ScriptName = "SenseGloveJointKinematicsKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGJointKinematicsKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Perform forward Kinematics on a set of joints, defined by a start position- and rotation, + * joint angles and the lengths in between. Outputs the calculated positions and rotations. + */ + UFUNCTION(BlueprintCallable, DisplayName="Forward Kinematics", + Category="SenseGlove | Core | Kinematics | Joint Kinematics") + static bool ForwardKinematics_SP_FQuat_SR_JL_JA_OutNP_TArrayFQuat_OutNR( + const FVector& StartPosition, const FQuat& StartRotation, + const TArray& JointLengths, const TArray& JointAngles, + TArray& OutNewPositions, TArray& OutNewRotations); + + /** + * Perform forward Kinematics on a set of joints, defined by a start position- and rotation, + * joint angles and the lengths in between. Outputs the calculated positions and rotations. + */ + UFUNCTION(BlueprintCallable, DisplayName="Forward Kinematics", + Category="SenseGlove | Core | Kinematics | Joint Kinematics") + static bool + ForwardKinematics_SP_FRotator_SR_JL_JA_OutNP_TArrayFRotator_OutNR( + const FVector& StartPosition, const FRotator& StartRotation, + const TArray& JointLengths, const TArray& JointAngles, + TArray& OutNewPositions, TArray& OutNewRotations); + + /** + * Calculate positions and rotations of a finger based on input angles and profile. + */ + UFUNCTION(BlueprintCallable, DisplayName="Forward Kinematics", + Category="SenseGlove | Core | Kinematics | Joint Kinematics") + static bool ForwardKinematics_P_F_JA_OutNP_TArrayFQuat_OutNR( + const USGBasicHandModel* Profile, ESGFinger Finger, const TArray& JointAngles, + TArray& OutNewPositions, TArray& OutNewRotations); + + /** + * Calculate positions and rotations of a finger based on input angles and profile. + */ + UFUNCTION(BlueprintCallable, DisplayName="Forward Kinematics", + Category="SenseGlove | Core | Kinematics | Joint Kinematics") + static bool ForwardKinematics_P_F_JA_OutNP_TArrayFRotator_OutNR( + const USGBasicHandModel* Profile, ESGFinger Finger, const TArray& JointAngles, + TArray& OutNewPositions, TArray& OutNewRotations); +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGLibraryKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGLibraryKismetLibrary.h new file mode 100644 index 0000000..8bc1377 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGLibraryKismetLibrary.h @@ -0,0 +1,71 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Information about the SGCore C++ Library. + */ + + +#pragma once + +#include "Containers/UnrealString.h" + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" + +#include "SGLibraryKismetLibrary.generated.h" + +/** + * Provides information about this C++ Library. + */ +UCLASS(meta=(ScriptName = "SenseGloveLibraryKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGLibraryKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * The version of this C++ Library in string representation. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Library") + static FString GetVersion(); + + /** + * Back-End version in string notation. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Library") + static FString GetBackendVersion(); + + /** + * If possible, check what version of SGConnect is paired with this API. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Library") + static FString GetSGConnectVersion(); +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGNova2GloveKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGNova2GloveKismetLibrary.h new file mode 100644 index 0000000..01d97ec --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGNova2GloveKismetLibrary.h @@ -0,0 +1,473 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Interface for Nova 2.0 Gloves. A soft glove with detachable force-feedback + * and sensor module, and active contact feedback in the front strap. + * Since the Nova 2.0 is significantly different from the Nova 1 Glove, it gets + * its own separate device interface. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" +#include "SGTypes/SGVectorArray.h" + +#include "SGNova2GloveKismetLibrary.generated.h" + +class USGBasicHandModel; +class USGDevice; +class USGHandPose; +class USGHandProfile; +class USGNova2Glove; +class USGNova2GloveHandProfile; +class USGNova2GloveSensorData; + +/** + * Interface for Nova 2.0 Gloves. A soft glove with detachable force-feedback and sensor module, and active contact + * feedback in the front strap. + */ +UCLASS(meta=(ScriptName = "SenseGloveNova2GloveKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGNova2GloveKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Deserializes a Nova 2.0 from its ConstantsString. Returns a nullptr if unsuccessful. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova 2 Glove", + meta=(WorldContext="WorldContextObject")) + static USGDevice* Parse(UObject* WorldContextObject, const FString& ConstantsString); + + /** + * Retrieve all Nova 2.0's. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova 2 Glove", + meta=(WorldContext="WorldContextObject")) + static TArray GetNova2Gloves(UObject* WorldContextObject); + + /** + * Retrieve the first connected Nova 2.0 there is. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Nova2 Glove", Category="SenseGlove | Core | Nova | Nova 2 Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetNova2Glove_OutG(UObject* WorldContextObject, USGNova2Glove*& OutGlove); + + /** + * Retrieve the first (connected) right or left handed Nova 2.0. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Nova2 Glove", Category="SenseGlove | Core | Nova | Nova 2 Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetNova2Glove_bRH_OutG(UObject* WorldContextObject, + bool bRightHanded, USGNova2Glove*& OutGlove); + + /** + * Retrieve the location of the glove origin, based on a reference location without requiring an object reference. + */ + UFUNCTION(BlueprintCallable, DisplayName="Calculate Glove Location", + Category="SenseGlove | Core | Nova | Nova 2 Glove") + static void CalculateGloveLocation_RP_FQuat_RR_TH_bRH_HW_OutGP_OutGR( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, const FString& HardwareVersion, + FVector& OutGlovePosition, FQuat& OutGloveRotation); + + /** + * Retrieve the location of the glove origin, based on a reference location without requiring an object reference. + */ + UFUNCTION(BlueprintCallable, DisplayName="Calculate Glove Location", + Category="SenseGlove | Core | Nova | Nova 2 Glove") + static void CalculateGloveLocation_RP_FRotator_RR_TH_bRH_HW_OutGP_OutGR( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, const FString& HardwareVersion, + FVector& OutGlovePosition, FRotator& OutGloveRotation); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets, without + * needing an object reference. + * + * @remarks The simplest interface, using default offsets. + */ + UFUNCTION(BlueprintCallable, DisplayName="Calculate Wrist Location", + Category="SenseGlove | Core | Nova | Nova 2 Glove") + static void CalculateWristLocation_RP_FQuat_RR_TH_bRH_HW_OutWP_OutWR( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, const FString& HardwareVersion, + FVector& OutWristPosition, FQuat& OutWristRotation); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets, without + * needing an object reference. + * + * @remarks The simplest interface, using default offsets. + */ + UFUNCTION(BlueprintCallable, DisplayName="Calculate Wrist Location", + Category="SenseGlove | Core | Nova | Nova 2 Glove") + static void CalculateWristLocation_RP_FRotator_RR_TH_bRH_HW_OutWP_OutWR( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, const FString& HardwareVersion, + FVector& OutWristPosition, FRotator& OutWristRotation); + + /** + * Special Byte to identify the command as a Streaming Byte. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static FString GetStreamByte(); + + /** + * Ranges before a Nova 2.0 Sensor is allowed to move. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static TArray GetNova2SensorRanges(); + + /** + * Converts Nova 2.0 Sensor Data into floating point inputs for normalization. + */ + UFUNCTION(BlueprintCallable, DisplayName="To Normalized Values", + Category="SenseGlove | Core | Nova | Nova 2 Glove") + static TArray ToNormalizedValues_SD(const USGNova2GloveSensorData* SensorData); + + /** + * Convert Sensor Data into a series of normalized values. + */ + UFUNCTION(BlueprintCallable, DisplayName="To Normalized Values", + Category="SenseGlove | Core | Nova | Nova 2 Glove", meta=(WorldContext="WorldContextObject")) + static TArray ToNormalizedValues_SD_OutSN( + UObject* WorldContextObject, + const USGNova2GloveSensorData* SensorData, USGSensorNormalization*& OutSensorNormalizer); + + /** + * Calculate Hand Angles for a Nova 2.0 Glove, based on normalized input. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static TArray CalculateHandAngles( + const TArray& NormalizedValues, const USGHandInterpolator* Interpolator, bool bInfluenceIndex); + + /** + * Convert normalized inputs (5-6 sensors) to input for an Interpolator. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static TArray ToNormalizedAngles( + const TArray& NormalizedData, const USGNovaGloveInfo* GloveInfo); + + /** + * Return the DeviceType of this Nova. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static ESGDeviceType GetDeviceType(const USGNova2Glove* Nova2Glove); + + /** + * Returns this device's unique identifier. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static FString GetDeviceId(const USGNova2Glove* Nova2Glove); + + /** + * Access this device's hardware designation. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static FString GetHardwareVersion(const USGNova2Glove* Nova2Glove); + + /** + * Access this device's main firmware version. (ex: v3.2 -> 3). + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static int32 GetFirmwareVersion(const USGNova2Glove* Nova2Glove); + + /** + * Access this device's sub-firmware version. (ex: v3.2 -> 2). + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static int32 GetSubFirmwareVersion(const USGNova2Glove* Nova2Glove); + + /** + * Returns true if this device operates on a battery. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static bool HasBattery(const USGNova2Glove* Nova2Glove); + + /** + * Returns true if this device is currently charging. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static bool IsCharging(UPARAM(ref) USGNova2Glove* Nova2Glove); + + /** + * Returns the device's battery level, as a value between 0 (empty) and 1 (full). + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static bool GetBatteryLevel(UPARAM(ref) USGNova2Glove* Nova2Glove, float& OutBatteryLevel); + + /** + * Returns true if this glove is meant for right hands. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static bool IsRight(const USGNova2Glove* Nova2Glove); + + /** + * Retrieve this glove's latest IMU rotation, if one is present. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Imu Rotation", Category="SenseGlove | Core | Nova | Nova 2 Glove") + static bool GetImuRotation_FQuat_OutI(UPARAM(ref) USGNova2Glove* Nova2Glove, FQuat& OutImu); + + /** + * Retrieve this glove's latest IMU rotation, if one is present. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Imu Rotation", Category="SenseGlove | Core | Nova | Nova 2 Glove") + static bool GetImuRotation_FRotator_OutI(UPARAM(ref) USGNova2Glove* Nova2Glove, FRotator& OutImu); + + /** + * Retrieve a new hand pose using this glove, based on (calibrated) user data. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Hand Pose", Category="SenseGlove | Core | Nova | Nova 2 Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetHandPose(UObject* WorldContextObject, + UPARAM(ref) USGNova2Glove* Nova2Glove, + const USGBasicHandModel* HandModel, + USGHandPose*& OutHandPose); + + /** + * Returns the Hand Angles calculated by this Nova2 Glove. Used for input for HandPoses, but can be used in and of + * itself. + * + * @param OutHandAngles + */ + UFUNCTION(BlueprintPure, DisplayName="Get Hand Pose", Category="SenseGlove | Core | Nova | Nova 2 Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetHandAngles(const USGNova2Glove* Nova2Glove, TArray& OutHandAngles); + + /* + * Retrieve the calibration status of this Nova 2.0 Glove. + */ + UFUNCTION(BlueprintPure, Category="Nova2Glove | Core | Nova | Nova 2 Glove") + static ESGHapticGloveCalibrationState GetCalibrationState(const USGNova2Glove* Nova2Glove); + + /* + * Completes sensor Normalization on the Nova 2.0's end. + */ + UFUNCTION(BlueprintCallable, Category="Nova2Glove | Core | Nova | Nova 2 Glove") + static void EndCalibration(UPARAM(ref) USGNova2Glove* Nova2Glove); + + /* + * Completes sensor Normalization on the Nova 2.0's end. + */ + UFUNCTION(BlueprintCallable, Category="Nova2Glove | Core | Nova | Nova 2 Glove") + static void ResetCalibration(UPARAM(ref) USGNova2Glove* Nova2Glove); + +public: + /* + * Stop all haptic feedback effects playing on this device. + */ + UFUNCTION(BlueprintCallable, Category="Nova2Glove | Core | Nova | Nova 2 Glove") + static void StopHaptics(UPARAM(ref) USGNova2Glove* Nova2Glove); + + /** + * Stop only all vibrotactile feedback. + */ + UFUNCTION(BlueprintCallable, Category="Nova2Glove | Core | Nova | Nova 2 Glove") + static void StopVibrations(UPARAM(ref) USGNova2Glove* Nova2Glove); + + /** + * Flush all streaming haptic effects on the different fingers to the Nova 2.0 Glove. + */ + UFUNCTION(BlueprintCallable, Category="Nova2Glove | Core | SG | Nova 2 Glove") + static bool SendHaptics(UPARAM(ref) USGNova2Glove* Nova2Glove); + + /** + * Returns true if this Glove supports the chosen haptic location. + */ + UFUNCTION(BlueprintPure, Category="Nova2Glove | Core | Nova | Nova 2 Glove") + static bool SupportsCustomWaveform(const USGNova2Glove* Nova2Glove, ESGHapticLocation AtLocation); + + /** + * Send a custom waveform to the Nova 2.0. + */ + UFUNCTION(BlueprintCallable, Category="Nova2Glove | Core | Nova | Nova 2 Glove") + static bool SendCustomWaveform(UPARAM(ref) USGNova2Glove* Nova2Glove, + USGCustomWaveform* OutWaveform, ESGHapticLocation Location); + + /** + * Queue a list of force-feedback levels, between 0.0 and 1.0. Your list should be sorted from thumb to pinky. + * + * @remarks Devices that 'only' have on/off FFB will treat any value > 0.0 as 1.0. + */ + UFUNCTION(BlueprintCallable, Category="Nova2Glove | Core | Nova | Nova 2 Glove") + static bool QueueForceFeedbackLevels(UPARAM(ref) USGNova2Glove* Nova2Glove, const TArray& Levels01); + + /** + * Set the Force-Feedback value of a particular finger to a specific level. + */ + UFUNCTION(BlueprintCallable, Category="Nova2Glove | Core | Nova | Nova 2 Glove") + static bool QueueForceFeedbackLevel(UPARAM(ref) USGNova2Glove* Nova2Glove, int32 Finger, float Level01); + + /** + * Queue a list of vibration levels, between 0.0 and 1.0. Your list should be sorted from thumb to pinky. + * + * @remarks Devices that 'only' have on/off FFB will treat any value > 0.0 as 1.0. + */ + UFUNCTION(BlueprintCallable, Category="Nova2Glove | Core | Nova | Nova 2 Glove") + static bool QueueVibroLevels(UPARAM(ref) USGNova2Glove* Nova2Glove, const TArray& Amplitudes); + + /** + * Queue a command to set the (continuous) vibration level at a specific location to a set amplitude. This is to + * support backwards compatibility for older plugins. Use of Customwaveforms is encouraged. + */ + UFUNCTION(BlueprintCallable, Category="Nova2Glove | Core | Nova | Nova 2 Glove") + static bool QueueVibroLevel(UPARAM(ref) USGNova2Glove* Nova2Glove, ESGHapticLocation Location, float Level01); + + /** + * Retrieve the location of the glove origin, based on a reference location. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Glove Location", Category="SenseGlove | Core | Nova | Nova 2 Glove") + static void GetGloveLocation_RP_FQuat_RR_TH_OutGP_FQuat_OutGR( + const USGNova2Glove* Nova2Glove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation); + + /** + * Retrieve the location of the glove origin, based on a reference location. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Glove Location", Category="SenseGlove | Core | Nova | Nova 2 Glove") + static void GetGloveLocation_RP_FRotator_RR_TH_OutGP_FRotator_OutGR( + const USGNova2Glove* Nova2Glove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FRotator& OutGloveRotation); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Wrist Location", Category="SenseGlove | Core | Nova | Nova 2 Glove") + static void GetWristLocation_RP_FQuat_RR_TH_OutWP_FQuat_OutWR( + const USGNova2Glove* Nova2Glove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Wrist Location", Category="SenseGlove | Core | Nova | Nova 2 Glove") + static void GetWristLocation_RP_FRotator_RR_TH_OutWP_FRotator_OutWR( + const USGNova2Glove* Nova2Glove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FRotator& OutWristRotation); + + /** + * Access DeviceInfo of this Nova. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove", + meta=(WorldContext="WorldContextObject")) + static USGNovaGloveInfo* GetGloveInfo(UObject* WorldContextObject, const USGNova2Glove* Nova2Glove); + + /** + * If true, the Index Finger sensors will influence the tracking of the other fingers. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static bool DoesIndexInfluenceOthers(const USGNova2Glove* Nova2Glove); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static void SetIndexInfluencesOthers(UPARAM(ref) USGNova2Glove* Nova2Glove, bool bInfluenceOthers); + + /** + * If true, this glove's sensor calibration runs on board the device. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static bool SupportsOnBoardNormalization(const USGNova2Glove* Nova2Glove); + + /** + * Get the latest Sensor Data from this Glove. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova 2 Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetSensorData(UObject* WorldContextObject, + UPARAM(ref) USGNova2Glove* Nova2Glove, USGNova2GloveSensorData*& OutSensorData); + + /** + * Returns the normalized Sensor Data of this Nova2 Glove. If no normalization is running on the glove(s), then + * it's done on the PC side. + * + * @param OutNormalizedValues + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static bool GetNormalizedInput(const USGNova2Glove* Nova2Glove, TArray& OutNormalizedValues); + + /** + * Tell the Nova Glove to send Raw Data instead of normalized data. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static bool SendRawData(UPARAM(ref) USGNova2Glove* Nova2Glove); + + /** + * Tell the Nova Glove to send normalized data. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static bool SendNormalizedData(UPARAM(ref) USGNova2Glove* Nova2Glove); + + /** + * Convert a HapticLocation into a Nova 2.0 Motor location. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static ESGNova2VibroMotor ToNovaMotor(const USGNova2Glove* Nova2Glove, ESGHapticLocation Location); + + /** + * Returns the channel index for a particular motor. Can make this as complex as I want for the Nova2 GLove(s). + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static int32 ChannelIndex(const USGNova2Glove* Nova2Glove, ESGNova2VibroMotor Motor); + + /** + * Ensures the waveform that is to be sent to this Nova2 Glove has the appropriate parameters. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static void ValidateWaveform(const USGNova2Glove* Nova2Glove, + USGCustomWaveform* OutWaveform, ESGNova2VibroMotor Motor); + + /** + * Directly sends a custom waveform to the Nova 2.0 Glove motors, as opposed to specifying a Haptic Location. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static bool SendCustomWaveform_Nova2( + UPARAM(ref) USGNova2Glove* Nova2Glove, + USGCustomWaveform* OutWaveform, ESGNova2VibroMotor Motor, bool bValidateWaveform = true); + + /** + * Create a string representation of this device for reporting purposes. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove") + static FString ToString(const USGNova2Glove* Nova2Glove); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGNova2GloveSensorDataKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGNova2GloveSensorDataKismetLibrary.h new file mode 100644 index 0000000..846a35c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGNova2GloveSensorDataKismetLibrary.h @@ -0,0 +1,159 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Sensor Data coming off the Nova2 2.0 Glove. + * Has certain features the Nova2 1.0 Glove does not have, such as multiple + * flexion sensors, normalization states and Active Strap info. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" +#include "SGTypes/SGVectorArray.h" + +#include "SGNova2GloveSensorDataKismetLibrary.generated.h" + +class USGNovaGloveInfo; +class USGNova2GloveSensorData; + +/** + * Nova Glove 2.0 Sensor data, which had additional feedback and calibration parameters. + */ +UCLASS(meta=(ScriptName = "SenseGloveNova2GloveSensorDataKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGNova2GloveSensorDataKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Default constructor for Nova2GloveSensorData. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova 2 Glove Sensor Data", + meta=(WorldContext="WorldContextObject")) + static USGNova2GloveSensorData* MakeNova2GloveSensorData(UObject* WorldContextObject); + + /** + * Create a new instance of a Nova2GloveSensorData. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Nova2 Glove Sensor Data", + Category="SenseGlove | Core | Nova | Nova 2 Glove Sensor Data", meta=(WorldContext="WorldContextObject")) + static USGNova2GloveSensorData* MakeNova2GloveSensorData_NS_V_PV_FQuat_IR_bIP_BL_bC( + UObject* WorldContextObject, ESGNormalizationState NormalizationState, + const TArray& Values, int32 ParsedValues, + const FQuat& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + + /** + * Create a new instance of a Nova2GloveSensorData. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Nova2 Glove Sensor Data", + Category="SenseGlove | Core | Nova | Nova 2 Glove Sensor Data", meta=(WorldContext="WorldContextObject")) + static USGNova2GloveSensorData* MakeNova2GloveSensorData_NS_V_PV_FRotator_IR_bIP_BL_b( + UObject* WorldContextObject, ESGNormalizationState NormalizationState, + const TArray& Values, int32 ParsedValues, + const FRotator& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + + /** + * Parse the bytes as they come in from the device into usable values. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova 2 Glove Sensor Data", + meta=(WorldContext="WorldContextObject")) + static USGNova2GloveSensorData* Parse(UObject* WorldContextObject, + const FString& RawData, const USGNovaGloveInfo* GloveInfo); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove Sensor Data") + static ESGNormalizationState GetSensorState(const USGNova2GloveSensorData* Nova2GloveSensorData); + + /** + * Pronation/Supination, Flexion/Extension and Abduction/Adduction values for each finger. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove Sensor Data") + static TArray GetSensorValues(const USGNova2GloveSensorData* Nova2GloveSensorData); + + /** + * Returns the sensor movement of a specific finger. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove Sensor Data") + static float GetSensorValue(const USGNova2GloveSensorData* Nova2GloveSensorData, + ESGFinger Finger, ESGNova2SensorLocation Location); + + /** + * The number of values that were parsed from the sensor string. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove Sensor Data") + static int32 GetParsedValues(const USGNova2GloveSensorData* Nova2GloveSensorData); + + /** + * Quaternion rotation relative to magnetic north. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Imu Rotation", + Category="SenseGlove | Core | Nova | Nova 2 Glove Sensor Data") + static FQuat GetImuRotation_FQuat(const USGNova2GloveSensorData* Nova2GloveSensorData); + + /** + * Rotation relative to magnetic north. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Imu Rotation", + Category="SenseGlove | Core | Nova | Nova 2 Glove Sensor Data") + static FRotator GetImuRotation_FRotator(const USGNova2GloveSensorData* Nova2GloveSensorData); + + /** + * Whether the IMU values were all successfully parsed, or not. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove Sensor Data") + static bool IsImuParsed(const USGNova2GloveSensorData* Nova2GloveSensorData); + + /** + * A value between 0..1 that represents the battery level of this Nova2 Glove (0 .. 100%). Returns -1 if the value + * wasn't received. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove Sensor Data") + static float GetBatteryLevel(const USGNova2GloveSensorData* Nova2GloveSensorData); + + /** + * Returns true if this NovaGlove is connected to a power source. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove Sensor Data") + static bool IsCharging(const USGNova2GloveSensorData* Nova2GloveSensorData); + + /** + * Returns true if this sensor data contains the same values as another. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove Sensor Data") + static bool Equals(const USGNova2GloveSensorData* A, const USGNova2GloveSensorData* B); + + /** + * Create a readable string representation of this Sensor Data. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova 2 Glove Sensor Data") + static FString ToString(const USGNova2GloveSensorData* Nova2GloveSensorData); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGNovaGloveInfoKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGNovaGloveInfoKismetLibrary.h new file mode 100644 index 0000000..35b2938 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGNovaGloveInfoKismetLibrary.h @@ -0,0 +1,163 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Contains information on Nova's hardware, extracted from the device. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" + +#include "SGNovaGloveInfoKismetLibrary.generated.h" + +class USGNovaGloveInfo; + +/** + * Device information extracted from a Nova Glove. + */ +UCLASS(meta=(ScriptName = "SenseGloveNovaGloveInfoKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGNovaGloveInfoKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * The default constructor. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove Info", + meta=(WorldContext="WorldContextObject")) + static USGNovaGloveInfo* MakeNovaGloveInfo(UObject* WorldContextObject); + + /** + * Create a new instance of a NovaGloveInfo. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Nova Glove Info", + Category="SenseGlove | Core | Nova | Nova Glove Info", meta=(WorldContext="WorldContextObject")) + static USGNovaGloveInfo* MakeNovaGloveInfo_DI_HV_FV_SFV_bRH_IC_NOS( + UObject* WorldContextObject, + const FString& DeviceId, const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion, + bool bRightHanded, const FQuat& ImuCorrection, int32 NumberOfSensors); + + /** + * Parse a constants string into a NovaGloveInfo class. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove Info", + meta=(WorldContext="WorldContextObject")) + static bool Parse(UObject* WorldContextObject, const FString& ConstantsString, USGNovaGloveInfo*& OutGloveInfo); + + /** + * Convert a string representation back into a NovaGloveInfo class. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove Info", + meta=(WorldContext="WorldContextObject")) + static USGNovaGloveInfo* Deserialize(UObject* WorldContextObject, const FString& SerializedString); + + /** + * Unique identifier of this device. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Info") + static FString GetDeviceId(const USGNovaGloveInfo* NovaGloveInfo); + + /** + * Hardware (sub) version of this Sense Glove Device. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Info") + static FString GetHardwareVersion(const USGNovaGloveInfo* NovaGloveInfo); + + /** + * Firmware version running on the device's MicroController. (as v4.12, this is the 4). + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Info") + static int32 GetFirmwareVersion(const USGNovaGloveInfo* NovaGloveInfo); + + /** + * Sub firmware version running on the device's microcontroller (as v4.12, this is the .12). + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Info") + static int32 GetSubFirmwareVersion(const USGNovaGloveInfo* NovaGloveInfo); + + /** + * Determines if this is a right-handed Nova. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Info") + static bool IsRight(const USGNovaGloveInfo* NovaGloveInfo); + + /** + * The IMU correction of this Nova. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Imu Correction", Category="SenseGlove | Core | Nova | Nova Glove Info") + static FQuat GetImuCorrection_FQuat(const USGNovaGloveInfo* NovaGloveInfo); + + /** + * The IMU correction of this Nova. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Imu Correction", Category="SenseGlove | Core | Nova | Nova Glove Info") + static FRotator GetImuCorrection_FRotator(const USGNovaGloveInfo* NovaGloveInfo); + + /** + * The number of sensors in this device. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Info") + static int32 GetNumberOfSensors(const USGNovaGloveInfo* NovaGloveInfo); + + /** + * Returns true if this glove's firmware is newer than certain version. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Info") + bool FirmwareNewerThan(const USGNovaGloveInfo* NovaGloveInfo, + int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const; + + /** + * Returns true if this glove's firmware is older than certain version. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Info") + bool FirmwareOlderThan(const USGNovaGloveInfo* NovaGloveInfo, + int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const; + + /** + * Returns true if this GloveInfo contains the same information as another. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Info") + static bool Equals(const USGNovaGloveInfo* A, const USGNovaGloveInfo* B); + + /** + * Create a string representation of this Glove Info. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Info") + static FString ToString(const USGNovaGloveInfo* NovaGloveInfo); + + /** + * Convert this class into a string representation so it can be unpacked later. + */ + UFUNCTION(BlueprintPure, DisplayName="Serialize", Category="SenseGlove | Core | Nova | Nova Glove Info") + static FString SGSerialize(const USGNovaGloveInfo* NovaGloveInfo); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGNovaGloveKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGNovaGloveKismetLibrary.h new file mode 100644 index 0000000..0c9207a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGNovaGloveKismetLibrary.h @@ -0,0 +1,514 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 NovaGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * An interface for the "Nova" - a soft glove. + * Contains methods for Kinematics, Haptics and Serialization. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" +#include "SGTypes/SGVectorArray.h" + +#include "SGNovaGloveKismetLibrary.generated.h" + +class USGBasicHandModel; +class USGDevice; +class USGHandPose; +class USGHandProfile; +class USGNovaGlove; +class USGNovaGloveHandProfile; +class USGNovaGloveSensorData; + +/** + * A soft glove with Force- and Vibrotactile Feedback and limited tracking. + */ +UCLASS(meta=(ScriptName = "SenseGloveNovaGloveKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGNovaGloveKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Deserializes a Nova from its ConstantsString. Returns a nullptr if unsuccessful. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove", + meta=(WorldContext="WorldContextObject")) + static USGDevice* Parse(UObject* WorldContextObject, const FString& ConstantsString); + + /** + * Retrieve all Nova's. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove", + meta=(WorldContext="WorldContextObject")) + static TArray GetNovaGloves(UObject* WorldContextObject); + + /** + * Retrieve the first connected Nova there is. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Nova Glove", Category="SenseGlove | Core | Nova | Nova Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetNovaGlove_OutG(UObject* WorldContextObject, USGNovaGlove*& OutGlove); + + /** + * Retrieve the first (connected) right or left handed Nova. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Nova Glove", Category="SenseGlove | Core | Nova | Nova Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetNovaGlove_bRH_OutG(UObject* WorldContextObject, + bool bRightHanded, USGNovaGlove*& OutGlove); + + /** + * Retrieve the location of the glove origin, based on a reference location without requiring an object reference. + */ + UFUNCTION(BlueprintCallable, DisplayName="Calculate Glove Location", + Category="SenseGlove | Core | Nova | Nova Glove") + static void CalculateGloveLocation_RP_FQuat_RR_TH_bRH_OutGP_OutGR( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, + FVector& OutGlovePosition, FQuat& OutGloveRotation); + + /** + * Retrieve the location of the glove origin, based on a reference location without requiring an object reference. + */ + UFUNCTION(BlueprintCallable, DisplayName="Calculate Glove Location", + Category="SenseGlove | Core | Nova | Nova Glove") + static void CalculateGloveLocation_RP_FRotator_RR_TH_bRH_OutGP_OutGR( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, + FVector& OutGlovePosition, FRotator& OutGloveRotation); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets, without + * needing an object reference. + * + * @remarks The simplest interface, using default offsets. + */ + UFUNCTION(BlueprintCallable, DisplayName="Calculate Wrist Location", + Category="SenseGlove | Core | Nova | Nova Glove") + static void CalculateWristLocation_RP_FQuat_RR_TH_bRH_OutWP_OutWR( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, + FVector& OutWristPosition, FQuat& OutWristRotation); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets, without + * needing an object reference. + * + * @remarks The simplest interface, using default offsets. + */ + UFUNCTION(BlueprintCallable, DisplayName="Calculate Wrist Location", + Category="SenseGlove | Core | Nova | Nova Glove") + static void CalculateWristLocation_RP_FRotator_RR_TH_bRH_OutWP_OutWR( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, + FVector& OutWristPosition, FRotator& OutWristRotation); + + /** + * Byte indicating a new Nova haptic command. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static FString GetHapticsByte(); + + /** + * Byte indicating a new Nova thresholds command. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static FString GetThresholdsByte(); + + /** + * Byte to ignore Thresholds. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static FString GetIgnoreThresholdsByte(); + + /** + * Ranges before a Nova 1.0 Sensor is allowed to move. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static TArray GetNovaSensorRanges(); + + /** + * Converts Nova Sensor Data into floating point inputs for normalization. + */ + UFUNCTION(BlueprintCallable, DisplayName="To Normalized Values", Category="SenseGlove | Core | Nova | Nova Glove") + static TArray ToNormalizedValues_SD(const USGNovaGloveSensorData* SensorData); + + /** + * Convert Sensor Data into a series of normalized values. + */ + UFUNCTION(BlueprintCallable, DisplayName="To Normalized Values", Category="SenseGlove | Core | Nova | Nova Glove", + meta=(WorldContext="WorldContextObject")) + static TArray ToNormalizedValues_SD_OutSN( + UObject* WorldContextObject, + const USGNovaGloveSensorData* SensorData, USGSensorNormalization*& OutSensorNormalizer); + + /** + * Calculate Hand Angles for a Nova Glove, based on normalized input. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static TArray CalculateHandAngles( + const TArray& NormalizedValues, const USGHandInterpolator* Interpolator); + + /** + * Converts a Threshold command into a Nova Glove command. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static FString ToNovaCommandAsFlexion(const USGThresholdCommand* Thresholds); + + /** + * Converts a Threshold command into a Nova Glove command. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static FString ToNovaCommandAsRaw( + const USGThresholdCommand* Thresholds, const USGSensorNormalization* Interpolator); + + /** + * Return the DeviceType of this Nova. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove") + static ESGDeviceType GetDeviceType(const USGNovaGlove* NovaGlove); + + /** + * Returns this device's unique identifier. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove") + static FString GetDeviceId(const USGNovaGlove* NovaGlove); + + /** + * Access this device's hardware designation. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove") + static FString GetHardwareVersion(const USGNovaGlove* NovaGlove); + + /** + * Access this device's main firmware version. (ex: v3.2 -> 3). + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove") + static int32 GetFirmwareVersion(const USGNovaGlove* NovaGlove); + + /** + * Access this device's sub-firmware version. (ex: v3.2 -> 2). + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove") + static int32 GetSubFirmwareVersion(const USGNovaGlove* NovaGlove); + + /** + * Change this device's index within the SenseCom. Warning: Can cause errors. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static void SetDeviceIndex(UPARAM(ref) USGNovaGlove* NovaGlove, int32 NewIndex); + + /** + * Returns true if this device operates on a battery. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove") + static bool HasBattery(const USGNovaGlove* NovaGlove); + + /** + * Returns true if this device is currently charging. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static bool IsCharging(UPARAM(ref) USGNovaGlove* NovaGlove); + + /** + * Returns the device's battery level, as a value between 0 (empty) and 1 (full). + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static bool GetBatteryLevel(UPARAM(ref) USGNovaGlove* NovaGlove, float& OutBatteryLevel); + + /** + * Returns true if this glove is meant for right hands. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove") + static bool IsRight(const USGNovaGlove* NovaGlove); + + /** + * Retrieve Nova rotation. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Imu Rotation", Category="SenseGlove | Core | Nova | Nova Glove") + static bool GetImuRotation_FQuat_OutI(UPARAM(ref) USGNovaGlove* NovaGlove, FQuat& OutImu); + + /** + * Retrieve Nova rotation. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Imu Rotation", Category="SenseGlove | Core | Nova | Nova Glove") + static bool GetImuRotation_FRotator_OutI(UPARAM(ref) USGNovaGlove* NovaGlove, FRotator& OutImu); + + /** + * Retrieve a new hand pose using this glove, based on (calibrated) user data. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Hand Pose", Category="SenseGlove | Core | Nova | Nova Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetHandPose(UObject* WorldContextObject, + UPARAM(ref) USGNovaGlove* NovaGlove, + const USGBasicHandModel* HandModel, + USGHandPose*& OutHandPose); + + /** + * Returns the Hand Angles calculated by this Nova Glove. Used for input for HandPoses, but can be used in and of + * itself. + * + * @param OutHandAngles + */ + UFUNCTION(BlueprintPure, DisplayName="Get Hand Pose", Category="SenseGlove | Core | Nova | Nova Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetHandAngles(const USGNovaGlove* NovaGlove, TArray& OutHandAngles); + + /* + * Retrieve the calibration status of this Nova Glove. + */ + UFUNCTION(BlueprintPure, Category="NovaGlove | Core | Nova | Nova Glove") + static ESGHapticGloveCalibrationState GetCalibrationState(const USGNovaGlove* NovaGlove); + + /* + * Completes sensor Normalization on the Nova's end. + */ + UFUNCTION(BlueprintCallable, Category="NovaGlove | Core | Nova | Nova Glove") + static void EndCalibration(UPARAM(ref) USGNovaGlove* NovaGlove); + + /* + * Completes sensor Normalization on the Nova's end. + */ + UFUNCTION(BlueprintCallable, Category="NovaGlove | Core | Nova | Nova Glove") + static void ResetCalibration(UPARAM(ref) USGNovaGlove* NovaGlove); + +public: + /* + * Stop all haptic feedback effects playing on this device. + */ + UFUNCTION(BlueprintCallable, Category="NovaGlove | Core | Nova | Nova Glove") + static void StopHaptics(UPARAM(ref) USGNovaGlove* NovaGlove); + + /** + * Stop only all vibrotactile feedback. + */ + UFUNCTION(BlueprintCallable, Category="NovaGlove | Core | Nova | Nova Glove") + static void StopVibrations(UPARAM(ref) USGNovaGlove* NovaGlove); + + /** + * Take all active commands in the device queue, compile them into one and send them to the device. + * + * @returns Returns true if the message was successfully sent to SenseCom. Returns false if no changes to commands + * were detected. + * + * @remarks Generic function across any Haptic Interface in SGCore. + */ + UFUNCTION(BlueprintCallable, Category="NovaGlove | Core | SG | Nova Glove") + static bool SendHaptics(UPARAM(ref) USGNovaGlove* NovaGlove); + + /** + * Returns true if this Glove supports the chosen haptic location. + */ + UFUNCTION(BlueprintPure, Category="NovaGlove | Core | Nova | Nova Glove") + static bool SupportsCustomWaveform(const USGNovaGlove* NovaGlove, ESGHapticLocation AtLocation); + + /** + * Send a custom waveform to the Nova. + */ + UFUNCTION(BlueprintCallable, Category="NovaGlove | Core | Nova | Nova Glove") + static bool SendCustomWaveform(UPARAM(ref) USGNovaGlove* NovaGlove, + USGCustomWaveform* OutWaveform, ESGHapticLocation Location); + + /** + * Queue a list of force-feedback levels, between 0.0 and 1.0. Your list should be sorted from thumb to pinky. + * + * @remarks Devices that 'only' have on/off FFB will treat any value > 0.0 as 1.0. + */ + UFUNCTION(BlueprintCallable, Category="NovaGlove | Core | Nova | Nova Glove") + static bool QueueForceFeedbackLevels(UPARAM(ref) USGNovaGlove* NovaGlove, const TArray& Levels01); + + /** + * Set the Force-Feedback value of a particular finger to a specific level. + */ + UFUNCTION(BlueprintCallable, Category="NovaGlove | Core | Nova | Nova Glove") + static bool QueueForceFeedbackLevel(UPARAM(ref) USGNovaGlove* NovaGlove, int32 Finger, float Level01); + + /** + * Queue a vibrotactile level for each finger. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static bool QueueVibroLevels(UPARAM(ref) USGNovaGlove* NovaGlove, const TArray& Amplitudes); + + /** + * Queue a command to set the (continuous) vibration level at a specific location to a set amplitude. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static bool QueueVibroLevel_L_L(UPARAM(ref) USGNovaGlove* NovaGlove, ESGHapticLocation Location, float Level01); + + /** + * Retrieve the location of the glove origin, based on a reference location. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Glove Location", Category="SenseGlove | Core | Nova | Nova Glove") + static void GetGloveLocation_RP_FQuat_RR_TH_OutGP_FQuat_OutGR( + const USGNovaGlove* NovaGlove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation); + + /** + * Retrieve the location of the glove origin, based on a reference location. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Glove Location", Category="SenseGlove | Core | Nova | Nova Glove") + static void GetGloveLocation_RP_FRotator_RR_TH_OutGP_FRotator_OutGR( + const USGNovaGlove* NovaGlove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FRotator& OutGloveRotation); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Wrist Location", Category="SenseGlove | Core | Nova | Nova Glove") + static void GetWristLocation_RP_FQuat_RR_TH_OutWP_FQuat_OutWR( + const USGNovaGlove* NovaGlove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Wrist Location", Category="SenseGlove | Core | Nova | Nova Glove") + static void GetWristLocation_RP_FRotator_RR_TH_OutWP_FRotator_OutWR( + const USGNovaGlove* NovaGlove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FRotator& OutWristRotation); + + /** + * Access all sorts of device info specific to this Nova. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove", meta=(WorldContext="WorldContextObject")) + static USGNovaGloveInfo* GetGloveInfo(UObject* WorldContextObject, const USGNovaGlove* NovaGlove); + + /** + * If true, this Nova Glove supports sending special firmware commands to lock brakes at specific sensor values. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove") + static bool SupportsThresholds(const USGNovaGlove* NovaGlove); + + /** + * If true, this Nova Glove supports sending custom 'fire-and-forget' waveforms. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove") + static bool SupportsCustomWaveforms(const USGNovaGlove* NovaGlove); + + /** + * If true, this glove's sensor calibration runs on board the device. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove") + static bool SupportsOnBoardNormalization(const USGNovaGlove* NovaGlove); + + /** + * Get the latest Sensor Data from this Glove. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetSensorData(UObject* WorldContextObject, + UPARAM(ref) USGNovaGlove* NovaGlove, USGNovaGloveSensorData*& OutSensorData); + + /** + * Converts a set of commands into a series of bytes (string) this glove can understand. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove") + static FString ToNovaCommand( + const USGNovaGlove* NovaGlove, + const TArray& ForceFeedbackLevels, const TArray& BuzzLevels, float WristLevel); + + /** + * Queue a vibrotactle level for a specific finger. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static bool QueueVibroLevel_F_A(UPARAM(ref) USGNovaGlove* NovaGlove, int32 Finger, float Amplitude); + + /** + * Queue a command to the vibration amplitude of a general wrist actuator to a set level. + * + * @returns Returns true if the wrist command has been successfully queued. If false, the device might not support + * direct wrist control or have the appropriate firmware. + * + * @remarks This one isn't contained in an interface as it's not used outside of the NovaGlove class. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static bool QueueWristLevel(UPARAM(ref) USGNovaGlove* NovaGlove, float Amplitude); + + /** + * Convert a HapticLocation into a Nova Motor location. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove") + static ESGNovaVibroMotor ToNovaMotor(const USGNovaGlove* NovaGlove, ESGHapticLocation Location); + + /** + * Returns the channel index for a particular motor. Can make this as complex as I want for the Nova GLove(s). + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove") + static int32 ChannelIndex(const USGNovaGlove* NovaGlove, ESGNovaVibroMotor Motor); + + /** + * Ensures the waveform that is to be sent to this Nova Glove has the appropriate parameters. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static void ValidateWaveform(const USGNovaGlove* NovaGlove, + USGCustomWaveform* OutWaveform, ESGNovaVibroMotor Motor); + + /** + * Directly sends a custom waveform to the Nova Glove motors, as opposed to specifying a Haptic Location. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static bool SendCustomWaveform_Nova( + UPARAM(ref) USGNovaGlove* NovaGlove, + USGCustomWaveform* OutWaveform, ESGNovaVibroMotor Motor, bool bValidateWaveform = true); + + /** + * Stops the glove when flexing pas this point. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static bool QueueThresholdCommand_Flexion(UPARAM(ref) USGNovaGlove* NovaGlove, + int32 Finger, float FlexionThreshold); + + /** + * Queue a command to clear the threshold for a specific finger. + * + * @returns Returns true if the command was queued. If false, the device does not have the required firmware for + * these commands. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove") + static bool QueueClearThreshold(UPARAM(ref) USGNovaGlove* NovaGlove, int32 Finger); + + /** + * Create a string representation of this device for reporting purposes. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove") + static FString ToString(const USGNovaGlove* NovaGlove); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGNovaGloveSensorDataKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGNovaGloveSensorDataKismetLibrary.h new file mode 100644 index 0000000..9b7b663 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGNovaGloveSensorDataKismetLibrary.h @@ -0,0 +1,171 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Nova SensorData, parsed from rae string representations. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" + +#include "SGNovaGloveSensorDataKismetLibrary.generated.h" + +class USGNovaGloveInfo; +class USGNovaGloveSensorData; + +/** + * Sensor Data coming from a Nova, converted into useful values. + */ +UCLASS(meta=(ScriptName = "SenseGloveNovaGloveSensorDataKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGNovaGloveSensorDataKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Default constructor for NovaGloveSensorData. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove Sensor Data", + meta=(WorldContext="WorldContextObject")) + static USGNovaGloveSensorData* MakeNovaGloveSensorData(UObject* WorldContextObject); + + /** + * Create a new instance of a NovaGloveSensorData. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Nova Glove Sensor Data", + Category="SenseGlove | Core | Nova | Nova Glove Sensor Data", meta=(WorldContext="WorldContextObject")) + static USGNovaGloveSensorData* MakeNovaGloveSensorData_V_PV_FQuat_IR_bIP_BL_bC( + UObject* WorldContextObject, const TArray& Values, int32 ParsedValues, + const FQuat& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + + /** + * Create a new instance of a NovaGloveSensorData. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Nova Glove Sensor Data", + Category="SenseGlove | Core | Nova | Nova Glove Sensor Data", meta=(WorldContext="WorldContextObject")) + static USGNovaGloveSensorData* MakeNovaGloveSensorData_V_PV_FRotator_IR_bIP_BL_b( + UObject* WorldContextObject, const TArray& Values, int32 ParsedValues, + const FRotator& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging); + + /** + * Returns a NovaGloveSensorData without any values. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove Sensor Data", + meta=(WorldContext="WorldContextObject")) + static USGNovaGloveSensorData* Empty(UObject* WorldContextObject); + + /** + * Parse the bytes as they come in from the device into usable values. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove Sensor Data", + meta=(WorldContext="WorldContextObject")) + static USGNovaGloveSensorData* Parse(UObject* WorldContextObject, + const FString& RawData, const USGNovaGloveInfo* GloveInfo); + + /** + * Convert this sensor data into ta string representation. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Nova | Nova Glove Sensor Data", + meta=(WorldContext="WorldContextObject")) + static USGNovaGloveSensorData* Deserialize(UObject* WorldContextObject, const FString& SerializedString); + + /** + * Pronation/Supination, Flexion/Extension and Abduction/Adduction values for each finger. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Sensor Data") + static TArray GetSensorValues(const USGNovaGloveSensorData* NovaGloveSensorData); + + /** + * Returns the sensor movement of a specific finger. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Sensor Data") + static float GetSensorValue(const USGNovaGloveSensorData* NovaGloveSensorData, + ESGFinger Finger, ESGNovaSensorLocation Location); + + /** + * The number of values that were parsed from the sensor string. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Sensor Data") + static int32 GetParsedValues(const USGNovaGloveSensorData* NovaGloveSensorData); + + /** + * Quaternion rotation relative to magnetic north. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Imu Rotation", + Category="SenseGlove | Core | Nova | Nova Glove Sensor Data") + static FQuat GetImuRotation_FQuat(const USGNovaGloveSensorData* NovaGloveSensorData); + + /** + * Rotation relative to magnetic north. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Imu Rotation", + Category="SenseGlove | Core | Nova | Nova Glove Sensor Data") + static FRotator GetImuRotation_FRotator(const USGNovaGloveSensorData* NovaGloveSensorData); + + /** + * Whether the IMU values were all successfully parsed, or not. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Sensor Data") + static bool IsImuParsed(const USGNovaGloveSensorData* NovaGloveSensorData); + + /** + * A value between 0..1 that represents the battery level of this Nova Glove (0 .. 100%). Returns -1 if the value + * wasn't received. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Sensor Data") + static float GetBatteryLevel(const USGNovaGloveSensorData* NovaGloveSensorData); + + /** + * Returns true if this NovaGlove is connected to a power source. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Sensor Data") + static bool IsCharging(const USGNovaGloveSensorData* NovaGloveSensorData); + + /** + * Returns true if this sensor data contains the same values as another. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Sensor Data") + static bool Equals(const USGNovaGloveSensorData* A, const USGNovaGloveSensorData* B); + + /** + * Create a readable string representation of this Sensor Data. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Nova | Nova Glove Sensor Data") + static FString ToString(const USGNovaGloveSensorData* NovaGloveSensorData); + + /** + * Convert this sensor data into a string so it can be stored on disk. + */ + UFUNCTION(BlueprintPure, DisplayName="Serialize", Category="SenseGlove | Core | Nova | Nova Glove Sensor Data") + static FString SGSerialize(const USGNovaGloveSensorData* NovaGloveSensorData); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseComKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseComKismetLibrary.h new file mode 100644 index 0000000..39a5a4b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseComKismetLibrary.h @@ -0,0 +1,90 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "HAL/Platform.h" + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGVectorArray.h" + +#include "SGSenseComKismetLibrary.generated.h" + +/** + * + */ +UCLASS(meta=(ScriptName = "SenseGloveSenseComKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGSenseComKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Registers current process as the latest SenseCom build. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SenseCom") + static bool RegisterExe(); + + /** + * Register a particular path as the SenseGlove executable location. + */ + UFUNCTION(BlueprintCallable, DisplayName="Register Exe", Category="SenseGlove | Core | SenseCom") + static bool RegisterExe_EP(const FString& ExePath); + + /** + * Retrieve the location of SenseGlove executable. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SenseCom") + static bool GetExePath(FString& OutExePath); + + /** + * Returns true if SenseCom scanning is active. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SenseCom") + static bool ScanningActive(); + + /** + * Returns the directory of the current process. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SenseCom") + static bool GetCurrentExeDirectory(FString& OutDirectory); + + /** + * Force-starts the SenseCom application if it is active on the system. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SenseCom") + static bool StartupSenseCom(); +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGloveInfoKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGloveInfoKismetLibrary.h new file mode 100644 index 0000000..08b39e1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGloveInfoKismetLibrary.h @@ -0,0 +1,235 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Glove information taken from the Sense Glove. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" +#include "SGTypes/SGFloatArray.h" +#include "SGTypes/SGVectorArray.h" + +#include "SGSenseGloveInfoKismetLibrary.generated.h" + +class USGSenseGloveInfo; + +/** + * Glove Information taken from a SenseGlove. Contains everything from unique ID, firmware version, etc. + */ +UCLASS(meta=(ScriptName = "SenseGloveSenseGloveInfoKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGSenseGloveInfoKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * The default constructor. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove Info", + meta=(WorldContext="WorldContextObject")) + static USGSenseGloveInfo* MakeSenseGloveInfo(UObject* WorldContextObject); + + /** + * Create a new Sense Glove device model. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Sense Glove Info", + Category="SenseGlove | Core | SG | Sense Glove Info", meta=(WorldContext="WorldContextObject")) + static USGSenseGloveInfo* MakeSenseGloveInfo_DI_HV_FV_SFV_bRH_NOS_FQuat_IC_SP_TArrayFQuat_SR_GL_F( + UObject* WorldContextObject, const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion, + bool bRightHanded, int32 NumberOfSensors, const FQuat& ImuCorrection, + const TArray& StartPositions, const TArray& StartRotations, + const TArray& GloveLengths, const TArray& Functions); + + /** + * Create a new Sense Glove device model. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Sense Glove Info", + Category="SenseGlove | Core | SG | Sense Glove Info", meta=(WorldContext="WorldContextObject")) + static USGSenseGloveInfo* MakeSenseGloveInfo_DI_HV_FV_SFV_bRH_NOS_FRotator_IC_SP_TArrayFRotator_SR_GL_F( + UObject* WorldContextObject, const FString& DeviceId, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion, + bool bRightHanded, int32 NumberOfSensors, const FRotator& ImuCorrection, + const TArray& StartPositions, const TArray& StartRotations, + const TArray& GloveLengths, const TArray& Functions); + + /** + * Create an instance of the SGModel from its string representation. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove Info", + meta=(WorldContext="WorldContextObject")) + static bool Parse(UObject* WorldContextObject, + const FString& ConstantsString, USGSenseGloveInfo*& OutGloveInfo, + bool bUpdateOldModels = true); + + /** + * Deserialize a HandProfile back into usable values. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove Info", + meta=(WorldContext="WorldContextObject")) + static USGSenseGloveInfo* Deserialize(UObject* WorldContextObject, const FString& SerializedString); + + /** + * Unique identifier of this device. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Info") + static FString GetDeviceId(const USGSenseGloveInfo* SenseGloveInfo); + + /** + * Hardware (sub) version of this Sense Glove Device. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Info") + static FString GetHardwareVersion(const USGSenseGloveInfo* SenseGloveInfo); + + /** + * Firmware version running on the device's MicroController. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Info") + static int32 GetFirmwareVersion(const USGSenseGloveInfo* SenseGloveInfo); + + /** + * Sub-Firmware version running on the device's MicroController. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Info") + static int32 GetSubFirmwareVersion(const USGSenseGloveInfo* SenseGloveInfo); + + /** + * Check if this Sense Glove belongs to a left or right hand. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Info") + static bool IsRight(const USGSenseGloveInfo* SenseGloveInfo); + + /** + * The number of Sensors in this SenseGlove. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Info") + static int32 GetNumberOfSensors(const USGSenseGloveInfo* SenseGloveInfo); + + /** + * The IMU correction of this Sense Glove. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Imu Correction", Category="SenseGlove | Core | SG | Sense Glove Info") + static FQuat GetImuCorrection_FQuat(const USGSenseGloveInfo* SenseGloveInfo); + + /** + * The IMU correction of this Sense Glove. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Imu Correction", Category="SenseGlove | Core | SG | Sense Glove Info") + static FRotator GetImuCorrection_FRotator(const USGSenseGloveInfo* SenseGloveInfo); + + /** + * The starting positions of each Sense Glove finger, relative to the glove origin. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Info") + static TArray GetStartPositions(const USGSenseGloveInfo* SenseGloveInfo); + + /** + * The starting rotations of each Sense Glove finger, relative to the glove origin. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Start Rotations", Category="SenseGlove | Core | SG | Sense Glove Info") + static TArray GetStartRotations_TArrayFQuat(const USGSenseGloveInfo* SenseGloveInfo); + + /** + * The starting rotations of each Sense Glove finger, relative to the glove origin. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Start Rotations", Category="SenseGlove | Core | SG | Sense Glove Info") + static TArray GetStartRotations_TArrayFRotator(const USGSenseGloveInfo* SenseGloveInfo); + + /** + * The lengths of each Sense Glove finger section, in cm. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Info") + static TArray GetGloveLengths(const USGSenseGloveInfo* SenseGloveInfo); + + /** + * Whether this device has a specific function (T/F). + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Info") + static TArray GetFunctions(const USGSenseGloveInfo* SenseGloveInfo); + + /** + * The starting position of one Sense Glove finger, relative to the glove origin. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Info") + static FVector GetStartPosition(const USGSenseGloveInfo* SenseGloveInfo, ESGFinger Finger); + + /** + * The starting rotation of one Sense Glove finger, relative to the glove origin. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Start Rotation", Category="SenseGlove | Core | SG | Sense Glove Info") + static FQuat GetStartRotation_FQuat(const USGSenseGloveInfo* SenseGloveInfo, ESGFinger Finger); + + /** + * The starting rotation of one Sense Glove finger, relative to the glove origin. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Start Rotation", Category="SenseGlove | Core | SG | Sense Glove Info") + static FRotator GetStartRotation_FRotator(const USGSenseGloveInfo* SenseGloveInfo, ESGFinger Finger); + + /** + * The lengths of one Sense Glove finger's sections, in cm. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Glove Lengths", Category="SenseGlove | Core | SG | Sense Glove Info") + static TArray GetGloveLengths_F(const USGSenseGloveInfo* SenseGloveInfo, ESGFinger Finger); + + /** + * Place incoming sensor data into the right format, according to this glove's model. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Info") + static TArray ToGloveAngles(const USGSenseGloveInfo* SenseGloveInfo, + const TArray& SensorAngles); + + /** + * Returns true if this SG_Model has the same values as another. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Info") + static bool Equals(const USGSenseGloveInfo* A, const USGSenseGloveInfo* B); + + /** + * Create a string representation for fast logging. + */ + UFUNCTION(BlueprintPure, DisplayName="To String", Category="SenseGlove | Core | SG | Sense Glove Info") + static FString ToString_bSN(const USGSenseGloveInfo* SenseGloveInfo, bool bShortNotation); + + /** + * Create a string representation for logging. If shortNotation is false, all values are reported. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Info") + static FString ToString(const USGSenseGloveInfo* SenseGloveInfo); + + /** + * Serialize this HandProfile into a string representation. + */ + UFUNCTION(BlueprintPure, DisplayName="Serialize", Category="SenseGlove | Core | SG | Sense Glove Info") + static FString SGSerialize(const USGSenseGloveInfo* SenseGloveInfo); +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGloveKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGloveKismetLibrary.h new file mode 100644 index 0000000..69993e2 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGloveKismetLibrary.h @@ -0,0 +1,484 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * An interface for the Sense Glove exoskeleton glove. + * Contains methods for Kinematics, Haptics and Serialization. + */ + + +#pragma once + +#include "SGCore/SGHandPose.h" +#include "SGCore/SGSenseGlove.h" +#include "SGCore/SGSenseGlovePose.h" +#include "SGCore/SGSenseGloveSensorData.h" +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGVectorArray.h" + +#include "SGSenseGloveKismetLibrary.generated.h" + +class USGDevice; +class USGHandInterpolator; +class USGHandPose; +class USGSenseGlove; +class USGSenseGloveSensorNormalizer; + +/** + * Interface for the Sense Glove; and exoskeleton Force-Feedback glove. + */ +UCLASS(meta=(ScriptName = "SenseGloveSenseGloveKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGSenseGloveKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Deserializes a Sense Glove from its ConstantsString. Returns a nullptr if unsuccessful. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove", + meta=(WorldContext="WorldContextObject")) + static USGDevice* Parse(UObject* WorldContextObject, const FString& ConstantsString); + + /** + * Retrieve all Sense Gloves connected to this system. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove", + meta=(WorldContext="WorldContextObject")) + static TArray GetSenseGloves(UObject* WorldContextObject); + + /** + * Retrieve the first connected Sense Glove there is. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Sense Glove", Category="SenseGlove | Core | SG | Sense Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetSenseGlove_OutG(UObject* WorldContextObject, USGSenseGlove*& OutGlove); + + /** + * Retrieve the first (connected) right or left handed sense glove. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Sense Glove", Category="SenseGlove | Core | SG | Sense Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetSenseGlove_bRH_OutG(UObject* WorldContextObject, bool bRightHanded, USGSenseGlove*& OutGlove); + + /** + * Retrieve the location of the glove origin, based on a reference location without requiring an object reference. + */ + UFUNCTION(BlueprintCallable, DisplayName="Calculate Glove Location", + Category="SenseGlove | Core | SG | Sense Glove") + static void CalculateGloveLocation_RP_FQuat_RR_TH_bRH_MO_OutGP_FQuat_OutGR( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, ESGFinger MountedOn, + FVector& OutGlovePosition, FQuat& OutGloveRotation); + + /** + * Retrieve the location of the glove origin, based on a reference location without requiring an object reference. + */ + UFUNCTION(BlueprintCallable, DisplayName="Calculate Glove Location", + Category="SenseGlove | Core | SG | Sense Glove") + static void CalculateGloveLocation_RP_FRotator_RR_TH_bRH_MO_OutGP_FRotator_OutGR( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, ESGFinger MountedOn, + FVector& OutGlovePosition, FRotator& OutGloveRotation); + + /** + * Calculates the full wrist location. + */ + UFUNCTION(BlueprintCallable, DisplayName="Calculate Wrist Location", + Category="SenseGlove | Core | SG | Sense Glove") + static void CalculateWristLocation_RP_FQuat_RR_TH_bRH_MO_GWPOffset_FQuat_GWRO_OutWP_FQuat_OutWR( + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, ESGFinger MountedOn, + const FVector& GloveWristPositionOffset, const FQuat& GloveWristRotationOffset, + FVector& OutWristPosition, FQuat& OutWristRotation); + + /** + * Calculates the full wrist location. + */ + UFUNCTION(BlueprintCallable, DisplayName="Calculate Wrist Location", + Category="SenseGlove | Core | SG | Sense Glove") + static void CalculateWristLocation_RP_FRotator_RR_TH_bRH_MO_GWPOffset_FRotator_GWRO_OutWP_FRotator_OutWR( + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, ESGFinger MountedOn, + const FVector& GloveWristPositionOffset, const FRotator& GloveWristRotationOffset, + FVector& OutWristPosition, FRotator& OutWristRotation); + + /** + * Byte indicating a new Sense Glove haptic command. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove") + static FString GetHapticsByte(); + + /** + * Byte indicating a new Thumper command. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove") + static FString GetThumperByte(); + + /** + * Default offset from thimble to fingertip. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove") + static FVector GetDefaultThimbleOffset(); + + /** + * Calculates a GlovePose based on sensor angles and a glove model. + * + * @remarks Use this when you already have gloveAngles collected. + */ + UFUNCTION(BlueprintCallable, DisplayName="Calculate Glove Pose", Category="SenseGlove | Core | SG | Sense Glove", + meta=(WorldContext="WorldContextObject")) + static USGSenseGlovePose* CalculateGlovePose_SD_GM( + UObject* WorldContextObject, + const USGSenseGloveSensorData* SensorData, const USGSenseGloveInfo* GloveModel); + + /** + * Calculates a GlovePose based on gloveAngles and a glove model. + * + * @remarks Use this when you already have gloveAngles collected. + */ + UFUNCTION(BlueprintCallable, DisplayName="Calculate Glove Pose", Category="SenseGlove | Core | SG | Sense Glove", + meta=(WorldContext="WorldContextObject")) + static USGSenseGlovePose* CalculateGlovePose_GA_GM( + UObject* WorldContextObject, + const TArray& GloveAngles, const USGSenseGloveInfo* GloveModel); + + /** + * Returns normalized flexions and abductions. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove") + static void NormalizeValues(const TArray& SumAngles, + const USGSenseGloveSensorNormalizer* Normalizer, + TArray& OutFlexions, TArray& OutAbductions); + + /** + * Calculate Hand Angles from a GlovePose and relevant normalizers. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove") + static void CalculateHandAngles( + const USGSenseGlovePose* GlovePose, + const USGSenseGloveSensorNormalizer* Normalizer, const USGHandInterpolator* NormalizedToAngles, + TArray& OutHandAngles); + + /** + * Calculate a HandPose based on a glovePose and a solver. + * + * @remarks Use this when you already have a GlovePose. + */ + UFUNCTION(BlueprintCallable, DisplayName="Calculate Glove Pose", Category="SenseGlove | Core | SG | Sense Glove", + meta=(WorldContext="WorldContextObject")) + static void CalculateHandPose( + UObject* WorldContextObject, + const USGSenseGlovePose* GlovePose, const USGBasicHandModel* HandModel, + const USGSenseGloveSensorNormalizer* Normalizer, const USGHandInterpolator* NormalizedToAngles, + USGHandPose*& OutHandPose); + + /** + * Get the DeviceType enumerator of this SenseGlove, used in DeviceList enumeration. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove") + static ESGDeviceType GetDeviceType(const USGSenseGlove* SenseGlove); + + /** + * Retrieve this Sense Glove's unique identifier. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove") + static FString GetDeviceId(const USGSenseGlove* SenseGlove); + + /** + * Retrieve this glove's hardware (sub) version. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove") + static FString GetHardwareVersion(const USGSenseGlove* SenseGlove); + + /** + * Retrieve this device's firmware version. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove") + static int32 GetFirmwareVersion(const USGSenseGlove* SenseGlove); + + /** + * Retrieve this device's sub-firmware version. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove") + static int32 GetSubFirmwareVersion(const USGSenseGlove* SenseGlove); + + /** + * Check if this Sense Glove is right handed. + * + * @remarks While the variable is stored in SG_GloveModel, added direct access here since its frequently used. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove") + static bool IsRight(const USGSenseGlove* SenseGlove); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Imu Rotation", Category="SenseGlove | Core | SG | Sense Glove") + static bool GetImuRotation_FQuat_OutI(UPARAM(ref) USGSenseGlove* SenseGlove, FQuat& OutImu); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Imu Rotation", Category="SenseGlove | Core | SG | Sense Glove") + static bool GetImuRotation_FRotator_OutI(UPARAM(ref) USGSenseGlove* SenseGlove, FRotator& OutImu); + + /** + * Retrieve a new hand pose using this glove's data, based on (calibrated) user data. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetHandPose(UObject* WorldContextObject, + UPARAM(ref) USGSenseGlove* SenseGlove, + const USGBasicHandModel* HandModel, + USGHandPose*& OutHandPose); + + /** + * Returns the Hand Angles calculated by this Sense Glove. Used for input for HandPoses, but can be used in and of + * itself. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove") + static bool GetHandAngles(const USGSenseGlove* SenseGlove, TArray& OutHandAngles); + + /* + * Retrieve the calibration status of this Sense Glove. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove") + static ESGHapticGloveCalibrationState GetCalibrationState(const USGSenseGlove* SenseGlove); + + /* + * Completes sensor Normalization on the Glove's end. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove") + static void EndCalibration(UPARAM(ref) USGSenseGlove* SenseGlove); + + /* + * Completes sensor Normalization on the Glove's end. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove") + static void ResetCalibration(UPARAM(ref) USGSenseGlove* SenseGlove); + +public: + /* + * Stop all haptic feedback effects playing on this device. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove") + static void StopHaptics(UPARAM(ref) USGSenseGlove* SenseGlove); + + /** + * Stop only all vibrotactile feedback. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove") + static void StopVibrations(UPARAM(ref) USGSenseGlove* SenseGlove); + + /** + * Flush all streaming haptic effects on the different fingers to the Glove. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove") + static bool SendHaptics(UPARAM(ref) USGSenseGlove* SenseGlove); + + /** + * Set the Force-Feedback value of a particular finger to a specific level. + * + * @remarks Devices that 'only' have on/off FFB will treat any value > 0.0 as 1.0. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove") + static bool QueueForceFeedbackLevels(UPARAM(ref) USGSenseGlove* SenseGlove, const TArray& Levels01); + + /** + * Queue a list of force-feedback levels, between 0.0 and 1.0. Your list should be sorted from thumb to pinky. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove") + static bool QueueForceFeedbackLevel(UPARAM(ref) USGSenseGlove* SenseGlove, int32 Finger, float Level01); + + /** + * Queue a vibrotactile level for each finger. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove") + static bool QueueVibroLevels(UPARAM(ref) USGSenseGlove* SenseGlove, const TArray& Amplitudes); + + /** + * Queue a command to set the (continuous) vibration level at a specific location to a set amplitude. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove") + static bool QueueVibroLevel_L_L(UPARAM(ref) USGSenseGlove* SenseGlove, ESGHapticLocation Location, float Level01); + + /** + * Retrieve the location of the glove origin, based on a reference location. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Glove Location", Category="SenseGlove | Core | SG | Sense Glove") + static void GetGloveLocation_RP_FQuat_RR_TH_OutGP_FQuat_OutGR( + const USGSenseGlove* SenseGlove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FQuat& OutGloveRotation); + + /** + * Retrieve the location of the glove origin, based on a reference location. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Glove Location", Category="SenseGlove | Core | SG | Sense Glove") + static void GetGloveLocation_RP_FRotator_RR_TH_OutGP_FRotator_OutGR( + const USGSenseGlove* SenseGlove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutGlovePosition, FRotator& OutGloveRotation); + + /** + * Retrieve the location of the glove origin, based on a reference location. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Glove Location", Category="SenseGlove | Core | SG | Sense Glove") + static void GetGloveLocation_RP_FQuat_RR_TH_MO_OutGP_FQuat_OutGR( + const USGSenseGlove* SenseGlove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, ESGFinger MountedOn, + FVector& OutGlovePosition, FQuat& OutGloveRotation); + + /** + * Retrieve the location of the glove origin, based on a reference location. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Glove Location", Category="SenseGlove | Core | SG | Sense Glove") + static void GetGloveLocation_RP_FRotator_RR_TH_MO_OutGP_FRotator_OutGR( + const USGSenseGlove* SenseGlove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, ESGFinger MountedOn, + FVector& OutGlovePosition, FRotator& OutGloveRotation); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Wrist Location", Category="SenseGlove | Core | SG | Sense Glove") + static void GetWristLocation_RP_FQuat_RR_TH_OutWP_FQuat_OutWR( + const USGSenseGlove* SenseGlove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FQuat& OutWristRotation); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Wrist Location", Category="SenseGlove | Core | SG | Sense Glove") + static void GetWristLocation_RP_FRotator_RR_TH_OutWP_FRotator_OutWR( + const USGSenseGlove* SenseGlove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + FVector& OutWristPosition, FRotator& OutWristRotation); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Wrist Location", Category="SenseGlove | Core | SG | Sense Glove") + static void GetWristLocation_RP_FQuat_RR_TH_GWPO_FQuat_GWRO_OutWP_FQuat_OutWR( + const USGSenseGlove* SenseGlove, + const FVector& ReferencePosition, const FQuat& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + const FVector& GloveWristPositionOffset, + const FQuat& GloveWristRotationOffset, + FVector& OutWristPosition, FQuat& OutWristRotation); + + /** + * Retrieve the location of the wrist, based on a reference location and default glove-hand offsets. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Wrist Location", Category="SenseGlove | Core | SG | Sense Glove") + static void GetWristLocation_RP_FRotator_RR_TH_GWPO_FRotator_GWRO_OutWP_FRotator_OutWR( + const USGSenseGlove* SenseGlove, + const FVector& ReferencePosition, const FRotator& ReferenceRotation, + ESGPositionalTrackingHardware TrackingHardware, + const FVector& GloveWristPositionOffset, + const FRotator& GloveWristRotationOffset, + FVector& OutWristPosition, FRotator& OutWristRotation); + + /** + * Retrieve this glove's hardware model, which contains its hardware data. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove", meta=(WorldContext="WorldContextObject")) + static USGSenseGloveInfo* GetGloveInfo(UObject* WorldContextObject, const USGSenseGlove* SenseGlove); + + /** + * Offset from thimble to fingertip, used for Inverse Kinematics. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove") + static TArray GetFingerThimbleOffsets(const USGSenseGlove* SenseGlove); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove") + static void SetFingerThimbleOffset(UPARAM(ref) USGSenseGlove* SenseGlove, int32 Finger, const FVector& Offset); + + /** + * + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove") + static bool SupportsWristActuator(const USGSenseGlove* SenseGlove); + + /** + * Get the latest Sensor Data from this Sense Glove. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove", meta=(WorldContext="WorldContextObject")) + static bool GetSensorData(UObject* WorldContextObject, + const USGSenseGlove* SenseGlove, USGSenseGloveSensorData*& OutSensorData); + + /** + * Get the pose of this Sense Glove's hardware, based on its latest Sensor Data. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Glove Pose", Category="SenseGlove | Core | SG | Sense Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetGlovePose_OutGP(UObject* WorldContextObject, + UPARAM(ref) USGSenseGlove* SenseGlove, + USGSenseGlovePose*& OutGlovePose); + + /** + * Get the pose of this Sense Glove's hardware based on a set of Sensor Data. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Glove Pose", Category="SenseGlove | Core | SG | Sense Glove", + meta=(WorldContext="WorldContextObject")) + static bool GetGlovePose_SD_OutGP(UObject* WorldContextObject, + UPARAM(ref) USGSenseGlove* SenseGlove, + const USGSenseGloveSensorData* SensorData, + USGSenseGlovePose*& OutGlovePose); + + /** + * Queue a vibrotactle level for a specific finger. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove") + static bool QueueVibroLevel_F_A(UPARAM(ref) USGSenseGlove* SenseGlove, int32 Finger, float Amplitude); + + /** + * Queue a command for the SenseGlove Thumper actuator. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove") + static bool QueueThumperCommand(UPARAM(ref) USGSenseGlove* SenseGlove, ESGSenseGloveThumperCommand Command); + + /** + * Create a string representation of this device for reporting purposes. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove") + static FString ToString(const USGSenseGlove* SenseGlove); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGlovePoseKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGlovePoseKismetLibrary.h new file mode 100644 index 0000000..cc45de7 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGlovePoseKismetLibrary.h @@ -0,0 +1,181 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Contains position and rotation data of a SenseGlove's exoskeleton, along + * with accessors for relevant variables. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGQuatArray.h" +#include "SGTypes/SGRotatorArray.h" +#include "SGTypes/SGVectorArray.h" + +#include "SGSenseGlovePoseKismetLibrary.generated.h" + +class USGSenseGloveInfo; +class USGSenseGlovePose; + +/** + * Represents a pose of a Sense Glove exoskeleton. + */ +UCLASS(meta=(ScriptName = "SenseGloveSenseGlovePoseKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGSenseGlovePoseKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * The basic constructor. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove Pose", + meta=(WorldContext="WorldContextObject")) + static USGSenseGlovePose* MakeSenseGlovePose(UObject* WorldContextObject); + + /** + * Creates a new instance of a SenseGlovePose. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Sense Glove Pose", + Category="SenseGlove | Core | SG | Sense Glove Pose", meta=(WorldContext="WorldContextObject")) + static USGSenseGlovePose* MakeSenseGlovePose_bRH_JP_TArrayFSGQuatArray_JR_GA( + UObject* WorldContextObject, bool bRightHanded, + const TArray& JointPositions, + const TArray& JointRotations, + const TArray& GloveAngles); + + /** + * Creates a new instance of a SenseGlovePose. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Sense Glove Pose", + Category="SenseGlove | Core | SG | Sense Glove Pose", meta=(WorldContext="WorldContextObject")) + static USGSenseGlovePose* MakeSenseGlovePose_bRH_JP_TArrayFSGRotatorArray_JR_GA( + UObject* WorldContextObject, bool bRightHanded, + const TArray& JointPositions, + const TArray& JointRotations, + const TArray& GloveAngles); + + /** + * Returns an idle pose for the Sense Glove if no data can be found. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove Pose", + meta=(WorldContext="WorldContextObject")) + static USGSenseGlovePose* IdlePose(UObject* WorldContextObject, const USGSenseGloveInfo* GloveInfo); + + /** + * Deserialize a GlovePose back into usable values. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove Pose", + meta=(WorldContext="WorldContextObject")) + static USGSenseGlovePose* Deserialize(UObject* WorldContextObject, const FString& SerializedString); + + /** + * Whether this Glove Pose was created for be a right- or left hand, or not. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Pose") + static bool IsRight(const USGSenseGlovePose* SenseGlovePose); + + /** + * Positions of each glove joint, relative to the Glove's Origin. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Pose") + static TArray GetJointPositions(const USGSenseGlovePose* SenseGlovePose); + + /** + * Quaternion rotation of each glove joint, relative to the Glove Origin. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Joint Rotations", Category="SenseGlove | Core | SG | Sense Glove Pose") + static TArray GetJointRotations_TArrayFSGQuatArray(const USGSenseGlovePose* SenseGlovePose); + + /** + * Rotation of each glove joint, relative to the Glove Origin. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Joint Rotations", Category="SenseGlove | Core | SG | Sense Glove Pose") + static TArray GetJointRotations_TArrayFSGRotatorArray(const USGSenseGlovePose* SenseGlovePose); + + /** + * Glove joint angles in euler notation, relative to the last segment. + * + * @remarks Essentially sensor angles, though placed in their proper xyz notation. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Pose") + static TArray GetGloveAngles(const USGSenseGlovePose* SenseGlovePose); + + /** + * The position of the tip of the 'thimbles', the furthest link on each glove link. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Pose") + static TArray GetThimblePositions(const USGSenseGlovePose* SenseGlovePose); + + /** + * The (quaternion) rotation of the 'thimbles', the furthest link on each link. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Thimble Rotations", Category="SenseGlove | Core | SG | Sense Glove Pose") + static TArray GetThimbleRotations_FQuat(const USGSenseGlovePose* SenseGlovePose); + + /** + * The rotation of the 'thimbles', the furthest link on each link. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Thimble Rotations", Category="SenseGlove | Core | SG | Sense Glove Pose") + static TArray GetThimbleRotations_FRotator(const USGSenseGlovePose* SenseGlovePose); + + /** + * Sum of the Sensor angles in each (xyz) direction. "Total Pronation / Flexion / Abduction". + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Pose") + static TArray GetTotalGloveAngles(const USGSenseGlovePose* SenseGlovePose); + + /** + * Calculate fingertip positions, knowing the offset between thimble and fingertips. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Pose") + static TArray CalculateFingertips(const USGSenseGlovePose* SenseGlovePose, + const TArray& FingerOffsets); + + /** + * Returns true if this glove pose equals another. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Pose") + static bool Equals(const USGSenseGlovePose* A, const USGSenseGlovePose* B); + + /** + * Returns a user-friendly string representation of this GlovePose for reporting. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Pose") + static FString ToString(const USGSenseGlovePose* SenseGlovePose, bool bShortFormat = false); + + /** + * Serialize this GlovePose into a string representation. + */ + UFUNCTION(BlueprintPure, DisplayName="Serialize", Category="SenseGlove | Core | SG | Sense Glove Pose") + static FString SGSerialize(const USGSenseGlovePose* SenseGlovePose); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGloveSensorDataKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGloveSensorDataKismetLibrary.h new file mode 100644 index 0000000..0bd96d4 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGloveSensorDataKismetLibrary.h @@ -0,0 +1,165 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Parsed sensor data coming form a Sense Glove. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" +#include "SGTypes/SGFloatArray.h" + +#include "SGSenseGloveSensorDataKismetLibrary.generated.h" + +class USGSenseGloveInfo; +class USGSenseGloveSensorData; + +/** + * Sense Glove Sensor Data, parsed from a sensor string. + */ +UCLASS(meta=(ScriptName = "SenseGloveSenseGloveSensorDataKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGSenseGloveSensorDataKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * The basic constructor. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove Sensor Data", + meta=(WorldContext="WorldContextObject")) + static USGSenseGloveSensorData* MakeSenseGloveSensorData(UObject* WorldContextObject); + + /** + * Create a new instance of a Sense Glove Sensor Data class. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Sense Glove Sensor Data", + Category="SenseGlove | Core | SG | Sense Glove Sensor Data", meta=(WorldContext="WorldContextObject")) + static USGSenseGloveSensorData* MakeSenseGloveSensorData_SA_FQuatImuRotation_PV_bIP( + UObject* WorldContextObject, + const TArray& SensorAngles, const FQuat& ImuRotation, int32 ParsedValues, bool bImuParsed); + + /** + * Create a new instance of a Sense Glove Sensor Data class. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Sense Glove Sensor Data", + Category="SenseGlove | Core | SG | Sense Glove Sensor Data", meta=(WorldContext="WorldContextObject")) + static USGSenseGloveSensorData* MakeSenseGloveSensorData_SA_FRotatorImuRotation_PV_bIP( + UObject* WorldContextObject, + const TArray& SensorAngles, const FRotator& ImuRotation, int32 ParsedValues, bool bImuParsed); + + /** + * Returns sensor data with no values. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove Sensor Data", + meta=(WorldContext="WorldContextObject")) + static USGSenseGloveSensorData* Empty(UObject* WorldContextObject); + + /** + * Deserialize Sense Glove sensor data from a raw char[] received through IPC. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove Sensor Data", + meta=(WorldContext="WorldContextObject")) + static USGSenseGloveSensorData* Parse(UObject* WorldContextObject, + const FString& RawData, const USGSenseGloveInfo* GloveInfo); + + /** + * Deserialize a HandProfile back into useable values. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove Sensor Data", + meta=(WorldContext="WorldContextObject")) + static USGSenseGloveSensorData* Deserialize(UObject* WorldContextObject, const FString& SerializedString); + + /** + * Glove angles in degrees, sorted by finger, from proximal to distal. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Sensor Data") + static TArray GetSensorAngles(const USGSenseGloveSensorData* SenseGloveSensorData); + + /** + * Get the glove angles of a specific finger segment. + */ + UFUNCTION(BlueprintPure, DisplayName="Get Sensor Angles", + Category="SenseGlove | Core | SG | Sense Glove Sensor Data") + static TArray GetSensorAngles_F(const USGSenseGloveSensorData* SenseGloveSensorData, ESGFinger Finger); + + /** + * Returns all glove angles in a sequence, without splitting them per finger. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Sensor Data") + static TArray GetAngleSequence(const USGSenseGloveSensorData* SenseGloveSensorData); + + /** + * + */ + UFUNCTION(BlueprintPure, DisplayName="Get Imu Rotation", + Category="SenseGlove | Core | SG | Sense Glove Sensor Data") + static FQuat GetImuRotation_FQuat(const USGSenseGloveSensorData* SenseGloveSensorData); + + /** + * + */ + UFUNCTION(BlueprintPure, DisplayName="Get Imu Rotation", + Category="SenseGlove | Core | SG | Sense Glove Sensor Data") + static FRotator GetImuRotation_FRotator(const USGSenseGloveSensorData* SenseGloveSensorData); + + /** + * Check how many values have been parsed from the Sensor String. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Sensor Data") + static int32 GetParsedValues(const USGSenseGloveSensorData* SenseGloveSensorData); + + /** + * Check if the IMU was properly parsed. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Sensor Data") + static bool IsImuParsed(const USGSenseGloveSensorData* SenseGloveSensorData); + + /** + * Returns true if the values of both data are equal. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Sensor Data") + static bool Equals(const USGSenseGloveSensorData* A, const USGSenseGloveSensorData* B); + + /** + * Retrieve a simple representation of this sensor data for debugging purposes. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Sensor Data") + static FString ToString(const USGSenseGloveSensorData* SenseGloveSensorData); + + /** + * Serialize this HandProfile into a string representation. + */ + UFUNCTION(BlueprintPure, DisplayName="Serialize", Category="SenseGlove | Core | SG | Sense Glove Sensor Data") + static FString SGSerialize(const USGSenseGloveSensorData* SenseGloveSensorData); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGloveSensorNormalizerKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGloveSensorNormalizerKismetLibrary.h new file mode 100644 index 0000000..ec2e3c4 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGloveSensorNormalizerKismetLibrary.h @@ -0,0 +1,84 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Internal class that acts as a sort of 'in between' handProfile. This class + * converts SG Dk1 Angles into 'normalized data' - between 0 .. 1. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" + +#include "SGSenseGloveSensorNormalizerKismetLibrary.generated.h" + +class USGSenseGloveSensorNormalizer; + +/** + * Interface for Nova 2.0 Gloves. A soft glove with detachable force-feedback and sensor module, and active contact + * feedback in the front strap. + */ +UCLASS(meta=(ScriptName = "SenseGloveSenseGloveSensorNormalizerKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGSenseGloveSensorNormalizerKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * The default constructor. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove Sensor Normalizer", + meta=(WorldContext="WorldContextObject")) + static USGSenseGloveSensorNormalizer* MakeSenseGloveSensorNormalizer(UObject* WorldContextObject); + + /** + * Creates a new SenseGlove Sensor Normalizer based off the device's sensor angles. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Sense Glove Sensor Normalizer", + Category="SenseGlove | Core | SG | Sense Glove Sensor Normalizer", meta=(WorldContext="WorldContextObject")) + static USGSenseGloveSensorNormalizer* MakeSenseGloveSensorNormalizer_bRH( + UObject* WorldContextObject, + bool bRightHanded); + + /** + * Normalize a finger's flexion, based on the total flexion of the exoskeleton. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Sensor Normalizer") + static float NormalizeFlexion(const USGSenseGloveSensorNormalizer* SenseGloveSensorNormalizer, + int32 Finger, float SumFlexionAngles); + + /** + * Normalize a finger's abduction, based on the total abduction of the exoskeleton. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | SG | Sense Glove Sensor Normalizer") + static float NormalizeAbduction(const USGSenseGloveSensorNormalizer* SenseGloveSensorNormalizer, + int32 Finger, float SumAbductionAngles); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGloveVarsKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGloveVarsKismetLibrary.h new file mode 100644 index 0000000..ecd0e5c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSenseGloveVarsKismetLibrary.h @@ -0,0 +1,144 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Contains enumerators and classes to aid in Sense Glove Deserialization. + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "HAL/Platform.h" +#include "Math/Quat.h" +#include "Math/Vector.h" + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGVectorArray.h" + +#include "SGSenseGloveVarsKismetLibrary.generated.h" + +class USGSenseGloveInfo; + +/** + * "Database" class containing Sense Glove internal variables. + */ +UCLASS(meta=(ScriptName = "SenseGloveVarsKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGSenseGloveVarsKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Retrieve a basic ConstantsString for a Sense Glove of a specific Hardware Version. Used for debugging / unit tests. + * + * @returns Returns an empty string when an invalid glove version is requested. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove Vars") + static FString GetStandardConstantsString(const FString& HardwareVersion, float FirmwareVersion, bool bRightHanded); + + /** + * Retrieve an example sensor string of a Sense Glove with a particular hardware- and firmware version. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove Vars") + static FString GetSensorString(const FString& HardwareVersion, float FirmwareVersion); + + /** + * Retrieve the starting positions of a particular Sense Glove. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove Vars") + static TArray GetStartPositions(const FString& HardwareVersion, bool bRightHanded); + + /** + * Retrieve the starting rotations of a particular Sense Glove. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Start Rotations", + Category="SenseGlove | Core | SG | Sense Glove Vars") + static TArray GetStartRotations_TArrayFQuat(const FString& HardwareVersion, bool bRightHanded); + + /** + * Retrieve the starting rotations of a particular Sense Glove. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Start Rotations", + Category="SenseGlove | Core | SG | Sense Glove Vars") + static TArray GetStartRotations_TArrayFRotator(const FString& HardwareVersion, bool bRightHanded); + + /** + * Retrieve the glove finger lengths of a particular Sense Glove. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove Vars") + static TArray GetGloveLengths(const FString& HardwareVersion); + + /** + * Get the number of sensors of a SenseGlove. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove Vars") + static int32 GetSensors(const FString& HardwareVersion); + + /** + * Get the default IMUCorrection for the SenseGlove. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Imu Correction", Category="SenseGlove | Core | SG | Sense Glove Vars") + static FQuat GetImuCorrection_FQuat(const FString& HardwareVersion, + int32 FirmwareVersion, int32 SubFirmwareVersion); + + /** + * Get the default IMUCorrection for the SenseGlove. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Imu Correction", Category="SenseGlove | Core | SG | Sense Glove Vars") + static FRotator GetImuCorrection_FRotator(const FString& HardwareVersion, + int32 FirmwareVersion, int32 SubFirmwareVersion); + + /** + * Check all functionality of a SenseGlove. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | SG | Sense Glove Vars") + static TArray GetFunctions(const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion); + + /** + * Generate a custom glove info. + */ + UFUNCTION(BlueprintCallable, DisplayName="GenerateGloveModel", Category="SenseGlove | Core | SG | Sense Glove Vars", + meta=(WorldContext="WorldContextObject")) + static USGSenseGloveInfo* GenerateGloveModel_HV_FV_SFV_bRH( + UObject* WorldContextObject, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion, bool bRightHanded); + + /** + * Generate a custom glove info. + */ + UFUNCTION(BlueprintCallable, DisplayName="GenerateGloveModel", Category="SenseGlove | Core | SG | Sense Glove Vars", + meta=(WorldContext="WorldContextObject")) + static USGSenseGloveInfo* GenerateGloveModel_HV_FV_SFV_bRH_CI( + UObject* WorldContextObject, + const FString& HardwareVersion, int32 FirmwareVersion, int32 SubFirmwareVersion, bool bRightHanded, + const FString& CustomId); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSensorNormalizationKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSensorNormalizationKismetLibrary.h new file mode 100644 index 0000000..9b63a32 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGSensorNormalizationKismetLibrary.h @@ -0,0 +1,141 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * A script to normalize any set of floating point values by looking at their + * minimum and maximum values. Used for automagical calibration. + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" + +#include "SGSensorNormalizationKismetLibrary.generated.h" + +class USGSensorNormalization; + +/** + * Interface for Nova 2.0 Gloves. A soft glove with detachable force-feedback and sensor module, and active contact + * feedback in the front strap. + */ +UCLASS(meta=(ScriptName = "SenseGloveSensorNormalizationKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGSensorNormalizationKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * The default constructor. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Util | Sensor Normalization", + meta=(WorldContext="WorldContextObject")) + static USGSensorNormalization* MakeSensorNormalization(UObject* WorldContextObject); + + /** + * Create a new instance of SensorNormalization. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Sensor Normalization", + Category="SenseGlove | Core | Util | Sensor Normalization", meta=(WorldContext="WorldContextObject")) + static USGSensorNormalization* MakeSensorNormalization_MR( + UObject* WorldContextObject, + const TArray& MovementRanges); + + /** + * If true, the normalization collection is active. If false, we're no longer collecting min / max values. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Util | Sensor Normalization") + static bool CollectsNormalization(const USGSensorNormalization* SensorNormalization); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Util | Sensor Normalization") + static void SetCollectNormalization(UPARAM(ref) USGSensorNormalization* SensorNormalization, + bool bCollectNormalization); + + /** + * The amount of items in this collector Useful for FOR loops. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Util | Sensor Normalization") + static int32 GetLength(const USGSensorNormalization* SensorNormalization); + + /** + * The amount of values that have moved the appropriate amount. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Util | Sensor Normalization") + static int32 GetMoveCount(const USGSensorNormalization* SensorNormalization); + + /** + * Returns true if all sensors are allowed to move. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Util | Sensor Normalization") + static bool AllSensorsMoving(const USGSensorNormalization* SensorNormalization); + + /** + * Reset the normalization of values. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Util | Sensor Normalization") + static void ResetNormalization(UPARAM(ref) USGSensorNormalization* SensorNormalization); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Util | Sensor Normalization") + static void UpdateNormalization(UPARAM(ref) USGSensorNormalization* SensorNormalization, + float Value, int32 Index); + + /** + * Normalize a value on a specific index, and update Normalization while you're at it. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Util | Sensor Normalization") + static float NormalizeValue(UPARAM(ref) USGSensorNormalization* SensorNormalization, + float Value, int32 Index); + + /** + * Update and Normalize a set of values, provided this is the same length. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Util | Sensor Normalization") + static TArray NormalizeValues(UPARAM(ref) USGSensorNormalization* SensorNormalization, + const TArray& Values); + + /** + * Returns true if a sensor on this index has moved enough. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Util | Sensor Normalization") + static bool MovedEnough(const USGSensorNormalization* SensorNormalization, int32 Index); + + /** + * Turn a value from 0 .. 1 back into [minValue ... maxValue] range for the Nova Glove. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Util | Sensor Normalization") + static float Denormalize(const USGSensorNormalization* SensorNormalization, + float Value01, int32 Index, float FallbackValue = 1.0f); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGThresholdCommandKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGThresholdCommandKismetLibrary.h new file mode 100644 index 0000000..e9c8697 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGThresholdCommandKismetLibrary.h @@ -0,0 +1,130 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * Internal class to hold 'Threshold Commands' for specific fingers. Can be sent + * to a Device, or used internally. + * Threshold Commands tell our device "When your sensor data is higher than this + * threshold, lock FFB. Otherwise, turn it back off". + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" + +#include "SGThresholdCommandKismetLibrary.generated.h" + +class USGThresholdCommand; + +/** + * Internal class to hold 'Threshold Commands' for specific fingers. Can be sent to a Device, or used internally. + */ +UCLASS(meta=(ScriptName = "SenseGloveThresholdCommandKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGThresholdCommandKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * The default constructor. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptics | Threshold Command", + meta=(WorldContext="WorldContextObject")) + static USGThresholdCommand* MakeThresholdCommand(UObject* WorldContextObject); + + /** + * Create a new instance of ThresholdCommand. + */ + UFUNCTION(BlueprintCallable, DisplayName="Make Threshold Command", + Category="SenseGlove | Core | Haptics | Threshold Command", meta=(WorldContext="WorldContextObject")) + static USGThresholdCommand* MakeThresholdCommand_AF_TV( + UObject* WorldContextObject, + const TArray& AffectedFingers, const TArray& ThresholdValues); + + /** + * Retrieve the threshold of a particular finger. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptics | Threshold Command", + meta=(WorldContext="WorldContextObject")) + static float GetThreshold(const USGThresholdCommand* ThresholdCommand, int32 Finger); + + /** + * Activates the threshold for a finger at a particular value. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptics | Threshold Command") + static void SetThreshold(UPARAM(ref) USGThresholdCommand* ThresholdCommand, int32 Finger, float ThresholdValue); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptics | Threshold Command", + meta=(WorldContext="WorldContextObject")) + static TArray GetThresholds(const USGThresholdCommand* ThresholdCommand); + + /** + * Activates the threshold for a finger at a particular value. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptics | Threshold Command") + static void SetThresholds(UPARAM(ref) USGThresholdCommand* ThresholdCommand, + const TArray& AffectedFingers, const TArray& ThresholdValues); + + /** + * If true, the threshold on a finger should be active. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptics | Threshold Command", + meta=(WorldContext="WorldContextObject")) + static bool GetFingerActive(const USGThresholdCommand* ThresholdCommand, int32 Finger); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptics | Threshold Command") + static TArray GetActiveFingers(const USGThresholdCommand* ThresholdCommand); + + /** + * Deactivates Threshold Mode for a particular finger. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptics | Threshold Command") + static void ClearThreshold(UPARAM(ref) USGThresholdCommand* ThresholdCommand, int32 Finger); + + /** + * Disables Threshold mode for all fingers. Clears the ActiveFingers, but keeps the Thresholds value for now, in + * case you want to re-apply them later. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Haptics | Threshold Command") + static void ClearThresholds(UPARAM(ref) USGThresholdCommand* ThresholdCommand); + + /** + * Returns true if both values are exactly equal. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptics | Threshold Command") + static bool Equals(const USGThresholdCommand* A, const USGThresholdCommand* B); + + /** + * Print the contents of this Threshold Command. If inactive, a '-' is shown. + */ + UFUNCTION(BlueprintPure, Category="SenseGlove | Core | Haptics | Threshold Command") + static FString ToString(const USGThresholdCommand* ThresholdCommand); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGTrackingKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGTrackingKismetLibrary.h new file mode 100644 index 0000000..5a18719 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/Public/SGCoreKismet/SGTrackingKismetLibrary.h @@ -0,0 +1,753 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Math/Quat.h" +#include "Math/Rotator.h" +#include "Math/Vector.h" + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGCoreTypes.h" + +#include "SGTrackingKismetLibrary.generated.h" + +/** + * + */ +UCLASS(meta=(ScriptName = "SenseGloveTrackingKismetLibrary")) +class SENSEGLOVECOREKISMET_API USGTrackingKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + /** + * Knowing a position & rotation in 3D space, calculate a relative location based on offsets. + */ + UFUNCTION(BlueprintCallable, DisplayName="Calculate Location", Category="SenseGlove | Core | Tracking") + static void CalculateLocation_TP_FQuat_TR_PO_FQuat_RO_OutNP_FQuat_OutNR( + const FVector& TrackedPosition, const FQuat& TrackedRotation, + const FVector& PositionOffset, const FQuat& RotationOffset, + FVector& OutNewPosition, FQuat& OutNewRotation); + + /** + * Knowing a position & rotation in 3D space, calculate a relative location based on offsets. + */ + UFUNCTION(BlueprintCallable, DisplayName="Calculate Location", Category="SenseGlove | Core | Tracking") + static void CalculateLocation_TP_FRotator_TR_PO_FRotator_RO_OutNP_FRotator_OutNR( + const FVector& TrackedPosition, const FRotator& TrackedRotation, + const FVector& PositionOffset, const FRotator& RotationOffset, + FVector& OutNewPosition, FRotator& OutNewRotation); + + /** + * Positional offset from each finger to the glove origin. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static TArray GetSenseGloveFingerToGlovePositionOrigin(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get SenseGlove Finger To Glove Rotation Origin", + Category="SenseGlove | Core | Tracking") + static TArray GetSenseGloveFingerToGloveRotationOrigin_TArrayFQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get SenseGlove Finger To Glove Rotation Origin", + Category="SenseGlove | Core | Tracking") + static TArray GetSenseGloveFingerToGloveRotationOrigin_TArrayFRotator(); + + /** + * Default position offset from glove origin to wrist location, in cm. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetSenseGloveWristPositionOffset(); + + /** + * Default rotation offset from glove origin to wrist location. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get SenseGlove Wrist Rotation Offset", + Category="SenseGlove | Core | Tracking") + static FQuat GetSenseGloveWristRotationOffset_FQuat(); + + /** + * Default rotation offset from glove origin to wrist location. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get SenseGlove Wrist Rotation Offset", + Category="SenseGlove | Core | Tracking") + static FRotator GetSenseGloveWristRotationOffset_FRotator(); + + /** + * Get the position and rotation offsets to go from the glove origin to the mounted position. + * @remarks Based on CAD. needs to be inverted when going from tracker to glove origin. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get SenseGlove Mount Offset", Category="SenseGlove | Core | Tracking") + static void GetSenseGloveMountOffset_bRH_TF_OutIP_FQuat_OutIR( + bool bRightHanded, ESGFinger ToFinger, FVector& OutIPosition, FQuat& OutIRotation); + + /** + * Get the position and rotation offsets to go from the glove origin to the mounted position. + * @remarks Based on CAD. needs to be inverted when going from tracker to glove origin. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get SenseGlove Mount Offset", Category="SenseGlove | Core | Tracking") + static void GetSenseGloveMountOffset_bRH_TF_OutIP_FRotator_OutIR( + bool bRightHanded, ESGFinger ToFinger, FVector& OutIPosition, FRotator& OutIRotation); + + /** + * Get the offset to get from the TrackedHardware to a SenseGlove mounting location. Combined with Glove-Mount + * offset to get the glove location. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get SenseGlove Tracker Mouunt Offset", + Category="SenseGlove | Core | Tracking") + static void GetSenseGloveTrackerMountOffset_H_bRH_OutPO_FQuat_OutRO( + ESGPositionalTrackingHardware Hardware, bool bRightHanded, + FVector& OutPositionOffset, FQuat& OutRotationOffset); + + /** + * Get the offset to get from the TrackedHardware to a SenseGlove mounting location. Combined with Glove-Mount + * offset to get the glove location. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get SenseGlove Tracker Mouunt Offset", + Category="SenseGlove | Core | Tracking") + static void GetSenseGloveTrackerMountOffset_H_bRH_OutPO_FRotator_OutRO( + ESGPositionalTrackingHardware Hardware, bool bRightHanded, + FVector& OutPositionOffset, FRotator& OutRotationOffset); + + /** + * Vive Tracker origin to Finger rotational offset. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetSenseGloveViveToAttachPosition(); + + /** + * Vive Tracker origin to Finger rotational offset. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get SenseGlove Vive To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetSenseGloveViveToAttachRotation_FQuat(); + + /** + * Vive Tracker origin to Finger rotational offset. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get SenseGlove Vive To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetSenseGloveViveToAttachRotation_FRotator(); + + /** + * Oculus Touch origin to Finger rotational offset. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetSenseGloveOculusTouchToAttachPosition(); + + /** + * Oculus Touch origin to Finger rotational offset. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get SenseGlove Oculus Touch To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetSenseGloveOculusTouchToAttachRotation_FQuat(); + + /** + * Oculus Touch origin to Finger rotational offset. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get SenseGlove Oculus Touch To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetSenseGloveOculusTouchToAttachRotation_FRotator(); + + /** + * Positional offset between Nova Glove Origin and Wrist. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetNovaToWristPositionOffset(); + + /** + * Rotational offset between Nova Glove Origin and Wrist. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Nove To Wrist Rotation Offset", + Category="SenseGlove | Core | Tracking") + static FQuat GetNovaToWristRotationOffset_FQuat(); + + /** + * Rotational offset between Nova Glove Origin and Wrist. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Nove To Wrist Rotation Offset", + Category="SenseGlove | Core | Tracking") + static FRotator GetNovaToWristRotationOffset_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetRightNovaViveToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova Vive To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetRightNovaViveToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova Vive To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetRightNovaViveToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetLeftNovaViveToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova Vive To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetLeftNovaViveToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova Vive To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetLeftNovaViveToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetRightNovaQuest2ToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova Quest 2 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetRightNovaQuest2ToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova Quest 2 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetRightNovaQuest2ToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetLeftNovaQuest2ToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova Quest 2 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetLeftNovaQuest2ToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova Quest 2 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetLeftNovaQuest2ToAttachRotation_FRotator(); + + /** + * @remarks Left is a mirror, so we only need R pos. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetRightNovaPico2ToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova Pico 2 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetRightNovaPico2ToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova Pico 2 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetRightNovaPico2ToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova Pico 2 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetLeftNovaPico2ToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova Pico 2 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetLeftNovaPico2ToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetRightNovaQuestProToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova Quest Pro To To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetRightNovaQuestProToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova Quest Pro To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetRightNovaQuestProToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetLeftNovaQuestProToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova Quest Pro To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetLeftNovaQuestProToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova Quest Pro To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetLeftNovaQuestProToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetRightNovaViveFocus3ToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova Vive Focus 3 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetRightNovaViveFocus3ToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova Vive Focus 3 To Attach Rotattion", + Category="SenseGlove | Core | Tracking") + static FRotator GetRightNovaViveFocus3ToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetLeftNovaViveFocus3ToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova Vive Focus 3 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetLeftNovaViveFocus3ToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova Vive Focus 3 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetLeftNovaViveFocus3ToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetRightNovaQuest3ToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova Quest 3 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetRightNovaQuest3ToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova Quest 3 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetRightNovaQuest3ToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetLeftNovaQuest3ToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova Quest 3 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetLeftNovaQuest3ToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova Quest 3 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetLeftNovaQuest3ToAttachRotation_FRotator(); + + /** + * Returns the Offsets that will bring us from the Nova origin to the wrist position. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Nova Glove Wrist Offset", Category="SenseGlove | Core | Tracking") + static void GetNovaGloveWristOffset_bRH_OutPO_FQuat_OutRO( + bool bRightHanded, FVector& OutPositionOffset, FQuat& OutRotationOffset); + + /** + * Returns the Offsets that will bring us from the Nova origin to the wrist position. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Nova Glove Wrist Offset", Category="SenseGlove | Core | Tracking") + static void GetNovaGloveWristOffset_bRH_OutPO_FRotator_OutRO( + bool bRightHanded, FVector& OutPositionOffset, FRotator& OutRotationOffset); + + /** + * Retrieves Offsets for a particular device. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Nova Glove Tracker Offset", Category="SenseGlove | Core | Tracking") + static void GetNovaGloveTrackerOffset_H_bRH_OutPO_FQuat_OutRO( + ESGPositionalTrackingHardware Hardware, bool bRightHanded, + FVector& OutPositionOffset, FQuat& OutRotationOffset); + + /** + * Retrieves Offsets for a particular device. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Nova Glove Tracker Offset", Category="SenseGlove | Core | Tracking") + static void GetNovaGloveTrackerOffset_H_bRH_OutPO_FRotator_OutRO( + ESGPositionalTrackingHardware Hardware, bool bRightHanded, + FVector& OutPositionOffset, FRotator& OutRotationOffset); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetRightNova2ToWristPositionOffset(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova 2 To Wrist Rotation Offset", + Category="SenseGlove | Core | Tracking") + static FQuat GetRightNova2ToWristRotationOffset_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova 2 To Wrist Rotation Offset", + Category="SenseGlove | Core | Tracking") + static FRotator GetRightNova2ToWristRotationOffset_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetLeftNova2ToWristPositionOffset(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova 2 To Wrist Rotation Offset", + Category="SenseGlove | Core | Tracking") + static FQuat GetLeftNova2ToWristRotationOffset_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova 2 To Wrist Rotation Offset", + Category="SenseGlove | Core | Tracking") + static FRotator GetLeftNova2ToWristRotationOffset_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetRightNova2Quest2ToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova 2 Quest 2 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetRightNova2Quest2ToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova 2 Quest 2 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetRightNova2Quest2ToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetLeftNova2Quest2ToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova 2 Quest 2 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetLeftNova2Quest2ToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova 2 Quest 2 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetLeftNova2Quest2ToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetRightNova2QuestProToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova 2 Quest Pro To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetRightNova2QuestProToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova 2 Quest Pro To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetRightNova2QuestProToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetLeftNova2QuestProToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova 2 Quest Pro To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetLeftNova2QuestProToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova 2 Quest Pro To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetLeftNova2QuestProToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetRightNova2ViveTrackerToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova 2 Vive Tracker To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetRightNova2ViveTrackerToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova 2 Vive Tracker To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetRightNova2ViveTrackerToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetLeftNova2ViveTrackerToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova 2 Vive Tracker To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetLeftNova2ViveTrackerToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova 2 Vive Tracker To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetLeftNova2ViveTrackerToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetRightNova2ViveWristTrackerToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova 2 Vive Wrist Tracker To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetRightNova2ViveWristTrackerToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova 2 Vive Wrist Tracker To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetRightNova2ViveWristTrackerToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetLeftNova2ViveWristTrackerToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova 2 Vive Wrist Tracker To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetLeftNova2ViveWristTrackerToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova 2 Vive Wrist Tracker To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetLeftNova2ViveWristTrackerToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetRightNova2Quest3ToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova 2 Quest 3 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetRightNova2Quest3ToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Right Nova 2 Quest 3 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetRightNova2Quest3ToAttachRotation_FRotator(); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FVector GetLeftNova2Quest3ToAttachPosition(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova 2 Quest 3 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FQuat GetLeftNova2Quest3ToAttachRotation_FQuat(); + + /** + * + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Left Nova 2 Quest 3 To Attach Rotation", + Category="SenseGlove | Core | Tracking") + static FRotator GetLeftNova2Quest3ToAttachRotation_FRotator(); + + /** + * Returns the Offsets that will bring us from the Nova origin to the wrist position. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Nova 2 Glove Wrist Offset", Category="SenseGlove | Core | Tracking") + static void GetNova2GloveWristOffset_bRH_HW_OutPO_FQuat_OutRO( + bool bRightHanded, const FString& HardwareVersion, + FVector& OutPositionOffset, FQuat& OutRotationOffset); + + /** + * Returns the Offsets that will bring us from the Nova origin to the wrist position. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Nova 2 Glove Wrist Offset", Category="SenseGlove | Core | Tracking") + static void GetNova2GloveWristOffset_bRH_HW_OutPO_FRotator_OutRO( + bool bRightHanded, const FString& HardwareVersion, + FVector& OutPositionOffset, FRotator& OutRotationOffset); + + /** + * Retrieves Offsets for a particular device. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Nova 2 Glove Tracker Offset", Category="SenseGlove | Core | Tracking") + static void GetNova2GloveTrackerOffset_H_bRH_HW_OutPO_FQuat_OutRO( + ESGPositionalTrackingHardware Hardware, bool bRightHanded, + const FString& HardwareVersion, + FVector& OutPositionOffset, FQuat& OutRotationOffset); + /** + * Retrieves Offsets for a particular device. + */ + UFUNCTION(BlueprintCallable, DisplayName="Get Nova 2 Glove Tracker Offset", Category="SenseGlove | Core | Tracking") + static void GetNova2GloveTrackerOffset_H_bRH_HW_OutPO_FRotator_OutRO( + ESGPositionalTrackingHardware Hardware, bool bRightHanded, + const FString& HardwareVersion, + FVector& OutPositionOffset, FRotator& OutRotationOffset); + + /** + * + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Core | Tracking") + static FString ToString(ESGPositionalTrackingHardware Hardware); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveCoreKismet/SenseGloveCoreKismet.Build.cs b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/SenseGloveCoreKismet.Build.cs new file mode 100644 index 0000000..5387060 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveCoreKismet/SenseGloveCoreKismet.Build.cs @@ -0,0 +1,65 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGloveCoreKismet : ModuleRules +{ + public SenseGloveCoreKismet(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveCore", + "SenseGloveLog", + "SenseGloveKismet", + "SenseGloveTypes", + "SenseGloveUtils", + } + ); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SGDebug/SGDebugCube.cpp b/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SGDebug/SGDebugCube.cpp new file mode 100644 index 0000000..81f5492 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SGDebug/SGDebugCube.cpp @@ -0,0 +1,57 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGDebug/SGDebugCube.h" + +#include "DrawDebugHelpers.h" +#include "Engine/World.h" +#include "Kismet/GameplayStatics.h" +#include "Math/Color.h" +#include "UObject/Object.h" + +void FSGDebugCube::Draw(const UWorld* World, const FVector& Location, const FQuat& Rotation, + const FSGDebugCubeSettings& Settings) +{ + const float LifeTime = UGameplayStatics::GetWorldDeltaSeconds(World) * Settings.LifeTimeModifier; + DrawDebugBox(World, + Location, + Settings.Extent, + Rotation, + Settings.Color, + Settings.bPersistentLines, + LifeTime, + Settings.DepthPriority, + Settings.Thickness); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SGDebug/SGDebugGizmo.cpp b/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SGDebug/SGDebugGizmo.cpp new file mode 100644 index 0000000..733e0b8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SGDebug/SGDebugGizmo.cpp @@ -0,0 +1,60 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGDebug/SGDebugGizmo.h" + +#include "DrawDebugHelpers.h" +#include "Engine/World.h" +#include "Kismet/GameplayStatics.h" +#include "Math/Color.h" +#include "UObject/Object.h" + +void FSGDebugGizmo::Draw(const UWorld* World, const FVector& Location, const FQuat& Rotation, + const FSGDebugGizmoSettings& Settings) +{ + const float LifeTime = UGameplayStatics::GetWorldDeltaSeconds(World) * Settings.LifeTimeModifier; + + const FVector XAxisLineEnd(Location + Rotation.RotateVector(FVector(Settings.Length, 0.0f, 0.0f))); + DrawDebugLine(World, Location, XAxisLineEnd, + Settings.XAxisColor, Settings.bPersistentLines, LifeTime, Settings.DepthPriority, Settings.Thickness); + + const FVector YAxisLineEnd(Location + Rotation.RotateVector(FVector{0.0f, Settings.Length, 0.0f})); + DrawDebugLine(World, Location, YAxisLineEnd, + Settings.YAxisColor, Settings.bPersistentLines, LifeTime, Settings.DepthPriority, Settings.Thickness); + + const FVector ZAxisLineEnd{Location + Rotation.RotateVector(FVector{0.0f, 0.0f, Settings.Length})}; + DrawDebugLine(World, Location, ZAxisLineEnd, + Settings.ZAxisColor, Settings.bPersistentLines, LifeTime, Settings.DepthPriority, Settings.Thickness); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SGDebug/SGDebugVirtualHand.cpp b/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SGDebug/SGDebugVirtualHand.cpp new file mode 100644 index 0000000..acbeb38 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SGDebug/SGDebugVirtualHand.cpp @@ -0,0 +1,107 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGDebug/SGDebugVirtualHand.h" + +#include "DrawDebugHelpers.h" +#include "Engine/World.h" +#include "Kismet/GameplayStatics.h" +#include "Math/Color.h" +#include "UObject/Object.h" + +#include "SGDebug/SGDebugCube.h" +#include "SGDebug/SGDebugGizmo.h" + +void FSGDebugVirtualHand::Draw(const UWorld* World, + const FXRMotionControllerData& MotionControllerData, + const FSGVirtualHandDebuggingSettings& Settings) +{ + ensureAlwaysMsgf(Settings.DrawingMode != ESGDebugVirtualHandDrawingMode::None, + TEXT("Invalid virtual hand drawing mode!")); + + ensureAlwaysMsgf(MotionControllerData.bValid, + TEXT("Invalid motion controller data!")); + + ensureAlwaysMsgf(MotionControllerData.HandKeyPositions.Num() == MotionControllerData.HandKeyRotations.Num(), + TEXT("Mismatched motion controller data positions and rotations!")); + + for (TArray::SizeType HandKeyIndex = 0; + HandKeyIndex < MotionControllerData.HandKeyPositions.Num(); ++HandKeyIndex) + { + const FVector& HandKeyPosition{MotionControllerData.HandKeyPositions[HandKeyIndex]}; + const FQuat& HandKeyRotation{MotionControllerData.HandKeyRotations[HandKeyIndex]}; + + if (Settings.DrawingMode == ESGDebugVirtualHandDrawingMode::CubicJoints) + { + FSGDebugCube::Draw(World, HandKeyPosition, HandKeyRotation, Settings.DebugCubicHandSettings); + } + else if (Settings.DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints) + { + FSGDebugGizmo::Draw(World, HandKeyPosition, HandKeyRotation, Settings.DebugGizmoHandSettings); + } + } +} + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 +void FSGDebugVirtualHand::Draw(const UWorld* World, + const FXRHandTrackingState& HandTrackingState, + const FSGVirtualHandDebuggingSettings& Settings) +{ + ensureAlwaysMsgf(Settings.DrawingMode != ESGDebugVirtualHandDrawingMode::None, + TEXT("Invalid virtual hand drawing mode!")); + + ensureAlwaysMsgf(HandTrackingState.bValid, + TEXT("Invalid hand tracking state!")); + + ensureAlwaysMsgf(HandTrackingState.HandKeyLocations.Num() == HandTrackingState.HandKeyRotations.Num(), + TEXT("Mismatched hand tracking state locations and rotations!")); + + for (TArray::SizeType HandKeyIndex = 0; + HandKeyIndex < HandTrackingState.HandKeyLocations.Num(); ++HandKeyIndex) + { + const FVector& HandKeyLocation{HandTrackingState.HandKeyLocations[HandKeyIndex]}; + const FQuat& HandKeyRotation{HandTrackingState.HandKeyRotations[HandKeyIndex]}; + + if (Settings.DrawingMode == ESGDebugVirtualHandDrawingMode::CubicJoints) + { + FSGDebugCube::Draw(World, HandKeyLocation, HandKeyRotation, Settings.DebugCubicHandSettings); + } + else if (Settings.DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints) + { + FSGDebugGizmo::Draw(World, HandKeyLocation, HandKeyRotation, Settings.DebugGizmoHandSettings); + } + } +} +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SenseGloveDebug.cpp b/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SenseGloveDebug.cpp new file mode 100644 index 0000000..e4577e1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SenseGloveDebug.cpp @@ -0,0 +1,42 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveDebug.h" + +#include "Modules/ModuleManager.h" + +#include "SenseGloveDebugModule.h" + +IMPLEMENT_MODULE(FSenseGloveDebugModule, SenseGloveDebug) diff --git a/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SenseGloveDebug.h b/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SenseGloveDebug.h new file mode 100644 index 0000000..a30ce66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SenseGloveDebug.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SenseGloveDebugModule.cpp b/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SenseGloveDebugModule.cpp new file mode 100644 index 0000000..f3b7ce6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SenseGloveDebugModule.cpp @@ -0,0 +1,62 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveDebugModule.h" + +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveDebugModule" + +void FSenseGloveDebugModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveDebug module..."); +} + +void FSenseGloveDebugModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveDebug module..."); +} + +void FSenseGloveDebugModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveDebug module has succeeded!"); +} + +void FSenseGloveDebugModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveDebug module..."); +} + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SenseGloveDebugModule.h b/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SenseGloveDebugModule.h new file mode 100644 index 0000000..cb983ca --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebug/Private/SenseGloveDebugModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveDebug" + +class FSenseGloveDebugModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveDebug/Public/SGDebug/SGDebugCube.h b/Plugins/SenseGlove/Source/SenseGloveDebug/Public/SGDebug/SGDebugCube.h new file mode 100644 index 0000000..7898472 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebug/Public/SGDebug/SGDebugCube.h @@ -0,0 +1,63 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Math/Rotator.h" +#include "Math/Vector.h" + +#include "SGSettings/SGDebugCubeSettings.h" + +class SENSEGLOVEDEBUG_API FSGDebugCube final +{ +public: + static void Draw( + const UWorld* World, + const FVector& Location, const FQuat& Rotation, + const FSGDebugCubeSettings& Settings); + + static FORCEINLINE void Draw( + const UWorld* World, + const FVector& Location, const FRotator& Rotation, + const FSGDebugCubeSettings& Settings) + { + Draw(World, Location, Rotation.Quaternion(), Settings); + } + +public: + FSGDebugCube() = delete; + virtual ~FSGDebugCube() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveDebug/Public/SGDebug/SGDebugGizmo.h b/Plugins/SenseGlove/Source/SenseGloveDebug/Public/SGDebug/SGDebugGizmo.h new file mode 100644 index 0000000..3d692cd --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebug/Public/SGDebug/SGDebugGizmo.h @@ -0,0 +1,63 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Math/Rotator.h" +#include "Math/Vector.h" + +#include "SGSettings/SGDebugGizmoSettings.h" + +class SENSEGLOVEDEBUG_API FSGDebugGizmo final +{ +public: + static void Draw( + const UWorld* World, + const FVector& Location, const FQuat& Rotation, + const FSGDebugGizmoSettings& Settings); + + static FORCEINLINE void Draw( + const UWorld* World, + const FVector& Location, const FRotator& Rotation, + const FSGDebugGizmoSettings& Settings) + { + Draw(World, Location, Rotation.Quaternion(), Settings); + } + +public: + FSGDebugGizmo() = delete; + virtual ~FSGDebugGizmo() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveDebug/Public/SGDebug/SGDebugVirtualHand.h b/Plugins/SenseGlove/Source/SenseGloveDebug/Public/SGDebug/SGDebugVirtualHand.h new file mode 100644 index 0000000..b9027d4 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebug/Public/SGDebug/SGDebugVirtualHand.h @@ -0,0 +1,66 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "HeadMountedDisplayTypes.h" +#include "Math/Rotator.h" +#include "Math/Vector.h" +#include "Runtime/Launch/Resources/Version.h" + +#include "SGSettings/SGVirtualHandDebuggingSettings.h" + +class UWorld; + +class SENSEGLOVEDEBUG_API FSGDebugVirtualHand final +{ +public: + static void Draw( + const UWorld* World, + const FXRMotionControllerData& MotionControllerData, + const FSGVirtualHandDebuggingSettings& Settings); + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + static void Draw( + const UWorld* World, + const FXRHandTrackingState& HandTrackingState, + const FSGVirtualHandDebuggingSettings& Settings); +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + +public: + FSGDebugVirtualHand() = delete; + virtual ~FSGDebugVirtualHand() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveDebug/SenseGloveDebug.Build.cs b/Plugins/SenseGlove/Source/SenseGloveDebug/SenseGloveDebug.Build.cs new file mode 100644 index 0000000..b25b089 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebug/SenseGloveDebug.Build.cs @@ -0,0 +1,64 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGloveDebug : ModuleRules +{ + public SenseGloveDebug(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + "HeadMountedDisplay", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveLog", + "SenseGloveSettings", + "SenseGloveTypes", + } + ); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SGDebugKismet/SGDebugCubeKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SGDebugKismet/SGDebugCubeKismetLibrary.cpp new file mode 100644 index 0000000..6d6e450 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SGDebugKismet/SGDebugCubeKismetLibrary.cpp @@ -0,0 +1,56 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGDebugKismet/SGDebugCubeKismetLibrary.h" + +#include "SGDebug/SGDebugCube.h" + +void USGDebugCubeKismetLibrary::Draw_W_L_FQuat_R_S( + UObject* WorldContextObject, + const FVector& Location, const FQuat& Rotation, const FSGDebugCubeSettings& Settings) +{ + ensureAlwaysMsgf(WorldContextObject, TEXT("Invalid world context object!")); + + FSGDebugCube::Draw(WorldContextObject->GetWorld(), Location, Rotation, Settings); +} + +void USGDebugCubeKismetLibrary::Draw_W_L_FRotator_S( + UObject* WorldContextObject, + const FVector& Location, const FRotator& Rotation, const FSGDebugCubeSettings& Settings) +{ + ensureAlwaysMsgf(WorldContextObject, TEXT("Invalid world context object!")); + + FSGDebugCube::Draw(WorldContextObject->GetWorld(), Location, Rotation, Settings); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SGDebugKismet/SGDebugGizmoKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SGDebugKismet/SGDebugGizmoKismetLibrary.cpp new file mode 100644 index 0000000..ed0b9c5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SGDebugKismet/SGDebugGizmoKismetLibrary.cpp @@ -0,0 +1,56 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGDebugKismet/SGDebugGizmoKismetLibrary.h" + +#include "SGDebug/SGDebugGizmo.h" + +void USGDebugGizmoKismetLibrary::Draw_W_L_FQuat_R_S( + UObject* WorldContextObject, + const FVector& Location, const FQuat& Rotation, const FSGDebugGizmoSettings& Settings) +{ + ensureAlwaysMsgf(WorldContextObject, TEXT("Invalid world context object!")); + + FSGDebugGizmo::Draw(WorldContextObject->GetWorld(), Location, Rotation, Settings); +} + +void USGDebugGizmoKismetLibrary::Draw_W_L_FRotator_S( + UObject* WorldContextObject, + const FVector& Location, const FRotator& Rotation, const FSGDebugGizmoSettings& Settings) +{ + ensureAlwaysMsgf(WorldContextObject, TEXT("Invalid world context object!")); + + FSGDebugGizmo::Draw(WorldContextObject->GetWorld(), Location, Rotation, Settings); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SGDebugKismet/SGDebugVirtualHandKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SGDebugKismet/SGDebugVirtualHandKismetLibrary.cpp new file mode 100644 index 0000000..89c14e4 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SGDebugKismet/SGDebugVirtualHandKismetLibrary.cpp @@ -0,0 +1,50 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGDebugKismet/SGDebugVirtualHandKismetLibrary.h" + +#include "SGDebug/SGDebugVirtualHand.h" + +void USGDebugVirtualHandKismetLibrary::Draw_FXRMotionControllerData( + UObject* WorldContextObject, + const FXRMotionControllerData& MotionControllerData, + const FSGVirtualHandDebuggingSettings& Settings) +{ + ensureAlwaysMsgf(WorldContextObject, TEXT("Invalid world context object!")); + + PRAGMA_DISABLE_DEPRECATION_WARNINGS + FSGDebugVirtualHand::Draw(WorldContextObject->GetWorld(), MotionControllerData, Settings); + PRAGMA_ENABLE_DEPRECATION_WARNINGS +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SenseGloveDebugKismet.cpp b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SenseGloveDebugKismet.cpp new file mode 100644 index 0000000..d99eab9 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SenseGloveDebugKismet.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveDebugKismet.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveDebugKismetModule.h" + +IMPLEMENT_MODULE(FSenseGloveDebugKismetModule, SenseGloveDebugKismet) diff --git a/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SenseGloveDebugKismet.h b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SenseGloveDebugKismet.h new file mode 100644 index 0000000..a30ce66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SenseGloveDebugKismet.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SenseGloveDebugKismetModule.cpp b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SenseGloveDebugKismetModule.cpp new file mode 100644 index 0000000..7a629ef --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SenseGloveDebugKismetModule.cpp @@ -0,0 +1,62 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveDebugKismetModule.h" + +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveDebugKismetModule" + +void FSenseGloveDebugKismetModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveDebugKismet module..."); +} + +void FSenseGloveDebugKismetModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveDebugKismet module..."); +} + +void FSenseGloveDebugKismetModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveDebugKismet module has succeeded!"); +} + +void FSenseGloveDebugKismetModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveDebugKismet module..."); +} + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SenseGloveDebugKismetModule.h b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SenseGloveDebugKismetModule.h new file mode 100644 index 0000000..478cf08 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Private/SenseGloveDebugKismetModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveDebugKismet" + +class FSenseGloveDebugKismetModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Public/SGDebugKismet/SGDebugCubeKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Public/SGDebugKismet/SGDebugCubeKismetLibrary.h new file mode 100644 index 0000000..257f37f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Public/SGDebugKismet/SGDebugCubeKismetLibrary.h @@ -0,0 +1,64 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGDebug/SGDebugCube.h" + +#include "SGDebugCubeKismetLibrary.generated.h" + +class USGDebug; + +UCLASS(meta=(ScriptName = "SenseGloveDebugCubeKismetLibrary")) +class SENSEGLOVEDEBUGKISMET_API USGDebugCubeKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, DisplayName="Draw", Category="SenseGlove | Debug | Cube", + meta=(WorldContext="WorldContextObject")) + static void Draw_W_L_FQuat_R_S( + UObject* WorldContextObject, + const FVector& Location, const FQuat& Rotation, + const FSGDebugCubeSettings& Settings); + + UFUNCTION(BlueprintCallable, DisplayName="Draw", Category="SenseGlove | Debug | Cube", + meta=(WorldContext="WorldContextObject")) + static void Draw_W_L_FRotator_S( + UObject* WorldContextObject, + const FVector& Location, const FRotator& Rotation, + const FSGDebugCubeSettings& Settings); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Public/SGDebugKismet/SGDebugGizmoKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Public/SGDebugKismet/SGDebugGizmoKismetLibrary.h new file mode 100644 index 0000000..37ccde7 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Public/SGDebugKismet/SGDebugGizmoKismetLibrary.h @@ -0,0 +1,64 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGDebug/SGDebugGizmo.h" + +#include "SGDebugGizmoKismetLibrary.generated.h" + +class USGDebug; + +UCLASS(meta=(ScriptName = "SenseGloveDebugGizmoKismetLibrary")) +class SENSEGLOVEDEBUGKISMET_API USGDebugGizmoKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, DisplayName="Draw", Category="SenseGlove | Debug | Gizmo", + meta=(WorldContext="WorldContextObject")) + static void Draw_W_L_FQuat_R_S( + UObject* WorldContextObject, + const FVector& Location, const FQuat& Rotation, + const FSGDebugGizmoSettings& Settings); + + UFUNCTION(BlueprintCallable, DisplayName="Draw", Category="SenseGlove | Debug | Gizmo", + meta=(WorldContext="WorldContextObject")) + static void Draw_W_L_FRotator_S( + UObject* WorldContextObject, + const FVector& Location, const FRotator& Rotation, + const FSGDebugGizmoSettings& Settings); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Public/SGDebugKismet/SGDebugVirtualHandKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Public/SGDebugKismet/SGDebugVirtualHandKismetLibrary.h new file mode 100644 index 0000000..dda481a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/Public/SGDebugKismet/SGDebugVirtualHandKismetLibrary.h @@ -0,0 +1,59 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "UObject/ObjectMacros.h" +#include "HeadMountedDisplayTypes.h" + +#include "SGKismet/SGBlueprintFunctionLibrary.h" + +#include "SGDebugVirtualHandKismetLibrary.generated.h" + +class USGDebug; + +UCLASS(meta=(ScriptName = "SenseGloveDebugVirtualHandKismetLibrary")) +class SENSEGLOVEDEBUGKISMET_API USGDebugVirtualHandKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, DisplayName="Draw", Category="SenseGlove | Debug | Virtual Hand", + meta=(WorldContext="WorldContextObject")) + static void Draw_FXRMotionControllerData( + UObject* WorldContextObject, + const FXRMotionControllerData& MotionControllerData, + const FSGVirtualHandDebuggingSettings& Settings); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveDebugKismet/SenseGloveDebugKismet.Build.cs b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/SenseGloveDebugKismet.Build.cs new file mode 100644 index 0000000..90c630e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveDebugKismet/SenseGloveDebugKismet.Build.cs @@ -0,0 +1,66 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGloveDebugKismet : ModuleRules +{ + public SenseGloveDebugKismet(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + "HeadMountedDisplay", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveLog", + "SenseGloveDebug", + "SenseGloveKismet", + "SenseGloveSettings", + "SenseGloveTypes", + } + ); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SGEditor/SGAssetUtils.cpp b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SGEditor/SGAssetUtils.cpp new file mode 100644 index 0000000..5a2649b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SGEditor/SGAssetUtils.cpp @@ -0,0 +1,1032 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGEditor/SGAssetUtils.h" + +#include "Animation/DebugSkelMeshComponent.h" +#include "Animation/Skeleton.h" +#include "Containers/Array.h" +#include "Containers/UnrealString.h" +#include "Engine/SkeletalMesh.h" +#include "Engine/SkeletalMeshSocket.h" +#include "HeadMountedDisplayTypes.h" +#include "IEditableSkeleton.h" +#include "Internationalization/Text.h" +#include "IPersonaToolkit.h" +#include "ISkeletalMeshEditorModule.h" +#include "ISkeletonEditorModule.h" +#include "Misc/AssertionMacros.h" +#include "Misc/CoreMiscDefines.h" +#include "ReferenceSkeleton.h" +#include "Rendering/SkeletalMeshLODRenderData.h" +#include "Rendering/SkeletalMeshRenderData.h" +#include "Subsystems/AssetEditorSubsystem.h" +#include "UObject/Object.h" +#include "UObject/UnrealNames.h" + +#include "SGLog/SGLog.h" +#include "SGSettings/SGSettings.h" + +struct FSGAssetUtils::FImpl +{ + /************************ + * Static methods + ************************/ + + FORCEINLINE static const FSGVirtualHandSettings& GetVirtualHandSettings() + { + const USGSettings* Settings{USGSettings::GetInstance()}; + ensureAlwaysMsgf(Settings, TEXT("The settings subsystem has not been initialized!")); + const FSGVirtualHandSettings& VirtualHandSettings{Settings->GetVirtualHandSettings()}; + return VirtualHandSettings; + } + + FORCEINLINE static const FSGVirtualHandGrabSettings& GetVirtualHandGrabSettings() + { + const FSGVirtualHandSettings& VirtualHandSettings{GetVirtualHandSettings()}; + return VirtualHandSettings.GrabSettings; + } + + FORCEINLINE static const FSGVirtualHandMeshSettings& GetVirtualHandMeshSettings() + { + const FSGVirtualHandSettings& VirtualHandSettings{GetVirtualHandSettings()}; + return VirtualHandSettings.MeshSettings; + } + + FORCEINLINE static const FSGVirtualHandTouchSettings& GetVirtualHandTouchSettings() + { + const FSGVirtualHandSettings& VirtualHandSettings{GetVirtualHandSettings()}; + return VirtualHandSettings.TouchSettings; + } + + static bool IsHandBoneWeighted( + const ISkeletalMeshEditor* SkeletalMeshEditor, const USkeletalMesh* SkeletalMesh, const FName& BoneName); + + static FName GetHandBoneName(const ISkeletalMeshEditor* SkeletalMeshEditor, const USkeletalMesh* SkeletalMesh); + + static bool IsLeftHandMesh(const ISkeletalMeshEditor* SkeletalMeshEditor, const USkeletalMesh* SkeletalMesh); + static bool IsRightHandMesh(const ISkeletalMeshEditor* SkeletalMeshEditor, const USkeletalMesh* SkeletalMesh); + + static FTransform GetHandBoneRefTransform(const USkeletalMesh* SkeletalMesh, const FName& BoneName); + + static bool AddSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, + const FName& BoneName, const FName& SocketName, const FTransform& SocketTransform); + + static bool AddGrabAttachPointSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, bool bRight); + + static bool AddFingertipColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, + bool bRight, EHandKeypoint DistalKeypoint, const FName& SocketName); + + static bool AddGrabThumbColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, bool bRight); + static bool AddGrabIndexColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, bool bRight); + static bool AddGrabMiddleColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, bool bRight); + + static bool AddTouchThumbColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, bool bRight); + static bool AddTouchIndexColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, bool bRight); + static bool AddTouchMiddleColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, bool bRight); + static bool AddTouchRingColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, bool bRight); + static bool AddTouchLittleColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, bool bRight); + + static bool AddSenseGloveSockets(const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh); + + static bool AddSenseGloveSockets(USkeletalMesh* SkeletalMesh, USkeleton* Skeleton); + static bool ClearExistingSockets(USkeletalMesh* SkeletalMesh, USkeleton* Skeleton); +}; + +bool FSGAssetUtils::FImpl::IsHandBoneWeighted( + const ISkeletalMeshEditor* SkeletalMeshEditor, const USkeletalMesh* SkeletalMesh, const FName& BoneName) +{ + if (!ensureAlwaysMsgf(IsValid(SkeletalMesh), TEXT("Invalid SkeletalMesh!"))) + { + return false; + } + + if (!ensureAlwaysMsgf(BoneName != NAME_None, TEXT("Invalid BoneName!"))) + { + return false; + } + + const FReferenceSkeleton& RefSkeleton{SkeletalMesh->GetRefSkeleton()}; + const int32 BoneIndex = RefSkeleton.FindBoneIndex(BoneName); + + // MeshBoneIndex must be an index into the mesh's skeleton, *not* the source skeleton!!! + if (!ensureAlwaysMsgf(BoneIndex != INDEX_NONE, TEXT("Invalid BoneIndex!"))) + { + // If we get an invalid index, we are done here. + return false; + } + + const FSkeletalMeshRenderData* ResourceForRendering{SkeletalMesh->GetResourceForRendering()}; + if (!ensureAlwaysMsgf(ResourceForRendering, TEXT("Invalid ResourceForRendering!"))) + { + // If there's no mesh, then this bone can't possibly be weighted! + return false; + } + + const TIndirectArray& LODRenderData{ResourceForRendering->LODRenderData}; + const int32 LODRenderDataNum{LODRenderData.Num()}; + if (!ensureAlwaysMsgf(LODRenderDataNum > 0, TEXT("Invalid LODRenderDataNum!"))) + { + // If there's no mesh, then this bone can't possibly be weighted! + return false; + } + + const TSharedRef PersonaToolkit{SkeletalMeshEditor->GetPersonaToolkit()}; + const UDebugSkelMeshComponent* PreviewMeshComponent{PersonaToolkit->GetPreviewMeshComponent()}; + if (!ensureAlwaysMsgf(PreviewMeshComponent, TEXT("Invalid PreviewMeshComponent!"))) + { + return false; + } + + const int32 PredictedLODLevel = PreviewMeshComponent->GetPredictedLODLevel(); + + const USkeletalMesh* PreviewSkeletalMeshAsset{PreviewMeshComponent->GetSkeletalMeshAsset()}; + if (!ensureAlwaysMsgf(IsValid(PreviewSkeletalMeshAsset), TEXT("Invalid PreviewSkeletalMeshAsset!"))) + { + return false; + } + + const FSkeletalMeshRenderData* PreviewResourceForRendering{PreviewSkeletalMeshAsset->GetResourceForRendering()}; + if (!ensureAlwaysMsgf(PreviewResourceForRendering, TEXT("Invalid PreviewResourceForRendering!"))) + { + return false; + } + + const TIndirectArray& PreviewLODRenderData{PreviewResourceForRendering->LODRenderData}; + const int32 PreviewLODRenderDataNum{PreviewLODRenderData.Num()}; + if (!ensureAlwaysMsgf(LODRenderDataNum > 0, TEXT("Invalid LODRenderDataNum!"))) + { + return false; + } + + const int32 MaxPreviewLODRenderDataNum = PreviewLODRenderDataNum - 1; + + // Get current LOD + const int32 LODIndex = FMath::Clamp(PredictedLODLevel, 0, MaxPreviewLODRenderDataNum); + const FSkeletalMeshLODRenderData& LODData{PreviewLODRenderData[LODIndex]}; + + // Check whether the bone is vertex weighted + const int32 Index = LODData.ActiveBoneIndices.Find(IntCastChecked(BoneIndex)); + + return Index != INDEX_NONE; +} + +FName FSGAssetUtils::FImpl::GetHandBoneName( + const ISkeletalMeshEditor* SkeletalMeshEditor, const USkeletalMesh* SkeletalMesh) +{ + if (!ensureAlwaysMsgf(IsValid(SkeletalMesh), TEXT("Invalid SkeletalMesh!"))) + { + return NAME_None; + } + + static const FString HandBonePrefix{TEXT("hand_")}; + + const FReferenceSkeleton& RefSkeleton{SkeletalMesh->GetRefSkeleton()}; + const int32 BoneNum = RefSkeleton.GetNum(); + + for (int i = 0; i < BoneNum; ++i) + { + const FName BoneName{RefSkeleton.GetBoneName(i)}; + const FString BoneNameString{BoneName.ToString()}; + + if (!BoneNameString.StartsWith(HandBonePrefix)) + { + continue; + } + + if (!IsHandBoneWeighted(SkeletalMeshEditor, SkeletalMesh, BoneName)) + { + continue; + } + + return BoneName; + } + + SGLOG_ERROR("Invalid SenseGlove virtual hand mesh!"); + + return NAME_None; +} + +bool FSGAssetUtils::FImpl::IsLeftHandMesh( + const ISkeletalMeshEditor* SkeletalMeshEditor, const USkeletalMesh* SkeletalMesh) +{ + static constexpr int32 HandBoneNameIndex = static_cast(EHandKeypoint::Wrist); + + const FSGVirtualHandMeshSettings& MeshSettings{GetVirtualHandMeshSettings()}; + + if (!ensureAlwaysMsgf(HandBoneNameIndex < MeshSettings.RightHandBoneNames.Num() + && HandBoneNameIndex < MeshSettings.RightHandBoneNames.Num(), + TEXT("Invalid HandBoneNameIndex"))) + { + return false; + } + + const FName LeftHandBoneName{MeshSettings.LeftHandBoneNames[HandBoneNameIndex]}; + const FName HandBoneName{GetHandBoneName(SkeletalMeshEditor, SkeletalMesh)}; + + if (HandBoneName == NAME_None) + { + return false; + } + + if (HandBoneName != LeftHandBoneName) + { + return false; + } + + return true; +} + +bool FSGAssetUtils::FImpl::IsRightHandMesh( + const ISkeletalMeshEditor* SkeletalMeshEditor, const USkeletalMesh* SkeletalMesh) +{ + static constexpr int32 HandBoneNameIndex = static_cast(EHandKeypoint::Wrist); + + const FSGVirtualHandMeshSettings& MeshSettings{GetVirtualHandSettings().MeshSettings}; + + if (!ensureAlwaysMsgf(HandBoneNameIndex < MeshSettings.RightHandBoneNames.Num() + && HandBoneNameIndex < MeshSettings.RightHandBoneNames.Num(), + TEXT("Invalid HandBoneNameIndex"))) + { + return false; + } + + const FName RightHandBoneName{MeshSettings.RightHandBoneNames[HandBoneNameIndex]}; + const FName HandBoneName{GetHandBoneName(SkeletalMeshEditor, SkeletalMesh)}; + + if (HandBoneName == NAME_None) + { + return false; + } + + if (HandBoneName != RightHandBoneName) + { + return false; + } + + return true; +} + +FTransform FSGAssetUtils::FImpl::GetHandBoneRefTransform( + const USkeletalMesh* SkeletalMesh, const FName& BoneName) +{ + if (!ensureAlwaysMsgf(IsValid(SkeletalMesh), TEXT("Invalid SkeletalMesh"))) + { + return FTransform::Identity; + } + + const FReferenceSkeleton& ReferenceSkeleton{SkeletalMesh->GetRefSkeleton()}; + + const int32 BoneIndex = ReferenceSkeleton.FindBoneIndex(BoneName); + if (!ensureAlwaysMsgf(BoneIndex != INDEX_NONE, + TEXT("Could not find a bone index for the '%s' joint!"), *BoneName.ToString())) + { + return FTransform::Identity; + } + + const TArray Transforms{ReferenceSkeleton.GetRefBonePose()}; + if (!ensureAlwaysMsgf(Transforms.Num() > 0 && Transforms.Num() > BoneIndex, + TEXT("Invalid bone index '%d' or no transforms found!"), BoneIndex)) + { + return FTransform::Identity; + } + + const FTransform& Transform{Transforms[BoneIndex]}; + return Transform; +} + +bool FSGAssetUtils::FImpl::AddSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, + const FName& BoneName, const FName& SocketName, const FTransform& SocketTransform) +{ + if (!ensureAlwaysMsgf(SkeletalMeshEditor, TEXT("Invalid SkeletalMeshEditor!"))) + { + return false; + } + + if (!ensureAlwaysMsgf(IsValid(SkeletalMesh), TEXT("Invalid SkeletalMesh!"))) + { + return false; + } + + TSharedRef PersonaToolkit{SkeletalMeshEditor->GetPersonaToolkit()}; + TSharedPtr EditableSkeleton{PersonaToolkit->GetEditableSkeleton()}; + if (!ensureAlwaysMsgf(EditableSkeleton.IsValid(), TEXT("Invalid SkeletalMesh!"))) + { + return false; + } + + USkeletalMeshSocket* Socket{NewObject()}; + Socket->BoneName = BoneName; + Socket->SocketName = SocketName; + if (!ensureAlwaysMsgf(IsValid(Socket), TEXT("Invalid Socket!"))) + { + return false; + } + + const bool bDoesSocketAlreadyExistOnTheMesh = EditableSkeleton->DoesSocketAlreadyExist( + Socket, FText::FromName(SocketName), ESocketParentType::Mesh, SkeletalMesh); + const bool bDoesSocketAlreadyExistOnTheSkeleton = EditableSkeleton->DoesSocketAlreadyExist( + Socket, FText::FromName(SocketName), ESocketParentType::Skeleton, SkeletalMesh); + + if (bDoesSocketAlreadyExistOnTheMesh || bDoesSocketAlreadyExistOnTheSkeleton) + { + SGLOG_ERROR(FString::Printf(TEXT("Socket '%s' already exists on '%s'; refuse to add a duplicate!"), + *SocketName.ToString(), *SkeletalMesh->GetPathName())); + return false; + } + + Socket = EditableSkeleton->AddSocket(BoneName); + if (!ensureAlwaysMsgf(IsValid(Socket), TEXT("Invalid Socket!"))) + { + return false; + } + + EditableSkeleton->RenameSocket(Socket->SocketName, SocketName, SkeletalMesh); + + Socket->RelativeLocation = SocketTransform.GetLocation(); + Socket->RelativeRotation = SocketTransform.GetRotation().Rotator(); + Socket->RelativeScale = SocketTransform.GetScale3D(); + + return true; +} + +bool FSGAssetUtils::FImpl::AddGrabAttachPointSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, const bool bRight) +{ + static constexpr int32 BoneNameIndex = static_cast(EHandKeypoint::Wrist); + + const FSGVirtualHandMeshSettings MeshSettings{GetVirtualHandMeshSettings()}; + + if (!ensureAlwaysMsgf(BoneNameIndex < MeshSettings.RightHandBoneNames.Num() + && BoneNameIndex < MeshSettings.RightHandBoneNames.Num(), + TEXT("Invalid BoneNameIndex"))) + { + return false; + } + + const FName& BoneName{ + bRight + ? MeshSettings.RightHandBoneNames[BoneNameIndex] + : MeshSettings.LeftHandBoneNames[BoneNameIndex] + }; + + const FSGVirtualHandGrabSettings GrabSettings{GetVirtualHandGrabSettings()}; + const FName& SocketName{GrabSettings.GrabAttachPointSocketName}; + const FTransform& SocketTransform{GrabSettings.GrabAttachPointSocketTransform}; + + const bool bAddedSocket = AddSocket( + SkeletalMeshEditor, SkeletalMesh, BoneName, SocketName, SocketTransform); + if (!bAddedSocket) + { + SGLOG_ERROR(FString::Printf(TEXT("Failed to add the socket '%s' to '%s'!"), + *SocketName.ToString(), *SkeletalMesh->GetPathName())); + return false; + } + + return true; +} + +bool FSGAssetUtils::FImpl::AddFingertipColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, + const bool bRight, const EHandKeypoint DistalKeypoint, const FName& SocketName) +{ + const int32 BoneNameIndex = static_cast(DistalKeypoint); + + const FSGVirtualHandMeshSettings MeshSettings{GetVirtualHandMeshSettings()}; + + if (!ensureAlwaysMsgf(BoneNameIndex < MeshSettings.RightHandBoneNames.Num() + && BoneNameIndex < MeshSettings.RightHandBoneNames.Num(), + TEXT("Invalid BoneNameIndex"))) + { + return false; + } + + const FName& BoneName{ + bRight + ? MeshSettings.RightHandBoneNames[BoneNameIndex] + : MeshSettings.LeftHandBoneNames[BoneNameIndex] + }; + + FTransform SocketTransform{ + GetHandBoneRefTransform(SkeletalMesh, BoneName) + }; + + const bool bAddedSocket = AddSocket( + SkeletalMeshEditor, SkeletalMesh, BoneName, SocketName, MoveTemp(SocketTransform)); + + if (!bAddedSocket) + { + SGLOG_ERROR(FString::Printf(TEXT("Failed to add the socket '%s' to '%s'!"), + *BoneName.ToString(), *SkeletalMesh->GetPathName())); + return false; + } + + return true; +} + +bool FSGAssetUtils::FImpl::AddGrabThumbColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, const bool bRight) +{ + const FSGVirtualHandGrabSettings GrabSettings{GetVirtualHandGrabSettings()}; + const FName& SocketName{GrabSettings.ThumbColliderSocketName}; + return AddFingertipColliderSocket(SkeletalMeshEditor, SkeletalMesh, + bRight, EHandKeypoint::ThumbDistal, SocketName); +} + +bool FSGAssetUtils::FImpl::AddGrabIndexColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, const bool bRight) +{ + const FSGVirtualHandGrabSettings GrabSettings{GetVirtualHandGrabSettings()}; + const FName& SocketName{GrabSettings.IndexColliderSocketName}; + return AddFingertipColliderSocket(SkeletalMeshEditor, SkeletalMesh, + bRight, EHandKeypoint::IndexDistal, SocketName); +} + +bool FSGAssetUtils::FImpl::AddGrabMiddleColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, const bool bRight) +{ + const FSGVirtualHandGrabSettings GrabSettings{GetVirtualHandGrabSettings()}; + const FName& SocketName{GrabSettings.MiddleColliderSocketName}; + return AddFingertipColliderSocket(SkeletalMeshEditor, SkeletalMesh, + bRight, EHandKeypoint::MiddleDistal, SocketName); +} + +bool FSGAssetUtils::FImpl::AddTouchThumbColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, const bool bRight) +{ + const FSGVirtualHandTouchSettings TouchSettings{GetVirtualHandTouchSettings()}; + const FName& SocketName{TouchSettings.ThumbColliderSocketName}; + return AddFingertipColliderSocket(SkeletalMeshEditor, SkeletalMesh, + bRight, EHandKeypoint::ThumbDistal, SocketName); +} + +bool FSGAssetUtils::FImpl::AddTouchIndexColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, const bool bRight) +{ + const FSGVirtualHandTouchSettings TouchSettings{GetVirtualHandTouchSettings()}; + const FName& SocketName{TouchSettings.IndexColliderSocketName}; + return AddFingertipColliderSocket(SkeletalMeshEditor, SkeletalMesh, + bRight, EHandKeypoint::IndexDistal, SocketName); +} + +bool FSGAssetUtils::FImpl::AddTouchMiddleColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, const bool bRight) +{ + const FSGVirtualHandTouchSettings TouchSettings{GetVirtualHandTouchSettings()}; + const FName& SocketName{TouchSettings.MiddleColliderSocketName}; + return AddFingertipColliderSocket(SkeletalMeshEditor, SkeletalMesh, + bRight, EHandKeypoint::MiddleDistal, SocketName); +} + +bool FSGAssetUtils::FImpl::AddTouchRingColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, const bool bRight) +{ + const FSGVirtualHandTouchSettings TouchSettings{GetVirtualHandTouchSettings()}; + const FName& SocketName{TouchSettings.RingColliderSocketName}; + return AddFingertipColliderSocket(SkeletalMeshEditor, SkeletalMesh, + bRight, EHandKeypoint::RingDistal, SocketName); +} + +bool FSGAssetUtils::FImpl::AddTouchLittleColliderSocket( + const ISkeletalMeshEditor* SkeletalMeshEditor, USkeletalMesh* SkeletalMesh, const bool bRight) +{ + const FSGVirtualHandTouchSettings TouchSettings{GetVirtualHandTouchSettings()}; + const FName& SocketName{TouchSettings.PinkyColliderSocketName}; + return AddFingertipColliderSocket(SkeletalMeshEditor, SkeletalMesh, + bRight, EHandKeypoint::LittleDistal, SocketName); +} + +bool FSGAssetUtils::FImpl::AddSenseGloveSockets(const ISkeletalMeshEditor* SkeletalMeshEditor, + USkeletalMesh* SkeletalMesh) +{ + if (!ensureAlwaysMsgf(SkeletalMeshEditor, TEXT("Invalid SkeletalMeshEditor!"))) + { + return false; + } + + if (!ensureAlwaysMsgf(IsValid(SkeletalMesh), TEXT("Invalid SkeletalMesh!"))) + { + return false; + } + + const bool bIsLeft = IsLeftHandMesh(SkeletalMeshEditor, SkeletalMesh); + const bool bIsRight = IsRightHandMesh(SkeletalMeshEditor, SkeletalMesh); + const bool bIsHandMesh = bIsLeft || bIsRight; + if (!bIsHandMesh) + { + SGLOG_ERROR(FString::Printf(TEXT("Asset '%s' is not a valid virtual hand mesh!"), + *SkeletalMesh->GetPathName())); + return false; + } + + const bool bAddedGrabAttachPointSocket = AddGrabAttachPointSocket( + SkeletalMeshEditor, SkeletalMesh, bIsRight); + if (!bAddedGrabAttachPointSocket) + { + SGLOG_ERROR(FString::Printf(TEXT("Failed to add the grab attach point socket to asset '%s'!"), + *SkeletalMesh->GetPathName())); + return false; + } + + const bool GrabThumbCollider = AddGrabThumbColliderSocket( + SkeletalMeshEditor, SkeletalMesh, bIsRight); + if (!GrabThumbCollider) + { + SGLOG_ERROR(FString::Printf(TEXT("Failed to add the grab thumb collider socket to asset '%s'!"), + *SkeletalMesh->GetPathName())); + return false; + } + + const bool GrabIndexCollider = AddGrabIndexColliderSocket( + SkeletalMeshEditor, SkeletalMesh, bIsRight); + if (!GrabIndexCollider) + { + SGLOG_ERROR(FString::Printf(TEXT("Failed to add the grab index collider socket to asset '%s'!"), + *SkeletalMesh->GetPathName())); + return false; + } + + const bool GrabMiddleCollider = AddGrabMiddleColliderSocket( + SkeletalMeshEditor, SkeletalMesh, bIsRight); + if (!GrabMiddleCollider) + { + SGLOG_ERROR(FString::Printf(TEXT("Failed to add the grab middle collider socket to asset '%s'!"), + *SkeletalMesh->GetPathName())); + return false; + } + + const bool TouchThumbCollider = AddTouchThumbColliderSocket( + SkeletalMeshEditor, SkeletalMesh, bIsRight); + if (!TouchThumbCollider) + { + SGLOG_ERROR(FString::Printf(TEXT("Failed to add the touch thumb collider socket to asset '%s'!"), + *SkeletalMesh->GetPathName())); + return false; + } + + const bool TouchIndexCollider = AddTouchIndexColliderSocket( + SkeletalMeshEditor, SkeletalMesh, bIsRight); + if (!TouchIndexCollider) + { + SGLOG_ERROR(FString::Printf(TEXT("Failed to add the touch index collider socket to asset '%s'!"), + *SkeletalMesh->GetPathName())); + return false; + } + + const bool TouchMiddleCollider = AddTouchMiddleColliderSocket( + SkeletalMeshEditor, SkeletalMesh, bIsRight); + if (!TouchMiddleCollider) + { + SGLOG_ERROR(FString::Printf(TEXT("Failed to add the touch middle collider socket to asset '%s'!"), + *SkeletalMesh->GetPathName())); + return false; + } + + const bool TouchRingCollider = AddTouchRingColliderSocket( + SkeletalMeshEditor, SkeletalMesh, bIsRight); + if (!TouchRingCollider) + { + SGLOG_ERROR(FString::Printf(TEXT("Failed to add the touch ring collider socket to asset '%s'!"), + *SkeletalMesh->GetPathName())); + return false; + } + + const bool TouchLittleCollider = AddTouchLittleColliderSocket( + SkeletalMeshEditor, SkeletalMesh, bIsRight); + if (!TouchLittleCollider) + { + SGLOG_ERROR(FString::Printf(TEXT("Failed to add the touch little collider socket to asset '%s'!"), + *SkeletalMesh->GetPathName())); + return false; + } + + return true; +} + +bool FSGAssetUtils::FImpl::AddSenseGloveSockets(USkeletalMesh* SkeletalMesh, USkeleton* Skeleton) +{ + if (!ensureAlwaysMsgf(IsValid(SkeletalMesh), TEXT("Invalid SkeletalMesh!"))) + { + return false; + } + + if (!ensureAlwaysMsgf(IsValid(Skeleton), TEXT("Invalid Skeleton!"))) + { + return false; + } + + const bool bAssetEdotirOpenForSkeletalMesh = IsAssetEditorOpenForAsset(SkeletalMesh); + if (bAssetEdotirOpenForSkeletalMesh) + { + const int32 ClosedEditorsNum = CloseAllEditorsForAsset(SkeletalMesh); + (void) ClosedEditorsNum; + } + + const bool bAssetEdotirOpenForSkeleton = IsAssetEditorOpenForAsset(Skeleton); + if (bAssetEdotirOpenForSkeleton) + { + const int32 ClosedEditorsNum = CloseAllEditorsForAsset(Skeleton); + (void) ClosedEditorsNum; + } + + const bool bCanModifySkeletalMesh = SkeletalMesh->CanModify(); + if (!bCanModifySkeletalMesh) + { + SGLOG_ERROR(FString::Printf(TEXT("Could not modify the asset '%s'!"), *SkeletalMesh->GetPathName())); + return false; + } + + const bool bCanModifySkeleton = Skeleton->CanModify(); + if (!bCanModifySkeleton) + { + SGLOG_ERROR(FString::Printf(TEXT("Could not modify the asset '%s'!"), *Skeleton->GetPathName())); + return false; + } + + bool bOpenedSkeletalMeshEditor = OpenEditorForAsset(SkeletalMesh); + if (!bOpenedSkeletalMeshEditor) + { + SGLOG_ERROR(FString::Printf(TEXT("Could not open the editor for the asset '%s'!"), + *SkeletalMesh->GetPathName())); + return false; + } + + TArray AssetEditors{FindEditorsForAsset(SkeletalMesh)}; + if (AssetEditors.IsEmpty()) + { + SGLOG_ERROR(FString::Printf(TEXT("Could not find any editor for the asset '%s'!"), + *SkeletalMesh->GetPathName())); + return false; + } + + for (IAssetEditorInstance* AssetEditor: AssetEditors) + { + if (!ensureAlwaysMsgf(AssetEditor, TEXT("Invalid AssetEditor!"))) + { + return false; + } + + const ISkeletalMeshEditor* SkeletalMeshEditor{static_cast(AssetEditor)}; + if (!SkeletalMeshEditor) + { + continue; + } + + const bool bAddedSenseGloveSockets = AddSenseGloveSockets(SkeletalMeshEditor, SkeletalMesh); + if (!bAddedSenseGloveSockets) + { + SGLOG_ERROR(FString::Printf(TEXT("Failed to add the SenseGlove sockets to the asset '%s'!"), + *SkeletalMesh->GetPathName())); + const int32 ClosedEditorsNum = CloseAllEditorsForAsset(SkeletalMesh); + (void) ClosedEditorsNum; + return false; + } + + const int32 ClosedEditorsNum = CloseAllEditorsForAsset(SkeletalMesh); + (void) ClosedEditorsNum; + + break; + } + + SkeletalMesh->PostEditChange(); + Skeleton->PostEditChange(); + + const bool bMarkedSkeletalMeshPackageDirty = SkeletalMesh->MarkPackageDirty(); + if (!bMarkedSkeletalMeshPackageDirty) + { + SGLOG_ERROR(FString::Printf(TEXT("Could not mark the asset '%s' as dirty!"), *SkeletalMesh->GetPathName())); + return false; + } + + const bool bMarkedSkeletonPackageDirty = Skeleton->MarkPackageDirty(); + if (!bMarkedSkeletonPackageDirty) + { + SGLOG_ERROR(FString::Printf(TEXT("Could not mark the asset '%s' as dirty!"), *Skeleton->GetPathName())); + return false; + } + + bOpenedSkeletalMeshEditor = OpenEditorForAsset(SkeletalMesh); + if (!bOpenedSkeletalMeshEditor) + { + SGLOG_ERROR(FString::Printf(TEXT("Could not refresh the editor for the asset '%s'!"), + *SkeletalMesh->GetPathName())); + return false; + } + + const bool bOpenedSkeletonEditor = OpenEditorForAsset(Skeleton); + if (!bOpenedSkeletonEditor) + { + SGLOG_ERROR(FString::Printf(TEXT("Could not refresh the editor for the asset '%s'!"), + *Skeleton->GetPathName())); + return false; + } + + return true; +} + +bool FSGAssetUtils::FImpl::ClearExistingSockets(USkeletalMesh* SkeletalMesh, USkeleton* Skeleton) +{ + if (!ensureAlwaysMsgf(IsValid(SkeletalMesh), TEXT("Invalid SkeletalMesh!"))) + { + return false; + } + + if (!ensureAlwaysMsgf(IsValid(Skeleton), TEXT("Invalid Skeleton!"))) + { + return false; + } + + const bool bAssetEdotirOpenForSkeletalMesh = IsAssetEditorOpenForAsset(SkeletalMesh); + if (bAssetEdotirOpenForSkeletalMesh) + { + const int32 ClosedEditorsNum = CloseAllEditorsForAsset(SkeletalMesh); + (void) ClosedEditorsNum; + } + + const bool bAssetEdotirOpenForSkeleton = IsAssetEditorOpenForAsset(Skeleton); + if (bAssetEdotirOpenForSkeleton) + { + const int32 ClosedEditorsNum = CloseAllEditorsForAsset(Skeleton); + (void) ClosedEditorsNum; + } + + const bool bCanModifySkeletalMesh = SkeletalMesh->CanModify(); + if (!bCanModifySkeletalMesh) + { + SGLOG_ERROR(FString::Printf(TEXT("Could not modify the asset '%s'!"), *SkeletalMesh->GetPathName())); + return false; + } + + const bool bCanModifySkeleton = Skeleton->CanModify(); + if (!bCanModifySkeleton) + { + SGLOG_ERROR(FString::Printf(TEXT("Could not modify the asset '%s'!"), *Skeleton->GetPathName())); + return false; + } + + Skeleton->Sockets.Empty(); + + SkeletalMesh->PostEditChange(); + Skeleton->PostEditChange(); + + const bool bMarkedSkeletalMeshPackageDirty = SkeletalMesh->MarkPackageDirty(); + if (!bMarkedSkeletalMeshPackageDirty) + { + SGLOG_ERROR(FString::Printf(TEXT("Could not mark the asset '%s' as dirty!"), *SkeletalMesh->GetPathName())); + return false; + } + + const bool bMarkedSkeletonPackageDirty = Skeleton->MarkPackageDirty(); + if (!bMarkedSkeletonPackageDirty) + { + SGLOG_ERROR(FString::Printf(TEXT("Could not mark the asset '%s' as dirty!"), *Skeleton->GetPathName())); + return false; + } + + const bool bOpenedSkeletalMeshEditor = OpenEditorForAsset(SkeletalMesh); + if (!bOpenedSkeletalMeshEditor) + { + SGLOG_ERROR(FString::Printf(TEXT("Could not refresh the editor for the asset '%s'!"), + *SkeletalMesh->GetPathName())); + return false; + } + + const bool bOpenedSkeletonEditor = OpenEditorForAsset(Skeleton); + if (!bOpenedSkeletonEditor) + { + SGLOG_ERROR(FString::Printf(TEXT("Could not refresh the editor for the asset '%s'!"), + *Skeleton->GetPathName())); + return false; + } + + return true; +} + +UAssetEditorSubsystem* FSGAssetUtils::GetAssetEditorSubsystem() +{ + if (!ensureAlwaysMsgf(GEditor, TEXT("Invalid GEditor!"))) + { + return nullptr; + } + + UAssetEditorSubsystem* AssetEditorSubsystem{GEditor->GetEditorSubsystem()}; + return AssetEditorSubsystem; +} + +UObject* FSGAssetUtils::GetEditedAsset() +{ + UAssetEditorSubsystem* AssetEditorSubsystem{GetAssetEditorSubsystem()}; + if (!ensureAlwaysMsgf(AssetEditorSubsystem, TEXT("Invalid AssetEditorSubsystem!"))) + { + return nullptr; + } + + TArray EditedAssets{AssetEditorSubsystem->GetAllEditedAssets()}; + for (UObject* EditedAsset: EditedAssets) + { + TArray AssetEditors{FindEditorsForAsset(EditedAsset)}; + for (IAssetEditorInstance* AssetEditor: AssetEditors) + { + if (!ensureAlwaysMsgf(AssetEditor, TEXT("Invalid AssetEditor!"))) + { + return nullptr; + } + + TSharedPtr TabManager = AssetEditor->GetAssociatedTabManager(); + if (!ensureAlwaysMsgf(TabManager.IsValid(), TEXT("Invalid TabManager!"))) + { + return nullptr; + } + + TSharedPtr OwnerTab{TabManager->GetOwnerTab()}; + if (!ensureAlwaysMsgf(OwnerTab.IsValid(), TEXT("Invalid OwnerTab!"))) + { + return nullptr; + } + + const bool bForeground = OwnerTab->IsForeground(); + if (bForeground) + { + return EditedAsset; + } + } + } + + ensureAlwaysMsgf(false, TEXT("The code flow should never reach here!")); + + return nullptr; +} + +bool FSGAssetUtils::IsAssetEditorOpenForAsset(UObject* Asset) +{ + if (!ensureAlwaysMsgf(Asset, TEXT("Invalid Asset!"))) + { + return false; + } + + TArray AssetEditors{FindEditorsForAsset(Asset)}; + return !AssetEditors.IsEmpty(); +} + +TArray FSGAssetUtils::FindEditorsForAsset(UObject* Asset) +{ + if (!ensureAlwaysMsgf(Asset, TEXT("Invalid Asset!"))) + { + return TArray{}; + } + + UAssetEditorSubsystem* AssetEditorSubsystem{GetAssetEditorSubsystem()}; + if (!ensureAlwaysMsgf(AssetEditorSubsystem, TEXT("Invalid AssetEditorSubsystem!"))) + { + return TArray{}; + } + + TArray AssetEditors{AssetEditorSubsystem->FindEditorsForAsset(Asset)}; + return AssetEditors; +} + +bool FSGAssetUtils::OpenEditorForAsset(UObject* Asset) +{ + if (!ensureAlwaysMsgf(Asset, TEXT("Invalid Asset!"))) + { + return false; + } + + UAssetEditorSubsystem* AssetEditorSubsystem{GetAssetEditorSubsystem()}; + if (!ensureAlwaysMsgf(AssetEditorSubsystem, TEXT("Invalid AssetEditorSubsystem!"))) + { + return false; + } + + const bool bOpenedEditor = AssetEditorSubsystem->OpenEditorForAsset(Asset); + return bOpenedEditor; +} + +int32 FSGAssetUtils::CloseAllEditorsForAsset(UObject* Asset) +{ + if (!ensureAlwaysMsgf(Asset, TEXT("Invalid Asset!"))) + { + return 0; + } + + UAssetEditorSubsystem* AssetEditorSubsystem{GetAssetEditorSubsystem()}; + if (!ensureAlwaysMsgf(AssetEditorSubsystem, TEXT("Invalid AssetEditorSubsystem!"))) + { + return false; + } + + const int32 ClosedEditorsNum = AssetEditorSubsystem->CloseAllEditorsForAsset(Asset); + return ClosedEditorsNum; +} + +bool FSGAssetUtils::AddSenseGloveSockets(USkeletalMesh* SkeletalMesh) +{ + if (!ensureAlwaysMsgf(IsValid(SkeletalMesh), TEXT("Invalid SkeletalMesh!"))) + { + return false; + } + + USkeleton* Skeleton{SkeletalMesh->GetSkeleton()}; + if (!ensureAlwaysMsgf(IsValid(Skeleton), TEXT("Invalid Skeleton!"))) + { + return false; + } + + const bool bAddedSenseGloveSockets = FImpl::AddSenseGloveSockets(SkeletalMesh, Skeleton); + return bAddedSenseGloveSockets; +} + +bool FSGAssetUtils::AddSenseGloveSockets(USkeleton* Skeleton) +{ + if (!ensureAlwaysMsgf(IsValid(Skeleton), TEXT("Invalid Skeleton!"))) + { + return false; + } + + USkeletalMesh* SkeletalMesh{Skeleton->GetPreviewMesh()}; + if (!ensureAlwaysMsgf(IsValid(SkeletalMesh), TEXT("Invalid SkeletalMesh!"))) + { + return false; + } + + const bool bAddedSenseGloveSockets = FImpl::AddSenseGloveSockets(SkeletalMesh, Skeleton); + return bAddedSenseGloveSockets; +} + +bool FSGAssetUtils::ClearExistingSockets(USkeletalMesh* SkeletalMesh) +{ + if (!ensureAlwaysMsgf(IsValid(SkeletalMesh), TEXT("Invalid SkeletalMesh!"))) + { + return false; + } + + USkeleton* Skeleton{SkeletalMesh->GetSkeleton()}; + if (!ensureAlwaysMsgf(IsValid(Skeleton), TEXT("Invalid Skeleton!"))) + { + return false; + } + + const bool bClearedExistingSockets = FImpl::ClearExistingSockets(SkeletalMesh, Skeleton); + return bClearedExistingSockets; +} + +bool FSGAssetUtils::ClearExistingSockets(USkeleton* Skeleton) +{ + if (!ensureAlwaysMsgf(IsValid(Skeleton), TEXT("Invalid Skeleton!"))) + { + return false; + } + + USkeletalMesh* SkeletalMesh{Skeleton->GetPreviewMesh()}; + if (!ensureAlwaysMsgf(IsValid(SkeletalMesh), TEXT("Invalid SkeletalMesh!"))) + { + return false; + } + + const bool bClearedExistingSockets = FImpl::ClearExistingSockets(SkeletalMesh, Skeleton); + return bClearedExistingSockets; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SGEditor/SGContentBrowserExtension.cpp b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SGEditor/SGContentBrowserExtension.cpp new file mode 100644 index 0000000..9a2601d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SGEditor/SGContentBrowserExtension.cpp @@ -0,0 +1,314 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGEditor/SGContentBrowserExtension.h" + +#include "Animation/Skeleton.h" +#include "AssetRegistry/AssetData.h" +#include "Containers/UnrealString.h" +#include "ContentBrowserDelegates.h" +#include "ContentBrowserModule.h" +#include "Editor.h" +#include "Engine/SkeletalMesh.h" +#include "Framework/Commands/UIAction.h" +#include "Framework/MultiBox/MultiBoxBuilder.h" +#include "Framework/MultiBox/MultiBoxExtender.h" +#include "GenericPlatform/GenericPlatformMisc.h" +#include "Internationalization/Text.h" +#include "Math/Transform.h" +#include "Misc/MessageDialog.h" +#include "ReferenceSkeleton.h" +#include "UObject/Object.h" + +#include "SGEditor/SGAssetUtils.h" +#include "SGEditor/SGPluginStyle.h" + +#define LOCTEXT_NAMESPACE "SGContentBrowserExtension" + +struct FSGContentBrowserExtension::FImpl +{ + /************************ + * Static methods + ************************/ + + static void TryAddSenseGloveSockets(const TArray& SelectedAssets); + static void TryClearExistingSockets(const TArray& SelectedAssets); +}; + +void FSGContentBrowserExtension::FImpl::TryAddSenseGloveSockets(const TArray& SelectedAssets) +{ + const FText ConfirmationDialogText{ + LOCTEXT("SenseGloveAddSocketsConfirmation", + "Do you want to add the SenseGlove sockets?") + }; + const EAppReturnType::Type DialogResult{ + FMessageDialog::Open(EAppMsgType::YesNo, ConfirmationDialogText) + }; + + if (DialogResult != EAppReturnType::Yes) + { + return; + } + + bool bAllAssetsSucceeded = true; + + for (const FAssetData& Asset: SelectedAssets) + { + USkeletalMesh* SkeletalMesh{Cast(Asset.GetAsset())}; + USkeleton* Skeleton{Cast(Asset.GetAsset())}; + + if (!IsValid(SkeletalMesh) && !IsValid(Skeleton)) + { + continue; + } + + bool bAddedSenseGloveSockets = false; + + if (IsValid(SkeletalMesh)) + { + bAddedSenseGloveSockets = FSGAssetUtils::AddSenseGloveSockets(SkeletalMesh); + } + else if (IsValid(Skeleton)) + { + bAddedSenseGloveSockets = FSGAssetUtils::AddSenseGloveSockets(Skeleton); + } + + if (!bAddedSenseGloveSockets) + { + bAllAssetsSucceeded = false; + + const FText ResultDialogText{ + FText::Format( + LOCTEXT("SenseGloveAddSocketsResultFailedOn", + "Failed to add the SenseGlove sockets to '{0}'!"), + FText::FromString(Asset.GetSoftObjectPath().ToString())) + }; + FMessageDialog::Open(EAppMsgType::Ok, ResultDialogText); + } + + if (!bAddedSenseGloveSockets) + { + break; + } + } + + if (bAllAssetsSucceeded) + { + const FText ResultDialogText{ + LOCTEXT("SenseGloveAddSocketsResultSuccess", + "Successfully added the SenseGlove grab and touch sockets. If you wish the changes to persist, save" + " the modified asset(s) now!") + }; + FMessageDialog::Open(EAppMsgType::Ok, ResultDialogText); + } +} + +void FSGContentBrowserExtension::FImpl::TryClearExistingSockets(const TArray& SelectedAssets) +{ + const FText ConfirmationDialogText{ + LOCTEXT("SenseGloveClearExistingSocketsConfirmation", + "Are you sure you want to clear all the existing sockets? This cannot be undone!") + }; + const EAppReturnType::Type DialogResult{ + FMessageDialog::Open(EAppMsgType::YesNo, ConfirmationDialogText) + }; + + if (DialogResult != EAppReturnType::Yes) + { + return; + } + + bool bAllAssetsSucceeded = true; + + for (const FAssetData& Asset: SelectedAssets) + { + USkeletalMesh* SkeletalMesh{Cast(Asset.GetAsset())}; + USkeleton* Skeleton{Cast(Asset.GetAsset())}; + + if (!IsValid(SkeletalMesh) && !IsValid(Skeleton)) + { + continue; + } + + bool bClearedExistingSockets = false; + + if (IsValid(SkeletalMesh)) + { + bClearedExistingSockets = FSGAssetUtils::ClearExistingSockets(SkeletalMesh); + } + else if (IsValid(Skeleton)) + { + bClearedExistingSockets = FSGAssetUtils::ClearExistingSockets(Skeleton); + } + + if (!bClearedExistingSockets) + { + bAllAssetsSucceeded = false; + + const FText ResultDialogText{ + FText::Format( + LOCTEXT("SenseGloveClearExistingSocketsResultFailedOn", + "Failed to clear all the existing sockets on '{0}'!"), + FText::FromString(Asset.GetSoftObjectPath().ToString())) + }; + FMessageDialog::Open(EAppMsgType::Ok, ResultDialogText); + } + + if (!bClearedExistingSockets) + { + break; + } + } + + if (bAllAssetsSucceeded) + { + const FText ResultDialogText{ + LOCTEXT("SenseGloveClearExistingSocketsResultSuccess", + "Successfully cleared all the existing sockets! If you wish the changes to persist, save the" + " modified asset(s) now!") + }; + FMessageDialog::Open(EAppMsgType::Ok, ResultDialogText); + } +} + +void FSGContentBrowserExtension::Register() +{ + FContentBrowserModule& ContentBrowserModule{ + FModuleManager::LoadModuleChecked(TEXT("ContentBrowser")) + }; + + TArray& ContextMenuDelegates{ + ContentBrowserModule.GetAllAssetViewContextMenuExtenders() + }; + + ContextMenuDelegates.Add(FContentBrowserMenuExtender_SelectedAssets::CreateStatic(&OnExtendAssetSelectionMenu)); +} + +TSharedRef FSGContentBrowserExtension::OnExtendAssetSelectionMenu( + const TArray& SelectedAssets) +{ + TSharedRef Extender{MakeShared()}; + Extender->AddMenuExtension( + "CommonAssetActions", + EExtensionHook::After, + nullptr, + FMenuExtensionDelegate::CreateStatic(&AssetExtenderCallback, SelectedAssets) + ); + return MoveTemp(Extender); +} + +void FSGContentBrowserExtension::AssetExtenderCallback( + FMenuBuilder& MenuBuilder, const TArray SelectedAssets) +{ + bool bShouldExtendTheMenu = true; + bool bAnySkeletalMeshSelected = false; + bool bAnySkeletonSelected = false; + + for (const FAssetData& Asset: SelectedAssets) + { + if (Asset.IsRedirector() + || FName{*Asset.AssetClassPath.ToString()} == NAME_Class + || (Asset.PackageFlags & PKG_FilterEditorOnly)) + { + bShouldExtendTheMenu = false; + break; + } + + const bool bIsChildOfUSkeletalMesh = Asset.GetClass()->IsChildOf(USkeletalMesh::StaticClass()); + const bool bIsChildOfUSkeleton = Asset.GetClass()->IsChildOf(USkeleton::StaticClass()); + + if (!bIsChildOfUSkeletalMesh && !bIsChildOfUSkeleton) + { + bShouldExtendTheMenu = false; + break; + } + + if (bIsChildOfUSkeletalMesh) + { + bAnySkeletalMeshSelected = true; + } + + if (bIsChildOfUSkeleton) + { + bAnySkeletonSelected = true; + } + + if (bAnySkeletalMeshSelected && bAnySkeletonSelected) + { + bShouldExtendTheMenu = false; + break; + } + } + + if (!bShouldExtendTheMenu) + { + return; + } + + MenuBuilder.BeginSection(FName{TEXT("SenseGloveSection")}, LOCTEXT("SenseGloveHeading", "SenseGlove")); + + MenuBuilder.AddMenuEntry( + LOCTEXT("SenseGloveAddSocketsLabel", "Add SenseGlove Sockets"), + LOCTEXT("SenseGloveAddSocketsToolTip", "Adds and sets up the SenseGlove grab and touch sockets"), + FSGPluginStyle::GetStyleSetIcon(), + FUIAction{ + FExecuteAction::CreateLambda([SelectedAssets]()-> void + { + FImpl::TryAddSenseGloveSockets(SelectedAssets); + }) + }, + NAME_None, + EUserInterfaceActionType::Button, + NAME_None); + + MenuBuilder.AddMenuEntry( + LOCTEXT("SenseGloveClearExistingSocketsLabel", "Clear Existing Sockets"), + LOCTEXT("SenseGloveClearExistingSocketsToolTip", + "Clears all the existing sockets; SenseGlove or otherwise"), + FSGPluginStyle::GetStyleSetIcon(), + FUIAction{ + FExecuteAction::CreateLambda([SelectedAssets]()-> void + { + FImpl::TryClearExistingSockets(SelectedAssets); + }) + }, + NAME_None, + EUserInterfaceActionType::Button, + NAME_None); + + MenuBuilder.EndSection(); +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SGEditor/SGPluginStyle.cpp b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SGEditor/SGPluginStyle.cpp new file mode 100644 index 0000000..8a401b4 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SGEditor/SGPluginStyle.cpp @@ -0,0 +1,169 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGEditor/SGPluginStyle.h" + +#include "Interfaces/IPluginManager.h" +#include "Styling/SlateStyleRegistry.h" + +#define LOCTEXT_NAMESPACE "SGPluginStyle" + +struct FSGPluginStyle::FImpl +{ + /************************ + * Static methods + ************************/ + + static FString GetPluginName(); + static FString GetPluginBaseDir(); + static FString GetPluginResourcesDir(); + static FString GetPluginIconPath(); + + /************************ + * Member variables + ************************/ + + /************************ + * Owner object + ************************/ + + FSGPluginStyle* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGPluginStyle* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; + + /************************ + * Methods + ************************/ + + void RegisterIcon(); + void Register(); + void Unregister(); +}; + +FString FSGPluginStyle::FImpl::GetPluginName() +{ + static const FString PluginName{"SenseGlove"}; + return PluginName; +} + +FString FSGPluginStyle::FImpl::GetPluginBaseDir() +{ + const FString PluginName{FImpl::GetPluginName()}; + const FString BaseDir{IPluginManager::Get().FindPlugin(PluginName)->GetBaseDir()}; + return BaseDir; +} + +FString FSGPluginStyle::FImpl::GetPluginResourcesDir() +{ + const FString BaseDir{GetPluginBaseDir()}; + const FString ResourcesDir{FPaths::Combine(BaseDir, "Resources")}; + return ResourcesDir; + +} + +FString FSGPluginStyle::FImpl::GetPluginIconPath() +{ + const FString ResourcesDir{GetPluginResourcesDir()}; + const FString IconPath{FPaths::Combine(ResourcesDir, "Icon128.png")}; + return IconPath; +} + +FSGPluginStyle::FSGPluginStyle() + : FSlateStyleSet{FName{TEXT("SenseGlove")}}, + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGPluginStyle::~FSGPluginStyle() = default; + +void FSGPluginStyle::Initialize() const +{ + Pimpl->Register(); +} + +void FSGPluginStyle::Deinitialize() const +{ + Pimpl->Unregister(); +} + +FSGPluginStyle::FImpl::FImpl(FSGPluginStyle* InOwner) + : Owner(InOwner) +{ +} + +FSGPluginStyle::FImpl::~FImpl() = default; + +void FSGPluginStyle::FImpl::RegisterIcon() +{ + FName IconName{FSGPluginStyle::GetStyleSetIconName()}; + FString IconPath{GetPluginIconPath()}; + FVector2d IconSize{128.0f, 128.0f}; + + Owner->Set(MoveTemp(IconName), + new FSlateImageBrush{ + MoveTemp(IconPath), MoveTemp(IconSize) + }); +} + +void FSGPluginStyle::FImpl::Register() +{ + RegisterIcon(); + + FSlateStyleRegistry::RegisterSlateStyle(*Owner); +} + +void FSGPluginStyle::FImpl::Unregister() +{ + FSlateStyleRegistry::UnRegisterSlateStyle(*Owner); +} + +void FSGPluginStyle::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SGEditor/SGSocketsEditor.cpp b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SGEditor/SGSocketsEditor.cpp new file mode 100644 index 0000000..b70901a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SGEditor/SGSocketsEditor.cpp @@ -0,0 +1,277 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGEditor/SGSocketsEditor.h" + +#include "Framework/MultiBox/MultiBoxExtender.h" +#include "ISkeletonEditorModule.h" +#include "Modules/ModuleManager.h" + +#include "SGEditor/SGPluginStyle.h" +#include "SGEditor/SGSocketsEditorCommands.h" + +#define LOCTEXT_NAMESPACE "SocketsEditor" + +struct FSGSocketsEditor::FImpl +{ + /************************ + * Member variables + ************************/ + + // TSharedPtr AssetActions; + TSharedPtr EditorCommands; + TSharedPtr MenuExtender; + TSharedPtr ToolbarExtender; + + /************************ + * Owner object + ************************/ + + FSGSocketsEditor* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGSocketsEditor* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + +TSharedRef FSGSocketsEditor::GetInstance() +{ + static TSharedPtr Instance{MakeShared()}; + return Instance.ToSharedRef(); +} + +FSGSocketsEditor::FSGSocketsEditor() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSGSocketsEditor::~FSGSocketsEditor() = default; + +void FSGSocketsEditor::Initialize() const +{ + RegisterCommands(); + ExtendMenu(); + ExtendToolbar(); +} + +void FSGSocketsEditor::Deinitialize() const +{ + UnregisterCommands(); +} + +void FSGSocketsEditor::RegisterCommands() const +{ + if (Pimpl->EditorCommands.IsValid()) + { + Pimpl->EditorCommands.Reset(); + } + Pimpl->EditorCommands = MakeShared(); + Pimpl->EditorCommands->RegisterCommands(); +} + +void FSGSocketsEditor::UnregisterCommands() const +{ + if (!Pimpl->EditorCommands.IsValid()) + { + return; + } + Pimpl->EditorCommands->Unregister(); +} + +void FSGSocketsEditor::ExtendMenu() const +{ + if (Pimpl->MenuExtender.IsValid()) + { + Pimpl->MenuExtender.Reset(); + } + Pimpl->MenuExtender = MakeShared(); + + ISkeletonEditorModule& SkeletalMeshEditorModule{ + FModuleManager::LoadModuleChecked("SkeletalMeshEditor") + }; + + ISkeletonEditorModule& SkeletonEditorModule{ + FModuleManager::LoadModuleChecked("SkeletonEditor") + }; + + const TSharedPtr SkeletalMeshExtensibilityManager{ + SkeletalMeshEditorModule.GetMenuExtensibilityManager() + }; + + const TSharedPtr SkeletonExtensibilityManager{ + SkeletonEditorModule.GetMenuExtensibilityManager() + }; + + if (!ensureAlwaysMsgf(SkeletonExtensibilityManager.IsValid(), + TEXT("Invalid SkeletonExtensibilityManager!"))) + { + return; + } + + if (!ensureAlwaysMsgf(SkeletalMeshExtensibilityManager.IsValid(), + TEXT("Invalid SkeletalMeshExtensibilityManager!"))) + { + return; + } + + Pimpl->MenuExtender->AddMenuExtension( + FName{TEXT("AssetEditorActions")}, + EExtensionHook::After, + Pimpl->EditorCommands->CommandList, + FMenuExtensionDelegate::CreateLambda([&](FMenuBuilder MenuBuilder)-> void + { + MenuBuilder.BeginSection(FName{TEXT("SenseGlove")}, LOCTEXT("SenseGloveHeading", "SenseGlove")); + { + MenuBuilder.AddMenuEntry( + Pimpl->EditorCommands->SenseGloveAddSockets, + NAME_None, + LOCTEXT("SenseGloveAddSocketsLabel", "Add SenseGlove Sockets"), + LOCTEXT( + "SenseGloveAddSocketsToolTip", "Adds and sets up the SenseGlove grab and touch sockets"), + FSGPluginStyle::GetStyleSetIcon(), + NAME_None); + + MenuBuilder.AddMenuEntry( + Pimpl->EditorCommands->SenseGloveClearExistingSockets, + NAME_None, + LOCTEXT("SenseGloveClearExistingSocketsLabel", "Clear Existing Sockets"), + LOCTEXT( + "SenseGloveClearSocketsToolTip", "Clears all sockets; SenseGlove or otherwise"), + FSlateIcon{FSGPluginStyle::GetStyleSetIcon()}, + NAME_None); + } + MenuBuilder.EndSection(); + })); + + SkeletalMeshExtensibilityManager->AddExtender(Pimpl->MenuExtender); + SkeletonExtensibilityManager->AddExtender(Pimpl->MenuExtender); +} + +void FSGSocketsEditor::ExtendToolbar() const +{ + if (Pimpl->ToolbarExtender.IsValid()) + { + Pimpl->ToolbarExtender.Reset(); + } + Pimpl->ToolbarExtender = MakeShared(); + + ISkeletonEditorModule& SkeletalMeshEditorModule{ + FModuleManager::LoadModuleChecked("SkeletalMeshEditor") + }; + + ISkeletonEditorModule& SkeletonEditorModule{ + FModuleManager::LoadModuleChecked("SkeletonEditor") + }; + + const TSharedPtr SkeletalMeshExtensibilityManager{ + SkeletalMeshEditorModule.GetToolBarExtensibilityManager() + }; + + const TSharedPtr SkeletonExtensibilityManager{ + SkeletonEditorModule.GetToolBarExtensibilityManager() + }; + + if (!ensureAlwaysMsgf(SkeletonExtensibilityManager.IsValid(), + TEXT("Invalid SkeletonExtensibilityManager!"))) + { + return; + } + + if (!ensureAlwaysMsgf(SkeletalMeshExtensibilityManager.IsValid(), + TEXT("Invalid SkeletalMeshExtensibilityManager!"))) + { + return; + } + + Pimpl->ToolbarExtender->AddToolBarExtension( + FName{TEXT("SkeletalMesh")}, + EExtensionHook::After, + Pimpl->EditorCommands->CommandList, + FToolBarExtensionDelegate::CreateLambda([&](FToolBarBuilder& ToolbarBuilder)-> void + { + ToolbarBuilder.BeginSection(FName{TEXT("SenseGlove")}); + { + ToolbarBuilder.AddToolBarButton( + Pimpl->EditorCommands->SenseGloveAddSockets, + NAME_None, + LOCTEXT("SenseGloveAddSocketsLabel", "Add SenseGlove Sockets"), + LOCTEXT( + "SenseGloveAddSocketsToolTip", "Adds and sets up the SenseGlove grab and touch sockets"), + FSGPluginStyle::GetStyleSetIcon(), + NAME_None, + FNewMenuDelegate{} + ); + + ToolbarBuilder.AddToolBarButton( + Pimpl->EditorCommands->SenseGloveClearExistingSockets, + NAME_None, + LOCTEXT("SenseGloveClearExistingSocketsLabel", "Clear Existing Sockets"), + LOCTEXT( + "SenseGloveClearSocketsToolTip", "Clears all sockets; SenseGlove or otherwise"), + FSGPluginStyle::GetStyleSetIcon(), + NAME_None, + FNewMenuDelegate{} + ); + } + ToolbarBuilder.EndSection(); + })); + + SkeletalMeshExtensibilityManager->AddExtender(Pimpl->ToolbarExtender); + SkeletonExtensibilityManager->AddExtender(Pimpl->ToolbarExtender); +} + +FSGSocketsEditor::FImpl::FImpl(FSGSocketsEditor* InOwner) + : Owner(InOwner) +{ +} + +FSGSocketsEditor::FImpl::~FImpl() = default; + +void FSGSocketsEditor::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SGEditor/SGSocketsEditorCommands.cpp b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SGEditor/SGSocketsEditorCommands.cpp new file mode 100644 index 0000000..50ef9f3 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SGEditor/SGSocketsEditorCommands.cpp @@ -0,0 +1,224 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGEditor/SGSocketsEditorCommands.h" + +#include "Animation/Skeleton.h" +#include "Containers/UnrealString.h" +#include "Engine/SkeletalMesh.h" +#include "Framework/Commands/UIAction.h" +#include "GenericPlatform/GenericPlatformMisc.h" +#include "Internationalization/Text.h" +#include "Misc/MessageDialog.h" +#include "UObject/Object.h" + +#include "SGEditor/SGAssetUtils.h" +#include "SGEditor/SGPluginStyle.h" + +#define LOCTEXT_NAMESPACE "SocketsEditorCommands" + +struct FSGSocketsEditorCommands::FImpl +{ + /************************ + * Static methods + ************************/ + + static void TryAddSenseGloveSockets(); + static void TryClearExistingSockets(); +}; + +void FSGSocketsEditorCommands::FImpl::TryAddSenseGloveSockets() +{ + const FText ConfirmationDialogText{ + LOCTEXT("SenseGloveAddSocketsConfirmation", + "Do you want to add the SenseGlove sockets?") + }; + const EAppReturnType::Type DialogResult{ + FMessageDialog::Open(EAppMsgType::YesNo, ConfirmationDialogText) + }; + + if (DialogResult != EAppReturnType::Yes) + { + return; + } + + UObject* EditedAsset{FSGAssetUtils::GetEditedAsset()}; + USkeletalMesh* EditedSkeletalMesh{Cast(EditedAsset)}; + USkeleton* EditedSkeleton{Cast(EditedAsset)}; + + bool bAddedSenseGloveSockets = false; + if (IsValid(EditedSkeletalMesh)) + { + bAddedSenseGloveSockets = FSGAssetUtils::AddSenseGloveSockets(EditedSkeletalMesh); + } + else if (IsValid(EditedSkeleton)) + { + bAddedSenseGloveSockets = FSGAssetUtils::AddSenseGloveSockets(EditedSkeleton); + } + + if (bAddedSenseGloveSockets) + { + const FText ResultDialogText{ + LOCTEXT("SenseGloveAddSocketsResultSuccess", + "Successfully added the SenseGlove grab and touch sockets. If you wish the changes to persist, save" + " the modified asset(s) now!") + }; + FMessageDialog::Open(EAppMsgType::Ok, ResultDialogText); + } + else + { + const FText ResultDialogText{ + LOCTEXT("SenseGloveAddSocketsResultSuccessFailed", + "Failed to add the SenseGlove sockets!") + }; + FMessageDialog::Open(EAppMsgType::Ok, ResultDialogText); + } +} + +void FSGSocketsEditorCommands::FImpl::TryClearExistingSockets() +{ + const FText ConfirmationDialogText{ + LOCTEXT("SenseGloveClearExistingSocketsConfirmation", + "Are you sure you want to clear all the existing sockets? This cannot be undone!") + }; + const EAppReturnType::Type DialogResult{ + FMessageDialog::Open(EAppMsgType::YesNo, ConfirmationDialogText) + }; + + if (DialogResult != EAppReturnType::Yes) + { + return; + } + + UObject* EditedAsset{FSGAssetUtils::GetEditedAsset()}; + USkeletalMesh* EditedSkeletalMesh{Cast(EditedAsset)}; + USkeleton* EditedSkeleton{Cast(EditedAsset)}; + + bool bClearedExistingSockets = false; + if (IsValid(EditedSkeletalMesh)) + { + bClearedExistingSockets = FSGAssetUtils::ClearExistingSockets(EditedSkeletalMesh); + } + else if (IsValid(EditedSkeleton)) + { + bClearedExistingSockets = FSGAssetUtils::ClearExistingSockets(EditedSkeleton); + } + + if (bClearedExistingSockets) + { + const FText ResultDialogText{ + LOCTEXT("SenseGloveClearExistingSocketsResultSuccess", + "Successfully cleared all the existing sockets! If you wish the changes to persist, save the" + " modified asset(s) now!") + }; + FMessageDialog::Open(EAppMsgType::Ok, ResultDialogText); + } + else + { + const FText ResultDialogText{ + LOCTEXT("SenseGloveClearExistingSocketsResultSuccessFailed", + "Failed to clear all the existing sockets!") + }; + FMessageDialog::Open(EAppMsgType::Ok, ResultDialogText); + } +} + +FSGSocketsEditorCommands::FSGSocketsEditorCommands() + : TCommands{ + TEXT("SGSocketsEditor"), + NSLOCTEXT("Contexts", "SGSocketsEditor", "SenseGlove Sockets Editor"), + NAME_None, + FSGPluginStyle::GetInstance()->GetStyleSetName() + } +{ +} + +FSGSocketsEditorCommands::~FSGSocketsEditorCommands() = default; + +void FSGSocketsEditorCommands::RegisterCommands() +{ + if (CommandList.IsValid()) + { + CommandList.Reset(); + } + + CommandList = MakeShared(); + + if (SenseGloveAddSockets.IsValid()) + { + SenseGloveAddSockets.Reset(); + } + + if (SenseGloveClearExistingSockets.IsValid()) + { + SenseGloveClearExistingSockets.Reset(); + } + + UI_COMMAND(SenseGloveAddSockets, + "Add SenseGlove Sockets", + "Adds and sets up the SenseGlove grab and touch sockets", + EUserInterfaceActionType::Button, + FInputChord{}); + + UI_COMMAND(SenseGloveClearExistingSockets, + "Clear Existing Sockets", + "Clears all the existing sockets; SenseGlove or otherwise", + EUserInterfaceActionType::Button, + FInputChord{}); + + CommandList->MapAction(SenseGloveAddSockets, + FExecuteAction::CreateLambda([&]()-> void + { + FImpl::TryAddSenseGloveSockets(); + }), + FCanExecuteAction::CreateLambda([&]()-> bool + { + return true; + }), + EUIActionRepeatMode::RepeatDisabled); + + CommandList->MapAction(SenseGloveClearExistingSockets, + FExecuteAction::CreateLambda([&]()-> void + { + FImpl::TryClearExistingSockets(); + }), + FCanExecuteAction::CreateLambda([&]()-> bool + { + return true; + }), + EUIActionRepeatMode::RepeatDisabled); +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SenseGloveEditor.cpp b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SenseGloveEditor.cpp new file mode 100644 index 0000000..3fabad0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SenseGloveEditor.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveEditor.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveEditorModule.h" + +IMPLEMENT_MODULE(FSenseGloveEditorModule, SenseGloveEditor) diff --git a/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SenseGloveEditor.h b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SenseGloveEditor.h new file mode 100644 index 0000000..a30ce66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SenseGloveEditor.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SenseGloveEditorModule.cpp b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SenseGloveEditorModule.cpp new file mode 100644 index 0000000..e40f349 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SenseGloveEditorModule.cpp @@ -0,0 +1,72 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveEditorModule.h" + +#include "SGEditor/SGContentBrowserExtension.h" +#include "SGEditor/SGPluginStyle.h" +#include "SGEditor/SGSocketsEditor.h" +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveEditorModule" + +void FSenseGloveEditorModule::StartupModule() +{ + SGLOG("Starting up SenseGloveEditor module..."); + + FSGPluginStyle::GetInstance()->Initialize(); + FSGContentBrowserExtension::Register(); + FSGSocketsEditor::GetInstance()->Initialize(); +} + +void FSenseGloveEditorModule::PreUnloadCallback() +{ + SGLOG("Unloading SenseGloveEditor module..."); +} + +void FSenseGloveEditorModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveEditor module has succeeded!"); +} + +void FSenseGloveEditorModule::ShutdownModule() +{ + SGLOG("Shutting down SenseGloveEditor module..."); + + FSGSocketsEditor::GetInstance()->Deinitialize(); + FSGPluginStyle::GetInstance()->Deinitialize(); +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SenseGloveEditorModule.h b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SenseGloveEditorModule.h new file mode 100644 index 0000000..12704c1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveEditor/Private/SenseGloveEditorModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveEditor" + +class FSenseGloveEditorModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveEditor/Public/SGEditor/SGAssetUtils.h b/Plugins/SenseGlove/Source/SenseGloveEditor/Public/SGEditor/SGAssetUtils.h new file mode 100644 index 0000000..eabd91a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveEditor/Public/SGEditor/SGAssetUtils.h @@ -0,0 +1,72 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "HAL/Platform.h" +#include "Templates/SharedPointer.h" + +class IAssetEditorInstance; +class UAssetEditorSubsystem; +class USkeletalMesh; +class USkeleton; +class UObject; + +class SENSEGLOVEEDITOR_API FSGAssetUtils final +{ +public: + static UAssetEditorSubsystem* GetAssetEditorSubsystem(); + + static UObject* GetEditedAsset(); + + static bool IsAssetEditorOpenForAsset(UObject* Asset); + static TArray FindEditorsForAsset(UObject* Asset); + static bool OpenEditorForAsset(UObject* Asset); + static int32 CloseAllEditorsForAsset(UObject* Asset); + + static bool AddSenseGloveSockets(USkeletalMesh* SkeletalMesh); + static bool AddSenseGloveSockets(USkeleton* Skeleton); + + static bool ClearExistingSockets(USkeletalMesh* SkeletalMesh); + static bool ClearExistingSockets(USkeleton* Skeleton); + +private: + struct FImpl; + +private: + FSGAssetUtils() = delete; + virtual ~FSGAssetUtils() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveEditor/Public/SGEditor/SGContentBrowserExtension.h b/Plugins/SenseGlove/Source/SenseGloveEditor/Public/SGEditor/SGContentBrowserExtension.h new file mode 100644 index 0000000..24e73b8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveEditor/Public/SGEditor/SGContentBrowserExtension.h @@ -0,0 +1,60 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Templates/SharedPointer.h" + +struct FAssetData; +class FMenuBuilder; +class USkeletalMesh; + +class SENSEGLOVEEDITOR_API FSGContentBrowserExtension +{ +public: + static void Register(); + +protected: + static TSharedRef OnExtendAssetSelectionMenu(const TArray& SelectedAssets); + static void AssetExtenderCallback(FMenuBuilder& MenuBuilder, const TArray SelectedAssets); + +private: + struct FImpl; + +private: + FSGContentBrowserExtension() = delete; + virtual ~FSGContentBrowserExtension() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveEditor/Public/SGEditor/SGPluginStyle.h b/Plugins/SenseGlove/Source/SenseGloveEditor/Public/SGEditor/SGPluginStyle.h new file mode 100644 index 0000000..51bf54d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveEditor/Public/SGEditor/SGPluginStyle.h @@ -0,0 +1,82 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Styling/SlateStyle.h" +#include "Templates/SharedPointer.h" + +class ISlateStyle; + +class SENSEGLOVEEDITOR_API FSGPluginStyle final : public FSlateStyleSet +{ +public: + FORCEINLINE static TSharedRef GetInstance() + { + static TSharedPtr Instance{MakeShared()}; + return Instance.ToSharedRef(); + } + + FORCEINLINE static const FName& GetStyleSetIconName() + { + static const FName IconName{TEXT("SenseGlove.Icon")}; + return IconName; + } + + FORCEINLINE static const FSlateIcon& GetStyleSetIcon() + { + static FSlateIcon Icon{GetInstance()->GetStyleSetName(), GetStyleSetIconName()}; + return Icon; + } + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGPluginStyle(); + virtual ~FSGPluginStyle(); + +public: + void Initialize() const; + void Deinitialize() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveEditor/Public/SGEditor/SGSocketsEditor.h b/Plugins/SenseGlove/Source/SenseGloveEditor/Public/SGEditor/SGSocketsEditor.h new file mode 100644 index 0000000..5bc6f45 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveEditor/Public/SGEditor/SGSocketsEditor.h @@ -0,0 +1,71 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Framework/MultiBox/MultiBoxExtender.h" +#include "Templates/SharedPointer.h" + +class SENSEGLOVEEDITOR_API FSGSocketsEditor +{ +public: + static TSharedRef GetInstance(); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + FSGSocketsEditor(); + virtual ~FSGSocketsEditor(); + +public: + void Initialize() const; + void Deinitialize() const; + + void RegisterCommands() const; + void UnregisterCommands() const; + + void ExtendMenu() const; + + void ExtendToolbar() const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveEditor/Public/SGEditor/SGSocketsEditorCommands.h b/Plugins/SenseGlove/Source/SenseGloveEditor/Public/SGEditor/SGSocketsEditorCommands.h new file mode 100644 index 0000000..4a76b13 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveEditor/Public/SGEditor/SGSocketsEditorCommands.h @@ -0,0 +1,58 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Framework/Commands/Commands.h" +#include "Framework/Commands/UICommandList.h" +#include "Templates/SharedPointer.h" + +class SENSEGLOVEEDITOR_API FSGSocketsEditorCommands final : public TCommands +{ +public: + TSharedPtr CommandList; + TSharedPtr SenseGloveAddSockets; + TSharedPtr SenseGloveClearExistingSockets; + +private: + struct FImpl; + +public: + FSGSocketsEditorCommands(); + virtual ~FSGSocketsEditorCommands() override; + +public: + virtual void RegisterCommands() override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveEditor/SenseGloveEditor.Build.cs b/Plugins/SenseGlove/Source/SenseGloveEditor/SenseGloveEditor.Build.cs new file mode 100644 index 0000000..2d41542 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveEditor/SenseGloveEditor.Build.cs @@ -0,0 +1,71 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGloveEditor : ModuleRules +{ + public SenseGloveEditor(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "AssetTools", + "Core", + "CoreUObject", + "Engine", + "InputCore", + "Projects", + "SkeletalMeshEditor", + "SkeletonEditor", + "Slate", + "SlateCore", + "UnrealEd", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveLog", + "SenseGloveSettings", + "SenseGloveTypes", + } + ); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGBackendType.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGBackendType.cpp new file mode 100644 index 0000000..304334f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGBackendType.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGBackendType.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGConnectionType.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGConnectionType.cpp new file mode 100644 index 0000000..3dfe7f8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGConnectionType.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGConnectionType.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGDeviceType.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGDeviceType.cpp new file mode 100644 index 0000000..9314e86 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGDeviceType.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGDeviceType.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGFinger.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGFinger.cpp new file mode 100644 index 0000000..eee22ba --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGFinger.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGFinger.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGFingerMovement.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGFingerMovement.cpp new file mode 100644 index 0000000..3d50932 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGFingerMovement.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGFingerMovement.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGFingerSolver.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGFingerSolver.cpp new file mode 100644 index 0000000..413988a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGFingerSolver.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGFingerSolver.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGHapticChannelType.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGHapticChannelType.cpp new file mode 100644 index 0000000..4fe08ef --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGHapticChannelType.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGHapticChannelType.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGHapticGloveCalibrationState.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGHapticGloveCalibrationState.cpp new file mode 100644 index 0000000..891e781 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGHapticGloveCalibrationState.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGHapticGloveCalibrationState.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGHapticLocation.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGHapticLocation.cpp new file mode 100644 index 0000000..7e4fb37 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGHapticLocation.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGHapticLocation.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGListFormat.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGListFormat.cpp new file mode 100644 index 0000000..07a371c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGListFormat.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGListFormat.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNormalizationState.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNormalizationState.cpp new file mode 100644 index 0000000..169453f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNormalizationState.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGNormalizationState.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNova2SensorLocation.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNova2SensorLocation.cpp new file mode 100644 index 0000000..961fccc --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNova2SensorLocation.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGNova2SensorLocation.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNova2VibroMotor.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNova2VibroMotor.cpp new file mode 100644 index 0000000..051786f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNova2VibroMotor.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGNova2VibroMotor.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNovaCVar.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNovaCVar.cpp new file mode 100644 index 0000000..c2d8e58 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNovaCVar.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGNovaCVar.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNovaData.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNovaData.cpp new file mode 100644 index 0000000..0422214 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNovaData.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGNovaData.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNovaSensorLocation.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNovaSensorLocation.cpp new file mode 100644 index 0000000..8e50951 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNovaSensorLocation.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGNovaSensorLocation.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNovaVibroMotor.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNovaVibroMotor.cpp new file mode 100644 index 0000000..da0c4b0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGNovaVibroMotor.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGNovaVibroMotor.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGPositionalTrackingHardware.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGPositionalTrackingHardware.cpp new file mode 100644 index 0000000..b8101b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGPositionalTrackingHardware.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGPositionalTrackingHardware.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGSenseGloveCVar.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGSenseGloveCVar.cpp new file mode 100644 index 0000000..3f63c27 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGSenseGloveCVar.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGSenseGloveCVar.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGSenseGloveSVar.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGSenseGloveSVar.cpp new file mode 100644 index 0000000..07317b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGSenseGloveSVar.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGSenseGloveSVar.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGSenseGloveThumperCommand.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGSenseGloveThumperCommand.cpp new file mode 100644 index 0000000..6a3ef4c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGSenseGloveThumperCommand.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGSenseGloveThumperCommand.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGSensorFormat.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGSensorFormat.cpp new file mode 100644 index 0000000..4381093 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGSensorFormat.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGSensorFormat.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGThumbMovement.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGThumbMovement.cpp new file mode 100644 index 0000000..fdfe075 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGThumbMovement.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGThumbMovement.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGThumbSolver.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGThumbSolver.cpp new file mode 100644 index 0000000..1340e6d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGThumbSolver.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGThumbSolver.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGWaveformType.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGWaveformType.cpp new file mode 100644 index 0000000..3b7fc30 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_ESGWaveformType.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_ESGWaveformType.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FQuat.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FQuat.cpp new file mode 100644 index 0000000..f2d879f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FQuat.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FQuat.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGBasicHandModelImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGBasicHandModelImpl.cpp new file mode 100644 index 0000000..e3bbc8e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGBasicHandModelImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGBasicHandModelImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGBetaDeviceImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGBetaDeviceImpl.cpp new file mode 100644 index 0000000..9dc59a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGBetaDeviceImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGBetaDeviceImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGCustomWaveformImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGCustomWaveformImpl.cpp new file mode 100644 index 0000000..2211482 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGCustomWaveformImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGCustomWaveformImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGDeviceImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGDeviceImpl.cpp new file mode 100644 index 0000000..669411d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGDeviceImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGDeviceImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGDeviceModelImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGDeviceModelImpl.cpp new file mode 100644 index 0000000..2169049 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGDeviceModelImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGDeviceModelImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGHandInterpolatorImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGHandInterpolatorImpl.cpp new file mode 100644 index 0000000..b52cf82 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGHandInterpolatorImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGHandInterpolatorImpl.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGHandPoseImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGHandPoseImpl.cpp new file mode 100644 index 0000000..dbbcdbe --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGHandPoseImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGHandPoseImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGHapticChannelInfoImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGHapticChannelInfoImpl.cpp new file mode 100644 index 0000000..b684f21 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGHapticChannelInfoImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGHapticChannelInfoImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGHapticGloveImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGHapticGloveImpl.cpp new file mode 100644 index 0000000..303626e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGHapticGloveImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGHapticGloveImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGInterpolationSetImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGInterpolationSetImpl.cpp new file mode 100644 index 0000000..157ae39 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGInterpolationSetImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGInterpolationSetImpl.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGNova2GloveImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGNova2GloveImpl.cpp new file mode 100644 index 0000000..b7037af --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGNova2GloveImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGNova2GloveImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGNova2GloveSensorDataImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGNova2GloveSensorDataImpl.cpp new file mode 100644 index 0000000..c9e256b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGNova2GloveSensorDataImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGNova2GloveSensorDataImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGNovaGloveImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGNovaGloveImpl.cpp new file mode 100644 index 0000000..ef5238d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGNovaGloveImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGNovaGloveImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGNovaGloveInfoImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGNovaGloveInfoImpl.cpp new file mode 100644 index 0000000..0ae19bd --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGNovaGloveInfoImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGNovaGloveInfoImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGNovaGloveSensorDataImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGNovaGloveSensorDataImpl.cpp new file mode 100644 index 0000000..85f74a1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGNovaGloveSensorDataImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGNovaGloveSensorDataImpl.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSenseGloveImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSenseGloveImpl.cpp new file mode 100644 index 0000000..ced08ce --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSenseGloveImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGSenseGloveImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSenseGloveInfoImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSenseGloveInfoImpl.cpp new file mode 100644 index 0000000..81bda54 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSenseGloveInfoImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGSenseGloveInfoImpl.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSenseGlovePoseImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSenseGlovePoseImpl.cpp new file mode 100644 index 0000000..31caa36 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSenseGlovePoseImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGSenseGlovePoseImpl.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSenseGloveSensorDataImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSenseGloveSensorDataImpl.cpp new file mode 100644 index 0000000..86d51c9 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSenseGloveSensorDataImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGSenseGloveSensorDataImpl.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSenseGloveSensorNormalizerImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSenseGloveSensorNormalizerImpl.cpp new file mode 100644 index 0000000..fce2c93 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSenseGloveSensorNormalizerImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGSenseGloveSensorNormalizerImpl.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSensorNormalizationImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSensorNormalizationImpl.cpp new file mode 100644 index 0000000..3c9e634 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGSensorNormalizationImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGSensorNormalizationImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGThresholdCommandImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGThresholdCommandImpl.cpp new file mode 100644 index 0000000..5ea5f55 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FSGThresholdCommandImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FSGThresholdCommandImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FString.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FString.cpp new file mode 100644 index 0000000..f3f5a3c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FString.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FString.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FVector.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FVector.cpp new file mode 100644 index 0000000..1da2f5f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_FVector.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_FVector.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_JNIEnv_Ptr.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_JNIEnv_Ptr.cpp new file mode 100644 index 0000000..633ba3d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_JNIEnv_Ptr.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_JNIEnv_Ptr.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FQuat.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FQuat.cpp new file mode 100644 index 0000000..eac58f2 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FQuat.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TArray_FQuat.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FSGNova2GloveImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FSGNova2GloveImpl.cpp new file mode 100644 index 0000000..0e2276a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FSGNova2GloveImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TArray_FSGNova2GloveImpl.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FSGNovaGloveImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FSGNovaGloveImpl.cpp new file mode 100644 index 0000000..efee7e9 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FSGNovaGloveImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TArray_FSGNovaGloveImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FSGSenseGloveImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FSGSenseGloveImpl.cpp new file mode 100644 index 0000000..07e33bb --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FSGSenseGloveImpl.cpp @@ -0,0 +1,35 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + +#include "SGInterop/SGIC_TArray_FSGSenseGloveImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FString.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FString.cpp new file mode 100644 index 0000000..84262c2 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FString.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TArray_FString.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FVector.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FVector.cpp new file mode 100644 index 0000000..7efa4a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_FVector.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TArray_FVector.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TArray_FQuat.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TArray_FQuat.cpp new file mode 100644 index 0000000..c5d211c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TArray_FQuat.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TArray_TArray_FQuat.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TArray_FSGInterpolationSetImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TArray_FSGInterpolationSetImpl.cpp new file mode 100644 index 0000000..94b6956 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TArray_FSGInterpolationSetImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TArray_TArray_FSGInterpolationSetImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TArray_FVector.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TArray_FVector.cpp new file mode 100644 index 0000000..9d5f9e6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TArray_FVector.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TArray_TArray_FVector.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TArray_bool.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TArray_bool.cpp new file mode 100644 index 0000000..34210d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TArray_bool.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TArray_TArray_bool.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TArray_float.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TArray_float.cpp new file mode 100644 index 0000000..fac98da --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TArray_float.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TArray_TArray_float.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TSharedRef_FSGDeviceImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TSharedRef_FSGDeviceImpl.cpp new file mode 100644 index 0000000..036721e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TSharedRef_FSGDeviceImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TArray_TSharedRef_FSGDeviceImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TSharedRef_FSGHapticGloveImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TSharedRef_FSGHapticGloveImpl.cpp new file mode 100644 index 0000000..433e6d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_TSharedRef_FSGHapticGloveImpl.cpp @@ -0,0 +1,35 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + +#include "SGInterop/SGIC_TArray_TSharedRef_FSGHapticGloveImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_bool.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_bool.cpp new file mode 100644 index 0000000..2e449e9 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_bool.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TArray_bool.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_float.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_float.cpp new file mode 100644 index 0000000..700522e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_float.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TArray_float.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_int32.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_int32.cpp new file mode 100644 index 0000000..08db712 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TArray_int32.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TArray_int32.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGBetaDeviceImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGBetaDeviceImpl.cpp new file mode 100644 index 0000000..3d46000 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGBetaDeviceImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TSharedPtr_FSGBetaDeviceImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGDeviceImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGDeviceImpl.cpp new file mode 100644 index 0000000..6793d81 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGDeviceImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TSharedPtr_FSGDeviceImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGHapticGloveImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGHapticGloveImpl.cpp new file mode 100644 index 0000000..b2b6843 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGHapticGloveImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TSharedPtr_FSGHapticGloveImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGNova2GloveImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGNova2GloveImpl.cpp new file mode 100644 index 0000000..4816879 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGNova2GloveImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TSharedPtr_FSGNova2GloveImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGNovaGloveImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGNovaGloveImpl.cpp new file mode 100644 index 0000000..e35d9fe --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGNovaGloveImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TSharedPtr_FSGNovaGloveImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGSenseGloveImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGSenseGloveImpl.cpp new file mode 100644 index 0000000..86fd26b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSharedPtr_FSGSenseGloveImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TSharedPtr_FSGSenseGloveImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSubclassOf_FSGDeviceImpl.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSubclassOf_FSGDeviceImpl.cpp new file mode 100644 index 0000000..e2f403b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_TSubclassOf_FSGDeviceImpl.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_TSubclassOf_FSGDeviceImpl.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_jclass.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_jclass.cpp new file mode 100644 index 0000000..754b21b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_jclass.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_jclass.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_jmethodID.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_jmethodID.cpp new file mode 100644 index 0000000..3831154 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SGInterop/SGIC_jmethodID.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGInterop/SGIC_jmethodID.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SenseGloveInterop.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SenseGloveInterop.cpp new file mode 100644 index 0000000..2eeaadd --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SenseGloveInterop.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveInterop.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveInteropModule.h" + +IMPLEMENT_MODULE(FSenseGloveInteropModule, SenseGloveInterop) diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SenseGloveInterop.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SenseGloveInterop.h new file mode 100644 index 0000000..ab121d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SenseGloveInterop.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SenseGloveInteropModule.cpp b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SenseGloveInteropModule.cpp new file mode 100644 index 0000000..307ac59 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SenseGloveInteropModule.cpp @@ -0,0 +1,61 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveInteropModule.h" +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveInteropModule" + +void FSenseGloveInteropModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveInterop module..."); +} + +void FSenseGloveInteropModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveInterop module..."); +} + +void FSenseGloveInteropModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveInterop module has succeeded!"); +} + +void FSenseGloveInteropModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveInterop module..."); +} + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SenseGloveInteropModule.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SenseGloveInteropModule.h new file mode 100644 index 0000000..b5980e5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Private/SenseGloveInteropModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveInterop" + +class FSenseGloveInteropModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGBackendType.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGBackendType.h new file mode 100644 index 0000000..5ea387e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGBackendType.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGBackendType +{ + ESGBackendType Type; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGConnectionType.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGConnectionType.h new file mode 100644 index 0000000..9dc9da6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGConnectionType.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGConnectionType +{ + ESGConnectionType Type; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGDeviceType.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGDeviceType.h new file mode 100644 index 0000000..db0d133 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGDeviceType.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGDeviceType +{ + ESGDeviceType Type; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGFinger.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGFinger.h new file mode 100644 index 0000000..f69f484 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGFinger.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGFinger +{ + ESGFinger Finger; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGFingerMovement.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGFingerMovement.h new file mode 100644 index 0000000..0c9d448 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGFingerMovement.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGFingerMovement +{ + ESGFingerMovement Movement; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGFingerSolver.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGFingerSolver.h new file mode 100644 index 0000000..e6bd867 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGFingerSolver.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGFingerSolver +{ + ESGFingerSolver Solver; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGHapticChannelType.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGHapticChannelType.h new file mode 100644 index 0000000..d5ab71a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGHapticChannelType.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGHapticChannelType +{ + ESGHapticChannelType Type; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGHapticGloveCalibrationState.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGHapticGloveCalibrationState.h new file mode 100644 index 0000000..de86799 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGHapticGloveCalibrationState.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGHapticGloveCalibrationState +{ + ESGHapticGloveCalibrationState State; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGHapticLocation.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGHapticLocation.h new file mode 100644 index 0000000..c7d5c41 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGHapticLocation.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGHapticLocation +{ + ESGHapticLocation Location; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGListFormat.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGListFormat.h new file mode 100644 index 0000000..c352a1e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGListFormat.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGListFormat +{ + ESGListFormat Format; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNormalizationState.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNormalizationState.h new file mode 100644 index 0000000..ed56955 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNormalizationState.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGNormalizationState +{ + ESGNormalizationState State; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNova2SensorLocation.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNova2SensorLocation.h new file mode 100644 index 0000000..19f8786 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNova2SensorLocation.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGNova2SensorLocation +{ + ESGNova2SensorLocation Location; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNova2VibroMotor.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNova2VibroMotor.h new file mode 100644 index 0000000..a6e3935 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNova2VibroMotor.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGNova2VibroMotor +{ + ESGNova2VibroMotor Motor; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNovaCVar.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNovaCVar.h new file mode 100644 index 0000000..9e5ad9e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNovaCVar.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGNovaCVar +{ + ESGNovaCVar Var; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNovaData.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNovaData.h new file mode 100644 index 0000000..e4aee2c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNovaData.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGNovaData +{ + ESGNovaData Data; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNovaSensorLocation.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNovaSensorLocation.h new file mode 100644 index 0000000..6500f5d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNovaSensorLocation.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGNovaSensorLocation +{ + ESGNovaSensorLocation Location; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNovaVibroMotor.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNovaVibroMotor.h new file mode 100644 index 0000000..010febb --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGNovaVibroMotor.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGNovaVibroMotor +{ + ESGNovaVibroMotor Motor; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGPositionalTrackingHardware.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGPositionalTrackingHardware.h new file mode 100644 index 0000000..ef546d2 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGPositionalTrackingHardware.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGPositionalTrackingHardware +{ + ESGPositionalTrackingHardware Hardware; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGSenseGloveCVar.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGSenseGloveCVar.h new file mode 100644 index 0000000..653c8ec --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGSenseGloveCVar.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGSenseGloveCVar +{ + ESGSenseGloveCVar Var; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGSenseGloveSVar.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGSenseGloveSVar.h new file mode 100644 index 0000000..ad47ad7 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGSenseGloveSVar.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGSenseGloveSVar +{ + ESGSenseGloveSVar Var; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGSenseGloveThumperCommand.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGSenseGloveThumperCommand.h new file mode 100644 index 0000000..6c8d15a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGSenseGloveThumperCommand.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGSenseGloveThumperCommand +{ + ESGSenseGloveThumperCommand Command; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGSensorFormat.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGSensorFormat.h new file mode 100644 index 0000000..3058c82 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGSensorFormat.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGSensorFormat +{ + ESGSensorFormat Format; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGThumbMovement.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGThumbMovement.h new file mode 100644 index 0000000..e1a752d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGThumbMovement.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGThumbMovement +{ + ESGThumbMovement Movement; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGThumbSolver.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGThumbSolver.h new file mode 100644 index 0000000..c127a6e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGThumbSolver.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGThumbSolver +{ + ESGThumbSolver Solver; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGWaveformType.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGWaveformType.h new file mode 100644 index 0000000..47cb958 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_ESGWaveformType.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGTypes/SGCoreTypes.h" + +struct FSGIC_ESGWaveformType +{ + ESGWaveformType Type; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FQuat.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FQuat.h new file mode 100644 index 0000000..11ac5a9 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FQuat.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Math/Quat.h" + +struct FSGIC_FQuat +{ + FQuat Quat; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGBasicHandModelImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGBasicHandModelImpl.h new file mode 100644 index 0000000..72c2241 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGBasicHandModelImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGBasicHandModelImpl.h" + +struct FSGIC_FSGBasicHandModelImpl +{ + FSGBasicHandModelImpl BasicHandModelImpl; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGBetaDeviceImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGBetaDeviceImpl.h new file mode 100644 index 0000000..edc558a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGBetaDeviceImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGBetaDeviceImpl.h" + +struct FSGIC_FSGBetaDeviceImpl +{ + FSGBetaDeviceImpl BetaDeviceImpl; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGCustomWaveformImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGCustomWaveformImpl.h new file mode 100644 index 0000000..dec1c89 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGCustomWaveformImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGCustomWaveformImpl.h" + +struct FSGIC_FSGCustomWaveformImpl +{ + FSGCustomWaveformImpl CustomWaveformImpl; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGDeviceImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGDeviceImpl.h new file mode 100644 index 0000000..630f9f3 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGDeviceImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGDeviceImpl.h" + +struct FSGIC_FSGDeviceImpl +{ + FSGDeviceImpl SGDeviceImpl; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGDeviceModelImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGDeviceModelImpl.h new file mode 100644 index 0000000..9287279 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGDeviceModelImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGDeviceModelImpl.h" + +struct FSGIC_FSGDeviceModelImpl +{ + FSGDeviceModelImpl DeviceModelImpl; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGHandInterpolatorImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGHandInterpolatorImpl.h new file mode 100644 index 0000000..39bc9d7 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGHandInterpolatorImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGHandInterpolatorImpl.h" + +struct FSGIC_FSGHandInterpolatorImpl +{ + FSGHandInterpolatorImpl HandInterpolatorImpl; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGHandPoseImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGHandPoseImpl.h new file mode 100644 index 0000000..b22ca79 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGHandPoseImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGHandPoseImpl.h" + +struct FSGIC_FSGHandPoseImpl +{ + FSGHandPoseImpl HandPoseImpl; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGHapticChannelInfoImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGHapticChannelInfoImpl.h new file mode 100644 index 0000000..94a724f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGHapticChannelInfoImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGHapticChannelInfoImpl.h" + +struct FSGIC_FSGHapticChannelInfoImpl +{ + FSGHapticChannelInfoImpl HapticChannelInfoImpl; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGHapticGloveImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGHapticGloveImpl.h new file mode 100644 index 0000000..a8f282b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGHapticGloveImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGHapticGloveImpl.h" + +struct FSGIC_FSGHapticGloveImpl +{ + FSGHapticGloveImpl HapticGloveImpl; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGInterpolationSetImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGInterpolationSetImpl.h new file mode 100644 index 0000000..844295e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGInterpolationSetImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGInterpolationSetImpl.h" + +struct FSGIC_FSGInterpolationSetImpl +{ + FSGInterpolationSetImpl InterpolationSetImpl; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGNova2GloveImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGNova2GloveImpl.h new file mode 100644 index 0000000..ad797e2 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGNova2GloveImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGNova2GloveImpl.h" + +struct FSGIC_FSGNova2GloveImpl +{ + FSGNova2GloveImpl Nova2GloveImpl; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGNova2GloveSensorDataImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGNova2GloveSensorDataImpl.h new file mode 100644 index 0000000..8b7ef3c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGNova2GloveSensorDataImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGNova2GloveSensorDataImpl.h" + +struct FSGIC_FSGNova2GloveSensorDataImpl +{ + FSGNova2GloveSensorDataImpl Nova2GloveSensorDataImpl; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGNovaGloveImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGNovaGloveImpl.h new file mode 100644 index 0000000..8d46951 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGNovaGloveImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGNovaGloveImpl.h" + +struct FSGIC_FSGNovaGloveImpl +{ + FSGNovaGloveImpl NovaGloveImpl; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGNovaGloveInfoImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGNovaGloveInfoImpl.h new file mode 100644 index 0000000..a81b6fa --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGNovaGloveInfoImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGNovaGloveInfoImpl.h" + +struct FSGIC_FSGNovaGloveInfoImpl +{ + FSGNovaGloveInfoImpl NovaGloveInfoImpl; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGNovaGloveSensorDataImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGNovaGloveSensorDataImpl.h new file mode 100644 index 0000000..7b4bc43 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGNovaGloveSensorDataImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGNovaGloveSensorDataImpl.h" + +struct FSGIC_FSGNovaGloveSensorDataImpl +{ + FSGNovaGloveSensorDataImpl NovaGloveSensorDataImpl; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSenseGloveImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSenseGloveImpl.h new file mode 100644 index 0000000..d1ae7b5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSenseGloveImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGSenseGloveImpl.h" + +struct FSGIC_FSGSenseGloveImpl +{ + FSGSenseGloveImpl SenseGloveImpl; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSenseGloveInfoImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSenseGloveInfoImpl.h new file mode 100644 index 0000000..4f65bc4 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSenseGloveInfoImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGSenseGloveInfoImpl.h" + +struct FSGIC_FSGSenseGloveInfoImpl +{ + FSGSenseGloveInfoImpl SenseGloveInfoImpl; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSenseGlovePoseImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSenseGlovePoseImpl.h new file mode 100644 index 0000000..62c3df8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSenseGlovePoseImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGSenseGlovePoseImpl.h" + +struct FSGIC_FSGSenseGlovePoseImpl +{ + FSGSenseGlovePoseImpl SenseGlovePoseImpl; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSenseGloveSensorDataImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSenseGloveSensorDataImpl.h new file mode 100644 index 0000000..5270b28 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSenseGloveSensorDataImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGSenseGloveSensorDataImpl.h" + +struct FSGIC_FSGSenseGloveSensorDataImpl +{ + FSGSenseGloveSensorDataImpl SenseGloveSensorDataImpl; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSenseGloveSensorNormalizerImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSenseGloveSensorNormalizerImpl.h new file mode 100644 index 0000000..c407a46 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSenseGloveSensorNormalizerImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGSenseGloveSensorNormalizerImpl.h" + +struct FSGIC_FSGSenseGloveSensorNormalizerImpl +{ + FSGSenseGloveSensorNormalizerImpl SenseGloveSensorNormalizerImpl; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSensorNormalizationImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSensorNormalizationImpl.h new file mode 100644 index 0000000..7f3d5b5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGSensorNormalizationImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGSensorNormalizationImpl.h" + +struct FSGIC_FSGSensorNormalizationImpl +{ + FSGSensorNormalizationImpl SensorNormalizationImpl; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGThresholdCommandImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGThresholdCommandImpl.h new file mode 100644 index 0000000..2cb20ee --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FSGThresholdCommandImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGThresholdCommandImpl.h" + +struct FSGIC_FSGThresholdCommandImpl +{ + FSGThresholdCommandImpl ThresholdCommandImpl; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FString.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FString.h new file mode 100644 index 0000000..a9cda2b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FString.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/UnrealString.h" + +struct FSGIC_FString +{ + FString String; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FVector.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FVector.h new file mode 100644 index 0000000..f1f3538 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_FVector.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Math/Vector.h" + +struct FSGIC_FVector +{ + FVector Vector; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_JNIEnv_Ptr.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_JNIEnv_Ptr.h new file mode 100644 index 0000000..c27a592 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_JNIEnv_Ptr.h @@ -0,0 +1,47 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" + +#if PLATFORM_ANDROID +#include "Android/AndroidJavaEnv.h" + +struct FSGIC_JNIEnv_Ptr +{ + JNIEnv* Ptr; +}; +#endif /* PLATFORM_ANDROID */ \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FQuat.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FQuat.h new file mode 100644 index 0000000..b9adac1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FQuat.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Math/Quat.h" + +struct FSGIC_TArray_FQuat +{ + TArray Array; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FSGNova2GloveImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FSGNova2GloveImpl.h new file mode 100644 index 0000000..9a83dd5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FSGNova2GloveImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGNova2GloveImpl.h" + +struct FSGIC_TArray_FSGNova2GloveImpl +{ + TArray Array; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FSGNovaGloveImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FSGNovaGloveImpl.h new file mode 100644 index 0000000..15cd804 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FSGNovaGloveImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGNovaGloveImpl.h" + +struct FSGIC_TArray_FSGNovaGloveImpl +{ + TArray Array; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FSGSenseGloveImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FSGSenseGloveImpl.h new file mode 100644 index 0000000..5fb647e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FSGSenseGloveImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGSenseGloveImpl.h" + +struct FSGIC_TArray_FSGSenseGloveImpl +{ + TArray Array; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FString.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FString.h new file mode 100644 index 0000000..67b4ef5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FString.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/UnrealString.h" + +struct FSGIC_TArray_FString +{ + TArray Array; +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FVector.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FVector.h new file mode 100644 index 0000000..6fcf53e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_FVector.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Math/Vector.h" + +struct FSGIC_TArray_FVector +{ + TArray Array; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TArray_FQuat.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TArray_FQuat.h new file mode 100644 index 0000000..10d9365 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TArray_FQuat.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Math/Quat.h" + +struct FSGIC_TArray_TArray_FQuat +{ + TArray> Array; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TArray_FSGInterpolationSetImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TArray_FSGInterpolationSetImpl.h new file mode 100644 index 0000000..53e21e3 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TArray_FSGInterpolationSetImpl.h @@ -0,0 +1,45 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" + +#include "SGCoreImpl/SGInterpolationSetImpl.h" + +struct FSGIC_TArray_TArray_FSGInterpolationSetImpl +{ + TArray> Array; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TArray_FVector.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TArray_FVector.h new file mode 100644 index 0000000..9c99c1e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TArray_FVector.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Math/Vector.h" + +struct FSGIC_TArray_TArray_FVector +{ + TArray> Array; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TArray_bool.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TArray_bool.h new file mode 100644 index 0000000..929e072 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TArray_bool.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" + +struct FSGIC_TArray_TArray_bool +{ + TArray> Array; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TArray_float.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TArray_float.h new file mode 100644 index 0000000..2cca213 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TArray_float.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" + +struct FSGIC_TArray_TArray_float +{ + TArray> Array; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TSharedRef_FSGDeviceImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TSharedRef_FSGDeviceImpl.h new file mode 100644 index 0000000..8ecd557 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TSharedRef_FSGDeviceImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGDeviceImpl.h" + +struct FSGIC_TArray_TSharedRef_FSGDeviceListImpl +{ + TArray> Array; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TSharedRef_FSGHapticGloveImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TSharedRef_FSGHapticGloveImpl.h new file mode 100644 index 0000000..301dd66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_TSharedRef_FSGHapticGloveImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGHapticGloveImpl.h" + +struct FSGIC_TArray_TSharedRef_FSGHapticGloveImpl +{ + TArray> Array; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_bool.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_bool.h new file mode 100644 index 0000000..21ac712 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_bool.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" + +struct FSGIC_TArray_bool +{ + TArray Array; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_float.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_float.h new file mode 100644 index 0000000..590b375 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_float.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" + +struct FSGIC_TArray_float +{ + TArray Array; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_int32.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_int32.h new file mode 100644 index 0000000..c30aed1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TArray_int32.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" + +struct FSGIC_TArray_int32 +{ + TArray Array; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGBetaDeviceImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGBetaDeviceImpl.h new file mode 100644 index 0000000..f058f40 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGBetaDeviceImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGBetaDeviceImpl.h" + +struct FSGIC_TSharedPtr_FSGBetaDeviceImpl +{ + TSharedPtr Ptr; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGDeviceImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGDeviceImpl.h new file mode 100644 index 0000000..699a987 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGDeviceImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGDeviceImpl.h" + +struct FSGIC_TSharedPtr_FSGDeviceImpl +{ + TSharedPtr Ptr; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGHapticGloveImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGHapticGloveImpl.h new file mode 100644 index 0000000..e1d78a8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGHapticGloveImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGHapticGloveImpl.h" + +struct FSGIC_TSharedPtr_FSGHapticGloveImpl +{ + TSharedPtr Ptr; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGNova2GloveImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGNova2GloveImpl.h new file mode 100644 index 0000000..182f0a3 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGNova2GloveImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGNova2GloveImpl.h" + +struct FSGIC_TSharedPtr_FSGNova2GloveImpl +{ + TSharedPtr Ptr; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGNovaGloveImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGNovaGloveImpl.h new file mode 100644 index 0000000..f516fa7 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGNovaGloveImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGNovaGloveImpl.h" + +struct FSGIC_TSharedPtr_FSGNovaGloveImpl +{ + TSharedPtr Ptr; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGSenseGloveImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGSenseGloveImpl.h new file mode 100644 index 0000000..15f7860 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSharedPtr_FSGSenseGloveImpl.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGCoreImpl/SGSenseGloveImpl.h" + +struct FSGIC_TSharedPtr_FSGSenseGloveImpl +{ + TSharedPtr Ptr; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSubclassOf_FSGDeviceImpl.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSubclassOf_FSGDeviceImpl.h new file mode 100644 index 0000000..f23b318 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_TSubclassOf_FSGDeviceImpl.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Templates/SubclassOf.h" +#include "SGCoreImpl/SGDeviceImpl.h" + +struct FSGIC_TSubclassOf_FSDeviceImpl +{ + TSubclassOf DeviceSubclassOf; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_jclass.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_jclass.h new file mode 100644 index 0000000..3a2e62a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_jclass.h @@ -0,0 +1,47 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" + +#if PLATFORM_ANDROID +#include "Android/AndroidJavaEnv.h" + +struct FSGIC_jclass +{ + jclass Class; +}; +#endif /* PLATFORM_ANDROID */ \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_jmethodID.h b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_jmethodID.h new file mode 100644 index 0000000..ffff80d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/Public/SGInterop/SGIC_jmethodID.h @@ -0,0 +1,47 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" + +#if PLATFORM_ANDROID +#include "Android/AndroidJavaEnv.h" + +struct FSGIC_jmethodID +{ + jmethodID MethodID; +}; +#endif /* PLATFORM_ANDROID */ \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveInterop/SenseGloveInterop.Build.cs b/Plugins/SenseGlove/Source/SenseGloveInterop/SenseGloveInterop.Build.cs new file mode 100644 index 0000000..69499e0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveInterop/SenseGloveInterop.Build.cs @@ -0,0 +1,70 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGloveInterop : ModuleRules +{ + public SenseGloveInterop(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveLog", + "SenseGloveTypes", + } + ); + + PrivateIncludePathModuleNames.AddRange( + new string[] + { + "SenseGloveBuildHacks", + "SenseGloveCoreImpl", + } + ); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGBlueprintFunctionLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGBlueprintFunctionLibrary.cpp new file mode 100644 index 0000000..d07e807 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGBlueprintFunctionLibrary.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGKismet/SGBlueprintFunctionLibrary.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGGameUserSettingsKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGGameUserSettingsKismetLibrary.cpp new file mode 100644 index 0000000..5ae9838 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGGameUserSettingsKismetLibrary.cpp @@ -0,0 +1,50 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGKismet/SGGameUserSettingsKismetLibrary.h" + +#include "SenseGlove/GameFramework/SGGameUserSettings.h" + +ESGEngineScalabilitySettings USGGameUserSettingsKismetLibrary::GetEngineScalabilitySettings( + const USGGameUserSettings* GameUserSettings) +{ + return GameUserSettings->GetEngineScalabilitySettings(); +} + +void USGGameUserSettingsKismetLibrary::SetEngineScalabilitySettings(USGGameUserSettings* GameUserSettings, + const ESGEngineScalabilitySettings Scalability) +{ + GameUserSettings->SetEngineScalabilitySettings(Scalability); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGGrabComponentKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGGrabComponentKismetLibrary.cpp new file mode 100644 index 0000000..3788442 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGGrabComponentKismetLibrary.cpp @@ -0,0 +1,149 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * A data class containing the minimum required data for a hand's forward + * kinematics. + * Used in both kinematics and calibration. + */ + + +#include "SGKismet/SGGrabComponentKismetLibrary.h" + +#include "SenseGlove/Components/SGGrabComponent.h" + +USGGrabComponent* UGrabComponentKismetLibrary::GetGrabComponent(const AActor* Actor) +{ + return USGGrabComponent::GetGrabComponent(Actor); +} + +bool UGrabComponentKismetLibrary::IsGrabbable(const AActor* Actor) +{ + return USGGrabComponent::IsGrabbable(Actor); +} + +EAttachmentRule UGrabComponentKismetLibrary::GetAttachmentLocationRule(const USGGrabComponent* GrabComponent) +{ + return GrabComponent->GetAttachmentLocationRule(); +} + +void UGrabComponentKismetLibrary::SetAttachmentLocationRule(USGGrabComponent* GrabComponent, + const EAttachmentRule InAttachmentLocationRule) +{ + GrabComponent->SetAttachmentLocationRule(InAttachmentLocationRule); +} + +EAttachmentRule UGrabComponentKismetLibrary::GetAttachmentRotationRule(const USGGrabComponent* GrabComponent) +{ + return GrabComponent->GetAttachmentRotationRule(); +} + +void UGrabComponentKismetLibrary::SetAttachmentRotationRule(USGGrabComponent* GrabComponent, + const EAttachmentRule InAttachmentRotationRule) +{ + GrabComponent->SetAttachmentRotationRule(InAttachmentRotationRule); +} + +EAttachmentRule UGrabComponentKismetLibrary::GetAttachmentScaleRule(const USGGrabComponent* GrabComponent) +{ + return GrabComponent->GetAttachmentScaleRule(); +} + +void UGrabComponentKismetLibrary::SetAttachmentScaleRule(USGGrabComponent* GrabComponent, + const EAttachmentRule InAttachmentScaleRule) +{ + GrabComponent->SetAttachmentScaleRule(InAttachmentScaleRule); +} + +bool UGrabComponentKismetLibrary::GetAttachmentWeldSimulatedBodies(const USGGrabComponent* GrabComponent) +{ + return GrabComponent->GetAttachmentWeldSimulatedBodies(); +} + +void UGrabComponentKismetLibrary::SetAttachmentWeldSimulatedBodies(USGGrabComponent* GrabComponent, + const bool bInAttachmentWeldSimulatedBodies) +{ + GrabComponent->SetAttachmentWeldSimulatedBodies(bInAttachmentWeldSimulatedBodies); +} + +const FName& UGrabComponentKismetLibrary::GetAttachmentSocketName(const USGGrabComponent* GrabComponent) +{ + return GrabComponent->GetAttachmentSocketName(); +} + +void UGrabComponentKismetLibrary::SetAttachmentSocketName(USGGrabComponent* GrabComponent, + const FName& InAttachmentSocketName) +{ + GrabComponent->SetAttachmentSocketName(InAttachmentSocketName); +} + +EDetachmentRule UGrabComponentKismetLibrary::GetDetachmentLocationRule(const USGGrabComponent* GrabComponent) +{ + return GrabComponent->GetDetachmentLocationRule(); +} + +void UGrabComponentKismetLibrary::SetDetachmentLocationRule(USGGrabComponent* GrabComponent, + const EDetachmentRule InDetachmentLocationRule) +{ + GrabComponent->SetDetachmentLocationRule(InDetachmentLocationRule); +} + +EDetachmentRule UGrabComponentKismetLibrary::GetDetachmentRotationRule(const USGGrabComponent* GrabComponent) +{ + return GrabComponent->GetDetachmentRotationRule(); +} + +void UGrabComponentKismetLibrary::SetDetachmentRotationRule(USGGrabComponent* GrabComponent, + const EDetachmentRule InDetachmentRotationRule) +{ + GrabComponent->SetDetachmentRotationRule(InDetachmentRotationRule); +} + +EDetachmentRule UGrabComponentKismetLibrary::GetDetachmentScaleRule(const USGGrabComponent* GrabComponent) +{ + return GrabComponent->GetDetachmentScaleRule(); +} + +void UGrabComponentKismetLibrary::SetDetachmentScaleRule(USGGrabComponent* GrabComponent, + const EDetachmentRule InDetachmentScaleRule) +{ + GrabComponent->SetDetachmentScaleRule(InDetachmentScaleRule); +} + +bool UGrabComponentKismetLibrary::GetDetachmentInCallModify(const USGGrabComponent* GrabComponent) +{ + return GrabComponent->GetDetachmentInCallModify(); +} + +void UGrabComponentKismetLibrary::SetDetachmentInCallModify(USGGrabComponent* GrabComponent, + const bool bInDetachmentInCallModify) +{ + GrabComponent->SetDetachmentInCallModify(bInDetachmentInCallModify); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGPawnKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGPawnKismetLibrary.cpp new file mode 100644 index 0000000..b95a664 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGPawnKismetLibrary.cpp @@ -0,0 +1,261 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGKismet/SGPawnKismetLibrary.h" + +#include "Camera/CameraComponent.h" +#include "Components/SphereComponent.h" +#include "Runtime/Launch/Resources/Version.h" +#include "XRDeviceVisualizationComponent.h" + +#include "SenseGlove/Components/SGVirtualHandComponent.h" +#include "SenseGlove/Components/SGWristTrackerComponent.h" +#include "SenseGlove/GameFramework/SGPawn.h" + +UCameraComponent* UPawnKismetLibrary::GetCamera(const ASGPawn* Pawn) +{ + return Pawn->GetCamera(); +} + +USGWristTrackerComponent* UPawnKismetLibrary::GetWristTrackerLeft(const ASGPawn* Pawn) +{ + return Pawn->GetWristTrackerLeft(); +} + +UXRDeviceVisualizationComponent* UPawnKismetLibrary::GetControllerVisualizerLeft(const ASGPawn* Pawn) +{ + return Pawn->GetControllerVisualizerLeft(); +} + +USGVirtualHandComponent* UPawnKismetLibrary::GetHandLeft(const ASGPawn* Pawn) +{ + return Pawn->GetHandLeft(); +} + +USGVirtualHandComponent* UPawnKismetLibrary::GetRealHandLeft(const ASGPawn* Pawn) +{ + return Pawn->GetHandLeft(); +} + +USphereComponent* UPawnKismetLibrary::GetLeftThumbFingertipGrabCollider(const ASGPawn* Pawn) +{ + return Pawn->GetLeftThumbFingertipGrabCollider(); +} + +USphereComponent* UPawnKismetLibrary::GetLeftIndexFingertipGrabCollider(const ASGPawn* Pawn) +{ + return Pawn->GetLeftIndexFingertipGrabCollider(); +} + +USphereComponent* UPawnKismetLibrary::GetLeftMiddleFingertipGrabCollider(const ASGPawn* Pawn) +{ + return Pawn->GetLeftMiddleFingertipGrabCollider(); +} + +USphereComponent* UPawnKismetLibrary::GetLeftThumbFingertipTouchCollider(const ASGPawn* Pawn) +{ + return Pawn->GetLeftThumbFingertipTouchCollider(); +} + +USphereComponent* UPawnKismetLibrary::GetLeftIndexFingertipTouchCollider(const ASGPawn* Pawn) +{ + return Pawn->GetLeftIndexFingertipTouchCollider(); +} + +USphereComponent* UPawnKismetLibrary::GetLeftMiddleFingertipTouchCollider(const ASGPawn* Pawn) +{ + return Pawn->GetLeftMiddleFingertipTouchCollider(); +} + +USphereComponent* UPawnKismetLibrary::GetLeftRingFingertipTouchCollider(const ASGPawn* Pawn) +{ + return Pawn->GetLeftRingFingertipTouchCollider(); +} + +USphereComponent* UPawnKismetLibrary::GetLeftPinkyFingertipTouchCollider(const ASGPawn* Pawn) +{ + return Pawn->GetLeftPinkyFingertipTouchCollider(); +} + +USGWristTrackerComponent* UPawnKismetLibrary::GetWristTrackerRight(const ASGPawn* Pawn) +{ + return Pawn->GetWristTrackerRight(); +} + +UXRDeviceVisualizationComponent* UPawnKismetLibrary::GetControllerVisualizerRight(const ASGPawn* Pawn) +{ + return Pawn->GetControllerVisualizerRight(); +} + +USGVirtualHandComponent* UPawnKismetLibrary::GetHandRight(const ASGPawn* Pawn) +{ + return Pawn->GetHandRight(); +} + +USGVirtualHandComponent* UPawnKismetLibrary::GetRealHandRight(const ASGPawn* Pawn) +{ + return Pawn->GetRealHandRight(); +} + +USphereComponent* UPawnKismetLibrary::GetRightThumbFingertipGrabCollider(const ASGPawn* Pawn) +{ + return Pawn->GetRightThumbFingertipGrabCollider(); +} + +USphereComponent* UPawnKismetLibrary::GetRightIndexFingertipGrabCollider(const ASGPawn* Pawn) +{ + return Pawn->GetRightIndexFingertipGrabCollider(); +} + +USphereComponent* UPawnKismetLibrary::GetRightMiddleFingertipGrabCollider(const ASGPawn* Pawn) +{ + return Pawn->GetRightMiddleFingertipGrabCollider(); +} + +USphereComponent* UPawnKismetLibrary::GetRightThumbFingertipTouchCollider(const ASGPawn* Pawn) +{ + return Pawn->GetRightThumbFingertipTouchCollider(); +} + +USphereComponent* UPawnKismetLibrary::GetRightIndexFingertipTouchCollider(const ASGPawn* Pawn) +{ + return Pawn->GetRightIndexFingertipTouchCollider(); +} + +USphereComponent* UPawnKismetLibrary::GetRightMiddleFingertipTouchCollider(const ASGPawn* Pawn) +{ + return Pawn->GetRightMiddleFingertipTouchCollider(); +} + +USphereComponent* UPawnKismetLibrary::GetRightRingFingertipTouchCollider(const ASGPawn* Pawn) +{ + return Pawn->GetRightRingFingertipTouchCollider(); +} + +USphereComponent* UPawnKismetLibrary::GetRightPinkyFingertipTouchCollider(const ASGPawn* Pawn) +{ + return Pawn->GetRightPinkyFingertipTouchCollider(); +} + +bool UPawnKismetLibrary::CanLeftHandGrab(const ASGPawn* Pawn, const AActor* Actor) +{ + return Pawn->CanLeftHandGrab(Actor); +} + +bool UPawnKismetLibrary::IsLeftHandGrabbing_Actor(const ASGPawn* Pawn, const AActor* Actor) +{ + return Pawn->IsLeftHandGrabbing(Actor); +} + +bool UPawnKismetLibrary::IsLeftHandGrabbing_OutActor(const ASGPawn* Pawn, AActor*& OutActor) +{ + return Pawn->IsLeftHandGrabbing(OutActor); +} + +bool UPawnKismetLibrary::IsLeftHandGrabbing(const ASGPawn* Pawn) +{ + return Pawn->IsLeftHandGrabbing(); +} + +bool UPawnKismetLibrary::CanRightHandGrab(const ASGPawn* Pawn, const AActor* Actor) +{ + return Pawn->CanRightHandGrab(Actor); +} + +bool UPawnKismetLibrary::IsRightHandGrabbing_Actor(const ASGPawn* Pawn, const AActor* Actor) +{ + return Pawn->IsRightHandGrabbing(Actor); +} + +bool UPawnKismetLibrary::IsRightHandGrabbing_OutActor(const ASGPawn* Pawn) +{ + return Pawn->IsRightHandGrabbing(); +} + +bool UPawnKismetLibrary::IsRightHandGrabbing(const ASGPawn* Pawn, AActor*& OutActor) +{ + return Pawn->IsRightHandGrabbing(); +} + +bool UPawnKismetLibrary::CanGrab(const ASGPawn* Pawn, const USGVirtualHandComponent* Hand, const AActor* Actor) +{ + return Pawn->CanGrab(Hand, Actor); +} + +bool UPawnKismetLibrary::IsGrabbing_Actor(const ASGPawn* Pawn, const USGVirtualHandComponent* Hand, const AActor* Actor) +{ + return Pawn->IsGrabbing(Hand, Actor); +} + +bool UPawnKismetLibrary::IsGrabbing_OutActor(const ASGPawn* Pawn, const USGVirtualHandComponent* Hand, + AActor*& OutActor) +{ + return Pawn->IsGrabbing(Hand, OutActor); +} + +bool UPawnKismetLibrary::IsGrabbing(const ASGPawn* Pawn, const USGVirtualHandComponent* Hand) +{ + return Pawn->IsGrabbing(Hand); +} + +void UPawnKismetLibrary::GrabLeft(ASGPawn* Pawn, AActor* Actor) +{ + Pawn->GrabLeft(Actor); +} + +void UPawnKismetLibrary::GrabRight(ASGPawn* Pawn, AActor* Actor) +{ + Pawn->GrabRight(Actor); +} + +void UPawnKismetLibrary::Grab(ASGPawn* Pawn, USGVirtualHandComponent* Hand, AActor* Actor) +{ + Pawn->Grab(Hand, Actor); +} + +void UPawnKismetLibrary::ReleaseLeft(ASGPawn* Pawn) +{ + Pawn->ReleaseLeft(); +} + +void UPawnKismetLibrary::ReleaseRight(ASGPawn* Pawn) +{ + Pawn->ReleaseRight(); +} + +void UPawnKismetLibrary::Release(ASGPawn* Pawn, const USGVirtualHandComponent* Hand) +{ + Pawn->Release(Hand); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGTouchComponentKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGTouchComponentKismetLibrary.cpp new file mode 100644 index 0000000..9661a1f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGTouchComponentKismetLibrary.cpp @@ -0,0 +1,81 @@ + +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * A data class containing the minimum required data for a hand's forward + * kinematics. + * Used in both kinematics and calibration. + */ + + +#include "SGKismet/SGTouchComponentKismetLibrary.h" + +#include "SenseGlove/Components/SGTouchComponent.h" + +USGTouchComponent* UTouchComponentKismetLibrary::GetTouchComponent(const AActor* Actor) +{ + return USGTouchComponent::GetTouchComponent(Actor); +} + +bool UTouchComponentKismetLibrary::IsTouchable(const AActor* Actor) +{ + return USGTouchComponent::IsTouchable(Actor); +} + +int32 UTouchComponentKismetLibrary::GetForceFeedbackLevel(const USGTouchComponent* TouchComponent) +{ + return TouchComponent->GetForceFeedbackLevel(); +} + +void UTouchComponentKismetLibrary::SetForceFeedbackLevel(USGTouchComponent* TouchComponent, const float Level) +{ + TouchComponent->SetForceFeedbackLevel(Level); +} + +float UTouchComponentKismetLibrary::GetVibrotactileLevel(const USGTouchComponent* TouchComponent) +{ + return TouchComponent->GetVibrotactileLevel(); +} + +void UTouchComponentKismetLibrary::SetVibrotactileLevel(USGTouchComponent* TouchComponent, const float Level) +{ + TouchComponent->SetVibrotactileLevel(Level); +} + +float UTouchComponentKismetLibrary::GetVibrotactileDuration(const USGTouchComponent* TouchComponent) +{ + return TouchComponent->GetVibrotactileDuration(); +} + +void UTouchComponentKismetLibrary::SetVibrotactileDuration(USGTouchComponent* TouchComponent, const float Duration) +{ + TouchComponent->SetVibrotactileDuration(Duration); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGVirtualHandComponentKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGVirtualHandComponentKismetLibrary.cpp new file mode 100644 index 0000000..bdc4143 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGVirtualHandComponentKismetLibrary.cpp @@ -0,0 +1,161 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGKismet/SGVirtualHandComponentKismetLibrary.h" + +#include "SenseGlove/Components/SGVirtualHandComponent.h" +#include "SGCore/SGHapticGlove.h" + +const TArray& UVirtualHandComponentKismetLibrary::GetLeftHandBoneNames() +{ + return USGVirtualHandComponent::GetLeftHandBoneNames(); +} + +const TArray& UVirtualHandComponentKismetLibrary::GetRightHandBoneNames() +{ + return USGVirtualHandComponent::GetRightHandBoneNames(); +} + +const FName& UVirtualHandComponentKismetLibrary::GetLeftHandBoneName(const int32 Joint) +{ + return USGVirtualHandComponent::GetLeftHandBoneName(Joint); +} + +const FName& UVirtualHandComponentKismetLibrary::GetRightHandBoneName(const int32 Joint) +{ + return USGVirtualHandComponent::GetRightHandBoneName(Joint); +} + +bool UVirtualHandComponentKismetLibrary::IsLeft(const USGVirtualHandComponent* VirtualHandComponent) +{ + return VirtualHandComponent->IsLeft(); +} + +bool UVirtualHandComponentKismetLibrary::IsRight(const USGVirtualHandComponent* VirtualHandComponent) +{ + return VirtualHandComponent->IsRight(); +} + +void UVirtualHandComponentKismetLibrary::SetRight( + USGVirtualHandComponent* VirtualHandComponent, const bool bInRight) +{ + VirtualHandComponent->SetRight(bInRight); +} + +bool UVirtualHandComponentKismetLibrary::OverridesPluginVirtualHandSettings( + const USGVirtualHandComponent* VirtualHandComponent) +{ + return VirtualHandComponent->OverridesPluginVirtualHandSettings(); +} + +const FSGVirtualHandSettingsOverrides& UVirtualHandComponentKismetLibrary::GetVirtualHandSettingsOverrides( + const USGVirtualHandComponent* VirtualHandComponent) +{ + return VirtualHandComponent->GetVirtualHandSettingsOverrides(); +} + +void UVirtualHandComponentKismetLibrary::SetVirtualHandSettingsOverrides( + USGVirtualHandComponent* VirtualHandComponent, + const FSGVirtualHandSettingsOverrides& InVirtualHandSettingsOverrides) +{ + VirtualHandComponent->SetVirtualHandSettingsOverrides(InVirtualHandSettingsOverrides); +} + +FSGVirtualHandSettings UVirtualHandComponentKismetLibrary::GetVirtualHandSettings( + const USGVirtualHandComponent* VirtualHandComponent) +{ + return VirtualHandComponent->GetVirtualHandSettings(); +} + +bool UVirtualHandComponentKismetLibrary::IsGloveConnected(const USGVirtualHandComponent* VirtualHandComponent) +{ + return VirtualHandComponent->IsGloveConnected(); +} + +USGHapticGlove* UVirtualHandComponentKismetLibrary::GetConnectedGlove( + const USGVirtualHandComponent* VirtualHandComponent) +{ + return VirtualHandComponent->GetConnectedGlove(); +} + +bool UVirtualHandComponentKismetLibrary::GetMotionControllerData( + USGVirtualHandComponent* VirtualHandComponent, FXRMotionControllerData& OutMotionControllerData) +{ + PRAGMA_DISABLE_DEPRECATION_WARNINGS + return VirtualHandComponent->GetMotionControllerData(OutMotionControllerData); + PRAGMA_ENABLE_DEPRECATION_WARNINGS +} + +const TArray& UVirtualHandComponentKismetLibrary::GetHandBoneNames( + const USGVirtualHandComponent* VirtualHandComponent) +{ + return VirtualHandComponent->GetHandBoneNames(); +} + +const FName& UVirtualHandComponentKismetLibrary::GetHandBoneName( + const USGVirtualHandComponent* VirtualHandComponent, const int32 Joint) +{ + return VirtualHandComponent->GetHandBoneName(Joint); +} + +const FTransform& UVirtualHandComponentKismetLibrary::GetHandBoneRefTransform_BN( + const USGVirtualHandComponent* VirtualHandComponent, const FName& BoneName) +{ + return VirtualHandComponent->GetHandBoneRefTransform(BoneName); +} + +const FTransform& UVirtualHandComponentKismetLibrary::GetHandBoneRefTransform_J( + const USGVirtualHandComponent* VirtualHandComponent, const int32 Joint) +{ + return VirtualHandComponent->GetHandBoneRefTransform(Joint); +} + +const FTransform& UVirtualHandComponentKismetLibrary::GetHandRootBoneRefTransform( + const USGVirtualHandComponent* VirtualHandComponent) +{ + return VirtualHandComponent->GetHandRootBoneRefTransform(); +} + +FRotator UVirtualHandComponentKismetLibrary::GetHandBoneRefRotation_BN( + const USGVirtualHandComponent* VirtualHandComponent, const FName& BoneName) +{ + return VirtualHandComponent->GetHandBoneRefRotation(BoneName); +} + +FRotator UVirtualHandComponentKismetLibrary::GetHandBoneRefRotation_J( + const USGVirtualHandComponent* VirtualHandComponent, const int32 Joint) +{ + return VirtualHandComponent->GetHandBoneRefRotation(Joint); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGWristTrackerComponentKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGWristTrackerComponentKismetLibrary.cpp new file mode 100644 index 0000000..1a8b295 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SGKismet/SGWristTrackerComponentKismetLibrary.cpp @@ -0,0 +1,99 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGKismet/SGWristTrackerComponentKismetLibrary.h" + +#include "SenseGlove/Components/SGWristTrackerComponent.h" + +bool UWristTrackerComponentKismetLibrary::IsLeft(const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->IsLeft(); +} + +bool UWristTrackerComponentKismetLibrary::IsRight(const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->IsRight(); +} + +void UWristTrackerComponentKismetLibrary::SetRight( + USGWristTrackerComponent* WristTrackerComponent, const bool bInRight) +{ + WristTrackerComponent->SetRight(bInRight); +} + +bool UWristTrackerComponentKismetLibrary::OverridesPluginWristTrackingSettings( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->OverridesPluginWristTrackingSettings(); +} + +const FSGWristTrackingSettingsOverrides& UWristTrackerComponentKismetLibrary::GetWristTrackingSettingsOverrides( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->GetWristTrackingSettingsOverrides(); +} + +void UWristTrackerComponentKismetLibrary::SetWristTrackingSettingsOverrides( + USGWristTrackerComponent* WristTrackerComponent, + const FSGWristTrackingSettingsOverrides& InWristTrackingSettingsOverrides) +{ + WristTrackerComponent->SetWristTrackingSettingsOverrides(InWristTrackingSettingsOverrides); +} + +FSGWristTrackingSettings UWristTrackerComponentKismetLibrary::GetWristTrackingSettings( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->GetWristTrackingSettings(); +} + +const FVector& UWristTrackerComponentKismetLibrary::GetWristLocation( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->GetWristLocation(); +} + +const FRotator& UWristTrackerComponentKismetLibrary::GetWristRotation( + const USGWristTrackerComponent* WristTrackerComponent) +{ + return WristTrackerComponent->GetWristRotation(); +} + +bool UWristTrackerComponentKismetLibrary::GetMotionControllerData( + USGWristTrackerComponent* WristTrackerComponent, FXRMotionControllerData& OutMotionControllerData) +{ + PRAGMA_DISABLE_DEPRECATION_WARNINGS + return WristTrackerComponent->GetMotionControllerData(OutMotionControllerData); + PRAGMA_ENABLE_DEPRECATION_WARNINGS +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SenseGloveKismet.cpp b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SenseGloveKismet.cpp new file mode 100644 index 0000000..0bfb93c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SenseGloveKismet.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveKismet.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveKismetModule.h" + +IMPLEMENT_MODULE(FSenseGloveKismetModule, SenseGloveKismet) diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SenseGloveKismet.h b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SenseGloveKismet.h new file mode 100644 index 0000000..ab121d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SenseGloveKismet.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SenseGloveKismetModule.cpp b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SenseGloveKismetModule.cpp new file mode 100644 index 0000000..650f05d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SenseGloveKismetModule.cpp @@ -0,0 +1,62 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveKismetModule.h" + +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveKismetModule" + +void FSenseGloveKismetModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveKismet module..."); +} + +void FSenseGloveKismetModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveKismet module..."); +} + +void FSenseGloveKismetModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveKismet module has succeeded!"); +} + +void FSenseGloveKismetModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveKismet module..."); +} + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SenseGloveKismetModule.h b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SenseGloveKismetModule.h new file mode 100644 index 0000000..0a71840 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Private/SenseGloveKismetModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveKismet" + +class FSenseGloveKismetModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGBlueprintFunctionLibrary.h b/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGBlueprintFunctionLibrary.h new file mode 100644 index 0000000..5d957a5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGBlueprintFunctionLibrary.h @@ -0,0 +1,50 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Kismet/BlueprintFunctionLibrary.h" + +#include "SGBlueprintFunctionLibrary.generated.h" + +/** + * This class is a base class for any function libraries exposed to blueprints. + * Methods in subclasses are expected to be static, and no methods should be added to this base class. + */ +UCLASS(Abstract) +class SENSEGLOVEKISMET_API USGBlueprintFunctionLibrary : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGGameUserSettingsKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGGameUserSettingsKismetLibrary.h new file mode 100644 index 0000000..94f4860 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGGameUserSettingsKismetLibrary.h @@ -0,0 +1,57 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGTypes.h" + +#include "SGGameUserSettingsKismetLibrary.generated.h" + +class USGGameUserSettings; + +UCLASS(meta=(ScriptName = "SenseGloveGameUserSettingsKismetLibrary")) +class SENSEGLOVEKISMET_API USGGameUserSettingsKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Game User Settings") + static ESGEngineScalabilitySettings GetEngineScalabilitySettings(const USGGameUserSettings* GameUserSettings); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Game Framework | Game User Settings") + static void SetEngineScalabilitySettings(UPARAM(ref) USGGameUserSettings* GameUserSettings, + ESGEngineScalabilitySettings Scalability); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGGrabComponentKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGGrabComponentKismetLibrary.h new file mode 100644 index 0000000..6f879c3 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGGrabComponentKismetLibrary.h @@ -0,0 +1,119 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" + +#include "SGGrabComponentKismetLibrary.generated.h" + +class AActor; +class USGGrabComponent; + +UCLASS(meta=(ScriptName = "SenseGloveGrabComponentKismetLibrary")) +class SENSEGLOVEKISMET_API UGrabComponentKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Grab Component") + static USGGrabComponent* GetGrabComponent(const AActor* Actor); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Grab Component") + static bool IsGrabbable(const AActor* Actor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Grab Component") + static EAttachmentRule GetAttachmentLocationRule(const USGGrabComponent* GrabComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Grab Component") + static void SetAttachmentLocationRule(UPARAM(ref) USGGrabComponent* GrabComponent, + EAttachmentRule InAttachmentLocationRule); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Grab Component") + static EAttachmentRule GetAttachmentRotationRule(const USGGrabComponent* GrabComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Grab Component") + static void SetAttachmentRotationRule(UPARAM(ref) USGGrabComponent* GrabComponent, + EAttachmentRule InAttachmentRotationRule); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Grab Component") + static EAttachmentRule GetAttachmentScaleRule(const USGGrabComponent* GrabComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Grab Component") + static void SetAttachmentScaleRule(UPARAM(ref) USGGrabComponent* GrabComponent, + EAttachmentRule InAttachmentScaleRule); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Grab Component") + static bool GetAttachmentWeldSimulatedBodies(const USGGrabComponent* GrabComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Grab Component") + static void SetAttachmentWeldSimulatedBodies(UPARAM(ref) USGGrabComponent* GrabComponent, + bool bInAttachmentWeldSimulatedBodies); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Grab Component") + static const FName& GetAttachmentSocketName(const USGGrabComponent* GrabComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Grab Component") + static void SetAttachmentSocketName(UPARAM(ref) USGGrabComponent* GrabComponent, + const FName& InAttachmentSocketName); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Grab Component") + static EDetachmentRule GetDetachmentLocationRule(const USGGrabComponent* GrabComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Grab Component") + static void SetDetachmentLocationRule(UPARAM(ref) USGGrabComponent* GrabComponent, + EDetachmentRule InDetachmentLocationRule); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Grab Component") + static EDetachmentRule GetDetachmentRotationRule(const USGGrabComponent* GrabComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Grab Component") + static void SetDetachmentRotationRule(UPARAM(ref) USGGrabComponent* GrabComponent, + EDetachmentRule InDetachmentRotationRule); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Grab Component") + static EDetachmentRule GetDetachmentScaleRule(const USGGrabComponent* GrabComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Grab Component") + static void SetDetachmentScaleRule(UPARAM(ref) USGGrabComponent* GrabComponent, + EDetachmentRule InDetachmentScaleRule); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Grab Component") + static bool GetDetachmentInCallModify(const USGGrabComponent* GrabComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Grab Component") + static void SetDetachmentInCallModify(UPARAM(ref) USGGrabComponent* GrabComponent, + bool bInDetachmentInCallModify); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGPawnKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGPawnKismetLibrary.h new file mode 100644 index 0000000..14c5560 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGPawnKismetLibrary.h @@ -0,0 +1,191 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/Map.h" +#include "GameFramework/Actor.h" +#include "Math/Rotator.h" +#include "Math/Transform.h" +#include "UObject/NameTypes.h" + +#include "SGKismet/SGBlueprintFunctionLibrary.h" + +#include "SGPawnKismetLibrary.generated.h" + +class UCameraComponent; +class USphereComponent; +class UXRDeviceVisualizationComponent; + +class ASGPawn; +class USGVirtualHandComponent; +class USGWristTrackerComponent; + +UCLASS(meta=(ScriptName = "SenseGlovePawnKismetLibrary")) +class SENSEGLOVEKISMET_API UPawnKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static UCameraComponent* GetCamera(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USGWristTrackerComponent* GetWristTrackerLeft(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static UXRDeviceVisualizationComponent* GetControllerVisualizerLeft(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USGVirtualHandComponent* GetHandLeft(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USGVirtualHandComponent* GetRealHandLeft(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USphereComponent* GetLeftThumbFingertipGrabCollider(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USphereComponent* GetLeftIndexFingertipGrabCollider(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USphereComponent* GetLeftMiddleFingertipGrabCollider(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USphereComponent* GetLeftThumbFingertipTouchCollider(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USphereComponent* GetLeftIndexFingertipTouchCollider(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USphereComponent* GetLeftMiddleFingertipTouchCollider(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USphereComponent* GetLeftRingFingertipTouchCollider(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USphereComponent* GetLeftPinkyFingertipTouchCollider(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USGWristTrackerComponent* GetWristTrackerRight(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static UXRDeviceVisualizationComponent* GetControllerVisualizerRight(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USGVirtualHandComponent* GetHandRight(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USGVirtualHandComponent* GetRealHandRight(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USphereComponent* GetRightThumbFingertipGrabCollider(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USphereComponent* GetRightIndexFingertipGrabCollider(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USphereComponent* GetRightMiddleFingertipGrabCollider(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USphereComponent* GetRightThumbFingertipTouchCollider(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USphereComponent* GetRightIndexFingertipTouchCollider(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USphereComponent* GetRightMiddleFingertipTouchCollider(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USphereComponent* GetRightRingFingertipTouchCollider(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static USphereComponent* GetRightPinkyFingertipTouchCollider(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool CanLeftHandGrab(const ASGPawn* Pawn, const AActor* Actor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsLeftHandGrabbing_Actor(const ASGPawn* Pawn, const AActor* Actor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsLeftHandGrabbing_OutActor(const ASGPawn* Pawn, AActor*& OutActor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsLeftHandGrabbing(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool CanRightHandGrab(const ASGPawn* Pawn, const AActor* Actor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsRightHandGrabbing_Actor(const ASGPawn* Pawn, const AActor* Actor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsRightHandGrabbing_OutActor(const ASGPawn* Pawn); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsRightHandGrabbing(const ASGPawn* Pawn, AActor*& OutActor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool CanGrab(const ASGPawn* Pawn, const USGVirtualHandComponent* Hand, const AActor* Actor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsGrabbing_Actor(const ASGPawn* Pawn, const USGVirtualHandComponent* Hand, const AActor* Actor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsGrabbing_OutActor(const ASGPawn* Pawn, const USGVirtualHandComponent* Hand, AActor*& OutActor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Game Framework | Pawn") + static bool IsGrabbing(const ASGPawn* Pawn, const USGVirtualHandComponent* Hand); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Game Framework | Pawn") + static void GrabLeft(UPARAM(ref) ASGPawn* Pawn, AActor* Actor); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Game Framework | Pawn") + static void GrabRight(UPARAM(ref) ASGPawn* Pawn, AActor* Actor); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Game Framework | Pawn") + void Grab(UPARAM(ref) ASGPawn* Pawn, USGVirtualHandComponent* Hand, AActor* Actor); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Game Framework | Pawn") + void ReleaseLeft(UPARAM(ref) ASGPawn* Pawn); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Game Framework | Pawn") + void ReleaseRight(UPARAM(ref) ASGPawn* Pawn); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Game Framework | Pawn") + static void Release(UPARAM(ref) ASGPawn* Pawn, const USGVirtualHandComponent* Hand); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGTouchComponentKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGTouchComponentKismetLibrary.h new file mode 100644 index 0000000..15b0e1a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGTouchComponentKismetLibrary.h @@ -0,0 +1,74 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" + +#include "SGTouchComponentKismetLibrary.generated.h" + +class AActor; +class USGTouchComponent; + +UCLASS(meta=(ScriptName = "SenseGloveTouchComponentKismetLibrary")) +class SENSEGLOVEKISMET_API UTouchComponentKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Touch Component") + static USGTouchComponent* GetTouchComponent(const AActor* Actor); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Touch Component") + static bool IsTouchable(const AActor* Actor); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Touch Component") + static int32 GetForceFeedbackLevel(const USGTouchComponent* TouchComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Touch Component") + static void SetForceFeedbackLevel(UPARAM(ref) USGTouchComponent* TouchComponent, float Level); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Touch Component") + static float GetVibrotactileLevel(const USGTouchComponent* TouchComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Touch Component") + static void SetVibrotactileLevel(UPARAM(ref) USGTouchComponent* TouchComponent, float Level); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Touch Component") + static float GetVibrotactileDuration(const USGTouchComponent* TouchComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Touch Component") + static void SetVibrotactileDuration(UPARAM(ref) USGTouchComponent* TouchComponent, float Duration); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGVirtualHandComponentKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGVirtualHandComponentKismetLibrary.h new file mode 100644 index 0000000..3ed6dd3 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGVirtualHandComponentKismetLibrary.h @@ -0,0 +1,138 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/Map.h" +#include "HeadMountedDisplayTypes.h" +#include "Math/Rotator.h" +#include "Math/Transform.h" +#include "UObject/NameTypes.h" + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGSettings/SGVirtualHandSettings.h" +#include "SGSettings/SGVirtualHandSettingsOverrides.h" + +#include "SGVirtualHandComponentKismetLibrary.generated.h" + +class USkeletalMeshComponent; + +class USGHandPose; +class USGHapticGlove; +class USGVirtualHandComponent; + +UCLASS(meta=(ScriptName = "SenseGloveVirtualHandComponentKismetLibrary")) +class SENSEGLOVEKISMET_API UVirtualHandComponentKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component") + static const TArray& GetLeftHandBoneNames(); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component") + static const TArray& GetRightHandBoneNames(); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component") + static const FName& GetLeftHandBoneName(int32 Joint); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component") + static const FName& GetRightHandBoneName(int32 Joint); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component") + static bool IsLeft(const USGVirtualHandComponent* VirtualHandComponent); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component") + static bool IsRight(const USGVirtualHandComponent* VirtualHandComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component") + static void SetRight(UPARAM(ref) USGVirtualHandComponent* VirtualHandComponent, bool bInRight); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component") + static bool OverridesPluginVirtualHandSettings(const USGVirtualHandComponent* VirtualHandComponent); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component") + static const FSGVirtualHandSettingsOverrides& GetVirtualHandSettingsOverrides( + const USGVirtualHandComponent* VirtualHandComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component") + static void SetVirtualHandSettingsOverrides( + UPARAM(ref) USGVirtualHandComponent* VirtualHandComponent, + const FSGVirtualHandSettingsOverrides& InVirtualHandSettingsOverrides); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component") + static FSGVirtualHandSettings GetVirtualHandSettings(const USGVirtualHandComponent* VirtualHandComponent); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component") + static bool IsGloveConnected(const USGVirtualHandComponent* VirtualHandComponent); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component") + static USGHapticGlove* GetConnectedGlove(const USGVirtualHandComponent* VirtualHandComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component") + static bool GetMotionControllerData(UPARAM(ref) USGVirtualHandComponent* VirtualHandComponent, + FXRMotionControllerData& OutMotionControllerData); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component") + static const TArray& GetHandBoneNames(const USGVirtualHandComponent* VirtualHandComponent); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component") + static const FName& GetHandBoneName(const USGVirtualHandComponent* VirtualHandComponent, + int32 Joint); + + UFUNCTION(BlueprintPure, DisplayName="Get Hand Bone Ref Transform", + Category="SenseGlove | Components | Virtual Hand Component") + static const FTransform& GetHandBoneRefTransform_BN(const USGVirtualHandComponent* VirtualHandComponent, + const FName& BoneName); + + UFUNCTION(BlueprintPure, DisplayName="Get Hand Bone Ref Transform", + Category="SenseGlove | Components | Virtual Hand Component") + static const FTransform& GetHandBoneRefTransform_J(const USGVirtualHandComponent* VirtualHandComponent, + int32 Joint); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component") + static const FTransform& GetHandRootBoneRefTransform(const USGVirtualHandComponent* VirtualHandComponent); + + UFUNCTION(BlueprintPure, DisplayName="Get Hand Bone Ref Rotation", + Category="SenseGlove | Components | Virtual Hand Component") + static FRotator GetHandBoneRefRotation_BN(const USGVirtualHandComponent* VirtualHandComponent, + const FName& BoneName); + + UFUNCTION(BlueprintPure, DisplayName="Get Hand Bone Ref Rotation", + Category="SenseGlove | Components | Virtual Hand Component") + static FRotator GetHandBoneRefRotation_J(const USGVirtualHandComponent* VirtualHandComponent, + int32 Joint); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGWristTrackerComponentKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGWristTrackerComponentKismetLibrary.h new file mode 100644 index 0000000..923b278 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/Public/SGKismet/SGWristTrackerComponentKismetLibrary.h @@ -0,0 +1,89 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HeadMountedDisplayTypes.h" + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGSettings/SGWristTrackingSettings.h" +#include "SGSettings/SGWristTrackingSettingsOverrides.h" + +#include "SGWristTrackerComponentKismetLibrary.generated.h" + +class USkeletalMeshComponent; + +class USGWristTrackerComponent; + +UCLASS(meta=(ScriptName = "SenseGloveWristTrackerComponentKismetLibrary")) +class SENSEGLOVEKISMET_API UWristTrackerComponentKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static bool IsLeft(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static bool IsRight(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static void SetRight(UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, bool bInRight); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static bool OverridesPluginWristTrackingSettings(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static const FSGWristTrackingSettingsOverrides& GetWristTrackingSettingsOverrides( + const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static void SetWristTrackingSettingsOverrides( + UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, + const FSGWristTrackingSettingsOverrides& InWristTrackingSettingsOverrides); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Wrist Tracker Component") + static FSGWristTrackingSettings GetWristTrackingSettings(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static const FVector& GetWristLocation(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static const FRotator& GetWristRotation(const USGWristTrackerComponent* WristTrackerComponent); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Wrist Tracker Component") + static bool GetMotionControllerData(UPARAM(ref) USGWristTrackerComponent* WristTrackerComponent, + FXRMotionControllerData& OutMotionControllerData); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveKismet/SenseGloveKismet.Build.cs b/Plugins/SenseGlove/Source/SenseGloveKismet/SenseGloveKismet.Build.cs new file mode 100644 index 0000000..3dbed49 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveKismet/SenseGloveKismet.Build.cs @@ -0,0 +1,73 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGloveKismet : ModuleRules +{ + public SenseGloveKismet(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + "HeadMountedDisplay", + // NOTE + // UE 5.3+ provides UXRDeviceVisualizationComponent as part of the XRBase plugin. + // UE 5.2 provides UXRDeviceVisualizationComponent as part of the HeadMountDisplay module. +#if UE_5_3_OR_LATER + "XRBase", +#endif + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGlove", + "SenseGloveCore", + "SenseGloveLog", + "SenseGloveSettings", + "SenseGloveTypes", + "SenseGloveUtils", + } + ); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveLog/Private/SGLog/SGLog.cpp b/Plugins/SenseGlove/Source/SenseGloveLog/Private/SGLog/SGLog.cpp new file mode 100644 index 0000000..1a62b55 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveLog/Private/SGLog/SGLog.cpp @@ -0,0 +1,244 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGLog/SGLog.h" +#include "Containers/Map.h" +#include "Logging/LogMacros.h" + +DEFINE_LOG_CATEGORY(LogEditor) +DEFINE_LOG_CATEGORY(LogGeneric) + +struct FSGLogCore::FStaticImpl +{ +public: + struct VerbosityMapper + { + FString Tag; + FColor Color; + + VerbosityMapper(const FString& InTag, const FColor& InColor); + }; + +public: + TMap VerbosityMap; + + bool bInitialized; + +public: + FStaticImpl(); +}; + +struct FSGLogCore::FImpl +{ +public: + FSGLogCore::EVerbosity Verbosity; + FSGLogCore::ECategory Category; + FString File; + FString Function; + FString Line; +}; + +FSGLogCore::FStaticImplDeleter FSGLogCore::SPimplDeleter; +std::unique_ptr FSGLogCore::SPimpl = + std::unique_ptr( + new FSGLogCore::FStaticImpl{}, FSGLogCore::SPimplDeleter); + +FSGLogCore::FSGLogCore(const EVerbosity& Verbosity, const ECategory& Category, const std::string& File, + const std::string& Function, const int32 Line) + : Pimpl(std::unique_ptr(new FImpl{}, PimplDeleter)), + bAnyEntries(false) +{ +#if defined ( SENSEGLOVE_LOGGING ) + if (!SPimpl->bInitialized) + { + SPimpl->VerbosityMap.Add(FSGLogCore::EVerbosity::Fatal, + FStaticImpl::VerbosityMapper(TEXT("FATAL"), FColor::White)); + SPimpl->VerbosityMap.Add(FSGLogCore::EVerbosity::Error, FStaticImpl::VerbosityMapper(TEXT("ERROR"), FColor::Red)); + SPimpl->VerbosityMap.Add(FSGLogCore::EVerbosity::Warning, + FStaticImpl::VerbosityMapper(TEXT("WARNING"), FColor::Yellow)); + SPimpl->VerbosityMap.Add(FSGLogCore::EVerbosity::Display, + FStaticImpl::VerbosityMapper(TEXT("DISPLAY"), FColor::Green)); + SPimpl->VerbosityMap.Add(FSGLogCore::EVerbosity::Log, FStaticImpl::VerbosityMapper(TEXT("LOG"), FColor::Silver)); + SPimpl->VerbosityMap.Add(FSGLogCore::EVerbosity::Verbose, + FStaticImpl::VerbosityMapper(TEXT("VERBOSE"), FColor::Purple)); + SPimpl->VerbosityMap.Add(FSGLogCore::EVerbosity::VeryVerbose, + FStaticImpl::VerbosityMapper(TEXT("VERY_VERBOSE"), FColor::Magenta)); + + SPimpl->bInitialized = true; + } + + Pimpl->Verbosity = Verbosity; + Pimpl->Category = Category; + Pimpl->File = FString(StringCast(File.c_str()).Get()); + Pimpl->Function = FString(StringCast(Function.c_str()).Get()); + Pimpl->Line = FString::FromInt(Line); +#endif /* defined ( SENSEGLOVE_LOGGING ) */ +} + +FSGLogCore::~FSGLogCore() +{ +#if defined ( SENSEGLOVE_LOGGING ) + const EVerbosity& Verbosity = Pimpl->Verbosity; + const ECategory& Category = Pimpl->Category; + const FStaticImpl::VerbosityMapper& VerbosityMapper = SPimpl->VerbosityMap[Verbosity]; + const FString& Tag = VerbosityMapper.Tag; + const FColor& Color = VerbosityMapper.Color; + + const FString Message(FString::Printf(TEXT("[%s %s %s %s] %s"), Tag.GetCharArray().GetData(), + Pimpl->File.GetCharArray().GetData(), + Pimpl->Function.GetCharArray().GetData(), + Pimpl->Line.GetCharArray().GetData(), Buffer.GetCharArray().GetData())); + + // Generic + if (Category == ECategory::Generic) + { + switch (Verbosity) + { + case EVerbosity::Display: + { + UE_LOG(LogGeneric, Display, TEXT("%s"), Message.GetCharArray().GetData()); + } + break; + + case EVerbosity::Error: + { + UE_LOG(LogGeneric, Error, TEXT("%s"), Message.GetCharArray().GetData()); + } + break; + + case EVerbosity::Fatal: + { + UE_LOG(LogGeneric, Fatal, TEXT("%s"), Message.GetCharArray().GetData()); + } + break; + + case EVerbosity::Log: + { + UE_LOG(LogGeneric, Log, TEXT("%s"), Message.GetCharArray().GetData()); + } + break; + + case EVerbosity::Verbose: + { + UE_LOG(LogGeneric, Verbose, TEXT("%s"), Message.GetCharArray().GetData()); + } + break; + + case EVerbosity::VeryVerbose: + { + UE_LOG(LogGeneric, VeryVerbose, TEXT("%s"), Message.GetCharArray().GetData()); + } + break; + + case EVerbosity::Warning: + { + UE_LOG(LogGeneric, Warning, TEXT("%s"), Message.GetCharArray().GetData()); + } + break; + } + } + + // Editor + if (Category == ECategory::Editor) + { + switch (Verbosity) + { + case EVerbosity::Display: + { + UE_LOG(LogEditor, Display, TEXT("%s"), Message.GetCharArray().GetData()); + } + break; + + case EVerbosity::Error: + { + UE_LOG(LogEditor, Error, TEXT("%s"), Message.GetCharArray().GetData()); + } + break; + + case EVerbosity::Fatal: + { + UE_LOG(LogEditor, Fatal, TEXT("%s"), Message.GetCharArray().GetData()); + } + break; + + case EVerbosity::Log: + { + UE_LOG(LogEditor, Log, TEXT("%s"), Message.GetCharArray().GetData()); + } + break; + + case EVerbosity::Verbose: + { + UE_LOG(LogEditor, Verbose, TEXT("%s"), Message.GetCharArray().GetData()); + } + break; + + case EVerbosity::VeryVerbose: + { + UE_LOG(LogEditor, VeryVerbose, TEXT("%s"), Message.GetCharArray().GetData()); + } + break; + + case EVerbosity::Warning: + { + UE_LOG(LogEditor, Warning, TEXT("%s"), Message.GetCharArray().GetData()); + } + break; + } + } +#endif /* defined ( SENSEGLOVE_LOGGING ) */ +} + +FSGLogCore::FStaticImpl::FStaticImpl() + : bInitialized(false) +{ +} + +FSGLogCore::FStaticImpl::VerbosityMapper::VerbosityMapper(const FString& InTag, + const FColor& InColor) + : Tag(InTag), + Color(InColor) +{ +} + +void FSGLogCore::FStaticImplDeleter::operator()(const FSGLogCore::FStaticImpl* Pointer) const +{ + delete Pointer; +} + +void FSGLogCore::FImplDeleter::operator()(const FSGLogCore::FImpl* Pointer) const +{ + delete Pointer; +} diff --git a/Plugins/SenseGlove/Source/SenseGloveLog/Private/SenseGloveLog.cpp b/Plugins/SenseGlove/Source/SenseGloveLog/Private/SenseGloveLog.cpp new file mode 100644 index 0000000..b92a659 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveLog/Private/SenseGloveLog.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveLog.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveLogModule.h" + +IMPLEMENT_MODULE(FSenseGloveLogModule, SenseGloveLog); diff --git a/Plugins/SenseGlove/Source/SenseGloveLog/Private/SenseGloveLog.h b/Plugins/SenseGlove/Source/SenseGloveLog/Private/SenseGloveLog.h new file mode 100644 index 0000000..ab121d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveLog/Private/SenseGloveLog.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveLog/Private/SenseGloveLogModule.cpp b/Plugins/SenseGlove/Source/SenseGloveLog/Private/SenseGloveLogModule.cpp new file mode 100644 index 0000000..0314003 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveLog/Private/SenseGloveLogModule.cpp @@ -0,0 +1,61 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveLogModule.h" +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveLogModule" + +void FSenseGloveLogModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveLog module..."); +} + +void FSenseGloveLogModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveLog module..."); +} + +void FSenseGloveLogModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveLog module has succeeded!"); +} + +void FSenseGloveLogModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveLog module..."); +} + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveLog/Private/SenseGloveLogModule.h b/Plugins/SenseGlove/Source/SenseGloveLog/Private/SenseGloveLogModule.h new file mode 100644 index 0000000..fea2d92 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveLog/Private/SenseGloveLogModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveLog" + +class FSenseGloveLogModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveLog/Public/SGLog/SGLog.h b/Plugins/SenseGlove/Source/SenseGloveLog/Public/SGLog/SGLog.h new file mode 100644 index 0000000..dd76a38 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveLog/Public/SGLog/SGLog.h @@ -0,0 +1,751 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include +#include +#include +#include + +#include "Containers/StringConv.h" +#include "Containers/UnrealString.h" +#include "GameFramework/Actor.h" +#include "Logging/LogVerbosity.h" +#include "Math/Rotator.h" +#include "Math/Transform.h" +#include "Math/Vector.h" +#include "Templates/UnrealTemplate.h" + +DECLARE_LOG_CATEGORY_EXTERN(LogEditor, All, All); + +DECLARE_LOG_CATEGORY_EXTERN(LogGeneric, All, All); + +template +struct TFSGLogString +{ + T T1; + FString T2; + static_assert(std::is_same::value, "Error: you are missing a template specialization!"); +}; + +template +struct TFSGLogString +{ + T T1; + FString T2; + static_assert(std::is_same::value, "Error: you are missing a template specialization!"); +}; + +template<> +struct TFSGLogString +{ + static void Format(const AActor* Actor, FString& OutString) + { + ensureAlwaysMsgf(Actor, TEXT("FATAL: cannot log a NULL actor object!")); + + OutString = FString::Printf(TEXT("%s"), Actor->GetName().GetCharArray().GetData()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const AActor* Actor, FString& OutString) + { + ensureAlwaysMsgf(Actor, TEXT("FATAL: cannot log a NULL actor object!")); + + OutString = FString::Printf(TEXT("%s"), Actor->GetName().GetCharArray().GetData()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const bool Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), (Value ? TEXT("True") : TEXT("False"))); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const bool Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), (Value ? TEXT("True") : TEXT("False"))); + } +}; + +template +struct TFSGLogString +{ + static void Format(const char* Value, FString& OutString) + { + OutString = FString(StringCast(Value).Get()); + } +}; + +template +struct TFSGLogString +{ + static void Format(const char* Value, FString& OutString) + { + OutString = FString(StringCast(Value).Get()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const char* Value, FString& OutString) + { + OutString = FString(StringCast(Value).Get()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const char* Value, FString& OutString) + { + OutString = FString(StringCast(Value).Get()); + } +}; + +#if ! PLATFORM_ANDROID && PLATFORM_LINUX + +template< std::size_t L> +struct TFSGLogString +{ + static void Format(const char16_t* Value, FString& OutString) + { + OutString = FString(StringCast(Value).Get()); + } +}; + +template< std::size_t L> +struct TFSGLogString +{ + static void Format(const char16_t* Value, FString& OutString) + { + OutString = FString(StringCast(Value).Get()); + } +}; + +template <> +struct TFSGLogString +{ + static void Format(const char16_t* Value, FString& OutString) + { + OutString = FString(StringCast(Value).Get()); + } +}; + +template <> +struct TFSGLogString +{ + static void Format(const char16_t* Value, FString& OutString) + { + OutString = FString(StringCast(Value).Get()); + } +}; + +#endif /* ! PLATFORM_ANDROID && PLATFORM_LINUX */ + +template<> +struct TFSGLogString +{ + static void Format(const double Value, FString& OutString) + { + char Buffer[100]; + std::snprintf(Buffer, sizeof(Buffer), "%f", Value); + + std::string String(Buffer); + + OutString = FString(StringCast(String.c_str()).Get()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const double Value, FString& OutString) + { + char Buffer[100]; + std::snprintf(Buffer, sizeof(Buffer), "%f", Value); + + std::string String(Buffer); + + OutString = FString(StringCast(String.c_str()).Get()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const float Value, FString& OutString) + { + OutString = FString::SanitizeFloat(StaticCast(Value), 1); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const float Value, FString& OutString) + { + OutString = FString::SanitizeFloat(StaticCast(Value), 1); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const FName& Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), Value.ToString().GetCharArray().GetData()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const FName& Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), Value.ToString().GetCharArray().GetData()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const FQuat& Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), Value.ToString().GetCharArray().GetData()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const FQuat& Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), Value.ToString().GetCharArray().GetData()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const FRotator& Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), Value.ToString().GetCharArray().GetData()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const FRotator& Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), Value.ToString().GetCharArray().GetData()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const FString& Value, FString& OutString) + { + OutString = Value; + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const FString& Value, FString& OutString) + { + OutString = Value; + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const FTransform& Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), Value.ToString().GetCharArray().GetData()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const FTransform& Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), Value.ToString().GetCharArray().GetData()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const FVector& Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), Value.ToString().GetCharArray().GetData()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const FVector& Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), Value.ToString().GetCharArray().GetData()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const int8 Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%d"), Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const int8 Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%d"), Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const int16 Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%d"), Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const int16 Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%d"), Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const int32 Value, FString& OutString) + { + OutString = FString::FromInt(Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const int32 Value, FString& OutString) + { + OutString = FString::FromInt(Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const int64 Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%d"), Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const int64 Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%d"), Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const long double Value, FString& OutString) + { + char Buffer[100]; + std::snprintf(Buffer, sizeof(Buffer), "%Lf", Value); + + std::string String(Buffer); + + OutString = FString(StringCast(String.c_str()).Get()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const long double Value, FString& OutString) + { + char Buffer[100]; + std::snprintf(Buffer, sizeof(Buffer), "%Lf", Value); + + std::string String(Buffer); + + OutString = FString(StringCast(String.c_str()).Get()); + } +}; + +#if ! PLATFORM_ANDROID && PLATFORM_LINUX +template<> +struct TFSGLogString +{ + static void Format(const std::size_t Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%d"), Value); + } +}; +#endif /* ! PLATFORM_ANDROID && PLATFORM_LINUX */ + +#if ! PLATFORM_ANDROID && PLATFORM_LINUX +template <> +struct TFSGLogString +{ + static void Format(const std::size_t Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%d"), Value); + } +}; +#endif /* ! PLATFORM_ANDROID && PLATFORM_LINUX */ + +template<> +struct TFSGLogString +{ + static void Format(const int8 Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%d"), Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const int8 Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%d"), Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const int16 Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%d"), Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const int16 Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%d"), Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const int32 Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%d"), Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const int32 Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%d"), Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const int64 Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%d"), Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const int64 Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%d"), Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const std::string& Value, FString& OutString) + { + OutString = FString(StringCast(Value.c_str()).Get()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const std::string& Value, FString& OutString) + { + OutString = FString(StringCast(Value.c_str()).Get()); + } +}; + +template +struct TFSGLogString +{ + static void Format(const wchar_t* Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), Value); + } +}; + +template +struct TFSGLogString +{ + static void Format(const wchar_t* Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const wchar_t* Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const wchar_t* Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), Value); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const std::wstring& Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), Value.c_str()); + } +}; + +template<> +struct TFSGLogString +{ + static void Format(const std::wstring& Value, FString& OutString) + { + OutString = FString::Printf(TEXT("%s"), Value.c_str()); + } +}; + +class SENSEGLOVELOG_API FSGLogCore +{ +public: + enum class EVerbosity : uint8 + { + /** Always prints s fatal error to console (and log file) and crashes (even if logging is disabled) */ + Fatal, + + /** + * Prints an error to console (and log file). + * Commandlets and the editor collect and report errors. Error messages result in commandlet failure. + */ + Error, + + /** + * Prints a warning to console (and log file). + * Commandlets and the editor collect and report warnings. Warnings can be treated as an error. + */ + Warning, + + /** Prints a message to console (and log file) */ + Display, + + /** Prints a message to a log file (does not print to console) */ + Log, + + /** + * Prints a verbose message to a log file (if Verbose logging is enabled for the given category, + * usually used for detailed logging) + */ + Verbose, + + /** + * Prints a verbose message to a log file (if VeryVerbose logging is enabled, + * usually used for detailed logging that would otherwise spam output) + */ + VeryVerbose, + }; + + enum class ECategory + { + Editor, + Generic, + }; + +private: + struct FStaticImpl; + + struct FStaticImplDeleter + { + void operator()(const FStaticImpl* Pointer) const; + }; + + static std::unique_ptr SPimpl; + static FStaticImplDeleter SPimplDeleter; + + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* Pointer) const; + }; + + std::unique_ptr Pimpl; + FImplDeleter PimplDeleter; + +private: + FString Buffer; + bool bAnyEntries; + +public: + FSGLogCore(const EVerbosity& Verbosity, const ECategory& Category, const std::string& File, + const std::string& Function, const int32 Line); + virtual ~FSGLogCore(); + +public: + template + FSGLogCore& operator,(const T& Argument) + { + if (bAnyEntries) + { + Buffer += FString(TEXT(" • ")); + } + + FString FormattedArgument; + TFSGLogString::Format(Argument, FormattedArgument); + Buffer += FormattedArgument; + bAnyEntries = true; + + return *this; + } +}; + +/* Generic */ + +#define SGLOG_FATAL( ... ) \ + (FSGLogCore(FSGLogCore::EVerbosity::Fatal, FSGLogCore::ECategory::Generic, __FILE__, __FUNCTION__, __LINE__)), __VA_ARGS__; + +#define SGLOG_ERROR( ... ) \ + (FSGLogCore(FSGLogCore::EVerbosity::Error, FSGLogCore::ECategory::Generic, __FILE__, __FUNCTION__, __LINE__)), __VA_ARGS__; + +#define SGLOG_WARNING( ... ) \ + (FSGLogCore(FSGLogCore::EVerbosity::Warning, FSGLogCore::ECategory::Generic, __FILE__, __FUNCTION__, __LINE__)), __VA_ARGS__; + +#define SGLOG_DISPLAY( ... ) \ + (FSGLogCore(FSGLogCore::EVerbosity::Display, FSGLogCore::ECategory::Generic, __FILE__, __FUNCTION__, __LINE__)), __VA_ARGS__; + +#define SGLOG_LOG( ... ) \ + (FSGLogCore(FSGLogCore::EVerbosity::Log, FSGLogCore::ECategory::Generic, __FILE__, __FUNCTION__, __LINE__)), __VA_ARGS__; + +#define SGLOG_VERBOSE( ... ) \ + (FSGLogCore(FSGLogCore::EVerbosity::Verbose, FSGLogCore::ECategory::Generic, __FILE__, __FUNCTION__, __LINE__)), __VA_ARGS__; + +#define SGLOG_VERY_VERBOSE( ... ) \ + (FSGLogCore(FSGLogCore::EVerbosity::VeryVerbose, FSGLogCore::ECategory::Generic, __FILE__, __FUNCTION__, __LINE__)), __VA_ARGS__; + +#define SGLOG( ... ) \ + (FSGLogCore(FSGLogCore::EVerbosity::Log, FSGLogCore::ECategory::Generic, __FILE__, __FUNCTION__, __LINE__)), __VA_ARGS__; + +/* Editor */ + +#define SGLOG_EDITOR_FATAL( ... ) \ + (FSGLogCore(FSGLogCore::EVerbosity::Fatal, FSGLogCore::ECategory::Editor, __FILE__, __FUNCTION__, __LINE__)), __VA_ARGS__; + +#define SGLOG_EDITOR_ERROR( ... ) \ + (FSGLogCore(FSGLogCore::EVerbosity::Error, FSGLogCore::ECategory::Editor, __FILE__, __FUNCTION__, __LINE__)), __VA_ARGS__; + +#define SGLOG_EDITOR_WARNING( ... ) \ + (FSGLogCore(FSGLogCore::EVerbosity::Warning, FSGLogCore::ECategory::Editor, __FILE__, __FUNCTION__, __LINE__)), __VA_ARGS__; + +#define SGLOG_EDITOR_DISPLAY( ... ) \ + (FSGLogCore(FSGLogCore::EVerbosity::Display, FSGLogCore::ECategory::Editor, __FILE__, __FUNCTION__, __LINE__)), __VA_ARGS__; + +#define SGLOG_EDITOR_LOG( ... ) \ + (FSGLogCore(FSGLogCore::EVerbosity::Log, FSGLogCore::ECategory::Editor, __FILE__, __FUNCTION__, __LINE__)), __VA_ARGS__; + +#define SGLOG_EDITOR_VERBOSE( ... ) \ + (FSGLogCore(FSGLogCore::EVerbosity::Verbose, FSGLogCore::ECategory::Editor, __FILE__, __FUNCTION__, __LINE__)), __VA_ARGS__; + +#define SGLOG_EDITOR_VERY_VERBOSE( ... ) \ + (FSGLogCore(FSGLogCore::EVerbosity::VeryVerbose, FSGLogCore::ECategory::Editor, __FILE__, __FUNCTION__, __LINE__)), __VA_ARGS__; + +#define SGLOG_EDITOR( ... ) \ + (FSGLogCore(FSGLogCore::EVerbosity::Log, FSGLogCore::ECategory::Editor, __FILE__, __FUNCTION__, __LINE__)), __VA_ARGS__; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveLog/SenseGloveLog.Build.cs b/Plugins/SenseGlove/Source/SenseGloveLog/SenseGloveLog.Build.cs new file mode 100644 index 0000000..4fa7e99 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveLog/SenseGloveLog.Build.cs @@ -0,0 +1,59 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGloveLog : ModuleRules +{ + public SenseGloveLog(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + } + ); + + if (Target.Configuration != UnrealTargetConfiguration.Shipping) + { + PublicDefinitions.Add("SENSEGLOVE_LOGGING"); + } + } +} diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGDebugCubeSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGDebugCubeSettings.cpp new file mode 100644 index 0000000..e41f178 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGDebugCubeSettings.cpp @@ -0,0 +1,64 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGDebugCubeSettings.h" + +FSGDebugCubeSettings::FSGDebugCubeSettings() + : FSGDebugCubeSettings{ + FVector{1.0f, 1.0f, 1.0f}, + FColor{255, 0, 0, 255}, + false, + 1.1f, + 0, + 1.0f, + } +{ +} + +FSGDebugCubeSettings::FSGDebugCubeSettings( + const FVector& InExtent, + const FColor& InColor, + const bool bInPersistentLines, + const float InLifeTimeModifier, + const uint8 InDepthPriority, + const float InThickness) + : Extent(InExtent), + Color(InColor), + bPersistentLines(bInPersistentLines), + LifeTimeModifier(InLifeTimeModifier), + DepthPriority(InDepthPriority), + Thickness(InThickness) +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGDebugGizmoSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGDebugGizmoSettings.cpp new file mode 100644 index 0000000..455c729 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGDebugGizmoSettings.cpp @@ -0,0 +1,70 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGDebugGizmoSettings.h" + +FSGDebugGizmoSettings::FSGDebugGizmoSettings() + : FSGDebugGizmoSettings{ + 1.0f, + FColor{255, 0, 0, 255}, + FColor{0, 255, 0, 255}, + FColor{0, 0, 255, 255}, + false, + 1.1f, + 0, + 1.0f, + } +{ +} + +FSGDebugGizmoSettings::FSGDebugGizmoSettings( + const float InLength, + const FColor& InXAxisColor, + const FColor& InYAxisColor, + const FColor& InZAxisColor, + const bool bInPersistentLines, + const float InLifeTimeModifier, + const uint8 InDepthPriority, + const float InThickness) + : Length(InLength), + XAxisColor{InXAxisColor}, + YAxisColor{InYAxisColor}, + ZAxisColor{InZAxisColor}, + bPersistentLines(bInPersistentLines), + LifeTimeModifier(InLifeTimeModifier), + DepthPriority(InDepthPriority), + Thickness(InThickness) +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGGameUserSettingsSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGGameUserSettingsSettings.cpp new file mode 100644 index 0000000..30fdaa9 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGGameUserSettingsSettings.cpp @@ -0,0 +1,47 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGGameUserSettingsSettings.h" + +FSGGameUserSettingsSettings::FSGGameUserSettingsSettings() + : HardwareBenchmarkingSettings{FSGHardwareBenchmarkingSettings{}} +{ +} + +FSGGameUserSettingsSettings::FSGGameUserSettingsSettings( + const FSGHardwareBenchmarkingSettings& InHardwareBenchmarkingSettings) + : HardwareBenchmarkingSettings{InHardwareBenchmarkingSettings} +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGGloveTrackingSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGGloveTrackingSettings.cpp new file mode 100644 index 0000000..230a9da --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGGloveTrackingSettings.cpp @@ -0,0 +1,49 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGGloveTrackingSettings.h" + +FSGGloveTrackingSettings::FSGGloveTrackingSettings() + : FSGGloveTrackingSettings{ + 1000.0f / 60.0f + } +{ +} + +FSGGloveTrackingSettings::FSGGloveTrackingSettings( + const float InGloveConnectivityCheckInterval) + : GloveConnectivityCheckInterval(InGloveConnectivityCheckInterval) +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGHMDTrackingSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGHMDTrackingSettings.cpp new file mode 100644 index 0000000..e52a236 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGHMDTrackingSettings.cpp @@ -0,0 +1,49 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGHMDTrackingSettings.h" + +FSGHMDTrackingSettings::FSGHMDTrackingSettings() + : FSGHMDTrackingSettings{ + ESGViveHMDDetectionPriority::FocusVision_XRElite_Focus3 + } +{ +} + +FSGHMDTrackingSettings::FSGHMDTrackingSettings( + const ESGViveHMDDetectionPriority InViveHmdDetectionPriority) + : ViveHMDDetectionPriority(InViveHmdDetectionPriority) +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGHandTrackingSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGHandTrackingSettings.cpp new file mode 100644 index 0000000..910f811 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGHandTrackingSettings.cpp @@ -0,0 +1,52 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGHandTrackingSettings.h" + +FSGHandTrackingSettings::FSGHandTrackingSettings() + : FSGHandTrackingSettings{ + false, + true + } +{ +} + +FSGHandTrackingSettings::FSGHandTrackingSettings( + const bool bInUseMoreSpecificMotionSourceNames, + const bool bInSupportLegacyControllerMotionSources) + : bUseMoreSpecificMotionSourceNames(bInUseMoreSpecificMotionSourceNames), + bSupportLegacyControllerMotionSources(bInSupportLegacyControllerMotionSources) +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGHardwareBenchmarkingSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGHardwareBenchmarkingSettings.cpp new file mode 100644 index 0000000..784a7ae --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGHardwareBenchmarkingSettings.cpp @@ -0,0 +1,55 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGHardwareBenchmarkingSettings.h" + +FSGHardwareBenchmarkingSettings::FSGHardwareBenchmarkingSettings() + : FSGHardwareBenchmarkingSettings{ + 10.0f, + 1.0f, + 1.0f + } +{ +} + +FSGHardwareBenchmarkingSettings::FSGHardwareBenchmarkingSettings( + const float InWorkScale, + const float InCPUMultiplier, + const float InGPUMultiplier) + : WorkScale(InWorkScale), + CPUMultiplier(InCPUMultiplier), + GPUMultiplier(InGPUMultiplier) +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGInitializationSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGInitializationSettings.cpp new file mode 100644 index 0000000..a544486 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGInitializationSettings.cpp @@ -0,0 +1,49 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGInitializationSettings.h" + +FSGInitializationSettings::FSGInitializationSettings() + : FSGInitializationSettings{ + false + } +{ +} + +FSGInitializationSettings::FSGInitializationSettings( + const bool bInValidateIfDefaultClassesAreSGCompliant) + : bValidateIfDefaultClassesAreSGCompliant(bInValidateIfDefaultClassesAreSGCompliant) +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGSettings.cpp new file mode 100644 index 0000000..8626eb5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGSettings.cpp @@ -0,0 +1,189 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGSettings.h" + +#include "Containers/Array.h" +#include "Engine/Engine.h" + +#if WITH_EDITOR +#include "PropertyEditorModule.h" +#endif /* WITH_EDITOR */ + +#include "UObject/NameTypes.h" +#include "UObject/Object.h" +#include "UObject/Package.h" +#include "UObject/UObjectGlobals.h" + +#include "SGLog/SGLog.h" + +#if WITH_EDITOR +#include "SGSettings/SGWristTrackingDetailsCustomization.h" +#endif /* WITH_EDITOR */ + +struct USGSettings::FImpl +{ + /************************ + * Static methods + ************************/ + + FORCENOINLINE static const FName& GetWristTrackingSettingsPropertyName() + { + static const FName Name{TEXT("SGWristTrackingSettings")}; + return Name; + } + + /************************ + * Owner object + ************************/ + + USGSettings* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGSettings* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; + + /************************ + * Methods + ************************/ + + void RegisterCustomPropertyTypeLayouts(); + void UnregisterCustomPropertyTypeLayouts(); +}; + +USGSettings* USGSettings::GetInstance() +{ + /// HACK + // Allow the game module to use the settings system in situations when GEngine is not initialized, yet! + // e.g. from SGPawn's CDO. + if (!GEngine) + { + USGSettings* StartupInstance{ + NewObject(GetTransientPackage(), FName(TEXT("SGSettings"))) + }; + return StartupInstance; + } + + USGSettings* Instance{GEngine->GetEngineSubsystem()}; + return Instance; +} + +USGSettings::USGSettings() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +bool USGSettings::ShouldCreateSubsystem(UObject* Outer) const +{ + return true; +} + +void USGSettings::Initialize(FSubsystemCollectionBase& Collection) +{ + SGLOG("Initializing the SenseGlove settings singleton with the engine lifetime..."); + + Super::Initialize(Collection); + +#if WITH_EDITOR + Pimpl->RegisterCustomPropertyTypeLayouts(); +#endif /* WITH_EDITOR */ + + SGLOG("The SenseGlove settings singleton has been successfully initialized with the engine lifetime!"); +} + +void USGSettings::Deinitialize() +{ + SGLOG("De-initializing the SenseGlove settings singleton due to the engine lifetime expiration..."); + + Super::Deinitialize(); + +#if WITH_EDITOR + Pimpl->UnregisterCustomPropertyTypeLayouts(); +#endif /* WITH_EDITOR */ + + (void) Pimpl.Release(); + + SGLOG("The SenseGlove settings singleton has been successfully de-initialized!"); +} + +USGSettings::FImpl::FImpl(USGSettings* InOwner) + : Owner(InOwner) +{ +} + +#if WITH_EDITOR +void USGSettings::FImpl::RegisterCustomPropertyTypeLayouts() +{ + SGLOG("Registering SGSettings custom property type layouts..."); + + FPropertyEditorModule& PropertyEditorModule = + FModuleManager::LoadModuleChecked(FName{TEXT("PropertyEditor")}); + + SGLOG("Registering SGSettings custom property type layout", GetWristTrackingSettingsPropertyName()); + PropertyEditorModule.RegisterCustomPropertyTypeLayout( + GetWristTrackingSettingsPropertyName(), + FOnGetPropertyTypeCustomizationInstance::CreateStatic( + &FSGWristTrackingDetailsCustomization::NewWristTrackingDetailsCustomization) + ); +} + +void USGSettings::FImpl::UnregisterCustomPropertyTypeLayouts() +{ + SGLOG("Unregistering SGSettings custom property type layouts..."); + + FPropertyEditorModule& PropertyEditorModule = + FModuleManager::LoadModuleChecked(FName{TEXT("PropertyEditor")}); + + SGLOG("Unregistering SGSettings custom property type layout", GetWristTrackingSettingsPropertyName()); + PropertyEditorModule.UnregisterCustomPropertyTypeLayout(GetWristTrackingSettingsPropertyName()); +} +#endif /* WITH_EDITOR */ + +USGSettings::FImpl::~FImpl() = default; + +void USGSettings::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGTrackingSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGTrackingSettings.cpp new file mode 100644 index 0000000..d91db35 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGTrackingSettings.cpp @@ -0,0 +1,61 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGTrackingSettings.h" + +FSGTrackingSettings::FSGTrackingSettings() + : FSGTrackingSettings{ + false, + FSGGloveTrackingSettings{}, + FSGHandTrackingSettings{}, + FSGHMDTrackingSettings{}, + FSGWristTrackingSettings{} + } +{ +} + +FSGTrackingSettings::FSGTrackingSettings( + const bool bInFallbackToHandTrackingIfNoGloveDetected, + const FSGGloveTrackingSettings& InGloveTrackingSettings, + const FSGHandTrackingSettings& InHandTrackingSettings, + const FSGHMDTrackingSettings& InHmdTrackingSettings, + const FSGWristTrackingSettings& InWristTrackingSettings) + : bFallbackToHandTrackingIfNoGloveDetected(bInFallbackToHandTrackingIfNoGloveDetected), + GloveTrackingSettings(InGloveTrackingSettings), + HandTrackingSettings(InHandTrackingSettings), + HMDTrackingSettings(InHmdTrackingSettings), + WristTrackingSettings(InWristTrackingSettings) +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandAnimationSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandAnimationSettings.cpp new file mode 100644 index 0000000..0aef199 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandAnimationSettings.cpp @@ -0,0 +1,52 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGVirtualHandAnimationSettings.h" + +FSGVirtualHandAnimationSettings::FSGVirtualHandAnimationSettings() + : FSGVirtualHandAnimationSettings{ + FRotator{0.0f, 90.0f, 90.0f}, + true + } +{ +} + +FSGVirtualHandAnimationSettings::FSGVirtualHandAnimationSettings( + const FRotator& InAnimationBoneRotationCorrectionOffset, + const bool bInShouldAnimationApplyBoneLocation) + : AnimationBoneRotationCorrectionOffset{InAnimationBoneRotationCorrectionOffset}, + bShouldAnimationApplyBoneLocation(bInShouldAnimationApplyBoneLocation) +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandDebuggingSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandDebuggingSettings.cpp new file mode 100644 index 0000000..d9a1e3a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandDebuggingSettings.cpp @@ -0,0 +1,74 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGVirtualHandDebuggingSettings.h" + +FSGVirtualHandDebuggingSettings::FSGVirtualHandDebuggingSettings() + : FSGVirtualHandDebuggingSettings{ + false, + ESGDebugVirtualHandDrawingMode::None, + FSGDebugCubeSettings{ + FVector{0.5f, 0.5f, 0.5f}, + FColor{255, 0, 0, 255}, + false, + 1.1f, + 0, + 0.2f, + }, + FSGDebugGizmoSettings{ + 1.0f, + FColor{255, 0, 0, 255}, + FColor{0, 255, 0, 255}, + FColor{0, 0, 255, 255}, + false, + 1.1f, + 0, + 0.25f, + }, + } +{ +} + +FSGVirtualHandDebuggingSettings::FSGVirtualHandDebuggingSettings( + const bool bInDrawDebugVirtualHand, + const ESGDebugVirtualHandDrawingMode InDrawingMode, + const FSGDebugCubeSettings& InDebugCubicHandSettings, + const FSGDebugGizmoSettings& InDebugGizmoHandSettings) + : bDrawDebugVirtualHand(bInDrawDebugVirtualHand), + DrawingMode(InDrawingMode), + DebugCubicHandSettings{InDebugCubicHandSettings}, + DebugGizmoHandSettings{InDebugGizmoHandSettings} +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandGrabSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandGrabSettings.cpp new file mode 100644 index 0000000..26b42f5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandGrabSettings.cpp @@ -0,0 +1,64 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGVirtualHandGrabSettings.h" + +FSGVirtualHandGrabSettings::FSGVirtualHandGrabSettings() + : FSGVirtualHandGrabSettings{ + FName{TEXT("GrabAttachPoint")}, + FTransform{FQuat::Identity, FVector{0.0f, 5.0f, -6.61557f}}, + FVector{0.04f, 0.04f, 0.04f}, + FName{TEXT("GrabThumbCollider")}, + FName{TEXT("GrabIndexCollider")}, + FName{TEXT("GrabMiddleCollider")} + } +{ +} + +FSGVirtualHandGrabSettings::FSGVirtualHandGrabSettings( + const FName& InGrabAttachPointSocketName, + const FTransform& InGrabAttachPointSocketTransform, + const FVector& InDefaultColliderSize, + const FName& InThumbColliderSocketName, + const FName& InIndexColliderSocketName, + const FName& InMiddleColliderSocketName) + : GrabAttachPointSocketName{InGrabAttachPointSocketName}, + GrabAttachPointSocketTransform{InGrabAttachPointSocketTransform}, + DefaultColliderSize{InDefaultColliderSize}, + ThumbColliderSocketName{InThumbColliderSocketName}, + IndexColliderSocketName{InIndexColliderSocketName}, + MiddleColliderSocketName{InMiddleColliderSocketName} +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandHapticsSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandHapticsSettings.cpp new file mode 100644 index 0000000..e71ea79 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandHapticsSettings.cpp @@ -0,0 +1,49 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGVirtualHandHapticsSettings.h" + +FSGVirtualHandHapticsSettings::FSGVirtualHandHapticsSettings() + : FSGVirtualHandHapticsSettings{ + true + } +{ +} + +FSGVirtualHandHapticsSettings::FSGVirtualHandHapticsSettings( + bool bInAutoStopAllHapticsOnEndPlay) + : bAutoStopAllHapticsOnEndPlay(bInAutoStopAllHapticsOnEndPlay) +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandMeshSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandMeshSettings.cpp new file mode 100644 index 0000000..5a68af9 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandMeshSettings.cpp @@ -0,0 +1,430 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGVirtualHandMeshSettings.h" + +#include "UObject/UnrealNames.h" + +#include "Engine/SkeletalMesh.h" + +FSGVirtualHandMeshSettings::FSGVirtualHandMeshSettings() + : FSGVirtualHandMeshSettings{ + nullptr, + nullptr, + FSGVirtualHandPhalangesLengthSettings{}, + FRotator{0.0f, -90.0f, 0.0f} + } +{ +} + +FSGVirtualHandMeshSettings::FSGVirtualHandMeshSettings( + const TSoftObjectPtr& InLeftHandReferenceMesh, + const TSoftObjectPtr& InRightHandReferenceMesh, + const FSGVirtualHandPhalangesLengthSettings& InDistalPhalangesLengthSettings, + const FRotator& InRootBoneRotationCorrection) + : LeftHandReferenceMesh{InLeftHandReferenceMesh}, + RightHandReferenceMesh{InRightHandReferenceMesh}, + DistalPhalangesLengthSettings{InDistalPhalangesLengthSettings}, + RootBoneRotationCorrection{InRootBoneRotationCorrection}, + LeftHandDefaultReferenceBoneTransforms{ + TPair{ + FName{TEXT("hand_l")}, + FTransform{ + FRotator{0.0f, -180.0f, 90.0f}, + FVector{0.0f, 0.0f, 0.0f} + } + }, + TPair{ + FName{TEXT("palm_l")}, + FTransform{ + FRotator{0.0f, 0.0f, 0.0f}, + FVector{0.0f, 0.0f, -6.61557f} + } + }, + TPair{ + FName{TEXT("thumb_01_l")}, + FTransform{ + FRotator{30.400068f, 75.42522f, 33.588919f}, + FVector{2.581536f, 1.356605f, -1.992447f} + } + }, + TPair{ + FName{TEXT("thumb_02_l")}, + FTransform{ + FRotator{-0.379136f, 4.00635f, -23.318826f}, + FVector{0.0f, 0.0f, -4.378f} + } + }, + TPair{ + FName{TEXT("thumb_03_l")}, + FTransform{ + FRotator{0.0f, 0.0f, -10.0f}, + FVector{0.0f, 0.0f, -3.086f} + } + }, + TPair{ + FName{TEXT("index_metacarpal_l")}, + FTransform{ + FRotator{7.277920f, 3.392215f, 1.032481f}, + FVector{2.379324f, -0.384681f, -3.444506f} + } + }, + TPair{ + FName{TEXT("index_01_l")}, + FTransform{ + FRotator{0.0f, 0.0f, -23.373f}, + FVector{-0.240876f, 0.043182f, -5.877098f} + } + }, + TPair{ + FName{TEXT("index_02_l")}, + FTransform{ + FRotator{0.0f, 0.0f, -14.892568f}, + FVector{0.0f, 0.0f, -4.08f} + } + }, + TPair{ + FName{TEXT("index_03_l")}, + FTransform{ + FRotator{0.0f, 0.0f, -12.516401f}, + FVector{0.0f, 0.0f, -2.595f} + } + }, + TPair{ + FName{TEXT("middle_metacarpal_l")}, + FTransform{ + FRotator{0.042392f, -4.274287f, 2.321687f}, + FVector{0.182864f, -0.753571f, -3.375834f} + } + }, + TPair{ + FName{TEXT("middle_01_l")}, + FTransform{ + FRotator{0.0f, 0.0f, -31.572682f}, + FVector{0.0f, 0.0f, -6.098209f} + } + }, + TPair{ + FName{TEXT("middle_02_l")}, + FTransform{ + FRotator{0.0f, 0.0f, -20.76921f}, + FVector{0.0f, 0.0f, -5.169f} + } + }, + TPair{ + FName{TEXT("middle_03_l")}, + FTransform{ + FRotator{0.0f, 0.0f, -10.0f}, + FVector{0.0f, 0.0f, -2.474f} + } + }, + TPair{ + FName{TEXT("ring_metacarpal_l")}, + FTransform{ + FRotator{-11.109678f, -13.886395f, 4.333313f}, + FVector{-1.091757f, -0.542517f, -3.374304f} + } + }, + TPair{ + FName{TEXT("ring_01_l")}, + FTransform{ + FRotator{3.034822f, 5.633827f, -29.271656f}, + FVector{0.020689f, -0.041625f, -5.645517f} + } + }, + TPair{ + FName{TEXT("ring_02_l")}, + FTransform{ + FRotator{0.0f, 0.0f, -18.964f}, + FVector{0.0f, 0.0f, -4.977f} + } + }, + TPair{ + FName{TEXT("ring_03_l")}, + FTransform{ + FRotator{0.0f, 0.0f, -9.167999f}, + FVector{0.0f, 0.0f, -2.265f} + } + }, + TPair{ + FName{TEXT("pinky_metacarpal_l")}, + FTransform{ + FRotator{-22.65256f, -25.358337f, -1.818999f}, + FVector{-2.391111f, -0.305917f, -3.314378f} + } + }, + TPair{ + FName{TEXT("pinky_01_l")}, + FTransform{ + FRotator{3.247850f, 9.999765f, -14.49391f}, + FVector{0.19884f, -0.14312f, -4.957568f} + } + }, + TPair{ + FName{TEXT("pinky_02_l")}, + FTransform{ + FRotator{0.0f, 0.0f, -21.286999f}, + FVector{0.0f, 0.0f, -3.816f} + } + }, + TPair{ + FName{TEXT("pinky_03_l")}, + FTransform{ + FRotator{0.0f, 0.0f, -4.917f}, + FVector{0.0f, 0.0f, -2.04f} + } + }, + }, + RightHandDefaultReferenceBoneTransforms{ + TPair{ + FName{TEXT("hand_r")}, + FTransform{ + FRotator{0.0f, -180.0f, 90.0f}, + FVector{0.0f, 0.0f, 0.0f} + } + }, + TPair{ + FName{TEXT("palm_r")}, + FTransform{ + FRotator{0.0f, 0.0f, 0.0f}, + FVector{0.000052f, -0.000629f, -6.615405f} + } + }, + TPair{ + FName{TEXT("thumb_01_r")}, + FTransform{ + FRotator{-30.400068f, -75.42522f, 33.588919f}, + FVector{-2.581326f, 1.356657f, -1.992833f} + } + }, + TPair{ + FName{TEXT("thumb_02_r")}, + FTransform{ + FRotator{0.379136f, -4.00635f, -23.318826f}, + FVector{0.000136f, -0.000427f, -4.377825f} + } + }, + TPair{ + FName{TEXT("thumb_03_r")}, + FTransform{ + FRotator{0.0f, 0.0f, -10.0f}, + FVector{-0.000046f, 0.000015f, -3.085952f} + } + }, + TPair{ + FName{TEXT("index_metacarpal_r")}, + FTransform{ + FRotator{-7.277920f, -3.392215f, 1.032481f}, + FVector{-2.379309f, -0.385167f, -3.444514f} + } + }, + TPair{ + FName{TEXT("index_01_r")}, + FTransform{ + FRotator{0.0f, 0.0f, -23.373f}, + FVector{0.240952f, 0.043412f, -5.877205f} + } + }, + TPair{ + FName{TEXT("index_02_r")}, + FTransform{ + FRotator{0.0f, 0.0f, -14.892568f}, + FVector{-0.000032f, -0.000005f, -4.079933f} + } + }, + TPair{ + FName{TEXT("index_03_r")}, + FTransform{ + FRotator{0.0f, 0.0f, -12.516401f}, + FVector{0.000004f, -0.00004f, -2.595076f} + } + }, + TPair{ + FName{TEXT("middle_metacarpal_r")}, + FTransform{ + FRotator{-0.042392f, 4.274287f, 2.321687f}, + FVector{-0.182806f, -0.754004f, -3.3758f} + } + }, + TPair{ + FName{TEXT("middle_01_r")}, + FTransform{ + FRotator{0.0f, 0.0f, -31.572682f}, + FVector{-0.000001f, 0.000124f, -6.098366f} + } + }, + TPair{ + FName{TEXT("middle_02_r")}, + FTransform{ + FRotator{0.0f, 0.0f, -20.76921f}, + FVector{0.000037f, 0.000077f, -5.168992f} + } + }, + TPair{ + FName{TEXT("middle_03_r")}, + FTransform{ + FRotator{0.0f, 0.0f, -10.0f}, + FVector{-0.000034f, -0.000046f, -2.474047f} + } + }, + TPair{ + FName{TEXT("ring_metacarpal_r")}, + FTransform{ + FRotator{11.109678f, 13.886395f, 4.333313f}, + FVector{1.091782f, -0.542992f, -3.374208f} + } + }, + TPair{ + FName{TEXT("ring_01_r")}, + FTransform{ + FRotator{-3.034822f, -5.633827f, -29.271656f}, + FVector{-0.020675f, -0.041443f, -5.645712f} + } + }, + TPair{ + FName{TEXT("ring_02_r")}, + FTransform{ + FRotator{0.0f, 0.0f, -18.964f}, + FVector{0.000024f, 0.000021f, -4.977067f} + } + }, + TPair{ + FName{TEXT("ring_03_r")}, + FTransform{ + FRotator{0.0f, 0.0f, -9.167999f}, + FVector{0.000011f, -0.00005f, -2.264975f} + } + }, + TPair{ + FName{TEXT("pinky_metacarpal_r")}, + FTransform{ + FRotator{22.65256f, 25.358337f, -1.818999f}, + FVector{2.391287f, -0.305935f, -3.314677f} + } + }, + TPair{ + FName{TEXT("pinky_01_r")}, + FTransform{ + FRotator{-3.24785f, -9.999765f, -14.49391f}, + FVector{-0.19892f, -0.143261f, -4.957301f} + } + }, + TPair{ + FName{TEXT("pinky_02_r")}, + FTransform{ + FRotator{0.0f, 0.0f, -21.286999f}, + FVector{-0.000033f, -0.00003f, -3.816036f} + } + }, + TPair{ + FName{TEXT("pinky_03_r")}, + FTransform{ + FRotator{0.0f, -0.000002f, -4.917f}, + FVector{0.000031f, 0.000018f, -2.04f} + } + }, + }, + LeftHandBoneNames + { + FName{TEXT("palm_l")},// Palm + FName{TEXT("hand_l")},// Wrist + FName{TEXT("thumb_01_l")},// ThumbMetacarpal + FName{TEXT("thumb_02_l")},// ThumbProximal + FName{TEXT("thumb_03_l")},// ThumbDistal + NAME_None,// ThumbTip + FName{TEXT("index_metacarpal_l")},// IndexMetacarpal + FName{TEXT("index_01_l")},// IndexProximal + FName{TEXT("index_02_l")},// IndexIntermediate + FName{TEXT("index_03_l")},// IndexDistal + NAME_None,// IndexTip + FName{TEXT("middle_metacarpal_l")},// MiddleMetacarpal + FName{TEXT("middle_01_l")},// MiddleProximal + FName{TEXT("middle_02_l")},// MiddleIntermediate + FName{TEXT("middle_03_l")},// MiddleDistal + NAME_None,// MiddleTip + FName{TEXT("ring_metacarpal_l")},// RingMetacarpal + FName{TEXT("ring_01_l")},// RingProximal + FName{TEXT("ring_02_l")},// RingIntermediate + FName{TEXT("ring_03_l")},// RingDistal + NAME_None,// RingTip + FName{TEXT("pinky_metacarpal_l")},// LittleMetacarpal + FName{TEXT("pinky_01_l")},// LittleProximal + FName{TEXT("pinky_02_l")},// LittleIntermediate + FName{TEXT("pinky_03_l")},// LittleDistal + NAME_None,// LittleTip + }, + RightHandBoneNames + { + FName{TEXT("palm_r")},// Palm + FName{TEXT("hand_r")},// Wrist + FName{TEXT("thumb_01_r")},// ThumbMetacarpal + FName{TEXT("thumb_02_r")},// ThumbProximal + FName{TEXT("thumb_03_r")},// ThumbDistal + NAME_None,// ThumbTip + FName{TEXT("index_metacarpal_r")},// IndexMetacarpal + FName{TEXT("index_01_r")},// IndexProximal + FName{TEXT("index_02_r")},// IndexIntermediate + FName{TEXT("index_03_r")},// IndexDistal + NAME_None,// IndexTip + FName{TEXT("middle_metacarpal_r")},// MiddleMetacarpal + FName{TEXT("middle_01_r")},// MiddleProximal + FName{TEXT("middle_02_r")},// MiddleIntermediate + FName{TEXT("middle_03_r")},// MiddleDistal + NAME_None,// MiddleTip + FName{TEXT("ring_metacarpal_r")},// RingMetacarpal + FName{TEXT("ring_01_r")},// RingProximal + FName{TEXT("ring_02_r")},// RingIntermediate + FName{TEXT("ring_03_r")},// RingDistal + NAME_None,// RingTip + FName{TEXT("pinky_metacarpal_r")},// LittleMetacarpal + FName{TEXT("pinky_01_r")},// LittleProximal + FName{TEXT("pinky_02_r")},// LittleIntermediate + FName{TEXT("pinky_03_r")},// LittleDistal + NAME_None// LittleTip + }, + DefaultLeftHandMeshPath{ + TEXT("SkeletalMesh'/SenseGlove/Meshes/SK_SenseGlove_VirtualHand_Left.SK_SenseGlove_VirtualHand_Left'") + }, + DefaultLeftHandMeshPathOnly{ + TEXT("/SenseGlove/Meshes/SK_SenseGlove_VirtualHand_Left.SK_SenseGlove_VirtualHand_Left") + }, + DefaultRightHandMeshPath{ + TEXT("SkeletalMesh'/SenseGlove/Meshes/SK_SenseGlove_VirtualHand_Right.SK_SenseGlove_VirtualHand_Right'") + }, + DefaultRightHandMeshPathOnly{ + TEXT("/SenseGlove/Meshes/SK_SenseGlove_VirtualHand_Right.SK_SenseGlove_VirtualHand_Right") + } +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandPhalangesLengthSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandPhalangesLengthSettings.cpp new file mode 100644 index 0000000..e6996f2 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandPhalangesLengthSettings.cpp @@ -0,0 +1,63 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGVirtualHandPhalangesLengthSettings.h" + +#include "Engine/SkeletalMesh.h" + +FSGVirtualHandPhalangesLengthSettings::FSGVirtualHandPhalangesLengthSettings() + : FSGVirtualHandPhalangesLengthSettings{ + 2.4f, + 2.4f, + 2.4f, + 2.4f, + 2.4f, + } +{ +} + +FSGVirtualHandPhalangesLengthSettings::FSGVirtualHandPhalangesLengthSettings( + const float InThumb, + const float InIndex, + const float InMiddle, + const float InRing, + const float InLittle) + : Thumb(InThumb), + Index(InIndex), + Middle(InMiddle), + Ring(InRing), + Little(InLittle) +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandSettings.cpp new file mode 100644 index 0000000..e121679 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandSettings.cpp @@ -0,0 +1,69 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGVirtualHandSettings.h" + +#include "Engine/SkeletalMesh.h" + +FSGVirtualHandSettings::FSGVirtualHandSettings() + : FSGVirtualHandSettings{ + false, + FSGVirtualHandAnimationSettings{}, + FSGVirtualHandDebuggingSettings{}, + FSGVirtualHandGrabSettings{}, + FSGVirtualHandHapticsSettings{}, + FSGVirtualHandMeshSettings{}, + FSGVirtualHandTouchSettings{} + } +{ +} + +FSGVirtualHandSettings::FSGVirtualHandSettings( + const bool bInVisibleWhenHandDataUnavailable, + const FSGVirtualHandAnimationSettings& InAnimationSettings, + const FSGVirtualHandDebuggingSettings& InDebuggingSettings, + const FSGVirtualHandGrabSettings& InGrabSettings, + const FSGVirtualHandHapticsSettings& InHapticsSettings, + const FSGVirtualHandMeshSettings& InMeshSettings, + const FSGVirtualHandTouchSettings& InTouchSettings) + : bVisibleWhenHandDataUnavailable(bInVisibleWhenHandDataUnavailable), + AnimationSettings{InAnimationSettings}, + DebuggingSettings{InDebuggingSettings}, + GrabSettings{InGrabSettings}, + HapticsSettings{InHapticsSettings}, + MeshSettings{InMeshSettings}, + TouchSettings{InTouchSettings} +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandSettingsOverrides.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandSettingsOverrides.cpp new file mode 100644 index 0000000..72e0524 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandSettingsOverrides.cpp @@ -0,0 +1,69 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGVirtualHandSettingsOverrides.h" + +#include "Engine/SkeletalMesh.h" + +FSGVirtualHandSettingsOverrides::FSGVirtualHandSettingsOverrides() + : FSGVirtualHandSettingsOverrides{ + false, + false, + FSGVirtualHandAnimationSettings{}, + FSGVirtualHandDebuggingSettings{}, + FSGVirtualHandGrabSettings{}, + FSGVirtualHandHapticsSettings{}, + FSGVirtualHandTouchSettings{} + } +{ +} + +FSGVirtualHandSettingsOverrides::FSGVirtualHandSettingsOverrides( + const bool bInOverridePluginSettings, + const bool bInVisibleWhenHandDataUnavailable, + const FSGVirtualHandAnimationSettings& InAnimationSettings, + const FSGVirtualHandDebuggingSettings& InDebuggingSettings, + const FSGVirtualHandGrabSettings& InGrabSettings, + const FSGVirtualHandHapticsSettings& InHapticsSettings, + const FSGVirtualHandTouchSettings& InTouchSettings) + : bOverridePluginSettings(bInOverridePluginSettings), + bVisibleWhenHandDataUnavailable(bInVisibleWhenHandDataUnavailable), + AnimationSettings{InAnimationSettings}, + DebuggingSettings{InDebuggingSettings}, + GrabSettings{InGrabSettings}, + HapticsSettings{InHapticsSettings}, + TouchSettings{InTouchSettings} +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandTouchSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandTouchSettings.cpp new file mode 100644 index 0000000..c6c5722 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGVirtualHandTouchSettings.cpp @@ -0,0 +1,64 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGVirtualHandTouchSettings.h" + +FSGVirtualHandTouchSettings::FSGVirtualHandTouchSettings() + : FSGVirtualHandTouchSettings{ + FVector{0.04f, 0.04f, 0.04f}, + FName{TEXT("TouchThumbCollider")}, + FName{TEXT("TouchIndexCollider")}, + FName{TEXT("TouchMiddleCollider")}, + FName{TEXT("TouchRingCollider")}, + FName{TEXT("TouchPinkyCollider")} + } +{ +} + +FSGVirtualHandTouchSettings::FSGVirtualHandTouchSettings( + const FVector& InDefaultColliderSize, + const FName& InThumbColliderSocketName, + const FName& InIndexColliderSocketName, + const FName& InMiddleColliderSocketName, + const FName& InRingColliderSocketName, + const FName& InPinkyColliderSocketName) + : DefaultColliderSize{InDefaultColliderSize}, + ThumbColliderSocketName{InThumbColliderSocketName}, + IndexColliderSocketName{InIndexColliderSocketName}, + MiddleColliderSocketName{InMiddleColliderSocketName}, + RingColliderSocketName{InRingColliderSocketName}, + PinkyColliderSocketName{InPinkyColliderSocketName} +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGWristTrackingDebuggingSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGWristTrackingDebuggingSettings.cpp new file mode 100644 index 0000000..c55197b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGWristTrackingDebuggingSettings.cpp @@ -0,0 +1,61 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGWristTrackingDebuggingSettings.h" + +FSGWristTrackingDebuggingSettings::FSGWristTrackingDebuggingSettings() + : FSGWristTrackingDebuggingSettings{ + false, + FSGDebugGizmoSettings{ + 4.0f, + FColor{255, 0, 0, 255}, + FColor{0, 255, 0, 255}, + FColor{0, 0, 255, 255}, + false, + 1.1f, + 0, + 0.4f, + }, + } +{ +} + +FSGWristTrackingDebuggingSettings::FSGWristTrackingDebuggingSettings( + const bool bInDrawDebugWristTracker, + const FSGDebugGizmoSettings& InDebugWristTrackerSettings) + : bDrawDebugWristTracker(bInDrawDebugWristTracker), + DebugWristTrackerSettings{InDebugWristTrackerSettings} +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGWristTrackingDetailsCustomization.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGWristTrackingDetailsCustomization.cpp new file mode 100644 index 0000000..104627f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGWristTrackingDetailsCustomization.cpp @@ -0,0 +1,222 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#if WITH_EDITOR + +#include "SGSettings/SGWristTrackingDetailsCustomization.h" + +#include "IMotionController.h" +#include "Widgets/Input/SComboBox.h" +#include "Widgets/Text/STextBlock.h" + +#include "SGLog/SGLog.h" + +struct FSGWristTrackingDetailsCustomization::FImpl +{ + /************************ + * Typedefs + ************************/ + + /************************ + * Static methods + ************************/ + + FORCENOINLINE static const FString& GetLeftHandMotionSourcePropertyName() + { + static const FString Name{TEXT("LeftHandMotionSource")}; + return Name; + } + + FORCENOINLINE static const FString& GetRightHandMotionSourcePropertyName() + { + static const FString Name{TEXT("RightHandMotionSource")}; + return Name; + } + + /************************ + * Member variables + ************************/ + + TArray> MotionSources; + + /************************ + * Owner object + ************************/ + + FSGWristTrackingDetailsCustomization* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGWristTrackingDetailsCustomization* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = delete; + FImpl& operator=(const FImpl& Rhs) = delete; + + /************************ + * Methods + ************************/ + + void PopulateComboBoxOptions(); +}; + +TSharedRef FSGWristTrackingDetailsCustomization::NewWristTrackingDetailsCustomization() +{ + return MakeShareable(new FSGWristTrackingDetailsCustomization{}); +} + +FSGWristTrackingDetailsCustomization::FSGWristTrackingDetailsCustomization() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +void FSGWristTrackingDetailsCustomization::CustomizeHeader( + TSharedRef PropertyHandle, + FDetailWidgetRow& HeaderRow, + IPropertyTypeCustomizationUtils& CustomizationUtils) +{ + HeaderRow.NameContent() + [ + PropertyHandle->CreatePropertyNameWidget() + ] + .ValueContent() + [ + PropertyHandle->CreatePropertyValueWidget() + ]; +} + +void FSGWristTrackingDetailsCustomization::CustomizeChildren( + TSharedRef PropertyHandle, + IDetailChildrenBuilder& ChildBuilder, + IPropertyTypeCustomizationUtils& CustomizationUtils) +{ + Pimpl->PopulateComboBoxOptions(); + + uint32 NumChildren; + PropertyHandle->GetNumChildren(NumChildren); + + for (uint32 Index = 0; Index < NumChildren; ++Index) + { + TSharedRef ChildHandle{PropertyHandle->GetChildHandle(Index).ToSharedRef()}; + + if (ChildHandle->GetProperty()->GetName() == Pimpl->GetLeftHandMotionSourcePropertyName() + || ChildHandle->GetProperty()->GetName() == Pimpl->GetRightHandMotionSourcePropertyName()) + { + ChildBuilder.AddCustomRow(ChildHandle->GetPropertyDisplayName()) + .NameContent() + [ + ChildHandle->CreatePropertyNameWidget() + ] + .ValueContent() + [ + SNew(SComboBox>) + .OptionsSource(&Pimpl->MotionSources) + .OnGenerateWidget_Lambda([](TSharedPtr InItem) + { + return SNew(STextBlock).Text(FText::FromName(*InItem)); + }) + .OnSelectionChanged_Lambda([ChildHandle](TSharedPtr NewValue, ESelectInfo::Type) + { + if (NewValue.IsValid()) + { + ChildHandle->SetValue(*NewValue); + } + }) + .Content() + [ + SNew(STextBlock) + .Text_Lambda([ChildHandle]() + { + FName CurrentValue; + ChildHandle->GetValue(CurrentValue); + return FText::FromName(CurrentValue); + }) + ] + ]; + } + else + { + ChildBuilder.AddProperty(ChildHandle); + } + } +} + +void FSGWristTrackingDetailsCustomization::FImpl::PopulateComboBoxOptions() +{ + SGLOG("Populating the FSGWristTrackingSettings MotionSources..."); + + MotionSources.Reset(); + + const TArray MotionControllers{ + IModularFeatures::Get().GetModularFeatureImplementations< + IMotionController>(IMotionController::GetModularFeatureName()) + }; + for (const IMotionController* MotionController: MotionControllers) + { + if (MotionController) + { + TArray MotionControllerSources; + MotionController->EnumerateSources(MotionControllerSources); + + MotionSources.Reserve(MotionSources.Num() + MotionControllerSources.Num()); + for (const FMotionControllerSource& MotionSource: MotionControllerSources) + { + SGLOG("Discovered a new motion source", MotionSource.SourceName); + + MotionSources.AddUnique(MakeShareable(new FName{MotionSource.SourceName})); + } + } + } +} + +FSGWristTrackingDetailsCustomization::FImpl::FImpl(FSGWristTrackingDetailsCustomization* InOwner) + : Owner(InOwner) +{ +} + +FSGWristTrackingDetailsCustomization::FImpl::~FImpl() = default; + +void FSGWristTrackingDetailsCustomization::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} + +#endif /* WITH_EDITOR */ \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGWristTrackingDetailsCustomization.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGWristTrackingDetailsCustomization.h new file mode 100644 index 0000000..979836b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGWristTrackingDetailsCustomization.h @@ -0,0 +1,79 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + + +#pragma once + +#if WITH_EDITOR + +#include "DetailWidgetRow.h" +#include "IDetailChildrenBuilder.h" +#include "IPropertyTypeCustomization.h" +#include "PropertyHandle.h" +#include "Templates/SharedPointer.h" +#include "Templates/UniquePtr.h" + +class SENSEGLOVESETTINGS_API FSGWristTrackingDetailsCustomization : public IPropertyTypeCustomization +{ +public: + static TSharedRef NewWristTrackingDetailsCustomization(); + +private: + FSGWristTrackingDetailsCustomization(); + +public: + virtual void CustomizeHeader( + TSharedRef PropertyHandle, + FDetailWidgetRow& HeaderRow, + IPropertyTypeCustomizationUtils& CustomizationUtils) override; + + virtual void CustomizeChildren( + TSharedRef PropertyHandle, + IDetailChildrenBuilder& ChildBuilder, + IPropertyTypeCustomizationUtils& CustomizationUtils) override; + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; +}; + +#endif /* WITH_EDITOR */ \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGWristTrackingSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGWristTrackingSettings.cpp new file mode 100644 index 0000000..4130d45 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGWristTrackingSettings.cpp @@ -0,0 +1,73 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGWristTrackingSettings.h" + +FSGWristTrackingSettings::FSGWristTrackingSettings() + : FSGWristTrackingSettings{ + ESGOpenXRPositionalTrackingProvider::None, + ESGPositionalTrackingHardware::None, + FVector::ZeroVector, + FVector::ZeroVector, + FRotator::ZeroRotator, + FRotator::ZeroRotator, + FName{TEXT("Left")}, + FName{TEXT("Right")}, + FSGWristTrackingDebuggingSettings{}, + } +{ +} + +FSGWristTrackingSettings::FSGWristTrackingSettings( + const ESGOpenXRPositionalTrackingProvider InOpenXRPositionalTrackingProvider, + const ESGPositionalTrackingHardware InTrackingHardware, + const FVector& InTrackingHardwareLocationOffsetLeftHand, + const FVector& InTrackingHardwareLocationOffsetRightHand, + const FRotator& InTrackingHardwareRotationOffsetLeftHand, + const FRotator& InTrackingHardwareRotationOffsetRightHand, + const FName InLeftHandMotionSource, + const FName InRightHandMotionSource, + const FSGWristTrackingDebuggingSettings& InDebuggingSettings) + : OpenXRPositionalTrackingProvider(InOpenXRPositionalTrackingProvider), + TrackingHardware(InTrackingHardware), + TrackingHardwareLocationOffsetLeftHand{InTrackingHardwareLocationOffsetLeftHand}, + TrackingHardwareLocationOffsetRightHand{InTrackingHardwareLocationOffsetRightHand}, + TrackingHardwareRotationOffsetLeftHand{InTrackingHardwareRotationOffsetLeftHand}, + TrackingHardwareRotationOffsetRightHand{InTrackingHardwareRotationOffsetRightHand}, + LeftHandMotionSource(InLeftHandMotionSource), + RightHandMotionSource(InRightHandMotionSource), + DebuggingSettings{InDebuggingSettings} +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGWristTrackingSettingsOverrides.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGWristTrackingSettingsOverrides.cpp new file mode 100644 index 0000000..b4a584e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SGSettings/SGWristTrackingSettingsOverrides.cpp @@ -0,0 +1,52 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettings/SGWristTrackingSettingsOverrides.h" + +FSGWristTrackingSettingsOverrides::FSGWristTrackingSettingsOverrides() + : FSGWristTrackingSettingsOverrides{ + false, + FSGWristTrackingDebuggingSettings{} + } +{ +} + +FSGWristTrackingSettingsOverrides::FSGWristTrackingSettingsOverrides( + const bool bInOverridePluginSettings, + const FSGWristTrackingDebuggingSettings& InDebuggingSettings) + : bOverridePluginSettings(bInOverridePluginSettings), + DebuggingSettings{InDebuggingSettings} +{ +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SenseGloveSettings.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SenseGloveSettings.cpp new file mode 100644 index 0000000..b2fccd9 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SenseGloveSettings.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveSettings.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveSettingsModule.h" + +IMPLEMENT_MODULE(FSenseGloveSettingsModule, SenseGloveSettings) \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SenseGloveSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SenseGloveSettings.h new file mode 100644 index 0000000..a30ce66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SenseGloveSettings.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SenseGloveSettingsModule.cpp b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SenseGloveSettingsModule.cpp new file mode 100644 index 0000000..73efa0d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SenseGloveSettingsModule.cpp @@ -0,0 +1,132 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveSettingsModule.h" + +#include "ISettingsModule.h" +#include "ISettingsSection.h" +#include "Modules/ModuleManager.h" + +#include "SGLog/SGLog.h" +#include "SGSettings/SGSettings.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveSettingsModule" + +void FSenseGloveSettingsModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveSettings module..."); + + SGLOG("Trying to get the Unreal Engine's Settings module..."); + + ISettingsModule* SettingsModule{FModuleManager::GetModulePtr("Settings")}; + if (SettingsModule) + { + SGLOG("Registering the SenseGlove settings manager through the Unreal Engine's Settings module..."); + + ISettingsSectionPtr SenseGloveSettingsSection{ + SettingsModule->RegisterSettings( + "Project", "Plugins", "SenseGloveSettings", + LOCTEXT("RuntimeSettingsName", "SenseGlove"), + LOCTEXT("RuntimeSettingsDescription", "Configure the SenseGlove settings"), + GetMutableDefault() + ) + }; + + if (SenseGloveSettingsSection.IsValid()) + { + SenseGloveSettingsSection->OnModified().BindRaw(this, &FSenseGloveSettingsModule::OnSettingsSaved); + + SGLOG("Successfully registered the SenseGlove settings manager!"); + } + else + { + SGLOG_ERROR("Failed to register the SenseGlove settings manager!"); + } + } + else + { + SGLOG_ERROR("Failed to get the Unreal Engine's Settings module!"); + } +} + +void FSenseGloveSettingsModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveSettings module..."); +} + +void FSenseGloveSettingsModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveSettings module has succeeded!"); +} + +void FSenseGloveSettingsModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveSettings module..."); + + SGLOG("Trying to get the Unreal Engine's Settings module..."); + + ISettingsModule* SettingsModule{FModuleManager::GetModulePtr("Settings")}; + if (SettingsModule) + { + SGLOG("Unregistering the SenseGlove settings manager through the Unreal Engine's Settings module..."); + + SettingsModule->UnregisterSettings("Project", "Plugins", "SenseGloveSettings"); + + SGLOG("Successfully unregistered the SenseGlove settings manager!"); + } + else + { + SGLOG_ERROR("Failed to get the Unreal Engine's Settings module!"); + } +} + +bool FSenseGloveSettingsModule::OnSettingsSaved() const +{ + USGSettings* Settings = GetMutableDefault(); + bool bResaveConfig = false; + + /// TODO + /// Validate settings here in case of invalid values. + /// In that case, we have to set bResaveConfig to true. + + if (bResaveConfig) + { + Settings->SaveConfig(); + } + + return true; +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SenseGloveSettingsModule.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SenseGloveSettingsModule.h new file mode 100644 index 0000000..07afceb --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Private/SenseGloveSettingsModule.h @@ -0,0 +1,54 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveSettings" + +class FSenseGloveSettingsModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; + +private: + bool OnSettingsSaved() const; +}; + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGDebugCubeSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGDebugCubeSettings.h new file mode 100644 index 0000000..b563291 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGDebugCubeSettings.h @@ -0,0 +1,82 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" +#include "Math/Color.h" +#include "Math/Vector.h" +#include "UObject/ObjectMacros.h" + +#include "SGDebugCubeSettings.generated.h" + +/** +* Implements the debug cube settings. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGDebugCubeSettings +{ + GENERATED_USTRUCT_BODY() + +public: + UPROPERTY(Config, EditDefaultsOnly, Category = "Debug Cube") + FVector Extent; + + UPROPERTY(Config, EditDefaultsOnly, Category = "Debug Cube") + FColor Color; + + UPROPERTY(Config, EditDefaultsOnly, Category = "Debug Cube") + bool bPersistentLines; + + UPROPERTY(Config, EditDefaultsOnly, Category = "Debug Cube") + float LifeTimeModifier; + + UPROPERTY(Config, EditDefaultsOnly, Category = "Debug Cube") + uint8 DepthPriority; + + UPROPERTY(Config, EditDefaultsOnly, Category = "Debug Cube") + float Thickness; + +public: + FSGDebugCubeSettings(); + + FSGDebugCubeSettings( + const FVector& InExtent, + const FColor& InColor, + bool bInPersistentLines, + float InLifeTimeModifier, + uint8 InDepthPriority, + float InThickness); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGDebugGizmoSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGDebugGizmoSettings.h new file mode 100644 index 0000000..f5bb741 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGDebugGizmoSettings.h @@ -0,0 +1,89 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" +#include "Math/Color.h" +#include "UObject/ObjectMacros.h" + +#include "SGDebugGizmoSettings.generated.h" + +/** +* Implements the debug gizmo settings. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGDebugGizmoSettings +{ + GENERATED_USTRUCT_BODY() + +public: + UPROPERTY(Config, EditDefaultsOnly, Category = "Debug Gizmo") + float Length; + + UPROPERTY(Config, EditDefaultsOnly, Category = "Debug Gizmo") + FColor XAxisColor; + + UPROPERTY(Config, EditDefaultsOnly, Category = "Debug Gizmo") + FColor YAxisColor; + + UPROPERTY(Config, EditDefaultsOnly, Category = "Debug Gizmo") + FColor ZAxisColor; + + UPROPERTY(Config, EditDefaultsOnly, Category = "Debug Gizmo") + bool bPersistentLines; + + UPROPERTY(Config, EditDefaultsOnly, Category = "Debug Gizmo") + float LifeTimeModifier; + + UPROPERTY(Config, EditDefaultsOnly, Category = "Debug Gizmo") + uint8 DepthPriority; + + UPROPERTY(Config, EditDefaultsOnly, Category = "Debug Gizmo") + float Thickness; + +public: + FSGDebugGizmoSettings(); + + FSGDebugGizmoSettings( + float InLength, + const FColor& InXAxisColor, + const FColor& InYAxisColor, + const FColor& InZAxisColor, + bool bInPersistentLines, + float InLifeTimeModifier, + uint8 InDepthPriority, + float InThickness); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGGameUserSettingsSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGGameUserSettingsSettings.h new file mode 100644 index 0000000..9116e73 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGGameUserSettingsSettings.h @@ -0,0 +1,74 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "UObject/ObjectMacros.h" + +#include "SGSettings/SGHardwareBenchmarkingSettings.h" + +#include "SGGameUserSettingsSettings.generated.h" + +/** +* Implements the game user settings. +* +* The Game User Settings control the behavior of the SenseGlove instance of UGameUserSettings. The USGGameUserSettings +* class extends the functionality of UGameUserSettings to provide enhanced customization options specifically for +* applications that utilize the SenseGlove Unreal Engine Plugin. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGGameUserSettingsSettings +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * The hardware-benchmarking settings. + * + * The settings in this section are utilized by the USGGameUserSettings::SetEngineScalabilitySettings() method when + * the Scalability parameter is set to ESGEngineScalabilitySettings::Auto. When the engine scalability settings set + * to auto the graphics settings are determined by running a hardware benchmark by calling the + * UGameUserSettings::RunHardwareBenchmark(). The settings listed here are basically the parameters passed to + * UGameUserSettings::RunHardwareBenchmark(). + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "Game User Settings") + FSGHardwareBenchmarkingSettings HardwareBenchmarkingSettings; + +public: + FSGGameUserSettingsSettings(); + + FSGGameUserSettingsSettings( + const FSGHardwareBenchmarkingSettings& InHardwareBenchmarkingSettings); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGGloveTrackingSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGGloveTrackingSettings.h new file mode 100644 index 0000000..862b372 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGGloveTrackingSettings.h @@ -0,0 +1,66 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "UObject/ObjectMacros.h" + +#include "SGGloveTrackingSettings.generated.h" + +/** +* Implements the glove tracking settings for the SenseGlove Tracking module. +* +* Provides the tracking settings related to SenseGlove devices. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGGloveTrackingSettings +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * The interval in which the tracking module checks for glove connectivity (in milliseconds). + * + * The default is 16.666666f which means 60 times per second. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Glove Tracking") + float GloveConnectivityCheckInterval; + +public: + FSGGloveTrackingSettings(); + + explicit FSGGloveTrackingSettings( + float InGloveConnectivityCheckInterval); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGHMDTrackingSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGHMDTrackingSettings.h new file mode 100644 index 0000000..bb207f1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGHMDTrackingSettings.h @@ -0,0 +1,67 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "UObject/ObjectMacros.h" + +#include "SGTypes/SGTrackingTypes.h" + +#include "SGHMDTrackingSettings.generated.h" + +/** +* Implements the HMD tracking settings for the SenseGlove Tracking module. +* +* Provides the tracking settings related to head-mounted displays (HDMs) and their auto-detection functionality. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGHMDTrackingSettings +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * Determines which VIVE HMD to prioritize for detection, as the current detection mechanism cannot differentiate + * between HTC VIVE Focus Vision, HTC VIVE XR Elite, and HTC VIVE Focus 3. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="HMD Tracking") + ESGViveHMDDetectionPriority ViveHMDDetectionPriority; + +public: + FSGHMDTrackingSettings(); + + explicit FSGHMDTrackingSettings( + ESGViveHMDDetectionPriority InViveHmdDetectionPriority); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGHandTrackingSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGHandTrackingSettings.h new file mode 100644 index 0000000..a242fe4 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGHandTrackingSettings.h @@ -0,0 +1,77 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" +#include "UObject/ObjectMacros.h" + +#include "SGHandTrackingSettings.generated.h" + +/** +* Implements the hand tracking settings for the SenseGlove Tracking module. +* +* The settings in this section only affects the hand-tracking functionality when it's enabled and available. When +* enabled the bare hands can be used instead of SenseGlove devices to interact within the VR simulation, of course +* without the haptics feedback provided by the SenseGlove devices. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGHandTrackingSettings +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * If disabled, (the default) the motion sources for hand tracking will be of the form '[Left|Right][Keypoint]'. If + * enabled, they will be of the form 'HandTracking[Left|Right][Keypoint]'. It is recommended to be enabled to avoid + * collisions between motion sources from different device types. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Hand Tracking") + bool bUseMoreSpecificMotionSourceNames; + + /** + * If enabled, hand tracking supports the 'Left' and 'Right' legacy motion sources. If disabled, it does not. It is + * recommended to be disabled unless you need legacy compatibility in older unreal projects. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Hand Tracking") + bool bSupportLegacyControllerMotionSources; + +public: + FSGHandTrackingSettings(); + + FSGHandTrackingSettings( + bool bInUseMoreSpecificMotionSourceNames, + bool bInSupportLegacyControllerMotionSources); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGHardwareBenchmarkingSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGHardwareBenchmarkingSettings.h new file mode 100644 index 0000000..73091cb --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGHardwareBenchmarkingSettings.h @@ -0,0 +1,85 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "UObject/ObjectMacros.h" + +#include "SGHardwareBenchmarkingSettings.generated.h" + +/** +* Implements the hardware-benchmarking settings. +* +* The settings in this section are utilized by the USGGameUserSettings::SetEngineScalabilitySettings() method when the +* Scalability parameter is set to ESGEngineScalabilitySettings::Auto. When the engine scalability settings set to auto +* the graphics settings are determined by running a hardware benchmark by calling the +* UGameUserSettings::RunHardwareBenchmark(). The settings listed here are basically the parameters passed to +* UGameUserSettings::RunHardwareBenchmark(). +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGHardwareBenchmarkingSettings +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * The WorkScale parameter determines the intensity of the benchmark test. Higher values result in more intensive + * testing, which can help achieve more accurate scalability settings. + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "Hardware Benchmarking") + float WorkScale; + + /** + * The CPUMultiplier parameter allows you to adjust the impact of CPU performance on the benchmark results. + * Increasing this value will emphasize CPU performance more heavily in determining scalability settings. + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "Hardware Benchmarking") + float CPUMultiplier; + + /** + * The GPUMultiplier parameter lets you modify the influence of GPU performance on the benchmark outcomes. A higher + * value will increase the weight of GPU performance in setting scalability. + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "Hardware Benchmarking") + float GPUMultiplier; + +public: + FSGHardwareBenchmarkingSettings(); + + FSGHardwareBenchmarkingSettings( + float InWorkScale, + float InCPUMultiplier, + float InGPUMultiplier); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGInitializationSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGInitializationSettings.h new file mode 100644 index 0000000..791e7f6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGInitializationSettings.h @@ -0,0 +1,70 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" +#include "UObject/ObjectMacros.h" + +#include "SGInitializationSettings.generated.h" + +/** +* Implements the plugin initialization settings. +* +* The Initialization Settings section is designed to control how the SenseGlove Unreal Engine Plugin is initialized, +* allowing you to customize its behavior to suit your project's needs. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGInitializationSettings +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * If enabled, the plugin tries to check and validate whether the default for classes such as GameMode, + * GameInstance, etc. are indeed SenseGlove classes or SenseGlove-derived classes. If not, it attempts to set them. + * If you don't like this behavior for whatever reason, consider disabling this option. + * + * By default, this option is disabled. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Initialization") + bool bValidateIfDefaultClassesAreSGCompliant; + +public: + FSGInitializationSettings(); + + explicit FSGInitializationSettings( + bool bInValidateIfDefaultClassesAreSGCompliant); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGSettings.h new file mode 100644 index 0000000..acce0ef --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGSettings.h @@ -0,0 +1,153 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Subsystems/EngineSubsystem.h" +#include "Templates/UniquePtr.h" +#include "UObject/ObjectMacros.h" + +#include "SGSettings/SGGameUserSettingsSettings.h" +#include "SGSettings/SGInitializationSettings.h" +#include "SGSettings/SGTrackingSettings.h" +#include "SGSettings/SGVirtualHandSettings.h" + +#include "SGSettings.generated.h" + +/** +* Implements the settings for the SenseGlove Unreal Engine Plugin. +*/ +UCLASS(config = SenseGloveSettings, DefaultConfig) +class SENSEGLOVESETTINGS_API USGSettings : public UEngineSubsystem +{ + GENERATED_BODY() + +public: + static USGSettings* GetInstance(); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +private: + /** + * The Initialization Settings section is designed to control how the SenseGlove Unreal Engine Plugin is + * initialized, allowing you to customize its behavior to suit your project's needs. + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "SenseGlove") + FSGInitializationSettings InitializationSettings; + + /** + * The Game User Settings control the behavior of the SenseGlove instance of UGameUserSettings. The + * USGGameUserSettings class extends the functionality of UGameUserSettings to provide enhanced customization + * options specifically for applications that utilize the SenseGlove Unreal Engine Plugin. + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "SenseGlove") + FSGGameUserSettingsSettings GameUserSettings; + + /** + * The tracking settings are primarily used by the SenseGlove Tracking module and are divided into various + * subsections, each focusing on a specific aspect of tracking. These subsections, along with the other settings + * directly provided by this section, provide comprehensive control over the tracking functionalities. + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "SenseGlove") + FSGTrackingSettings TrackingSettings; + + /** + * The Virtual Hand Settings are utilized by various SenseGlove modules such as Debug, Editor, Tracking, and the + * main module. These settings are divided into several subsections, each focusing on a specific aspect of the + * virtual hand functionality. Together with the settings provided directly in this section, they offer + * comprehensive control over any system or component that utilizes the virtual hand. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="SenseGlove") + FSGVirtualHandSettings VirtualHandSettings; + +private: + USGSettings(); + +public: + FORCEINLINE const FSGInitializationSettings& GetInitializationSettings() const + { + return InitializationSettings; + } + + void SetInitializationSettings(const FSGInitializationSettings& InInitializationSettings) + { + InitializationSettings = InInitializationSettings; + } + + FORCEINLINE const FSGGameUserSettingsSettings& GetGameUserSettings() const + { + return GameUserSettings; + } + + void SetGameUserSettings(const FSGGameUserSettingsSettings& InGameUserSettings) + { + GameUserSettings = InGameUserSettings; + } + + FORCEINLINE const FSGTrackingSettings& GetTrackingSettings() const + { + return TrackingSettings; + } + + void SetTrackingSettings(const FSGTrackingSettings& InTrackingSettings) + { + TrackingSettings = InTrackingSettings; + } + + FORCEINLINE const FSGVirtualHandSettings& GetVirtualHandSettings() const + { + return VirtualHandSettings; + } + + void SetVirtualHandSettings(const FSGVirtualHandSettings& InVirtualHandSettings) + { + VirtualHandSettings = InVirtualHandSettings; + } + +public: + virtual bool ShouldCreateSubsystem(UObject* Outer) const override; + + virtual void Initialize(FSubsystemCollectionBase& Collection) override; + virtual void Deinitialize() override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGTrackingSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGTrackingSettings.h new file mode 100644 index 0000000..6cd3093 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGTrackingSettings.h @@ -0,0 +1,109 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" +#include "UObject/ObjectMacros.h" + +#include "SGSettings/SGGloveTrackingSettings.h" +#include "SGSettings/SGHandTrackingSettings.h" +#include "SGSettings/SGHMDTrackingSettings.h" +#include "SGSettings/SGWristTrackingSettings.h" + +#include "SGTrackingSettings.generated.h" + +/** +* Implements the settings for the SenseGlove Tracking module. +* +* The tracking settings are primarily used by the SenseGlove Tracking module and are divided into various subsections, +* each focusing on a specific aspect of tracking. These subsections, along with the other settings directly provided by +* this section, provide comprehensive control over the tracking functionalities. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGTrackingSettings +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * Determines whether to fall back to hand-tracking, or not, when no SenseGlove device is detected: + * + * - If disabled, only a real glove will be tracked. + * - If enabled, the plugin will fall back to hand-tracking when it's available and supported by the HMD device. + * + * Note: disabling this option hides the hand-tracking settings section, while enabling it makes the hand-tracking + * settings visible. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Tracking") + bool bFallbackToHandTrackingIfNoGloveDetected; + + /** + * Provides the tracking settings related to SenseGlove devices. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Tracking") + FSGGloveTrackingSettings GloveTrackingSettings; + + /** + * The settings in this section only affects the hand-tracking functionality when it's enabled and available. When + * enabled the bare hands can be used instead of SenseGlove devices to interact within the VR simulation, of course + * without the haptics feedback provided by the SenseGlove devices. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Tracking", + meta=(EditCondition="bFallbackToHandTrackingIfNoGloveDetected", EditConditionHides)) + FSGHandTrackingSettings HandTrackingSettings; + + /** + * Provides the tracking settings related to head-mounted displays (HDMs) and their auto-detection functionality. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Tracking") + FSGHMDTrackingSettings HMDTrackingSettings; + + /** + * Provides the tracking settings applicable to wrist-tracking hardware. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Tracking") + FSGWristTrackingSettings WristTrackingSettings; + +public: + FSGTrackingSettings(); + + FSGTrackingSettings( + bool bInFallbackToHandTrackingIfNoGloveDetected, + const FSGGloveTrackingSettings& InGloveTrackingSettings, + const FSGHandTrackingSettings& InHandTrackingSettings, + const FSGHMDTrackingSettings& InHmdTrackingSettings, + const FSGWristTrackingSettings& InWristTrackingSettings); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandAnimationSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandAnimationSettings.h new file mode 100644 index 0000000..7730ea1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandAnimationSettings.h @@ -0,0 +1,82 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" +#include "Math/Rotator.h" +#include "UObject/ObjectMacros.h" +#include "UObject/SoftObjectPtr.h" + +#include "SGVirtualHandAnimationSettings.generated.h" + +class USkeletalMesh; + +/** +* Implements the virtual hand animation settings. +* +* Controls how the virtual hand model is animated by the animation system. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGVirtualHandAnimationSettings +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * Specifies the offset to apply to each bone's rotation when translating hand pose data to the virtual hand bones. + * This is useful if the virtual hand mesh was imported with an initial rotation. For example, the virtual hand + * model shipped with Unreal Engine's VRTemplate typically has an initial 90.0f degrees rotation on the Yaw axis. + * By default, this option has been set up with the Unreal Engine's VRTemplate virtual hand model in mind. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Animation") + FRotator AnimationBoneRotationCorrectionOffset; + + /** + * When enabled, the animation system applies the joint locations to the current virtual hand mesh bones in + * addition to the joint rotation. Otherwise, only the joint rotations are applied, and joint locations are + * ignored, leaving the bone locations untouched on the virtual hand mesh when animating it. Enabling this option + * typically improves the virtual hand animation. By default, this option is enabled. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Animation") + bool bShouldAnimationApplyBoneLocation; + +public: + FSGVirtualHandAnimationSettings(); + + FSGVirtualHandAnimationSettings( + const FRotator& InAnimationBoneRotationCorrectionOffset, + bool bInShouldAnimationApplyBoneLocation); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandDebuggingSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandDebuggingSettings.h new file mode 100644 index 0000000..b616ea4 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandDebuggingSettings.h @@ -0,0 +1,99 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" +#include "UObject/ObjectMacros.h" + +#include "SGSettings/SGDebugCubeSettings.h" +#include "SGSettings/SGDebugGizmoSettings.h" +#include "SGTypes/SGDebugTypes.h" + +#include "SGVirtualHandDebuggingSettings.generated.h" + +/** +* Implements the virtual hand debugging settings. +* +* Primarily used for visually debugging low-level hand data. When enabled, the Virtual Hand Component visualizes a +* debug virtual hand by drawing all individual hand joints. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGVirtualHandDebuggingSettings +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * If enabled, visualizes the debug virtual hand where possible. + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "Debugging") + bool bDrawDebugVirtualHand; + + /** + * Determines the virtual hand drawing mode. If set to `CubicJoints, for every joint a debug cube will be drawn. + * If set to GizmoJoints, for every joint a debug gizmo will be drawn. + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "Debugging", + meta=(EditCondition="bDrawDebugVirtualHand", EditConditionHides)) + ESGDebugVirtualHandDrawingMode DrawingMode; + + /** + * Visible and valid only if bDrawDebugVirtualHand is enabled and DrawingMode has been set to + * ESGDebugVirtualHandDrawingMode::CubicJoints. + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "Debugging", + meta=(EditCondition="bDrawDebugVirtualHand && DrawingMode == ESGDebugVirtualHandDrawingMode::CubicJoints", + EditConditionHides)) + FSGDebugCubeSettings DebugCubicHandSettings; + + /** + * Visible and valid only if bDrawDebugVirtualHand is enabled and DrawingMode has been set to + * ESGDebugVirtualHandDrawingMode::GizmoJoints. + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "Debugging", + meta=(EditCondition="bDrawDebugVirtualHand && DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints", + EditConditionHides)) + FSGDebugGizmoSettings DebugGizmoHandSettings; + +public: + FSGVirtualHandDebuggingSettings(); + + FSGVirtualHandDebuggingSettings( + bool bInDrawDebugVirtualHand, + ESGDebugVirtualHandDrawingMode InDrawingMode, + const FSGDebugCubeSettings& InDebugCubicHandSettings, + const FSGDebugGizmoSettings& InDebugGizmoHandSettings); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandGrabSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandGrabSettings.h new file mode 100644 index 0000000..aac8297 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandGrabSettings.h @@ -0,0 +1,109 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Math/Transform.h" +#include "Math/Vector.h" +#include "UObject/NameTypes.h" +#include "UObject/ObjectMacros.h" +#include "UObject/SoftObjectPtr.h" + +#include "SGVirtualHandGrabSettings.generated.h" + +class USkeletalMesh; + +/** +* Implements the virtual hand grab settings. +* +* Utilized by the SenseGlove Sockets Editor to automatically generate the hand sockets required by the Grab +* system to function. +* +* The SGPawn also utilizes these settings to set up the grab colliders on the virtual hand components. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGVirtualHandGrabSettings +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * The default socket name for the grab attach point, usually located at the palm of the hand. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Grab") + FName GrabAttachPointSocketName; + + /** + * The default socket transform (location, rotation, scale) for the grab attach point, usually located at the palm + * of the hand. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Grab") + FTransform GrabAttachPointSocketTransform; + + /** + * The default collider size for the fingers' grab colliders. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Grab") + FVector DefaultColliderSize; + + /** + * The default socket name for the thumb finger's grab collider, usually located at the tip of the thumb finger. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Grab") + FName ThumbColliderSocketName; + + /** + * The default socket name for the index finger's grab collider, usually located at the tip of the index finger. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Grab") + FName IndexColliderSocketName; + + /** + * The default socket name for the middle finger's grab collider, usually located at the tip of the middle finger. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Grab") + FName MiddleColliderSocketName; + +public: + FSGVirtualHandGrabSettings(); + + FSGVirtualHandGrabSettings( + const FName& InGrabAttachPointSocketName, + const FTransform& InGrabAttachPointSocketTransform, + const FVector& InDefaultColliderSize, + const FName& InThumbColliderSocketName, + const FName& InIndexColliderSocketName, + const FName& InMiddleColliderSocketName); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandHapticsSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandHapticsSettings.h new file mode 100644 index 0000000..1cc5d8e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandHapticsSettings.h @@ -0,0 +1,69 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "UObject/ObjectMacros.h" +#include "UObject/SoftObjectPtr.h" + +#include "SGVirtualHandHapticsSettings.generated.h" + +class USkeletalMesh; + +/** +* Implements the virtual hand haptics settings. +* +* Utilized by the haptics system. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGVirtualHandHapticsSettings +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * Forces all haptics to stop automatically on the EndPlay event. This is useful for situations where the + * simulation has ended, but ongoing haptic feedback might remain active on the glove indefinitely. By default, + * this setting is enabled. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Haptics") + bool bAutoStopAllHapticsOnEndPlay; + +public: + FSGVirtualHandHapticsSettings(); + + FSGVirtualHandHapticsSettings( + bool bInAutoStopAllHapticsOnEndPlay); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandMeshSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandMeshSettings.h new file mode 100644 index 0000000..85951a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandMeshSettings.h @@ -0,0 +1,179 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Containers/Map.h" +#include "Containers/UnrealString.h" +#include "Engine/SkeletalMesh.h" +#include "Math/Rotator.h" +#include "Math/Transform.h" +#include "UObject/NameTypes.h" +#include "UObject/ObjectMacros.h" +#include "UObject/SoftObjectPtr.h" + +#include "SGSettings/SGVirtualHandPhalangesLengthSettings.h" + +#include "SGVirtualHandMeshSettings.generated.h" + +class USkeletalMesh; + +/** +* Implements the virtual hand mesh settings. +* +* Utilized by the SenseGlove Tracking module to account for the current virtual hand mesh when generating hand pose +* data, resulting in more accurate glove or hand data representation and also smoother animations. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGVirtualHandMeshSettings +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * The virtual hand model for the left hand is to be used by the SenseGlove Tracking module to generate all the 26 + * joint data present in the FXRMotionControllerData. The main reason the Tracking module requires a virtual hand + * mesh as a reference is the SenseGlove Hand Pose format only provides 15 joints. So, the remaining joint data for + * FXRMotionControllerData are calculated from a virtual hand mesh compatible with the Epic rig and also the values + * specified by DistalPhalangesLengthSettings. Furthermore, when calculating the existing joints data, their + * current locations and rotations are taken into account in calculating the resulting FXRMotionControllerData. + * + * By default, no virtual hand mesh is set. + * + * Caution: + * If no virtual hand mesh is set, the Tracking module will fall back to hard-coded values extracted from the + * standard virtual hand model shipped by Unreal Engine VRTemplate. This may result in distorted hand mesh while + * animating a hand in case a different hand mesh other than the default Epic virtual hand mesh is being set on the + * virtual hand components. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Mesh") + TSoftObjectPtr LeftHandReferenceMesh; + + /** + * The virtual hand model for the right hand is to be used by the SenseGlove Tracking module to generate all the 26 + * joint data present in the FXRMotionControllerData. The main reason the Tracking module requires a virtual hand + * mesh as a reference is the SenseGlove Hand Pose format only provides 15 joints. So, the remaining joint data for + * FXRMotionControllerData are calculated from a virtual hand mesh compatible with the Epic rig and also the values + * specified by DistalPhalangesLengthSettings. Furthermore, when calculating the existing joints data, their + * current locations and rotations are taken into account in calculating the resulting FXRMotionControllerData. + * + * By default, no virtual hand mesh is set. + * + * Caution: + * If no virtual hand mesh is set, the Tracking module will fall back to hard-coded values extracted from the + * standard virtual hand model shipped by Unreal Engine VRTemplate. This may result in distorted hand mesh while + * animating a hand in case a different hand mesh other than the default Epic virtual hand mesh is being set on the + * virtual hand components. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Mesh") + TSoftObjectPtr RightHandReferenceMesh; + + /** + * The length of distal phalanges that cannot be retrieved from any virtual hand mesh compliant with the Epic + * standard rig. Also, the SenseGlove Hand Pose format does not provide these. This is used by SenseGlove Tracking + * module to calculate an FXRMotionControllerData the all 26 joints. The values you specify here depend on the + * shape of the virtual hand mesh and the defaults are approximated for the virtual hand model shipped with the + * Unreal Engine VRTemplate. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Mesh") + FSGVirtualHandPhalangesLengthSettings DistalPhalangesLengthSettings; + + /** + * Used mostly by the SenseGlove Tracking module and SGPawn to offset for any initial rotation during the virtual + * hand mesh import process. This is the case for example with the virtual hand model shipped with Unreal Engine's + * VRTemplate, which typically has an initial -90.0f degrees rotation on the Yaw axis. By default, this option has + * been set up with the Unreal Engine's VRTemplate virtual hand model in mind. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Mesh") + FRotator RootBoneRotationCorrection; + + /** + * Read-only and for internal use only. + */ + UPROPERTY(Config, VisibleDefaultsOnly, Category="Mesh") + TMap LeftHandDefaultReferenceBoneTransforms; + + /** + * Read-only and for internal use only. + */ + UPROPERTY(Config, VisibleDefaultsOnly, Category="Mesh") + TMap RightHandDefaultReferenceBoneTransforms; + + /** + * Read-only and for internal use only. + */ + UPROPERTY(Config, VisibleDefaultsOnly, Category="Mesh") + TArray LeftHandBoneNames; + + /** + * Read-only and for internal use only. + */ + UPROPERTY(Config, VisibleDefaultsOnly, Category="Mesh") + TArray RightHandBoneNames; + + /** + * Read-only and for internal use only. + */ + UPROPERTY(Config, VisibleDefaultsOnly, Category="Mesh") + FString DefaultLeftHandMeshPath; + + /** + * Read-only and for internal use only. + */ + UPROPERTY(Config, VisibleDefaultsOnly, Category="Mesh") + FString DefaultLeftHandMeshPathOnly; + + /** + * Read-only and for internal use only. + */ + UPROPERTY(Config, VisibleDefaultsOnly, Category="Mesh") + FString DefaultRightHandMeshPath; + + /** + * Read-only and for internal use only. + */ + UPROPERTY(Config, VisibleDefaultsOnly, Category="Mesh") + FString DefaultRightHandMeshPathOnly; + +public: + FSGVirtualHandMeshSettings(); + + FSGVirtualHandMeshSettings( + const TSoftObjectPtr& InLeftHandReferenceMesh, + const TSoftObjectPtr& InRightHandReferenceMesh, + const FSGVirtualHandPhalangesLengthSettings& InDistalPhalangesLengthSettings, + const FRotator& InRootBoneRotationCorrection); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandPhalangesLengthSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandPhalangesLengthSettings.h new file mode 100644 index 0000000..16fb9db --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandPhalangesLengthSettings.h @@ -0,0 +1,78 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "UObject/ObjectMacros.h" +#include "UObject/SoftObjectPtr.h" + +#include "SGVirtualHandPhalangesLengthSettings.generated.h" + +class USkeletalMesh; + +/** +* Implements the virtual hand phalanges length settings. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGVirtualHandPhalangesLengthSettings +{ + GENERATED_USTRUCT_BODY() + +public: + UPROPERTY(Config, EditDefaultsOnly, Category="Phalanges Length") + float Thumb; + + UPROPERTY(Config, EditDefaultsOnly, Category="Phalanges Length") + float Index; + + UPROPERTY(Config, EditDefaultsOnly, Category="Phalanges Length") + float Middle; + + UPROPERTY(Config, EditDefaultsOnly, Category="Phalanges Length") + float Ring; + + UPROPERTY(Config, EditDefaultsOnly, Category="Phalanges Length") + float Little; + +public: + FSGVirtualHandPhalangesLengthSettings(); + + FSGVirtualHandPhalangesLengthSettings( + float InThumb, + float InIndex, + float InMiddle, + float InRing, + float InLittle); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandSettings.h new file mode 100644 index 0000000..8713320 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandSettings.h @@ -0,0 +1,128 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "UObject/ObjectMacros.h" +#include "UObject/SoftObjectPtr.h" + +#include "SGSettings/SGVirtualHandAnimationSettings.h" +#include "SGSettings/SGVirtualHandDebuggingSettings.h" +#include "SGSettings/SGVirtualHandGrabSettings.h" +#include "SGSettings/SGVirtualHandHapticsSettings.h" +#include "SGSettings/SGVirtualHandMeshSettings.h" +#include "SGSettings/SGVirtualHandTouchSettings.h" + +#include "SGVirtualHandSettings.generated.h" + +/** +* Implements the virtual hand settings. +* +* The Virtual Hand Settings are utilized by various SenseGlove modules such as Debug, Editor, Tracking, and the main +* module. These settings are divided into several subsections, each focusing on a specific aspect of the virtual hand +* functionality. Together with the settings provided directly in this section, they offer comprehensive control over +* any system or component that utilizes the virtual hand. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGVirtualHandSettings +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * Used by the Virtual Hand Component to determine its visibility when no hand data, either from a SenseGlove or + * hand-tracking, is available. If enabled, the virtual hand mesh remains visible even when no data is available. + * By default, this setting is disabled, providing users of the simulation with a clear indicator that no hand data + * is currently available. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Virtual Hand") + bool bVisibleWhenHandDataUnavailable; + + /** + * Controls how the virtual hand model is animated by the animation system. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Virtual Hand") + FSGVirtualHandAnimationSettings AnimationSettings; + + /** + * Primarily used for visually debugging low-level hand data. When enabled, the Virtual Hand Component visualizes a + * debug virtual hand by drawing all individual hand joints. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Virtual Hand") + FSGVirtualHandDebuggingSettings DebuggingSettings; + + /** + * Utilized by the SenseGlove Sockets Editor to automatically generate the hand sockets required by the Grab + * system to function. + * + * The SGPawn also utilizes these settings to set up the grab colliders on the virtual hand components. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Virtual Hand") + FSGVirtualHandGrabSettings GrabSettings; + + /** + * Utilized by the haptics system. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Virtual Hand") + FSGVirtualHandHapticsSettings HapticsSettings; + + /** + * Utilized by the SenseGlove Tracking module to account for the current virtual hand mesh when generating hand + * pose data, resulting in more accurate glove or hand data representation and also smoother animations. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Virtual Hand") + FSGVirtualHandMeshSettings MeshSettings; + + /** + * Utilized by the SenseGlove Sockets Editor to automatically generate the hand sockets required by the touch + * system to function. + * + * The SGPawn also utilizes these settings to set up the grab colliders on the virtual hand components. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Virtual Hand") + FSGVirtualHandTouchSettings TouchSettings; + +public: + FSGVirtualHandSettings(); + + FSGVirtualHandSettings( + bool bInVisibleWhenHandDataUnavailable, + const FSGVirtualHandAnimationSettings& InAnimationSettings, + const FSGVirtualHandDebuggingSettings& InDebuggingSettings, + const FSGVirtualHandGrabSettings& InGrabSettings, + const FSGVirtualHandHapticsSettings& InHapticsSettings, + const FSGVirtualHandMeshSettings& InMeshSettings, + const FSGVirtualHandTouchSettings& InTouchSettings); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandSettingsOverrides.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandSettingsOverrides.h new file mode 100644 index 0000000..27d659c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandSettingsOverrides.h @@ -0,0 +1,127 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "UObject/ObjectMacros.h" +#include "UObject/SoftObjectPtr.h" + +#include "SGSettings/SGVirtualHandAnimationSettings.h" +#include "SGSettings/SGVirtualHandDebuggingSettings.h" +#include "SGSettings/SGVirtualHandGrabSettings.h" +#include "SGSettings/SGVirtualHandHapticsSettings.h" +#include "SGSettings/SGVirtualHandTouchSettings.h" + +#include "SGVirtualHandSettingsOverrides.generated.h" + +/** +* Implements the virtual hand settings' overrides. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGVirtualHandSettingsOverrides +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * Determines whether to override the plugin's virtual hand settings or not. + */ + UPROPERTY(EditAnywhere, Category = "SenseGlove") + bool bOverridePluginSettings; + + /** + * Used by the Virtual Hand Component to determine its visibility when no hand data, either from a SenseGlove or + * hand-tracking, is available. If enabled, the virtual hand mesh remains visible even when no data is available. + * By default, this setting is disabled, providing users of the simulation with a clear indicator that no hand data + * is currently available. + */ + UPROPERTY(EditAnywhere, Category = "SenseGlove", + meta=(EditCondition="bOverridePluginSettings", EditConditionHides)) + bool bVisibleWhenHandDataUnavailable; + + /** + * Controls how the virtual hand model is animated by the animation system. + */ + UPROPERTY(EditAnywhere, Category = "SenseGlove", + meta=(EditCondition="bOverridePluginSettings", EditConditionHides)) + FSGVirtualHandAnimationSettings AnimationSettings; + + /** + * Primarily used for visually debugging low-level hand data. When enabled, the Virtual Hand Component visualizes a + * debug virtual hand by drawing all individual hand joints. + */ + UPROPERTY(EditAnywhere, Category = "SenseGlove", + meta=(EditCondition="bOverridePluginSettings", EditConditionHides)) + FSGVirtualHandDebuggingSettings DebuggingSettings; + + /** + * Utilized by the SenseGlove Sockets Editor to automatically generate the hand sockets required by the Grab + * system to function. + * + * The SGPawn also utilizes these settings to set up the grab colliders on the virtual hand components. + */ + UPROPERTY(EditAnywhere, Category = "SenseGlove", + meta=(EditCondition="bOverridePluginSettings", EditConditionHides)) + FSGVirtualHandGrabSettings GrabSettings; + + /** + * Utilized by the haptics system. + */ + UPROPERTY(EditAnywhere, Category = "SenseGlove", + meta=(EditCondition="bOverridePluginSettings", EditConditionHides)) + FSGVirtualHandHapticsSettings HapticsSettings; + + /** + * Utilized by the SenseGlove Sockets Editor to automatically generate the hand sockets required by the touch + * system to function. + * + * The SGPawn also utilizes these settings to set up the grab colliders on the virtual hand components. + */ + UPROPERTY(EditAnywhere, Category = "SenseGlove", + meta=(EditCondition="bOverridePluginSettings", EditConditionHides)) + FSGVirtualHandTouchSettings TouchSettings; + +public: + FSGVirtualHandSettingsOverrides(); + + FSGVirtualHandSettingsOverrides( + bool bInOverridePluginSettings, + bool bInVisibleWhenHandDataUnavailable, + const FSGVirtualHandAnimationSettings& InAnimationSettings, + const FSGVirtualHandDebuggingSettings& InDebuggingSettings, + const FSGVirtualHandGrabSettings& InGrabSettings, + const FSGVirtualHandHapticsSettings& InHapticsSettings, + const FSGVirtualHandTouchSettings& InTouchSettings); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandTouchSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandTouchSettings.h new file mode 100644 index 0000000..3a4937e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGVirtualHandTouchSettings.h @@ -0,0 +1,107 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Math/Vector.h" +#include "UObject/NameTypes.h" +#include "UObject/ObjectMacros.h" +#include "UObject/SoftObjectPtr.h" + +#include "SGVirtualHandTouchSettings.generated.h" + +class USkeletalMesh; + +/** +* Implements the virtual hand touch settings. +* +* Utilized by the SenseGlove Sockets Editor to automatically generate the hand sockets required by the touch +* system to function. +* +* The SGPawn also utilizes these settings to set up the grab colliders on the virtual hand components. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGVirtualHandTouchSettings +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * The default collider size for the fingers' touch colliders. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Touch") + FVector DefaultColliderSize; + + /** + * The default socket name for the thumb finger's touch collider, usually located at the tip of the thumb finger. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Touch") + FName ThumbColliderSocketName; + + /** + * The default socket name for the index finger's touch collider, usually located at the tip of the index finger. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Touch") + FName IndexColliderSocketName; + + /** + * The default socket name for the middle finger's touch collider, usually located at the tip of the middle finger. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Touch") + FName MiddleColliderSocketName; + + /** + * The default socket name for the ring finger's touch collider, usually located at the tip of the ring finger. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Touch") + FName RingColliderSocketName; + + /** + * The default socket name for the pinky finger's touch collider, usually located at the tip of the pinky finger. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Touch") + FName PinkyColliderSocketName; + +public: + FSGVirtualHandTouchSettings(); + + FSGVirtualHandTouchSettings( + const FVector& InDefaultColliderSize, + const FName& InThumbColliderSocketName, + const FName& InIndexColliderSocketName, + const FName& InMiddleColliderSocketName, + const FName& InRingColliderSocketName, + const FName& InPinkyColliderSocketName); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGWristTrackingDebuggingSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGWristTrackingDebuggingSettings.h new file mode 100644 index 0000000..01ce183 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGWristTrackingDebuggingSettings.h @@ -0,0 +1,77 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" +#include "Math/Color.h" +#include "Math/Vector.h" +#include "UObject/ObjectMacros.h" + +#include "SGDebugGizmoSettings.h" + +#include "SGWristTrackingDebuggingSettings.generated.h" + +/** +* Implements the wrist tracking debugging settings. +* +* Provides debugging options for visually debugging the wrist tracker. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGWristTrackingDebuggingSettings +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * If enabled, visualizes the debug wrist trackers where possible. + */ + UPROPERTY(EditAnywhere, Category = "Debugging") + bool bDrawDebugWristTracker; + + /** + * Visible and valid only if bDrawDebugGizmo is enabled. + */ + UPROPERTY(EditAnywhere, Category = "Debugging", + meta=(EditCondition="bDrawDebugWristTracker", EditConditionHides)) + FSGDebugGizmoSettings DebugWristTrackerSettings; + +public: + FSGWristTrackingDebuggingSettings(); + + FSGWristTrackingDebuggingSettings( + bool bInDrawDebugWristTracker, + const FSGDebugGizmoSettings& InDebugWristTrackerSettings); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGWristTrackingSettings.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGWristTrackingSettings.h new file mode 100644 index 0000000..7de8e41 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGWristTrackingSettings.h @@ -0,0 +1,193 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" +#include "InputCoreTypes.h" +#include "Math/Rotator.h" +#include "Math/Vector.h" +#include "UObject/NameTypes.h" +#include "UObject/ObjectMacros.h" + +#include "SGSettings/SGWristTrackingDebuggingSettings.h" +#include "SGTypes/SGCoreTypes.h" +#include "SGTypes/SGTrackingTypes.h" + +#include "SGWristTrackingSettings.generated.h" + +/** +* Implements the wrist tracking settings. +* +* Provides the tracking settings applicable to wrist-tracking hardware. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGWristTrackingSettings +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * Specifies the type of OpenXR provider to use in order to extract the positional tracking data from the + * underlying XR system. If set to None, the plugin attempts to set this automatically by considering a combination + * of approaches including, the current value of `TrackingHardware` specified below, the platform it's targeted at, + * the available OpenXR plugins, along with HMD auto-detection mechanism to specify a compatible OpenXR tracking + * provider. Please note that the OpenXR provider depends on the combination of plugins, platform, and the settings + * you use. For example, it is possible to use a Vive Focus 3 Wrist Tracker on Microsoft Windows along with the + * Epic `OpenXRViveTracker` plugin and check the option `Emulate VIVE Wrist Tracker as VIVE Tracker` inside the + * VIVE Business Streaming application's Input settings. In that case, the correct OpenXR positional tracking + * provider to use would be `OpenXRViveTracker`. However, using the official ViveOpenXR plugin on Android, the + * correct OpenXR provider would be `OpenXRViveWristTracker`. + * + * Caution: + * HMD auto-detection is currently an experimental feature and may fail because HMD vendors occasionally change the + * properties utilized by the plugin for HMD detection. If you encounter issues, such as incorrect tracker offsets, + * it is recommended to explicitly specify the tracking hardware. + * + * Caution: + * Due to highly experimental nature of the HMD auto-detection feature, the HTC VIVE Focus Vision, HTC VIVE XR + * Elite, and HTC VIVE Focus Vision cannot be distinguished from each other in the current iteration. However, + * since the tracker devices and offsets for all these headsets are the same, this should not affect the + * performance or any functionality. The order in which the HMD is detected can be specified through the + * HMD-tracker setting `ViveHMDDetectionPriority`. + * + * Note: + * Ultimate Tracker and ViveOpenXRXrTracker are not supported, yet. + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "Wrist Tracking") + ESGOpenXRPositionalTrackingProvider OpenXRPositionalTrackingProvider; + + /** + * Specifies the type of tracking hardware to use. If set to None, the plugin attempts at HMD auto-detection to + * automatically specify a compatible tracking hardware. If set to `Custom`, any desired location and rotation can + * be specified. + * + * Caution: + * HMD auto-detection is currently an experimental feature and may fail because HMD vendors occasionally change the + * properties utilized by the plugin for HMD detection. If you encounter issues, such as incorrect tracker offsets, + * it is recommended to explicitly specify the tracking hardware. + * + * Caution: + * Due to highly experimental nature of the HMD auto-detection feature, the HTC VIVE Focus Vision, HTC VIVE XR + * Elite, and HTC VIVE Focus Vision cannot be distinguished from each other in the current iteration. However, + * since the tracker devices and offsets for all these headsets are the same, this should not affect the + * performance or any functionality. The order in which the HMD is detected can be specified through the + * HMD-tracker setting `ViveHMDDetectionPriority`. + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "Wrist Tracking") + ESGPositionalTrackingHardware TrackingHardware; + + /** + * Sets a custom location offset for left hand's wrist-tracking hardware. + * + * Note: + * This setting is visible and valid only if TrackingHardware is set to Custom. + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "Wrist Tracking", + meta=(EditCondition="TrackingHardware == ESGPositionalTrackingHardware::Custom", EditConditionHides)) + FVector TrackingHardwareLocationOffsetLeftHand; + + /** + * Sets a custom location offset for right hand's wrist-tracking hardware. + * + * Note: + * This setting is visible and valid only if TrackingHardware is set to Custom. + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "Wrist Tracking", + meta=(EditCondition="TrackingHardware == ESGPositionalTrackingHardware::Custom", EditConditionHides)) + FVector TrackingHardwareLocationOffsetRightHand; + + /** + * Sets a custom rotation offset for left hand's wrist-tracking hardware. + * + * Note: + * This setting is visible and valid only if TrackingHardware is set to Custom. + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "Wrist Tracking", + meta=(EditCondition="TrackingHardware == ESGPositionalTrackingHardware::Custom", EditConditionHides)) + FRotator TrackingHardwareRotationOffsetLeftHand; + + /** + * Sets a custom rotation offset for right hand's wrist-tracking hardware. + * + * Note: + * This setting is visible and valid only if TrackingHardware is set to Custom. + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "Wrist Tracking", + meta=(EditCondition="TrackingHardware == ESGPositionalTrackingHardware::Custom", EditConditionHides)) + FRotator TrackingHardwareRotationOffsetRightHand; + + /** + * Determines the motion source for the left hand. For Oculus HMDs, this is usually Left, and for VIVE HMDs, it's + * typically LeftFoot. + * + * Note: + * For VIVE devices using SteamVR, the motion source hardware for the left hand can be specified by the user + * through the SteamVR app. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Wrist Tracking") + FName LeftHandMotionSource; + + /** + * Determines the motion source for the left hand. For Oculus HMDs, this is usually Right, and for VIVE HMDs, it's + * typically RightFoot. + * + * Note: + * For VIVE devices using SteamVR, the motion source hardware for the right hand can be specified by the user + * through the SteamVR app. + */ + UPROPERTY(Config, EditDefaultsOnly, Category="Wrist Tracking") + FName RightHandMotionSource; + + /** + * Provides debugging options for visually debugging the wrist tracker. + */ + UPROPERTY(Config, EditDefaultsOnly, Category = "Wrist Tracking") + FSGWristTrackingDebuggingSettings DebuggingSettings; + +public: + FSGWristTrackingSettings(); + + FSGWristTrackingSettings( + const ESGOpenXRPositionalTrackingProvider InOpenXRPositionalTrackingProvider, + ESGPositionalTrackingHardware InTrackingHardware, + const FVector& InTrackingHardwareLocationOffsetLeftHand, + const FVector& InTrackingHardwareLocationOffsetRightHand, + const FRotator& InTrackingHardwareRotationOffsetLeftHand, + const FRotator& InTrackingHardwareRotationOffsetRightHand, + FName InLeftHandMotionSource, + FName InRightHandMotionSource, + const FSGWristTrackingDebuggingSettings& InDebuggingSettings); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGWristTrackingSettingsOverrides.h b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGWristTrackingSettingsOverrides.h new file mode 100644 index 0000000..3dfdc59 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/Public/SGSettings/SGWristTrackingSettingsOverrides.h @@ -0,0 +1,74 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" +#include "InputCoreTypes.h" +#include "UObject/ObjectMacros.h" + +#include "SGWristTrackingDebuggingSettings.h" + +#include "SGWristTrackingSettingsOverrides.generated.h" + +/** +* Implements the wrist tracking settings' overrides. +*/ +USTRUCT(BlueprintType) +struct SENSEGLOVESETTINGS_API FSGWristTrackingSettingsOverrides +{ + GENERATED_USTRUCT_BODY() + +public: + /** + * Determines whether to override the plugin's wrist tracking settings or not. + */ + UPROPERTY(EditAnywhere, Category = "SenseGlove") + bool bOverridePluginSettings; + + /** + * Provides debugging options for visually debugging the wrist tracker. + */ + UPROPERTY(EditAnywhere, Category = "SenseGlove", + meta=(EditCondition="bOverridePluginSettings", EditConditionHides)) + FSGWristTrackingDebuggingSettings DebuggingSettings; + +public: + FSGWristTrackingSettingsOverrides(); + + FSGWristTrackingSettingsOverrides( + bool bInOverridePluginSettings, + const FSGWristTrackingDebuggingSettings& InDebuggingSettings); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettings/SenseGloveSettings.Build.cs b/Plugins/SenseGlove/Source/SenseGloveSettings/SenseGloveSettings.Build.cs new file mode 100644 index 0000000..6e5135b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettings/SenseGloveSettings.Build.cs @@ -0,0 +1,86 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGloveSettings : ModuleRules +{ + public SenseGloveSettings(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + "HeadMountedDisplay", + "InputCore", + "SlateCore", + } + ); + + if (Target.bBuildEditor) + { + PrivateDependencyModuleNames.AddRange( + new string[] + { + "PropertyEditor", + "Slate", + "SlateCore", + } + ); + } + + PrivateIncludePathModuleNames.AddRange( + new string[] + { + "Settings", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveCore", + "SenseGloveLog", + "SenseGloveTypes", + "SenseGloveUtils", + } + ); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Private/SGSettingsKismet/SGSettingsKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Private/SGSettingsKismet/SGSettingsKismetLibrary.cpp new file mode 100644 index 0000000..1c49d05 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Private/SGSettingsKismet/SGSettingsKismetLibrary.cpp @@ -0,0 +1,87 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGSettingsKismet/SGSettingsKismetLibrary.h" + +#include "SGSettings/SGSettings.h" + +USGSettings* USGSettingsKismetLibrary::GetInstance() +{ + return USGSettings::GetInstance(); +} + +const FSGInitializationSettings& USGSettingsKismetLibrary::GetInitializationSettings(const USGSettings* Settings) +{ + return Settings->GetInitializationSettings(); +} + +void USGSettingsKismetLibrary::SetInitializationSettings( + USGSettings* Settings, const FSGInitializationSettings& InInitializationSettings) +{ + Settings->SetInitializationSettings(InInitializationSettings); +} + +const FSGGameUserSettingsSettings& USGSettingsKismetLibrary::GetGameUserSettings(const USGSettings* Settings) +{ + return Settings->GetGameUserSettings(); +} + +void USGSettingsKismetLibrary::SetGameUserSettings( + USGSettings* Settings, const FSGGameUserSettingsSettings& InGameUserSettingsSettings) +{ + Settings->SetGameUserSettings(InGameUserSettingsSettings); +} + +const FSGTrackingSettings& USGSettingsKismetLibrary::GetTrackingSettings(const USGSettings* Settings) +{ + return Settings->GetTrackingSettings(); +} + +void USGSettingsKismetLibrary::SetTrackingSettings( + USGSettings* Settings, const FSGTrackingSettings& InTrackingSettings) +{ + Settings->SetTrackingSettings(InTrackingSettings); +} + +const FSGVirtualHandSettings& USGSettingsKismetLibrary::GetVirtualHandSettings(const USGSettings* Settings) +{ + return Settings->GetVirtualHandSettings(); +} + +void USGSettingsKismetLibrary::SetVirtualHandSettings( + USGSettings* Settings, const FSGVirtualHandSettings& InVirtualHandSettings) +{ + Settings->SetVirtualHandSettings(InVirtualHandSettings); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Private/SenseGloveSettingsKismet.cpp b/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Private/SenseGloveSettingsKismet.cpp new file mode 100644 index 0000000..bbfa01c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Private/SenseGloveSettingsKismet.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveSettingsKismet.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveSettingsKismetModule.h" + +IMPLEMENT_MODULE(FSenseGloveSettingsKismetModule, SenseGloveSettingsKismet) diff --git a/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Private/SenseGloveSettingsKismet.h b/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Private/SenseGloveSettingsKismet.h new file mode 100644 index 0000000..a30ce66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Private/SenseGloveSettingsKismet.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Private/SenseGloveSettingsKismetModule.cpp b/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Private/SenseGloveSettingsKismetModule.cpp new file mode 100644 index 0000000..6265a93 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Private/SenseGloveSettingsKismetModule.cpp @@ -0,0 +1,62 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveSettingsKismetModule.h" + +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveSettingsKismetModule" + +void FSenseGloveSettingsKismetModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveSettingsKismet module..."); +} + +void FSenseGloveSettingsKismetModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveSettingsKismet module..."); +} + +void FSenseGloveSettingsKismetModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveSettingsKismet module has succeeded!"); +} + +void FSenseGloveSettingsKismetModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveSettingsKismet module..."); +} + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Private/SenseGloveSettingsKismetModule.h b/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Private/SenseGloveSettingsKismetModule.h new file mode 100644 index 0000000..2ca5c22 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Private/SenseGloveSettingsKismetModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveSettingsKismet" + +class FSenseGloveSettingsKismetModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Public/SGSettingsKismet/SGSettingsKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Public/SGSettingsKismet/SGSettingsKismetLibrary.h new file mode 100644 index 0000000..6ef0bf8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/Public/SGSettingsKismet/SGSettingsKismetLibrary.h @@ -0,0 +1,84 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGSettings/SGInitializationSettings.h" +#include "SGSettings/SGGameUserSettingsSettings.h" +#include "SGSettings/SGTrackingSettings.h" +#include "SGSettings/SGVirtualHandSettings.h" + +#include "SGSettingsKismetLibrary.generated.h" + +class USGSettings; + +UCLASS(meta=(ScriptName = "SenseGloveSettingsKismetLibrary")) +class SENSEGLOVESETTINGSKISMET_API USGSettingsKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, Category="SenseGlove | Settings") + static USGSettings* GetInstance(); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Settings") + static const FSGInitializationSettings& GetInitializationSettings(const USGSettings* Settings); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Settings") + static void SetInitializationSettings(UPARAM(ref) USGSettings* Settings, + const FSGInitializationSettings& InInitializationSettings); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Settings") + static const FSGGameUserSettingsSettings& GetGameUserSettings(const USGSettings* Settings); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Settings") + static void SetGameUserSettings(UPARAM(ref) USGSettings* Settings, + const FSGGameUserSettingsSettings& InGameUserSettings); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Settings") + static const FSGTrackingSettings& GetTrackingSettings(const USGSettings* Settings); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Settings") + static void SetTrackingSettings(UPARAM(ref) USGSettings* Settings, + const FSGTrackingSettings& InTrackingSettings); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Settings") + static const FSGVirtualHandSettings& GetVirtualHandSettings(const USGSettings* Settings); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Settings") + static void SetVirtualHandSettings(UPARAM(ref) USGSettings* Settings, + const FSGVirtualHandSettings& InVirtualHandSettings); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/SenseGloveSettingsKismet.Build.cs b/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/SenseGloveSettingsKismet.Build.cs new file mode 100644 index 0000000..0f0b438 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveSettingsKismet/SenseGloveSettingsKismet.Build.cs @@ -0,0 +1,64 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGloveSettingsKismet : ModuleRules +{ + public SenseGloveSettingsKismet(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveLog", + "SenseGloveKismet", + "SenseGloveSettings", + "SenseGloveTypes", + } + ); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SGTracking/SGGloveTracker.cpp b/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SGTracking/SGGloveTracker.cpp new file mode 100644 index 0000000..012e8f7 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SGTracking/SGGloveTracker.cpp @@ -0,0 +1,211 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGTracking/SGGloveTracker.h" + +#include "Engine/Engine.h" +#include "Engine/TimerHandle.h" +#include "Engine/World.h" +#include "TimerManager.h" + +#include "SGBackend/SGBackend.h" +#include "SGBuildHacks/SGPlatform.h" +#include "SGCore/SGHapticGlove.h" +#include "SGLog/SGLog.h" +#include "SGSettings/SGSettings.h" +#include "SGSettings/SGTrackingSettings.h" +#include "SGUtils/SGEngineUtils.h" + +struct USGGloveTracker::FImpl +{ + /************************ + * Static methods + ************************/ + + FORCEINLINE static float GetGloveConnectivityCheckInterval() + { + const USGSettings* Settings{USGSettings::GetInstance()}; + ensureAlwaysMsgf(Settings, TEXT("The settings subsystem has not been initialized!")); + return Settings->GetTrackingSettings().GloveTrackingSettings.GloveConnectivityCheckInterval * 0.001f; + } + + /************************ + * Member variables + ************************/ + + FTimerHandle GloveConnectivityCheckTimer; + + /************************ + * Owner object + ************************/ + + USGGloveTracker* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(USGGloveTracker* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; + + /************************ + * Methods + ************************/ + + void UpdateGloves() const; +}; + +USGGloveTracker* USGGloveTracker::GetInstance(const UObject* WorldContextObject) +{ + const UWorld* World{WorldContextObject ? WorldContextObject->GetWorld() : FSGEngineUtils::GetWorld()}; + USGGloveTracker* Instance{IsValid(World) ? World->GetSubsystem() : nullptr}; + return Instance; +} + +USGGloveTracker::USGGloveTracker() + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)), + LeftGlove(nullptr), + RightGlove(nullptr) +{ +} + +bool USGGloveTracker::ShouldCreateSubsystem(UObject* Outer) const +{ + return true; +} + +void USGGloveTracker::Initialize(FSubsystemCollectionBase& Collection) +{ + SGLOG("Initializing the SenseGlove tracking singleton with the world lifetime..."); + + Super::Initialize(Collection); + + const UWorld* World{GetWorld()}; + if (ensureAlwaysMsgf(World, TEXT("Invalid world!"))) + { + SGLOG("Starting the glove connectivity check timer..."); + + const float GloveConnectivityCheckInterval = FImpl::GetGloveConnectivityCheckInterval(); + + FTimerDelegate GloveConnectivityCheckHandler; + GloveConnectivityCheckHandler.BindLambda([= SG_CAPTURE_THIS]()-> void + { + Pimpl->UpdateGloves(); + }); + + FTimerManager& TimerManager = World->GetTimerManager(); + TimerManager.SetTimer( + Pimpl->GloveConnectivityCheckTimer, GloveConnectivityCheckHandler, GloveConnectivityCheckInterval, + true, -1.0f); + + if (ensureAlwaysMsgf(TimerManager.IsTimerActive(Pimpl->GloveConnectivityCheckTimer), + TEXT("GloveConnectivityCheckTimer is not active"))) + { + SGLOG("The glove connectivity check timer has been started successfully!"); + SGLOG("The glove connectivity timer interval is: ", GloveConnectivityCheckInterval); + } + else + { + SGLOG_ERROR("The glove connectivity check timer has failed to start!"); + } + } + + SGLOG("The SenseGlove tracking singleton has been successfully initialized with the world lifetime!"); +} + +void USGGloveTracker::Deinitialize() +{ + SGLOG("De-initializing the SenseGlove tracking singleton due to the world lifetime expiration..."); + + Super::Deinitialize(); + + const UWorld* World{GetWorld()}; + if (ensureAlwaysMsgf(World, TEXT("Invalid world!"))) + { + SGLOG("Stopping the glove connectivity check timer..."); + + FTimerManager& TimerManager = World->GetTimerManager(); + TimerManager.ClearTimer(Pimpl->GloveConnectivityCheckTimer); + + SGLOG("The glove connectivity check timer has been stopped successfully!"); + } + + (void) Pimpl.Release(); + + SGLOG("The SenseGlove tracking singleton has been successfully de-initialized!"); +} + +USGGloveTracker::FImpl::FImpl(USGGloveTracker* InOwner) + : Owner(InOwner) +{ +} + +USGGloveTracker::FImpl::~FImpl() = default; + +void USGGloveTracker::FImpl::UpdateGloves() const +{ + if (!USGBackend::GetInstance()->IsBackendInitialized()) + { + const bool bSucceeded = USGBackend::GetInstance()->InitializeBackend(); + if (!bSucceeded) + { + return; + } + } + + const bool bIsLeftGloveConnected = USGHapticGlove::GetGlove(Owner, false, Owner->LeftGlove); + if (!bIsLeftGloveConnected) + { + Owner->LeftGlove = nullptr; + } + + const bool bIsRightGloveConnected = USGHapticGlove::GetGlove(Owner, true, Owner->RightGlove); + if (!bIsRightGloveConnected) + { + Owner->RightGlove = nullptr; + } +} + +void USGGloveTracker::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SGTracking/SGHMDTracker.cpp b/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SGTracking/SGHMDTracker.cpp new file mode 100644 index 0000000..8c8e376 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SGTracking/SGHMDTracker.cpp @@ -0,0 +1,542 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGTracking/SGHMDTracker.h" + +#include "Engine/Engine.h" +#include "IHeadMountedDisplay.h" +#include "IXRTrackingSystem.h" + +#include "SGSettings/SGSettings.h" + +FName FSGHMDTracker::GetDeviceName() +{ + if (GEngine && GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowed()) + { + const IHeadMountedDisplay* Device{GEngine->XRSystem->GetHMDDevice()}; + if (Device) + { + const FName DeviceName{Device->GetHMDName()}; + return DeviceName; + } + } + return NAME_None; +} + +bool FSGHMDTracker::IsMetaQuest2() +{ + static const FName MetaQuest2DeviceIdentifier{TEXT("Meta Quest 2")}; + static const FName OculusQuest2DeviceIdentifier{TEXT("Oculus Quest2")}; + static const FString Quest2DeviceIdentifier1{TEXT("Quest 2")}; + static const FString Quest2DeviceIdentifier2{TEXT("Quest2")}; + + const FName DeviceName{GetDeviceName()}; + bool bMatched = DeviceName == MetaQuest2DeviceIdentifier || DeviceName == OculusQuest2DeviceIdentifier; + if (!bMatched) + { + const FString DeviceNameString{GetDeviceName().ToString()}; + bMatched = DeviceNameString.Contains(Quest2DeviceIdentifier1) + || DeviceNameString.Contains(Quest2DeviceIdentifier2); + } + + return bMatched; +} + +bool FSGHMDTracker::IsMetaQuestPro() +{ + static const FName MetaQuestProDeviceIdentifier{TEXT("Meta Quest Pro")}; + static const FName OculusQuestProDeviceIdentifier{TEXT("Oculus QuestPro")}; + static const FString QuestProDeviceIdentifier1{TEXT("Quest Pro")}; + static const FString QuestProDeviceIdentifier2{TEXT("QuestPro")}; + + const FName DeviceName{GetDeviceName()}; + bool bMatched = DeviceName == MetaQuestProDeviceIdentifier || DeviceName == OculusQuestProDeviceIdentifier; + if (!bMatched) + { + const FString DeviceNameString{GetDeviceName().ToString()}; + bMatched = DeviceNameString.Contains(QuestProDeviceIdentifier1) + || DeviceNameString.Contains(QuestProDeviceIdentifier2); + } + + return bMatched; +} + +bool FSGHMDTracker::IsMetaQuest3() +{ + static const FName MetaQuest3DeviceIdentifier{TEXT("Meta Quest 3")}; + static const FName OculusQuest3DeviceIdentifier{TEXT("Oculus Quest3")}; + static const FString Quest3DeviceIdentifier1{TEXT("Quest 3")}; + static const FString Quest3DeviceIdentifier2{TEXT("Quest3")}; + + const FName DeviceName{GetDeviceName()}; + bool bMatched = DeviceName == MetaQuest3DeviceIdentifier || DeviceName == OculusQuest3DeviceIdentifier; + if (!bMatched) + { + const FString DeviceNameString{GetDeviceName().ToString()}; + bMatched = DeviceNameString.Contains(Quest3DeviceIdentifier1) + || DeviceNameString.Contains(Quest3DeviceIdentifier2); + } + + return bMatched; +} + +bool FSGHMDTracker::IsHtcVivePro() +{ +#if PLATFORM_ANDROID + return false; +#else /* PLATFORM_ANDROID */ + static const FName DeviceIdentifier{TEXT("Vive OpenXR: Vive SRanipal")}; + static const FString ViveDeviceIdentifier{TEXT("Vive")}; + static const FString SRanipalDeviceIdentifier{TEXT("SRanipal")}; + + static const FName DeviceIdentifier2{TEXT("SteamVR/OpenXR : lighthouse")}; + static const FString LighthouseIdentifier{TEXT("lighthouse")}; + + const FName DeviceName{GetDeviceName()}; + + bool bNameMatches = DeviceName == DeviceIdentifier || DeviceName == DeviceIdentifier2; + if (!bNameMatches) + { + const FString DeviceNameString{GetDeviceName().ToString()}; + bNameMatches = DeviceNameString.Contains(ViveDeviceIdentifier) + || DeviceNameString.Contains(SRanipalDeviceIdentifier) + || DeviceNameString.Contains(LighthouseIdentifier); + } + + bool bResolutionMatches = false; + + if (bNameMatches) + { + if (GEngine && GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowed()) + { + IHeadMountedDisplay* Device{GEngine->XRSystem->GetHMDDevice()}; + if (Device) + { + IHeadMountedDisplay::MonitorInfo HmdMonitorInfo; + Device->GetHMDMonitorInfo(HmdMonitorInfo); + + /// NOTE + // VIVE Pro: + // - Official Spec: 1440 x 1600 pixels per eye (2880 x 1600 pixels combined) + // - Unreal OpenXR Resolution (PCVR): 4936 x 2740 + // VIVE Focus 3: + // - Official Spec: 2448 x 2448 pixels per eye (4896 x 2448 pixels combined) + // - Unreal OpenXR Resolution (PCVR): 5016 x 2508 + // - Unreal OpenXR Resolution (Standalone): ? + // VIVE XR Elite + // - Official Spec: 1920 x 1920 pixels per eye (3840 x 1920 pixels combined) + // - Unreal OpenXR Resolution (PCVR): 5016 x 2508 + // - Unreal OpenXR Resolution (Standalone): ? + // VIVE Focus Vision + // - Official Spec: 2448 x 2448 pixels per eye (4896 x 2448 pixels combined) + // - Unreal OpenXR Resolution (PCVR): 5016 x 2508 + // - Unreal OpenXR Resolution (Standalone): 1720 x 1720 + if (HmdMonitorInfo.ResolutionX < 5000 && HmdMonitorInfo.ResolutionY > 2700) + { + bResolutionMatches = true; + } + } + } + } + + const bool bMatched = bNameMatches && bResolutionMatches; + + return bMatched; +#endif /* PLATFORM_ANDROID */ +} + +bool FSGHMDTracker::IsHtcViveFocus3() +{ +#if PLATFORM_ANDROID + static const FName DeviceIdentifier{TEXT("WAVE:SUE")}; + + const FName DeviceName{GetDeviceName()}; + + const bool bNameMatches = DeviceName == DeviceIdentifier; +#else /* PLATFORM_ANDROID */ + static const FName DeviceIdentifier{TEXT("Vive OpenXR: Vive SRanipal")}; + static const FString ViveDeviceIdentifier{TEXT("Vive")}; + static const FString SRanipalDeviceIdentifier{TEXT("SRanipal")}; + + const FName DeviceName{GetDeviceName()}; + + bool bNameMatches = DeviceName == DeviceIdentifier; + if (!bNameMatches) + { + const FString DeviceNameString{GetDeviceName().ToString()}; + bNameMatches = DeviceNameString.Contains(ViveDeviceIdentifier) + || DeviceNameString.Contains(SRanipalDeviceIdentifier); + } +#endif /* PLATFORM_ANDROID */ + + /// NOTE + /// For the time being since we cannot distinguish between VIVE Focus Vision, VIVE XR Elite, and VIVE Focus 3 using + /// resolution checks, we skip the resolution checks altogether and assume it's not a VIVE Pro, as VIVE Pro won't + /// come with Android support. +#if PLATFORM_ANDROID + bool bResolutionMatches = true; +#else /* PLATFORM_ANDROID */ + bool bResolutionMatches = false; + + if (bNameMatches) + { + if (GEngine && GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowed()) + { + IHeadMountedDisplay* Device{GEngine->XRSystem->GetHMDDevice()}; + if (Device) + { + IHeadMountedDisplay::MonitorInfo HmdMonitorInfo; + Device->GetHMDMonitorInfo(HmdMonitorInfo); + + /// NOTE + // VIVE Pro: + // - Official Spec: 1440 x 1600 pixels per eye (2880 x 1600 pixels combined) + // - Unreal OpenXR Resolution (PCVR): 4936 x 2740 + // VIVE Focus 3: + // - Official Spec: 2448 x 2448 pixels per eye (4896 x 2448 pixels combined) + // - Unreal OpenXR Resolution (PCVR): 5016 x 2508 + // - Unreal OpenXR Resolution (Standalone): ? + // VIVE XR Elite + // - Official Spec: 1920 x 1920 pixels per eye (3840 x 1920 pixels combined) + // - Unreal OpenXR Resolution (PCVR): 5016 x 2508 + // - Unreal OpenXR Resolution (Standalone): ? + // VIVE Focus Vision + // - Official Spec: 2448 x 2448 pixels per eye (4896 x 2448 pixels combined) + // - Unreal OpenXR Resolution (PCVR): 5016 x 2508 + // - Unreal OpenXR Resolution (Standalone): 1720 x 1720 + if (HmdMonitorInfo.ResolutionX > 5000 && + (HmdMonitorInfo.ResolutionY > 2500 && HmdMonitorInfo.ResolutionY < 2700)) + { + bResolutionMatches = true; + } + } + } + } +#endif /* PLATFORM_ANDROID */ + + const bool bMatched = bNameMatches && bResolutionMatches; + + return bMatched; +} + +bool FSGHMDTracker::IsHtcViveXRElite() +{ +#if PLATFORM_ANDROID + static const FName DeviceIdentifier{TEXT("WAVE:SUE")}; + + const FName DeviceName{GetDeviceName()}; + + const bool bNameMatches = DeviceName == DeviceIdentifier; +#else /* PLATFORM_ANDROID */ + static const FName DeviceIdentifier{TEXT("Vive OpenXR: Vive SRanipal")}; + static const FString ViveDeviceIdentifier{TEXT("Vive")}; + static const FString SRanipalDeviceIdentifier{TEXT("SRanipal")}; + + const FName DeviceName{GetDeviceName()}; + + bool bNameMatches = DeviceName == DeviceIdentifier; + if (!bNameMatches) + { + const FString DeviceNameString{GetDeviceName().ToString()}; + bNameMatches = DeviceNameString.Contains(ViveDeviceIdentifier) + || DeviceNameString.Contains(SRanipalDeviceIdentifier); + } +#endif /* PLATFORM_ANDROID */ + + /// NOTE + /// For the time being since we cannot distinguish between VIVE Focus Vision, VIVE XR Elite, and VIVE Focus 3 using + /// resolution checks, we skip the resolution checks altogether and assume it's not a VIVE Pro, as VIVE Pro won't + /// come with Android support. +#if PLATFORM_ANDROID + bool bResolutionMatches = true; +#else /* PLATFORM_ANDROID */ + bool bResolutionMatches = false; + + if (bNameMatches) + { + if (GEngine && GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowed()) + { + IHeadMountedDisplay* Device{GEngine->XRSystem->GetHMDDevice()}; + if (Device) + { + IHeadMountedDisplay::MonitorInfo HmdMonitorInfo; + Device->GetHMDMonitorInfo(HmdMonitorInfo); + + /// NOTE + // VIVE Pro: + // - Official Spec: 1440 x 1600 pixels per eye (2880 x 1600 pixels combined) + // - Unreal OpenXR Resolution (PCVR): 4936 x 2740 + // VIVE Focus 3: + // - Official Spec: 2448 x 2448 pixels per eye (4896 x 2448 pixels combined) + // - Unreal OpenXR Resolution (PCVR): 5016 x 2508 + // - Unreal OpenXR Resolution (Standalone): ? + // VIVE XR Elite + // - Official Spec: 1920 x 1920 pixels per eye (3840 x 1920 pixels combined) + // - Unreal OpenXR Resolution (PCVR): 5016 x 2508 + // - Unreal OpenXR Resolution (Standalone): ? + // VIVE Focus Vision + // - Official Spec: 2448 x 2448 pixels per eye (4896 x 2448 pixels combined) + // - Unreal OpenXR Resolution (PCVR): 5016 x 2508 + // - Unreal OpenXR Resolution (Standalone): 1720 x 1720 + if (HmdMonitorInfo.ResolutionX > 5000 && + (HmdMonitorInfo.ResolutionY > 2500 && HmdMonitorInfo.ResolutionY < 2700)) + { + bResolutionMatches = true; + } + } + } + } +#endif /* PLATFORM_ANDROID */ + + const bool bMatched = bNameMatches && bResolutionMatches; + + return bMatched; +} + +bool FSGHMDTracker::IsHtcViveFocusVision() +{ +#if PLATFORM_ANDROID + static const FName DeviceIdentifier{TEXT("WAVE:SUE")}; + + const FName DeviceName{GetDeviceName()}; + + const bool bNameMatches = DeviceName == DeviceIdentifier; +#else /* PLATFORM_ANDROID */ + static const FName DeviceIdentifier{TEXT("Vive OpenXR: Vive SRanipal")}; + static const FString ViveDeviceIdentifier{TEXT("Vive")}; + static const FString SRanipalDeviceIdentifier{TEXT("SRanipal")}; + + const FName DeviceName{GetDeviceName()}; + + bool bNameMatches = DeviceName == DeviceIdentifier; + if (!bNameMatches) + { + const FString DeviceNameString{GetDeviceName().ToString()}; + bNameMatches = DeviceNameString.Contains(ViveDeviceIdentifier) + || DeviceNameString.Contains(SRanipalDeviceIdentifier); + } +#endif /* PLATFORM_ANDROID */ + + /// NOTE + /// For the time being since we cannot distinguish between VIVE Focus Vision, VIVE XR Elite, and VIVE Focus 3 using + /// resolution checks, we skip the resolution checks altogether and assume it's not a VIVE Pro, as VIVE Pro won't + /// come with Android support. +#if PLATFORM_ANDROID + bool bResolutionMatches = true; +#else /* PLATFORM_ANDROID */ + bool bResolutionMatches = false; + + if (bNameMatches) + { + if (GEngine && GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowed()) + { + IHeadMountedDisplay* Device{GEngine->XRSystem->GetHMDDevice()}; + if (Device) + { + IHeadMountedDisplay::MonitorInfo HmdMonitorInfo; + Device->GetHMDMonitorInfo(HmdMonitorInfo); + + /// NOTE + // VIVE Pro: + // - Official Spec: 1440 x 1600 pixels per eye (2880 x 1600 pixels combined) + // - Unreal OpenXR Resolution (PCVR): 4936 x 2740 + // VIVE Focus 3: + // - Official Spec: 2448 x 2448 pixels per eye (4896 x 2448 pixels combined) + // - Unreal OpenXR Resolution (PCVR): 5016 x 2508 + // - Unreal OpenXR Resolution (Standalone): ? + // VIVE XR Elite + // - Official Spec: 1920 x 1920 pixels per eye (3840 x 1920 pixels combined) + // - Unreal OpenXR Resolution (PCVR): 5016 x 2508 + // - Unreal OpenXR Resolution (Standalone): ? + // VIVE Focus Vision + // - Official Spec: 2448 x 2448 pixels per eye (4896 x 2448 pixels combined) + // - Unreal OpenXR Resolution (PCVR): 5016 x 2508 + // - Unreal OpenXR Resolution (Standalone): 1720 x 1720 + if (HmdMonitorInfo.ResolutionX > 5000 && + (HmdMonitorInfo.ResolutionY > 2500 && HmdMonitorInfo.ResolutionY < 2700)) + { + bResolutionMatches = true; + } + } + } + } +#endif /* PLATFORM_ANDROID */ + + const bool bMatched = bNameMatches && bResolutionMatches; + + return bMatched; +} + +ESGHeadMountedDisplayDevice FSGHMDTracker::GetDeviceType() +{ + if (IsMetaQuest2()) + { + return ESGHeadMountedDisplayDevice::MetaQuest2; + } + + if (IsMetaQuestPro()) + { + return ESGHeadMountedDisplayDevice::MetaQuestPro; + } + + if (IsMetaQuest3()) + { + return ESGHeadMountedDisplayDevice::MetaQuest3; + } + + if (IsHtcVivePro()) + { + return ESGHeadMountedDisplayDevice::HtcVivePro; + } + + const USGSettings* Settings{USGSettings::GetInstance()}; + ensureAlwaysMsgf(Settings, TEXT("The settings subsystem has not been initialized!")); + + if (Settings->GetTrackingSettings().HMDTrackingSettings.ViveHMDDetectionPriority == + ESGViveHMDDetectionPriority::FocusVision_XRElite_Focus3) + { + if (IsHtcViveFocusVision()) + { + return ESGHeadMountedDisplayDevice::HtcViveFocusVision; + } + + if (IsHtcViveXRElite()) + { + return ESGHeadMountedDisplayDevice::HtcViveXRElite; + } + + if (IsHtcViveFocus3()) + { + return ESGHeadMountedDisplayDevice::HtcViveFocus3; + } + } + + if (Settings->GetTrackingSettings().HMDTrackingSettings.ViveHMDDetectionPriority == + ESGViveHMDDetectionPriority::FocusVision_Focus3_XRElite) + { + if (IsHtcViveFocusVision()) + { + return ESGHeadMountedDisplayDevice::HtcViveFocusVision; + } + + if (IsHtcViveFocus3()) + { + return ESGHeadMountedDisplayDevice::HtcViveFocus3; + } + + if (IsHtcViveXRElite()) + { + return ESGHeadMountedDisplayDevice::HtcViveXRElite; + } + } + + if (Settings->GetTrackingSettings().HMDTrackingSettings.ViveHMDDetectionPriority == + ESGViveHMDDetectionPriority::XRElite_FocusVision_Focus3) + { + if (IsHtcViveXRElite()) + { + return ESGHeadMountedDisplayDevice::HtcViveXRElite; + } + + if (IsHtcViveFocusVision()) + { + return ESGHeadMountedDisplayDevice::HtcViveFocusVision; + } + + if (IsHtcViveFocus3()) + { + return ESGHeadMountedDisplayDevice::HtcViveFocus3; + } + } + + if (Settings->GetTrackingSettings().HMDTrackingSettings.ViveHMDDetectionPriority == + ESGViveHMDDetectionPriority::XRElite_Focus3_FocusVision) + { + if (IsHtcViveXRElite()) + { + return ESGHeadMountedDisplayDevice::HtcViveXRElite; + } + + if (IsHtcViveFocus3()) + { + return ESGHeadMountedDisplayDevice::HtcViveFocus3; + } + + if (IsHtcViveFocusVision()) + { + return ESGHeadMountedDisplayDevice::HtcViveFocusVision; + } + } + + if (Settings->GetTrackingSettings().HMDTrackingSettings.ViveHMDDetectionPriority == + ESGViveHMDDetectionPriority::Focus3_FocusVision_XRElite) + { + if (IsHtcViveFocus3()) + { + return ESGHeadMountedDisplayDevice::HtcViveFocus3; + } + + if (IsHtcViveFocusVision()) + { + return ESGHeadMountedDisplayDevice::HtcViveFocusVision; + } + + if (IsHtcViveXRElite()) + { + return ESGHeadMountedDisplayDevice::HtcViveXRElite; + } + } + + if (Settings->GetTrackingSettings().HMDTrackingSettings.ViveHMDDetectionPriority == + ESGViveHMDDetectionPriority::Focus3_XRElite_FocusVision) + { + if (IsHtcViveFocus3()) + { + return ESGHeadMountedDisplayDevice::HtcViveFocus3; + } + + if (IsHtcViveXRElite()) + { + return ESGHeadMountedDisplayDevice::HtcViveXRElite; + } + + if (IsHtcViveFocusVision()) + { + return ESGHeadMountedDisplayDevice::HtcViveFocusVision; + } + } + + return ESGHeadMountedDisplayDevice::None; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SGTracking/SGXRHandState.cpp b/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SGTracking/SGXRHandState.cpp new file mode 100644 index 0000000..9d491ed --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SGTracking/SGXRHandState.cpp @@ -0,0 +1,71 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGTracking/SGXRHandState.h" + +FSGXRHandState::FSGXRHandState() + : HandTracker{}, + JointLocations{}, + JointVelocities{}, + Velocities{XR_TYPE_HAND_JOINT_VELOCITIES_EXT}, + Locations{XR_TYPE_HAND_JOINT_LOCATIONS_EXT}, + KeypointTransforms{}, + Radii{}, + bHasReceivedJointPoses(false), + bTracked(false) +{ + Velocities.jointCount = XR_HAND_JOINT_COUNT_EXT; + Velocities.jointVelocities = JointVelocities; + + Locations.next = &Velocities; + Locations.jointCount = XR_HAND_JOINT_COUNT_EXT; + Locations.jointLocations = JointLocations; +} + +FSGXRHandState::~FSGXRHandState() = default; + +bool FSGXRHandState::GetTransform(const EHandKeypoint Keypoint, FTransform& OutTransform) const +{ + check(static_cast(Keypoint) < EHandKeypointCount); + OutTransform = KeypointTransforms[static_cast(Keypoint)]; + + return bHasReceivedJointPoses; +} + +const FTransform& FSGXRHandState::GetTransform(const EHandKeypoint Keypoint) const +{ + check(static_cast(Keypoint) < EHandKeypointCount); + return KeypointTransforms[static_cast(Keypoint)]; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SGTracking/SGXRTracker.cpp b/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SGTracking/SGXRTracker.cpp new file mode 100644 index 0000000..ccbd07f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SGTracking/SGXRTracker.cpp @@ -0,0 +1,2812 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGTracking/SGXRTracker.h" + +#include "Containers/Array.h" +#include "Containers/Map.h" +#include "Engine/Engine.h" +#include "Engine/SkeletalMesh.h" +#include "Engine/World.h" +#include "GameFramework/WorldSettings.h" +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4 +#include "IOpenXRHMD.h" +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4 */ +#include "IOpenXRHMDModule.h" +#include "IXRTrackingSystem.h" +#include "OpenXRCore.h" +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION <= 3 +#include "OpenXRHMD.h" +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION <= 3 */ + +#include "SGCore/SGHapticGlove.h" +#include "SGLog/SGLog.h" +#include "SGSettings/SGSettings.h" +#include "SGTracking/SGGloveTracker.h" +#include "SGTracking/SGHMDTracker.h" +#include "SGTracking/SGXRHandState.h" +#include "SGTypes/SGCoreTypes.h" +#include "SGTypes/SGTrackingTypes.h" +#include "SGUtils/SGEngineUtils.h" +#include "SGUtils/SGPluginUtils.h" + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION <= 3 +void EnumerateOpenXRApiLayers(TArray& OutProperties) +{ + uint32 Count = 0; + XR_ENSURE(xrEnumerateApiLayerProperties(0, &Count, nullptr)); + OutProperties.SetNum(Count); + for (auto& Prop: OutProperties) + { + Prop = XrApiLayerProperties{XR_TYPE_API_LAYER_PROPERTIES}; + } + XR_ENSURE(xrEnumerateApiLayerProperties(Count, &Count, OutProperties.GetData())); +} +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION <= 3 */ + +struct FSGXRTracker::FImpl +{ + /************************ + * Typedefs + ************************/ + + // bool true == left, false == right + typedef TPair FSGMotionSourceInfo; + + /************************ + * Static methods + ************************/ + + /** + * Parses the enum name removing the prefix. + */ + static FName GetHandKeypointEnumName(const EHandKeypoint HandKeypoint); + + FORCEINLINE static FName GetHandKeypointEnumName(const int32 HandKeypointIndex) + { + return GetHandKeypointEnumName(static_cast(HandKeypointIndex)); + } + + static FName GetControllerHandEnumName(const EControllerHand ControllerHand); + + static FName GetOpenXRPositionalTrackingProviderEnumName( + const ESGOpenXRPositionalTrackingProvider OpenXRPositionalTrackingProvider); + + FORCEINLINE static bool ShouldFallbackToHandTrackingIfNoGloveDetected() + { + const USGSettings* Settings{USGSettings::GetInstance()}; + ensureAlwaysMsgf(Settings, TEXT("The settings subsystem has not been initialized!")); + const bool bFallbackToHandTrackingIfNoGloveDetected = + Settings->GetTrackingSettings().bFallbackToHandTrackingIfNoGloveDetected; + return bFallbackToHandTrackingIfNoGloveDetected; + } + + FORCEINLINE static bool ShouldUseMoreSpecificMotionSourceNames() + { + const USGSettings* Settings{USGSettings::GetInstance()}; + ensureAlwaysMsgf(Settings, TEXT("The settings subsystem has not been initialized!")); + const bool bFallbackToHandTrackingIfNoGloveDetected = ShouldFallbackToHandTrackingIfNoGloveDetected(); + const bool bUseMoreSpecificMotionSourceNames = + bFallbackToHandTrackingIfNoGloveDetected + ? Settings->GetTrackingSettings().HandTrackingSettings.bUseMoreSpecificMotionSourceNames + : false; + return bUseMoreSpecificMotionSourceNames; + } + + FORCEINLINE static bool ShouldSupportLegacyControllerMotionSources() + { + const USGSettings* Settings{USGSettings::GetInstance()}; + ensureAlwaysMsgf(Settings, TEXT("The settings subsystem has not been initialized!")); + const bool bFallbackToHandTrackingIfNoGloveDetected = ShouldFallbackToHandTrackingIfNoGloveDetected(); + const bool bSupportLegacyControllerMotionSources = + bFallbackToHandTrackingIfNoGloveDetected + ? Settings->GetTrackingSettings().HandTrackingSettings.bSupportLegacyControllerMotionSources + : false; + return bSupportLegacyControllerMotionSources; + } + + FORCEINLINE static const FSGHandTrackingSettings& GetHandTrackingSettings() + { + const USGSettings* Settings{USGSettings::GetInstance()}; + ensureAlwaysMsgf(Settings, TEXT("The settings subsystem has not been initialized!")); + return Settings->GetTrackingSettings().HandTrackingSettings; + } + + FORCEINLINE static const FSGVirtualHandSettings& GetVirtualHandSettings() + { + const USGSettings* Settings{USGSettings::GetInstance()}; + ensureAlwaysMsgf(Settings, TEXT("The settings subsystem has not been initialized!")); + return Settings->GetVirtualHandSettings(); + } + + FORCEINLINE static const FSGWristTrackingSettings& GetWristTrackingSettings() + { + const USGSettings* Settings{USGSettings::GetInstance()}; + ensureAlwaysMsgf(Settings, TEXT("The settings subsystem has not been initialized!")); + return Settings->GetTrackingSettings().WristTrackingSettings; + } + + FORCEINLINE static const FName& GetDefaultLeftHandTrackingMotionSourceName() + { + static const FName Name(TEXT("Left")); + return Name; + } + + FORCEINLINE static const FName& GetDefaultRightHandTrackingMotionSourceName() + { + static const FName Name(TEXT("Right")); + return Name; + } + + FORCEINLINE static const FName& GetDefaultHandTrackingMotionSourceName(const EControllerHand Hand) + { + const FName& Name{ + Hand == EControllerHand::Right + ? GetDefaultRightHandTrackingMotionSourceName() + : GetDefaultLeftHandTrackingMotionSourceName() + }; + return Name; + } + + FORCEINLINE static const FName& GetDefaultHandTrackingMotionSourceName(const bool bRight) + { + const FName& Name{ + bRight + ? GetDefaultRightHandTrackingMotionSourceName() + : GetDefaultLeftHandTrackingMotionSourceName() + }; + return Name; + } + + FORCEINLINE static const FName& GetLegacyControllerLeftHandTrackingMotionSourceName() + { + static const FName Name(TEXT("Left")); + return Name; + } + + FORCEINLINE static const FName& GetLegacyControllerRightHandTrackingMotionSourceName() + { + static const FName Name(TEXT("Right")); + return Name; + } + + FORCEINLINE static const FName& GetLegacyControllerHandTrackingMotionSourceName(const EControllerHand Hand) + { + const FName& Name{ + Hand == EControllerHand::Right + ? GetLegacyControllerRightHandTrackingMotionSourceName() + : GetLegacyControllerLeftHandTrackingMotionSourceName() + }; + return Name; + } + + FORCEINLINE static const FName& GetLegacyControllerHandTrackingMotionSourceName(const bool bRight) + { + const FName& Name{ + bRight + ? GetLegacyControllerRightHandTrackingMotionSourceName() + : GetLegacyControllerLeftHandTrackingMotionSourceName() + }; + return Name; + } + + FORCEINLINE static const FName& GetMoreSpecificLeftHandTrackingMotionSourceName() + { + static const FName Name(TEXT("HandTrackingLeft")); + return Name; + } + + FORCEINLINE static const FName& GetMoreSpecificRightHandTrackingMotionSourceName() + { + static const FName Name(TEXT("HandTrackingRight")); + return Name; + } + + FORCEINLINE static const FName& GetMoreSpecificHandTrackingMotionSourceName(const EControllerHand Hand) + { + const FName& Name{ + Hand == EControllerHand::Right + ? GetMoreSpecificRightHandTrackingMotionSourceName() + : GetMoreSpecificLeftHandTrackingMotionSourceName() + }; + return Name; + } + + FORCEINLINE static const FName& GetMoreSpecificHandTrackingMotionSourceName(const bool bRight) + { + const FName& Name{ + bRight + ? GetMoreSpecificRightHandTrackingMotionSourceName() + : GetMoreSpecificLeftHandTrackingMotionSourceName() + }; + return Name; + } + + FORCEINLINE static const FName& GetLeftHandTrackingMotionSourceName() + { + const bool bUseMoreSpecificMotionSourceNames = ShouldUseMoreSpecificMotionSourceNames(); + const FName& Name{ + bUseMoreSpecificMotionSourceNames + ? GetMoreSpecificLeftHandTrackingMotionSourceName() + : GetDefaultLeftHandTrackingMotionSourceName() + }; + return Name; + } + + FORCEINLINE static const FName& GetRightHandTrackingMotionSourceName() + { + const bool bUseMoreSpecificMotionSourceNames = ShouldUseMoreSpecificMotionSourceNames(); + const FName& Name{ + bUseMoreSpecificMotionSourceNames + ? GetMoreSpecificRightHandTrackingMotionSourceName() + : GetDefaultRightHandTrackingMotionSourceName() + }; + return Name; + } + + FORCEINLINE static const FName& GetHandTrackingMotionSourceName(const EControllerHand Hand) + { + const FName& Name{ + Hand == EControllerHand::Right + ? GetRightHandTrackingMotionSourceName() + : GetLeftHandTrackingMotionSourceName()}; + return Name; + } + + FORCEINLINE static const FName& GetHandTrackingMotionSourceName(const bool bRight) + { + const FName& Name{ + bRight + ? GetRightHandTrackingMotionSourceName() + : GetLeftHandTrackingMotionSourceName() + }; + return Name; + } + + FORCEINLINE static const FName& GetLeftPositionalTrackingHardwareMotionSourceName() + { + const FName& Name{GetWristTrackingSettings().LeftHandMotionSource}; + return Name; + } + + FORCEINLINE static const FName& GetRightPositionalTrackingHardwareMotionSourceName() + { + const FName& Name{GetWristTrackingSettings().RightHandMotionSource}; + return Name; + } + + FORCEINLINE static FName GetPositionalTrackingHardwareMotionSourceName(const EControllerHand Hand) + { + const FName Name{ + Hand == EControllerHand::Right + ? GetRightPositionalTrackingHardwareMotionSourceName() + : GetLeftPositionalTrackingHardwareMotionSourceName()}; + return Name; + } + + FORCEINLINE static FName GetPositionalTrackingHardwareMotionSourceName(const bool bRight) + { + const FName& Name{ + bRight + ? GetRightPositionalTrackingHardwareMotionSourceName() + : GetLeftPositionalTrackingHardwareMotionSourceName() + }; + return Name; + } + + static ESGPositionalTrackingHardware GetPositionalTrackingHardware(); + + FORCEINLINE static USGHapticGlove* GetGlove(const EControllerHand Hand) + { + const bool bRight = Hand == EControllerHand::Right; + const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()}; + return IsValid(GloveTracker) ? GloveTracker->GetGlove(bRight) : nullptr; + } + + FORCEINLINE static USGHapticGlove* GetGlove(const bool bRight) + { + const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()}; + return IsValid(GloveTracker) ? GloveTracker->GetGlove(bRight) : nullptr; + } + + FORCEINLINE static USGHapticGlove* GetLeftGlove() + { + const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()}; + return IsValid(GloveTracker) ? GloveTracker->GetLeftGlove() : nullptr; + } + + FORCEINLINE static USGHapticGlove* GetRightGlove() + { + const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()}; + return IsValid(GloveTracker) ? GloveTracker->GetRightGlove() : nullptr; + } + + FORCEINLINE static bool IsGloveConnected(const EControllerHand Hand) + { + const bool bRight = Hand == EControllerHand::Right; + const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()}; + return IsValid(GloveTracker) ? GloveTracker->IsGloveConnected(bRight) : false; + } + + FORCEINLINE static bool IsGloveConnected(const bool bRight) + { + const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()}; + return IsValid(GloveTracker) ? GloveTracker->IsGloveConnected(bRight) : false; + } + + FORCEINLINE static bool IsLeftGloveConnected() + { + const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()}; + return IsValid(GloveTracker) ? GloveTracker->IsLeftGloveConnected() : false; + } + + FORCEINLINE static bool IsRightGloveConnected() + { + const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()}; + return IsValid(GloveTracker) ? GloveTracker->IsRightGloveConnected() : false; + } + + FORCEINLINE static bool IsAnyGloveConnected() + { + const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()}; + return IsValid(GloveTracker) ? GloveTracker->IsAnyGloveConnected() : false; + } + + static TArray GetFingerLengths( + bool bRight, + EHandKeypoint Joint2nd, EHandKeypoint Joint3rd, + float DistalPhalanxLength); + + static TArray> GetFingerLengths(bool bRight); + static TArray GetFingerStartTransforms(bool bRight); + static TArray GetFingerStartPositions(bool bRight); + static TArray GetFingerStartRotations(bool bRight); + static USGBasicHandModel* GetHandModel(bool bRight); + + FORCEINLINE static USGBasicHandModel* GetHandModel(const EControllerHand Hand) + { + const bool bRight = Hand == EControllerHand::Right; + USGBasicHandModel* HandModel{GetHandModel(bRight)}; + return HandModel; + } + + static USGHandPose* GetHandPose(bool bRight); + + FORCEINLINE static USGHandPose* GetHandPose(const EControllerHand Hand) + { + const bool bRight = Hand == EControllerHand::Right; + USGHandPose* HandPose{GetHandPose(bRight)}; + return HandPose; + } + + FORCEINLINE static const FName& GetLeftMeshBoneName(const int32 JointIndex) + { + const FName& Name{GetVirtualHandSettings().MeshSettings.LeftHandBoneNames[JointIndex]}; + return Name; + } + + FORCEINLINE static const FName& GetLeftMeshBoneName(const EHandKeypoint HandKeypoint) + { + const int32 JointIndex = static_cast(HandKeypoint); + const FName& Name{GetLeftMeshBoneName(JointIndex)}; + return Name; + } + + FORCEINLINE static const FName& GetRightMeshBoneName(const int32 JointIndex) + { + const FName& Name{GetVirtualHandSettings().MeshSettings.RightHandBoneNames[JointIndex]}; + return Name; + } + + FORCEINLINE static const FName& GetRightMeshBoneName(const EHandKeypoint HandKeypoint) + { + const int32 JointIndex = static_cast(HandKeypoint); + const FName& Name{GetRightMeshBoneName(JointIndex)}; + return Name; + } + + FORCEINLINE static const FName& GetMeshBoneName(const bool bRight, const int32 Joint) + { + const FName& Name{ + bRight + ? GetRightMeshBoneName(Joint) + : GetLeftMeshBoneName(Joint) + }; + return Name; + } + + FORCEINLINE static const FName& GetMeshBoneName(const bool bRight, const EHandKeypoint HandKeypoint) + { + const int32 JointIndex = static_cast(HandKeypoint); + const FName& Name{GetMeshBoneName(bRight, JointIndex)}; + return Name; + } + + FORCEINLINE static const FName& GetMeshBoneName(const EControllerHand Hand, const int32 JointIndex) + { + const bool bRight = Hand == EControllerHand::Right; + const FName& Name{GetMeshBoneName(bRight, JointIndex)}; + return Name; + } + + static FTransform GetMeshRawBoneRefTransform(bool bRight, const FName& BoneName); + + FORCEINLINE static FTransform GetMeshRawBoneRefTransform(const bool bRight, const int32 JointIndex) + { + const FName& BoneName{GetMeshBoneName(bRight, JointIndex)}; + const FTransform& Transform{GetMeshRawBoneRefTransform(bRight, BoneName)}; + return Transform; + } + + FORCEINLINE static FTransform GetMeshRawBoneRefTransform(const bool bRight, const EHandKeypoint Keypoint) + { + const FName& BoneName{GetMeshBoneName(bRight, Keypoint)}; + const FTransform& Transform{GetMeshRawBoneRefTransform(bRight, BoneName)}; + return Transform; + } + + FORCEINLINE static FTransform GetMeshRawBoneRefTransform(const EControllerHand Hand, const FName& BoneName) + { + const bool bRight = Hand == EControllerHand::Right; + const FTransform& Transform{GetMeshRawBoneRefTransform(bRight, BoneName)}; + return Transform; + } + + FORCEINLINE static FTransform GetMeshRawBoneRefTransform(const EControllerHand Hand, const int32 JointIndex) + { + const bool bRight = Hand == EControllerHand::Right; + const FName& BoneName{GetMeshBoneName(bRight, JointIndex)}; + const FTransform& Transform{GetMeshRawBoneRefTransform(bRight, BoneName)}; + return Transform; + } + + FORCEINLINE static FTransform GetMeshRawBoneRefTransform( + const EControllerHand Hand, const EHandKeypoint Keypoint) + { + const bool bRight = Hand == EControllerHand::Right; + const FName& BoneName{GetMeshBoneName(bRight, Keypoint)}; + const FTransform& Transform{GetMeshRawBoneRefTransform(bRight, BoneName)}; + return Transform; + } + + static FTransform GetMeshWristChildBoneRefTransform(bool bRight, const FName& BoneName); + + FORCEINLINE static FTransform GetMeshWristChildBoneRefTransform( + const bool bRight, const int32 JointIndex) + { + const FName& BoneName{GetMeshBoneName(bRight, JointIndex)}; + const FTransform Transform{GetMeshWristChildBoneRefTransform(bRight, BoneName)}; + return Transform; + } + + FORCEINLINE static FTransform GetMeshWristChildBoneRefTransform( + const bool bRight, const EHandKeypoint Keypoint) + { + const FName& BoneName{GetMeshBoneName(bRight, Keypoint)}; + const FTransform Transform{GetMeshWristChildBoneRefTransform(bRight, BoneName)}; + return Transform; + } + + FORCEINLINE static FTransform GetMeshWristChildBoneRefTransform( + const EControllerHand Hand, const FName& BoneName) + { + const bool bRight = Hand == EControllerHand::Right; + const FTransform Transform{GetMeshWristChildBoneRefTransform(bRight, BoneName)}; + return Transform; + } + + FORCEINLINE static FTransform GetMeshWristChildBoneRefTransform( + const EControllerHand Hand, const int32 JointIndex) + { + const bool bRight = Hand == EControllerHand::Right; + const FTransform Transform{GetMeshWristChildBoneRefTransform(bRight, JointIndex)}; + return Transform; + } + + FORCEINLINE static FTransform GetMeshWristChildBoneRefTransform( + const EControllerHand Hand, const EHandKeypoint Keypoint) + { + const bool bRight = Hand == EControllerHand::Right; + const FTransform Transform{GetMeshWristChildBoneRefTransform(bRight, Keypoint)}; + return Transform; + } + + static FTransform GetMeshFingerStartBoneRefTransform( + bool bRight, EHandKeypoint Parent, const FName& BoneName); + + FORCEINLINE static FTransform GetMeshFingerStartBoneRefTransform( + const bool bRight, const EHandKeypoint Parent, const int32 JointIndex) + { + const FName& BoneName{GetMeshBoneName(bRight, JointIndex)}; + const FTransform Transform{GetMeshFingerStartBoneRefTransform(bRight, Parent, BoneName)}; + return Transform; + } + + FORCEINLINE static FTransform GetMeshFingerStartBoneRefTransform( + const bool bRight, const EHandKeypoint Parent, const EHandKeypoint Keypoint) + { + const FName& BoneName{GetMeshBoneName(bRight, Keypoint)}; + const FTransform Transform{GetMeshFingerStartBoneRefTransform(bRight, Parent, BoneName)}; + return Transform; + } + + FORCEINLINE static FTransform GetMeshFingerStartBoneRefTransform( + const EControllerHand Hand, const EHandKeypoint Parent, const FName& BoneName) + { + const bool bRight = Hand == EControllerHand::Right; + const FTransform Transform{GetMeshFingerStartBoneRefTransform(bRight, Parent, BoneName)}; + return Transform; + } + + FORCEINLINE static FTransform GetMeshFingerStartBoneRefTransform( + const EControllerHand Hand, const EHandKeypoint Parent, const int32 JointIndex) + { + const bool bRight = Hand == EControllerHand::Right; + const FTransform Transform{GetMeshFingerStartBoneRefTransform(bRight, Parent, JointIndex)}; + return Transform; + } + + FORCEINLINE static FTransform GetMeshFingerStartBoneRefTransform( + const EControllerHand Hand, const EHandKeypoint Parent, const EHandKeypoint Keypoint) + { + const bool bRight = Hand == EControllerHand::Right; + const FTransform Transform{GetMeshFingerStartBoneRefTransform(bRight, Parent, Keypoint)}; + return Transform; + } + + /************************ + * Member variables + ************************/ + + bool bHandTrackingAvailable; + + PFN_xrCreateHandTrackerEXT XRCreateHandTrackerEXT; + PFN_xrDestroyHandTrackerEXT XRDestroyHandTrackerEXT; + PFN_xrLocateHandJointsEXT XRLocateHandJointsEXT; + + IXRTrackingSystem* XRTrackingSystem; + + TSharedPtr MessageHandler; + int32 DeviceIndex; + + int32 CurrentHandTrackingDataIndex; + + TArray BoneParents; + TArray BoneKeypoints; + TMap MotionSourceToKeypointMap; + + FSGXRHandState HandStates[2]; + + TArray LeftAnimationTransforms; + TArray RightAnimationTransforms; + + /************************ + * Owner object + ************************/ + + FSGXRTracker* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSGXRTracker* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = delete; + FImpl& operator=(const FImpl& Rhs) = delete; + + /************************ + * Methods + ************************/ + + FORCEINLINE const FSGXRHandState& GetLeftHandState() const + { + return HandStates[0]; + } + + FORCEINLINE FSGXRHandState& GetLeftHandState() + { + return HandStates[0]; + } + + FORCEINLINE const FSGXRHandState& GetRightHandState() const + { + return HandStates[1]; + } + + FORCEINLINE FSGXRHandState& GetRightHandState() + { + return HandStates[1]; + } + + void BuildMotionSourceToKeypointMap(); + + bool CanOutputTrackingData(EControllerHand Hand) const; + + bool UpdateXRHandTrackingData(FSGXRHandState& OutHandState, const XrHandJointsLocateInfoEXT& LocateInfo) const; + + FName GetTargetOpenXRPositionalTrackingProviderName() const; + + bool GetControllerTransform(const FName MotionSource, const float WorldToMetersScale, + FTransform& OutTransform, bool& bOutMotionSourceHandTracking) const; + + bool GetWristTransform(bool bRight, FTransform& OutTransform) const; + + bool UpdateSGJointData(FSGXRHandState& OutHandState, const EHandKeypoint Joint, + const FTransform& JointTransform, const FTransform& WristTransform) const; + + bool UpdateSGWristJointData(FSGXRHandState& OutHandState, const FTransform& WristTransform) const; + + bool UpdateSGPalmJointData(FSGXRHandState& OutHandState, bool bRight, const FTransform& WristTransform) const; + + bool UpdateSGThumbJointData( + FSGXRHandState& OutHandState, + const TArray>& JointLocations, const TArray>& JointRotations, + const FTransform& WristTransform) const; + + bool UpdateSGIndexJointData( + FSGXRHandState& OutHandState, bool bRight, + const TArray>& JointLocations, const TArray>& JointRotations, + const FTransform& WristTransform) const; + + bool UpdateSGMiddleJointData( + FSGXRHandState& OutHandState, bool bRight, + const TArray>& JointLocations, const TArray>& JointRotations, + const FTransform& WristTransform) const; + + bool UpdateSGRingJointData( + FSGXRHandState& OutHandState, bool bRight, + const TArray>& JointLocations, const TArray>& JointRotations, + const FTransform& WristTransform) const; + + bool UpdateSGLittleJointData( + FSGXRHandState& OutHandState, bool bRight, + const TArray>& JointLocations, const TArray>& JointRotations, + const FTransform& WristTransform) const; + + bool UpdateSGHandState(bool bRight, FSGXRHandState& OutHandState) const; +}; + +FName FSGXRTracker::FImpl::GetHandKeypointEnumName(const EHandKeypoint HandKeypoint) +{ + static UEnum* EnumPtr{StaticEnum()}; + ensureAlwaysMsgf(EnumPtr, TEXT("Failed to find the EHandKeypoint enum!")); + static const int32 EnumNameLength = FString{TEXT("EHandKeypoint::")}.Len(); + + const FName EnumItemName{ + EnumPtr->GetNameByValue(static_cast(HandKeypoint)) + }; + const FString EnumItemString{EnumItemName.ToString()}; + const int32 EnumItemStringLength = EnumItemString.Len(); + const int32 EnumItemNameLength = EnumItemStringLength - EnumNameLength; + + const FName ParsedName{*EnumItemString.Right(EnumItemNameLength)}; + return ParsedName; +} + +FName FSGXRTracker::FImpl::GetControllerHandEnumName(const EControllerHand ControllerHand) +{ + static UEnum* EnumPtr{StaticEnum()}; + ensureAlwaysMsgf(EnumPtr, TEXT("Failed to find the EControllerHand enum!")); + static const int32 EnumNameLength = FString{TEXT("EControllerHand::")}.Len(); + + const FName EnumItemName{ + EnumPtr->GetNameByValue(static_cast(ControllerHand)) + }; + const FString EnumItemString{EnumItemName.ToString()}; + const int32 EnumItemStringLength = EnumItemString.Len(); + const int32 EnumItemNameLength = EnumItemStringLength - EnumNameLength; + + const FName ParsedName{*EnumItemString.Right(EnumItemNameLength)}; + return ParsedName; +} + +FName FSGXRTracker::FImpl::GetOpenXRPositionalTrackingProviderEnumName( + const ESGOpenXRPositionalTrackingProvider OpenXRPositionalTrackingProvider) +{ + static UEnum* EnumPtr{StaticEnum()}; + ensureAlwaysMsgf(EnumPtr, TEXT("Failed to find the ESGOpenXRPositionalTrackingProvider enum!")); + static const int32 EnumNameLength = FString{TEXT("ESGOpenXRPositionalTrackingProvider::")}.Len(); + + const FName EnumItemName{ + EnumPtr->GetNameByValue(static_cast(OpenXRPositionalTrackingProvider)) + }; + const FString EnumItemString{EnumItemName.ToString()}; + const int32 EnumItemStringLength = EnumItemString.Len(); + const int32 EnumItemNameLength = EnumItemStringLength - EnumNameLength; + + const FName ParsedName{*EnumItemString.Right(EnumItemNameLength)}; + return ParsedName; +} + +ESGPositionalTrackingHardware FSGXRTracker::FImpl::GetPositionalTrackingHardware() +{ + ESGPositionalTrackingHardware TrackerHardware = GetWristTrackingSettings().TrackingHardware; + + if (TrackerHardware == ESGPositionalTrackingHardware::None) + { + const ESGHeadMountedDisplayDevice HmdDevice = FSGHMDTracker::GetDeviceType(); + switch (HmdDevice) + { + case ESGHeadMountedDisplayDevice::MetaQuest2: + TrackerHardware = ESGPositionalTrackingHardware::Quest2Controller; + break; + case ESGHeadMountedDisplayDevice::MetaQuestPro: + TrackerHardware = ESGPositionalTrackingHardware::QuestProController; + break; + case ESGHeadMountedDisplayDevice::MetaQuest3: + TrackerHardware = ESGPositionalTrackingHardware::Quest3Controller; + break; + case ESGHeadMountedDisplayDevice::HtcVivePro: + TrackerHardware = ESGPositionalTrackingHardware::ViveTracker; + break; + case ESGHeadMountedDisplayDevice::HtcViveFocus3: + // Fall through + case ESGHeadMountedDisplayDevice::HtcViveXRElite: + TrackerHardware = ESGPositionalTrackingHardware::ViveFocus3WristTracker; + break; + default: + TrackerHardware = ESGPositionalTrackingHardware::Custom; + break; + } + } + + return TrackerHardware; +} + +TArray FSGXRTracker::FImpl::GetFingerLengths( + const bool bRight, + const EHandKeypoint Joint2nd, const EHandKeypoint Joint3rd, + const float DistalPhalanxLength) +{ + const FTransform& Joint2ndTransform{GetMeshRawBoneRefTransform(bRight, Joint2nd)}; + const FVector& Joint2ndLocation{Joint2ndTransform.GetLocation()}; + const FTransform& Joint3rdTransform{GetMeshRawBoneRefTransform(bRight, Joint3rd)}; + const FVector& Joint3rdLocation{Joint3rdTransform.GetLocation()}; + + const float PhalanxLength1st = static_cast(Joint2ndLocation.Size()); + const float PhalanxLength2nd = static_cast(Joint3rdLocation.Size()); + + const TArray Lengths{PhalanxLength1st, PhalanxLength2nd, DistalPhalanxLength}; + return Lengths; +} + +TArray> FSGXRTracker::FImpl::GetFingerLengths(const bool bRight) +{ + const FSGVirtualHandSettings& Settings{GetVirtualHandSettings()}; + + const TArray> Lengths{ + GetFingerLengths(bRight, + EHandKeypoint::ThumbProximal, + EHandKeypoint::ThumbDistal, + Settings.MeshSettings.DistalPhalangesLengthSettings.Thumb + ), + GetFingerLengths(bRight, + EHandKeypoint::IndexIntermediate, + EHandKeypoint::IndexDistal, + Settings.MeshSettings.DistalPhalangesLengthSettings.Index + ), + GetFingerLengths(bRight, + EHandKeypoint::MiddleIntermediate, + EHandKeypoint::MiddleDistal, + Settings.MeshSettings.DistalPhalangesLengthSettings.Middle + ), + GetFingerLengths(bRight, + EHandKeypoint::RingIntermediate, + EHandKeypoint::RingDistal, + Settings.MeshSettings.DistalPhalangesLengthSettings.Ring + ), + GetFingerLengths(bRight, + EHandKeypoint::LittleIntermediate, + EHandKeypoint::LittleDistal, + Settings.MeshSettings.DistalPhalangesLengthSettings.Little + ), + }; + + return Lengths; +} + +TArray FSGXRTracker::FImpl::GetFingerStartTransforms(const bool bRight) +{ + FTransform ThumbStartTransform{ + GetMeshWristChildBoneRefTransform(bRight, EHandKeypoint::ThumbMetacarpal).GetLocation() + }; + + FTransform IndexStartTransform{ + GetMeshFingerStartBoneRefTransform(bRight, EHandKeypoint::IndexMetacarpal, EHandKeypoint::IndexProximal) + }; + + FTransform MiddleStartTransform{ + GetMeshFingerStartBoneRefTransform(bRight, EHandKeypoint::MiddleMetacarpal, EHandKeypoint::MiddleProximal) + }; + + FTransform RingStartTransform{ + GetMeshFingerStartBoneRefTransform(bRight, EHandKeypoint::RingMetacarpal, EHandKeypoint::RingProximal) + }; + + FTransform LittleStartTransform{ + GetMeshFingerStartBoneRefTransform(bRight, EHandKeypoint::LittleMetacarpal, EHandKeypoint::LittleProximal) + }; + + TArray Transforms{ + MoveTemp(ThumbStartTransform), + MoveTemp(IndexStartTransform), + MoveTemp(MiddleStartTransform), + MoveTemp(RingStartTransform), + MoveTemp(LittleStartTransform), + }; + + return Transforms; +} + +TArray FSGXRTracker::FImpl::GetFingerStartPositions(const bool bRight) +{ + const TArray StartTransforms{GetFingerStartTransforms(bRight)}; + + ensureAlwaysMsgf(StartTransforms.Num() == 5, TEXT("Invalid number of finger start transforms!")); + + const TArray StartPositions{ + StartTransforms[0].GetLocation(), + StartTransforms[1].GetLocation(), + StartTransforms[2].GetLocation(), + StartTransforms[3].GetLocation(), + StartTransforms[4].GetLocation(), + }; + + return StartPositions; +} + +TArray FSGXRTracker::FImpl::GetFingerStartRotations(const bool bRight) +{ + const TArray StartRotations{ + FQuat::Identity, + FQuat::Identity, + FQuat::Identity, + FQuat::Identity, + FQuat::Identity, + }; + + return StartRotations; +} + +USGBasicHandModel* FSGXRTracker::FImpl::GetHandModel(const bool bRight) +{ + const TArray> FingerLengths{GetFingerLengths(bRight)}; + const TArray StartPositions{GetFingerStartPositions(bRight)}; + const TArray StartRotations{GetFingerStartRotations(bRight)}; + + UWorld* World{FSGEngineUtils::GetWorld()}; + + USGBasicHandModel* HandModel{ + USGBasicHandModel::NewBasicHandModel(World, bRight, FingerLengths, StartPositions, StartRotations) + }; + + return HandModel; +} + +USGHandPose* FSGXRTracker::FImpl::GetHandPose(const bool bRight) +{ + const USGHapticGlove* Glove{GetGlove(bRight)}; + if (!IsValid(Glove)) + { + return nullptr; + } + + UWorld* World{FSGEngineUtils::GetWorld()}; + const USGBasicHandModel* HandModel{GetHandModel(bRight)}; + USGHandPose* HandPose{nullptr}; + + const bool bGotHandPose = Glove->GetHandPose(World, HandModel, HandPose); + if (!bGotHandPose || !IsValid(HandPose)) + { + return nullptr; + } + + return HandPose; +} + +FTransform FSGXRTracker::FImpl::GetMeshRawBoneRefTransform(const bool bRight, const FName& BoneName) +{ + const FSGVirtualHandMeshSettings& MeshSettings{GetVirtualHandSettings().MeshSettings}; + + const TSoftObjectPtr& HandMesh{ + bRight + ? MeshSettings.LeftHandReferenceMesh + : MeshSettings.RightHandReferenceMesh + }; + + if (HandMesh.IsValid()) + { + const FReferenceSkeleton& ReferenceSkeleton{HandMesh->GetRefSkeleton()}; + const int32 BoneIndex = ReferenceSkeleton.FindBoneIndex(BoneName); + + if (BoneIndex == INDEX_NONE) + { + SGLOG_WARNING(FString::Printf(TEXT("Could not find a bone index for the '%s' joint!"), + *BoneName.ToString())); + } + + const TArray Transforms{ReferenceSkeleton.GetRefBonePose()}; + ensureAlwaysMsgf(Transforms.Num() > 0 && Transforms.Num() > BoneIndex, + TEXT("Invalid bone index '%d' or no transforms found!"), BoneIndex); + + const FTransform& Transform{Transforms[BoneIndex]}; + return Transform; + } + + ensureAlwaysMsgf( + bRight + ? MeshSettings.RightHandDefaultReferenceBoneTransforms.Contains(BoneName) + : MeshSettings.LeftHandDefaultReferenceBoneTransforms.Contains(BoneName), + TEXT("Invalid bone name '%s'!"), *BoneName.ToString()); + + const FTransform& Transform{ + bRight + ? MeshSettings.RightHandDefaultReferenceBoneTransforms[BoneName] + : MeshSettings.LeftHandDefaultReferenceBoneTransforms[BoneName] + }; + return Transform; +} + +FTransform FSGXRTracker::FImpl::GetMeshWristChildBoneRefTransform(const bool bRight, const FName& BoneName) +{ + const FSGVirtualHandMeshSettings& MeshSettings{GetVirtualHandSettings().MeshSettings}; + FQuat RootRotationCorrection{MeshSettings.RootBoneRotationCorrection}; + const FTransform& RootBoneRefTransform{GetMeshRawBoneRefTransform(bRight, EHandKeypoint::Wrist)}; + const FTransform& RawTransform{GetMeshRawBoneRefTransform(bRight, BoneName)}; + FQuat CorrectedRootBoneRefRotation{MoveTemp(RootRotationCorrection) * RootBoneRefTransform.GetRotation()}; + FVector CorrectedLocation{MoveTemp(CorrectedRootBoneRefRotation) * RawTransform.GetLocation()}; + + const FTransform Transform{RawTransform.GetRotation(), MoveTemp(CorrectedLocation)}; + return Transform; +} + +FTransform FSGXRTracker::FImpl::GetMeshFingerStartBoneRefTransform( + const bool bRight, const EHandKeypoint Parent, const FName& BoneName) +{ + const FSGVirtualHandMeshSettings& MeshSettings{GetVirtualHandSettings().MeshSettings}; + FQuat RootRotationCorrection{MeshSettings.RootBoneRotationCorrection}; + const FTransform& RootBoneRefTransform{GetMeshRawBoneRefTransform(bRight, EHandKeypoint::Wrist)}; + FQuat CorrectedRootBoneRefRotation{MoveTemp(RootRotationCorrection) * RootBoneRefTransform.GetRotation()}; + FTransform CorrectedRootBoneRefTransform{ + MoveTemp(CorrectedRootBoneRefRotation), RootBoneRefTransform.GetLocation() + }; + + FTransform ParentBoneRefTransform{ + GetMeshRawBoneRefTransform(bRight, Parent) * MoveTemp(CorrectedRootBoneRefTransform) + }; + + const FTransform Transform{GetMeshRawBoneRefTransform(bRight, BoneName) * MoveTemp(ParentBoneRefTransform)}; + return Transform; +} + +bool FSGXRTracker::GetMotionControllerData( + UObject* WorldContextObject, + const EControllerHand Hand, + FXRMotionControllerData& OutMotionControllerData) +{ + OutMotionControllerData.DeviceName = NAME_None; + OutMotionControllerData.ApplicationInstanceID = FApp::GetInstanceId(); + OutMotionControllerData.DeviceVisualType = EXRVisualType::Controller; + OutMotionControllerData.TrackingStatus = ETrackingStatus::NotTracked; + OutMotionControllerData.HandIndex = Hand; + OutMotionControllerData.bValid = false; + + if (!IsValid(WorldContextObject)) + { + return false; + } + + IXRTrackingSystem* XRTrackingSystem{GEngine ? GEngine->XRSystem.Get() : nullptr}; + if (!XRTrackingSystem) + { + return false; + } + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4 + IOpenXRHMD* OpenXRHMD{XRTrackingSystem->GetIOpenXRHMD()}; +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4 */ + FOpenXRHMD* OpenXRHMD{static_cast(GEngine->XRSystem.Get())}; +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4 */ + if (!OpenXRHMD) + { + return false; + } + + TArray Devices; + const int32 HandIndex = static_cast(Hand); + const bool bGotDevices = + XRTrackingSystem->EnumerateTrackedDevices(Devices, EXRTrackedDeviceType::Controller); + if (bGotDevices && Devices.IsValidIndex(HandIndex)) + { + const XrSession Session{OpenXRHMD->GetSession()}; + if (Session) + { + XrInteractionProfileState Profile = {XR_TYPE_INTERACTION_PROFILE_STATE}; + const XrPath TopLevelUserPath{OpenXRHMD->GetTrackedDevicePath(Devices[HandIndex])}; + const XrResult CurrentInteractionProfile{ + xrGetCurrentInteractionProfile(Session, TopLevelUserPath, &Profile) + }; + if (XR_SUCCEEDED(CurrentInteractionProfile) && Profile.interactionProfile != XR_NULL_PATH) + { + OutMotionControllerData.DeviceName = FOpenXRPath(Profile.interactionProfile); + } + } + } + + static const FName HandTrackerName{"OpenXRHandTracking"}; + TArray HandTrackers = IModularFeatures::Get().GetModularFeatureImplementations( + IHandTracker::GetModularFeatureName()); + IHandTracker* HandTracker{nullptr}; + for (IHandTracker* HandTrackerIterator: HandTrackers) + { + if (!HandTrackerIterator) + { + continue; + } + + const FName DeviceTypeName{HandTrackerIterator->GetHandTrackerDeviceTypeName()}; + if (DeviceTypeName != HandTrackerName) + { + continue; + } + + FSGXRTracker* SGXRTracker{static_cast(HandTrackerIterator)}; + if (!SGXRTracker) + { + continue; + } + + HandTracker = SGXRTracker; + break; + } + + if (Hand == EControllerHand::Left || Hand == EControllerHand::Right) + { + static const FName MotionControllerName("OpenXR"); + TArray MotionControllers{ + IModularFeatures::Get().GetModularFeatureImplementations( + IMotionController::GetModularFeatureName()) + }; + IMotionController* MotionController{nullptr}; + for (IMotionController* MotionControllerIterator: MotionControllers) + { + if (!MotionControllerIterator) + { + continue; + } + + const FName DeviceTypeName{MotionControllerIterator->GetMotionControllerDeviceTypeName()}; + if (DeviceTypeName != MotionControllerName) + { + continue; + } + + MotionController = MotionControllerIterator; + break; + } + + const float WorldToMeters = XRTrackingSystem->GetWorldToMetersScale(); + if (MotionController) + { + const FTransform TrackingToWorld{XRTrackingSystem->GetTrackingToWorldTransform()}; + + { + const FName AimSource{Hand == EControllerHand::Left ? FName{TEXT("LeftAim")} : FName{TEXT("RightAim")}}; + FRotator AimSourceRotation; + FVector AimSourcePosition; + const bool bGotAimOrientationAndPosition = + MotionController->GetControllerOrientationAndPosition( + 0, AimSource, AimSourceRotation, AimSourcePosition, WorldToMeters); + if (bGotAimOrientationAndPosition) + { + OutMotionControllerData.AimPosition = TrackingToWorld.TransformPosition(AimSourcePosition); + OutMotionControllerData.AimRotation = + TrackingToWorld.TransformRotation(AimSourceRotation.Quaternion()); + } + OutMotionControllerData.bValid |= bGotAimOrientationAndPosition; + } + + const FName GripSource{Hand == EControllerHand::Left ? FName{TEXT("LeftGrip")} : FName{TEXT("RightGrip")}}; + { + FRotator GripRotation; + FVector GripPosition; + const bool bGotGripSourceOrientationAndPosition = + MotionController->GetControllerOrientationAndPosition( + 0, GripSource, GripRotation, GripPosition, WorldToMeters); + if (bGotGripSourceOrientationAndPosition) + { + OutMotionControllerData.GripPosition = TrackingToWorld.TransformPosition(GripPosition); + OutMotionControllerData.GripRotation = + TrackingToWorld.TransformRotation(GripRotation.Quaternion()); + } + OutMotionControllerData.bValid |= bGotGripSourceOrientationAndPosition; + } + + { + const FName PalmSource{ + Hand == EControllerHand::Left ? FName{TEXT("LeftPalm")} : FName{TEXT("RightPalm")} + }; + FRotator PalmRotation; + FVector PalmPosition; + const bool bGotPalmOrientationAndPosition = MotionController->GetControllerOrientationAndPosition( + 0, PalmSource, PalmRotation, PalmPosition, WorldToMeters); + if (bGotPalmOrientationAndPosition) + { + OutMotionControllerData.GripPosition = TrackingToWorld.TransformPosition(PalmPosition); + OutMotionControllerData.GripRotation = + TrackingToWorld.TransformRotation(PalmRotation.Quaternion()); + } + OutMotionControllerData.bValid |= bGotPalmOrientationAndPosition; + } + + OutMotionControllerData.TrackingStatus = MotionController->GetControllerTrackingStatus(0, GripSource); + } + + const bool bHandTrackingStateValid = HandTracker && HandTracker->IsHandTrackingStateValid(); + if (bHandTrackingStateValid) + { + OutMotionControllerData.DeviceVisualType = EXRVisualType::Hand; + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + bool bTracked = false; +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + + OutMotionControllerData.bValid = HandTracker->GetAllKeypointStates( + Hand, + OutMotionControllerData.HandKeyPositions, + OutMotionControllerData.HandKeyRotations, + OutMotionControllerData.HandKeyRadii +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + , bTracked +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + ); + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + // Unused! + (void) bTracked; +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + // TODO + // Begin backward compatibility with the deprecated function, remove this block along with the deprecated + // GetAllKeypointStates (though it should be time to remove this entire function as well)! + if (!OutMotionControllerData.bValid) + { + PRAGMA_DISABLE_DEPRECATION_WARNINGS + OutMotionControllerData.bValid = HandTracker->GetAllKeypointStates( + Hand, + OutMotionControllerData.HandKeyPositions, + OutMotionControllerData.HandKeyRotations, + OutMotionControllerData.HandKeyRadii); + PRAGMA_ENABLE_DEPRECATION_WARNINGS + } + // End backward compability. +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + + if (!ensureAlwaysMsgf( + !OutMotionControllerData.bValid + || (OutMotionControllerData.HandKeyPositions.Num() == EHandKeypointCount + && OutMotionControllerData.HandKeyRotations.Num() == EHandKeypointCount + && OutMotionControllerData.HandKeyRadii.Num() == EHandKeypointCount), + TEXT("Corrupted OutMotionControllerData!"))) + { + OutMotionControllerData.bValid = false; + return false; + } + } + } + + if (OutMotionControllerData.bValid) + { + OutMotionControllerData.TrackingStatus = ETrackingStatus::Tracked; + } + + return OutMotionControllerData.bValid; +} + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + +bool FSGXRTracker::GetMotionControllerState( + UObject* WorldContextObject, + const EXRSpaceType XRSpaceType, const EControllerHand Hand, const EXRControllerPoseType XRControllerPoseType, + FXRMotionControllerState& OutMotionControllerState) +{ + auto ToMotionSourceName = []( + const EControllerHand Hand, const EXRControllerPoseType XRControllerPoseType) -> FLazyName + { + static FLazyName LeftAim = "LeftAim"; + static FLazyName LeftGrip = "LeftGrip"; + static FLazyName LeftPalm = "LeftPalm"; + static FLazyName RightAim = "RightAim"; + static FLazyName RightGrip = "RightGrip"; + static FLazyName RightPalm = "RightPalm"; + if (Hand == EControllerHand::Left) + { + switch (XRControllerPoseType) + { + case EXRControllerPoseType::Aim: + return LeftAim; + case EXRControllerPoseType::Grip: + return LeftGrip; + case EXRControllerPoseType::Palm: + return LeftPalm; + default: + check(false); + return LeftGrip; + } + } + else + { + switch (XRControllerPoseType) + { + case EXRControllerPoseType::Aim: + return RightAim; + case EXRControllerPoseType::Grip: + return RightGrip; + case EXRControllerPoseType::Palm: + return RightPalm; + default: + check(false); + return RightGrip; + } + } + }; + + OutMotionControllerState.DeviceName = NAME_None; + OutMotionControllerState.ApplicationInstanceID = FApp::GetInstanceId(); + OutMotionControllerState.TrackingStatus = ETrackingStatus::NotTracked; + OutMotionControllerState.Hand = Hand; + OutMotionControllerState.XRSpaceType = XRSpaceType; + OutMotionControllerState.bValid = false; + + if (!IsValid(WorldContextObject)) + { + return false; + } + + if (!IsValid(WorldContextObject)) + { + return false; + } + + IXRTrackingSystem* XRTrackingSystem{GEngine ? GEngine->XRSystem.Get() : nullptr}; + if (!XRTrackingSystem) + { + return false; + } + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4 + IOpenXRHMD* OpenXRHMD{XRTrackingSystem->GetIOpenXRHMD()}; +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4 */ + FOpenXRHMD* OpenXRHMD{static_cast(GEngine->XRSystem.Get())}; +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4 */ + if (!OpenXRHMD) + { + return false; + } + + TArray Devices; + const int32 HandIndex = static_cast(Hand); + const bool bGotDevices = + XRTrackingSystem->EnumerateTrackedDevices(Devices, EXRTrackedDeviceType::Controller); + if (bGotDevices && Devices.IsValidIndex(HandIndex)) + { + const XrSession Session{OpenXRHMD->GetSession()}; + if (Session) + { + XrInteractionProfileState Profile = {XR_TYPE_INTERACTION_PROFILE_STATE}; + const XrPath TopLevelUserPath{OpenXRHMD->GetTrackedDevicePath(Devices[HandIndex])}; + const XrResult CurrentInteractionProfile{ + xrGetCurrentInteractionProfile(Session, TopLevelUserPath, &Profile) + }; + if (XR_SUCCEEDED(CurrentInteractionProfile) && Profile.interactionProfile != XR_NULL_PATH) + { + OutMotionControllerState.DeviceName = FOpenXRPath(Profile.interactionProfile); + } + } + } + + if ((Hand == EControllerHand::Left) || (Hand == EControllerHand::Right)) + { + static const FName MotionControllerName("OpenXR"); + TArray MotionControllers{ + IModularFeatures::Get().GetModularFeatureImplementations( + IMotionController::GetModularFeatureName()) + }; + IMotionController* MotionController{nullptr}; + for (IMotionController* MotionControllerIterator: MotionControllers) + { + if (!MotionControllerIterator) + { + continue; + } + + const FName DeviceTypeName{MotionControllerIterator->GetMotionControllerDeviceTypeName()}; + if (DeviceTypeName != MotionControllerName) + { + continue; + } + + MotionController = MotionControllerIterator; + break; + } + + if (MotionController) + { + { + // Handle the pose that is actually being requested. + + const FName MotionSource{ToMotionSourceName(Hand, XRControllerPoseType)}; + const FTransform TrackingToWorld{ + XRSpaceType == EXRSpaceType::UnrealWorldSpace + ? XRTrackingSystem->GetTrackingToWorldTransform() + : FTransform::Identity + }; + const float WorldToMeters = XRSpaceType == EXRSpaceType::UnrealWorldSpace + ? XRTrackingSystem->GetWorldToMetersScale() + : 100.0f; + + FVector Position{FVector::ZeroVector}; + FRotator Rotation{FRotator::ZeroRotator}; + + bool bGotMotionControllerOrientationAndPosition = MotionController->GetControllerOrientationAndPosition( + 0, MotionSource, Rotation, Position, WorldToMeters); + + if (bGotMotionControllerOrientationAndPosition) + { + OutMotionControllerState.ControllerLocation = TrackingToWorld.TransformPosition(Position); + OutMotionControllerState.ControllerRotation = TrackingToWorld.TransformRotation(FQuat{Rotation}); + } + + OutMotionControllerState.bValid |= bGotMotionControllerOrientationAndPosition; + OutMotionControllerState.TrackingStatus = + MotionController->GetControllerTrackingStatus(0, MotionSource); + } + + { + // We always provide the grip transform in Unreal space for XRVisualizationFunctionLibrary; + // The bValid and TrackingStatus above are also valid for this pose. + + const FName MotionSource = ToMotionSourceName(Hand, EXRControllerPoseType::Grip); + const FTransform TrackingToWorld{XRTrackingSystem->GetTrackingToWorldTransform()}; + const float WorldToMeters = XRTrackingSystem->GetWorldToMetersScale(); + + FVector Position = FVector::ZeroVector; + FRotator Rotation = FRotator::ZeroRotator; + + bool bGotMotionControllerOrientationAndPosition = MotionController->GetControllerOrientationAndPosition( + 0, MotionSource, Rotation, Position, WorldToMeters); + + if (bGotMotionControllerOrientationAndPosition) + { + OutMotionControllerState.GripUnrealSpaceLocation = TrackingToWorld.TransformPosition(Position); + OutMotionControllerState.GripUnrealSpaceRotation = + TrackingToWorld.TransformRotation(FQuat(Rotation)); + } + } + } + } + + return OutMotionControllerState.bValid; +} + +bool FSGXRTracker::GetHandTrackingState( + UObject* WorldContextObject, + const EXRSpaceType XRSpaceType, const EControllerHand Hand, + FXRHandTrackingState& OutHandTrackingState) +{ + OutHandTrackingState.ApplicationInstanceID = FApp::GetInstanceId(); + OutHandTrackingState.TrackingStatus = ETrackingStatus::NotTracked; + OutHandTrackingState.Hand = Hand; + OutHandTrackingState.XRSpaceType = XRSpaceType; + OutHandTrackingState.bValid = false; + + if (!IsValid(WorldContextObject)) + { + return false; + } + + IXRTrackingSystem* XRTrackingSystem{GEngine ? GEngine->XRSystem.Get() : nullptr}; + if (!XRTrackingSystem) + { + return false; + } + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4 + IOpenXRHMD* OpenXRHMD{XRTrackingSystem->GetIOpenXRHMD()}; +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4 */ + FOpenXRHMD* OpenXRHMD{static_cast(GEngine->XRSystem.Get())}; +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 4 */ + if (!OpenXRHMD) + { + return false; + } + + FName HandTrackerName("OpenXRHandTracking"); + TArray HandTrackers = IModularFeatures::Get().GetModularFeatureImplementations( + IHandTracker::GetModularFeatureName()); + IHandTracker* HandTracker = nullptr; + for (auto Itr: HandTrackers) + { + if (Itr->GetHandTrackerDeviceTypeName() == HandTrackerName) + { + HandTracker = Itr; + break; + } + } + + if ((Hand == EControllerHand::Left) || (Hand == EControllerHand::Right)) + { + const bool bHandTrackingStateValid = HandTracker && HandTracker->IsHandTrackingStateValid(); + if (bHandTrackingStateValid) + { + bool bTracked = false; + OutHandTrackingState.bValid = HandTracker->GetAllKeypointStates( + Hand, + OutHandTrackingState.HandKeyLocations, + OutHandTrackingState.HandKeyRotations, + OutHandTrackingState.HandKeyRadii, + bTracked); + + /// TODO + // Begin backward compatibility with the deprecated function, remove this block along with the deprecated + // GetAllKeypointStates. + if (!OutHandTrackingState.bValid) + { + PRAGMA_DISABLE_DEPRECATION_WARNINGS + OutHandTrackingState.bValid = HandTracker->GetAllKeypointStates( + Hand, + OutHandTrackingState.HandKeyLocations, + OutHandTrackingState.HandKeyRotations, + OutHandTrackingState.HandKeyRadii); + PRAGMA_ENABLE_DEPRECATION_WARNINGS + bTracked = OutHandTrackingState.bValid; + // The inability to distinguish this is the reason for the deprecation. + } + // End backward compability. + + if (!ensureAlwaysMsgf( + !OutHandTrackingState.bValid + || (OutHandTrackingState.HandKeyLocations.Num() == EHandKeypointCount + && OutHandTrackingState.HandKeyRotations.Num() == EHandKeypointCount + && OutHandTrackingState.HandKeyRadii.Num() == EHandKeypointCount), + TEXT("Corrupted OutHandTrackingState!"))) + { + OutHandTrackingState.bValid = false; + return false; + } + + if (OutHandTrackingState.bValid) + { + OutHandTrackingState.TrackingStatus = bTracked ? ETrackingStatus::Tracked : ETrackingStatus::NotTracked; + } + } + } + + return OutHandTrackingState.bValid; +} + +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + +FSGXRTracker::FSGXRTracker(const TSharedRef& InMessageHandler) + : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ + Pimpl->MessageHandler = InMessageHandler; + + // Register the modular features manually. + IModularFeatures::Get().RegisterModularFeature(IHandTracker::GetModularFeatureName(), + static_cast(this)); + IModularFeatures::Get().RegisterModularFeature(IMotionController::GetModularFeatureName(), + static_cast(this)); + IModularFeatures::Get().RegisterModularFeature(IOpenXRExtensionPlugin::GetModularFeatureName(), + static_cast(this)); + + // We're implicitly requiring that the OpenXRPlugin has been loaded and initialized at this point. + if (!IOpenXRHMDModule::Get().IsAvailable()) + { + SGLOG_FATAL("The OpenXRHMD plugin isn't available!"); + ensureAlwaysMsgf(false, TEXT("The OpenXRHMD plugin isn't available!")); + } +} + +FSGXRTracker::FSGXRTracker(FSGXRTracker&& Rhs) SG_NOEXCEPT = default; + +FSGXRTracker::~FSGXRTracker() = default; + +FSGXRTracker& FSGXRTracker::operator=(FSGXRTracker&& Rhs) SG_NOEXCEPT = default; + +bool FSGXRTracker::IsHandTrackingSupportedByDevice() const +{ + const bool bFallbackToHandTrackingIfNoGloveDetected = FImpl::ShouldFallbackToHandTrackingIfNoGloveDetected(); + + const bool bAnyGloveConnected = FImpl::IsAnyGloveConnected(); + const bool bHandTrackingAvailable = Pimpl->bHandTrackingAvailable; + + const bool bHandTrackingSupportedByDevice = + bAnyGloveConnected || (bFallbackToHandTrackingIfNoGloveDetected && bHandTrackingAvailable); + + return bHandTrackingSupportedByDevice; +} + +const FSGXRHandState& FSGXRTracker::GetLeftHandState() const +{ + return Pimpl->GetLeftHandState(); +} + +const FSGXRHandState& FSGXRTracker::GetRightHandState() const +{ + return Pimpl->GetRightHandState(); +} + +FString FSGXRTracker::GetDisplayName() +{ + static const FString Name{TEXT("SenseGloveTracking")}; + return Name; +} + +bool FSGXRTracker::GetRequiredExtensions(TArray& OutExtensions) +{ + TArray Properties; + EnumerateOpenXRApiLayers(Properties); + + // Some API layers can crash the loader when enabled, if they're present we shouldn't enable the extension. + for (const XrApiLayerProperties& Layer: Properties) + { + if (FCStringAnsi::Strstr(Layer.layerName, "XR_APILAYER_VIVE_hand_tracking") + && Layer.layerVersion <= 1) + { + return false; + } + } + + OutExtensions.Add("XR_EXT_hand_tracking"); + + return true; +} + +const void* FSGXRTracker::OnGetSystem(const XrInstance InInstance, const void* InNext) +{ + // Store the extension open xr calls to member function pointers for convenient use. + XR_ENSURE(xrGetInstanceProcAddr(InInstance, + "xrCreateHandTrackerEXT", (PFN_xrVoidFunction*)&Pimpl->XRCreateHandTrackerEXT)); + XR_ENSURE(xrGetInstanceProcAddr(InInstance, + "xrDestroyHandTrackerEXT", (PFN_xrVoidFunction*)&Pimpl->XRDestroyHandTrackerEXT)); + XR_ENSURE(xrGetInstanceProcAddr(InInstance, + "xrLocateHandJointsEXT", (PFN_xrVoidFunction*)&Pimpl->XRLocateHandJointsEXT)); + + return InNext; +} + +const void* FSGXRTracker::OnCreateSession(const XrInstance InInstance, const XrSystemId InSystem, const void* InNext) +{ + // Need to wait until the EHandKeypoint enum has been loaded, so we do this here rather than in the constructor + // which runs too early. + Pimpl->BuildMotionSourceToKeypointMap(); + + XrSystemHandTrackingPropertiesEXT HandTrackingSystemProperties{ + XR_TYPE_SYSTEM_HAND_TRACKING_PROPERTIES_EXT}; + XrSystemProperties systemProperties{XR_TYPE_SYSTEM_PROPERTIES, + &HandTrackingSystemProperties}; + XR_ENSURE(xrGetSystemProperties(InInstance, InSystem, &systemProperties)); + + Pimpl->bHandTrackingAvailable = HandTrackingSystemProperties.supportsHandTracking == XR_TRUE; + + return InNext; +} + +const void* FSGXRTracker::OnBeginSession(const XrSession InSession, const void* InNext) +{ + const bool bHandTrackingAvailable = Pimpl->bHandTrackingAvailable; + + if (bHandTrackingAvailable) + { + static FName SystemName(TEXT("OpenXR")); + if (IsValid(GEngine) && GEngine->XRSystem.IsValid() && (GEngine->XRSystem->GetSystemName() == SystemName)) + { + Pimpl->XRTrackingSystem = GEngine->XRSystem.Get(); + } + + // Create a hand tracker for the left hand that tracks default set of hand joints. + FSGXRHandState& LeftHandState{Pimpl->GetLeftHandState()}; + { + XrHandTrackerCreateInfoEXT CreateInfo{XR_TYPE_HAND_TRACKER_CREATE_INFO_EXT}; + CreateInfo.hand = XR_HAND_LEFT_EXT; + CreateInfo.handJointSet = XR_HAND_JOINT_SET_DEFAULT_EXT; + XR_ENSURE(Pimpl->XRCreateHandTrackerEXT(InSession, &CreateInfo, &LeftHandState.HandTracker)); + } + + // Create a hand tracker for the right hand that tracks default set of hand joints. + FSGXRHandState& RightHandState{Pimpl->GetRightHandState()}; + { + XrHandTrackerCreateInfoEXT CreateInfo{XR_TYPE_HAND_TRACKER_CREATE_INFO_EXT}; + CreateInfo.hand = XR_HAND_RIGHT_EXT; + CreateInfo.handJointSet = XR_HAND_JOINT_SET_DEFAULT_EXT; + XR_ENSURE(Pimpl->XRCreateHandTrackerEXT(InSession, &CreateInfo, &RightHandState.HandTracker)); + } + } + + return InNext; +} + +void FSGXRTracker::UpdateDeviceLocations( + const XrSession InSession, const XrTime DisplayTime, const XrSpace TrackingSpace) +{ + if (!IsHandTrackingStateValid()) + { + return; + } + + XrHandJointsLocateInfoEXT LocateInfo{XR_TYPE_HAND_JOINTS_LOCATE_INFO_EXT}; + LocateInfo.baseSpace = TrackingSpace; + LocateInfo.time = DisplayTime; + + const bool bFallbackToHandTrackingIfNoGloveDetected = FImpl::ShouldFallbackToHandTrackingIfNoGloveDetected(); + + const bool bLeftGloveConnected = FImpl::IsLeftGloveConnected(); + if (bLeftGloveConnected) + { + /// NOTE + /// It's necessary to call the UpdateXRHandTrackingData first for the wrist-tracking to work properly when the + /// motion controllers are not active and we rely on the OpenXRHandTracking data for wrist tracking. + /// See the NOTE inside the FSGXRTracker::FImpl::GetWristTransform method. + Pimpl->UpdateXRHandTrackingData(Pimpl->GetLeftHandState(), LocateInfo); + Pimpl->UpdateSGHandState(false, Pimpl->GetLeftHandState()); + } + else + { + if (bFallbackToHandTrackingIfNoGloveDetected) + { + Pimpl->UpdateXRHandTrackingData(Pimpl->GetLeftHandState(), LocateInfo); + } + } + + const bool bRightGloveConnected = FImpl::IsRightGloveConnected(); + if (bRightGloveConnected) + { + /// NOTE + /// It's necessary to call the UpdateXRHandTrackingData first for the wrist-tracking to work properly when the + /// motion controllers are not active and we rely on the OpenXRHandTracking data for wrist tracking. + /// See the NOTE inside the FSGXRTracker::FImpl::GetWristLocationAndRotation method. + Pimpl->UpdateXRHandTrackingData(Pimpl->GetRightHandState(), LocateInfo); + Pimpl->UpdateSGHandState(true, Pimpl->GetRightHandState()); + } + else + { + if (bFallbackToHandTrackingIfNoGloveDetected) + { + Pimpl->UpdateXRHandTrackingData(Pimpl->GetRightHandState(), LocateInfo); + } + } +} + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 3 +bool FSGXRTracker::GetControllerOrientationAndPosition(const int32 ControllerIndex, const FName MotionSource, + FRotator& OutOrientation, FVector& OutPosition, + const float WorldToMetersScale) const +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 3 */ +bool FSGXRTracker::GetControllerOrientationAndPosition(const int32 ControllerIndex, const EControllerHand DeviceHand, + FRotator& OutOrientation, FVector& OutPosition, + const float WorldToMetersScale) const +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 3 */ +{ + if (!IsHandTrackingStateValid()) + { + return false; + } + + // Hand tracking currently does not support late update. Current hand tracking systems have latency that make it + // pointless. + if (!IsInGameThread()) + { + return false; + } + + if (ControllerIndex != Pimpl->DeviceIndex) + { + return false; + } + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION <= 2 + const FName& MotionSource{FImpl::GetControllerHandEnumName(DeviceHand)}; +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION <= 2 */ + + FTransform ControllerTransform; + bool bMotionSourceHandTracking; + const bool bGotTransform = Pimpl->GetControllerTransform(MotionSource, WorldToMetersScale, + ControllerTransform, bMotionSourceHandTracking); + (void) bMotionSourceHandTracking; + + OutOrientation = ControllerTransform.GetRotation().Rotator(); + OutPosition = ControllerTransform.GetLocation(); + + return bGotTransform; +} + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 3 +ETrackingStatus FSGXRTracker::GetControllerTrackingStatus(const int32 ControllerIndex, const FName MotionSource) const +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 3 */ +ETrackingStatus FSGXRTracker::GetControllerTrackingStatus(const int32 ControllerIndex, + const EControllerHand DeviceHand) const +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 3 */ +{ + if (!IsHandTrackingStateValid()) + { + return ETrackingStatus::NotTracked; + } + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION <= 2 + const FName& MotionSource{FImpl::GetControllerHandEnumName(DeviceHand)}; +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION <= 2 */ + + const FImpl::FSGMotionSourceInfo* KeyPointInfoPtr{Pimpl->MotionSourceToKeypointMap.Find(MotionSource)}; + if (!KeyPointInfoPtr) + { + return ETrackingStatus::NotTracked; + } + + const bool bRight = !KeyPointInfoPtr->Value; + + const bool bGlovePresent = + (bRight && FImpl::IsRightGloveConnected()) || (!bRight && FImpl::IsLeftGloveConnected()); + if (bGlovePresent) + { + return ETrackingStatus::Tracked; + } + + const bool bFallbackToHandTrackingIfNoGloveDetected = FImpl::ShouldFallbackToHandTrackingIfNoGloveDetected(); + if (bFallbackToHandTrackingIfNoGloveDetected) + { + const FSGXRHandState& HandState{bRight ? GetRightHandState() : GetLeftHandState()}; + return HandState.bTracked ? ETrackingStatus::Tracked : ETrackingStatus::NotTracked; + } + + return ETrackingStatus::NotTracked; +} + +FName FSGXRTracker::GetMotionControllerDeviceTypeName() const +{ + const static FName DefaultName(TEXT("OpenXRHandTracking")); + return DefaultName; +} + +void FSGXRTracker::EnumerateSources(TArray& SourcesOut) const +{ + ensureAlwaysMsgf(IsInGameThread(), TEXT("Is not in the game thread!")); + + SourcesOut.Reserve(SourcesOut.Num() + (EHandKeypointCount * 2)); + + const FName& Left(FImpl::GetLeftHandTrackingMotionSourceName()); + const FName& Right(FImpl::GetRightHandTrackingMotionSourceName()); + + for (int32 Keypoint = 0; Keypoint < EHandKeypointCount; Keypoint++) + { + const FName EnumName{FImpl::GetHandKeypointEnumName(Keypoint)}; + const FString EnumString{EnumName.ToString()}; + const FString StringLeft{FString::Printf(TEXT("%s%s"), *Left.ToString(), *EnumString)}; + const FString StringRight{FString::Printf(TEXT("%s%s"), *Right.ToString(), *EnumString)}; + FName SourceL(*(StringLeft)); + FName SourceR(*(StringRight)); + SourcesOut.Add(MoveTemp(SourceL)); + SourcesOut.Add(MoveTemp(SourceR)); + } +} + +void FSGXRTracker::Tick(const float DeltaTime) +{ +} + +void FSGXRTracker::SendControllerEvents() +{ +} + +void FSGXRTracker::SetMessageHandler(const TSharedRef& InMessageHandler) +{ + Pimpl->MessageHandler = InMessageHandler; +} + +bool FSGXRTracker::Exec(UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& Ar) +{ + return false; +} + +void FSGXRTracker::SetChannelValue( + const int32 ControllerId, const FForceFeedbackChannelType ChannelType, const float Value) +{ +} + +void FSGXRTracker::SetChannelValues(const int32 ControllerId, const FForceFeedbackValues& Values) +{ +} + +bool FSGXRTracker::SupportsForceFeedback(const int32 ControllerId) +{ + // FIXME + // For now it's true, but when we fall back to the hand tracking we might return false. + (void) ControllerId; + return true; +} + +bool FSGXRTracker::IsGamepadAttached() const +{ + return false; +} + +FName FSGXRTracker::GetHandTrackerDeviceTypeName() const +{ + return GetMotionControllerDeviceTypeName(); +} + +bool FSGXRTracker::IsHandTrackingStateValid() const +{ + const bool bFallbackToHandTrackingIfNoGloveDetected = FImpl::ShouldFallbackToHandTrackingIfNoGloveDetected(); + + const bool bHandTrackingAvailable = Pimpl->bHandTrackingAvailable; + const bool bAnyGloveConnected = FImpl::IsAnyGloveConnected(); + + const bool bHandTrackingStateValid = + bAnyGloveConnected || (bFallbackToHandTrackingIfNoGloveDetected && bHandTrackingAvailable); + + return bHandTrackingStateValid; +} + +bool FSGXRTracker::GetKeypointState( + const EControllerHand Hand, const EHandKeypoint Keypoint, FTransform& OutTransform, float& OutRadius) const +{ + if (!IsHandTrackingStateValid()) + { + return false; + } + + if (!Pimpl->CanOutputTrackingData(Hand)) + { + return false; + } + + const FSGXRHandState& HandState{ + Hand == EControllerHand::Left ? GetLeftHandState() : GetRightHandState() + }; + const bool bGotTransform = HandState.GetTransform(Keypoint, OutTransform); + OutRadius = HandState.Radii[static_cast(Keypoint)]; + + if (bGotTransform) + { + if (!ensureAlwaysMsgf(Pimpl->XRTrackingSystem, TEXT("Invalid XR tracking system!"))) + { + return false; + } + + // Convert to UE world space. + const FTransform& TrackingToWorldTransform{Pimpl->XRTrackingSystem->GetTrackingToWorldTransform()}; + OutTransform *= TrackingToWorldTransform; + } + + return bGotTransform; +} + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 +bool FSGXRTracker::GetAllKeypointStates( + const EControllerHand Hand, + TArray& OutPositions, TArray& OutRotations, TArray& OutRadii, + bool& OutIsTracked) const +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ +bool FSGXRTracker::GetAllKeypointStates( + const EControllerHand Hand, + TArray& OutPositions, TArray& OutRotations, TArray& OutRadii) const +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5*/ + +{ + if (!IsHandTrackingStateValid()) + { + return false; + } + + if (Hand != EControllerHand::Left && Hand != EControllerHand::Right) + { + return false; + } + + if (!Pimpl->CanOutputTrackingData(Hand)) + { + return false; + } + + const FSGXRHandState& HandState{ + Hand == EControllerHand::Left ? GetLeftHandState() : GetRightHandState() + }; + + if (!HandState.bHasReceivedJointPoses) + { + return false; + } + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + OutIsTracked = HandState.bTracked; +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5*/ + + // If we ever received poses we return the last data we received, even if not currently tracking to avoid poping + // back to (0.0f, 0.0f, 0.0f) and the like. + OutPositions.Empty(EHandKeypointCount); + OutRotations.Empty(EHandKeypointCount); + OutRadii.Empty(EHandKeypointCount); + + if (!ensureAlwaysMsgf(Pimpl->XRTrackingSystem, TEXT("Invalid XR tracking system!"))) + { + return false; + } + + const FTransform& TrackingToWorldTransform{Pimpl->XRTrackingSystem->GetTrackingToWorldTransform()}; + + for (int32 i = 0; i < EHandKeypointCount; ++i) + { + FTransform KeypointWorldTransform{HandState.KeypointTransforms[i] * TrackingToWorldTransform}; + OutPositions.Add(KeypointWorldTransform.GetLocation()); + OutRotations.Add(KeypointWorldTransform.GetRotation()); + } + + for (int32 i = 0; i < EHandKeypointCount; ++i) + { + OutRadii.Add(HandState.Radii[i]); + } + + return true; +} + +FSGXRTracker::FImpl::FImpl(FSGXRTracker* InOwner) + : bHandTrackingAvailable(false), + XRCreateHandTrackerEXT(nullptr), + XRDestroyHandTrackerEXT(nullptr), + XRLocateHandJointsEXT(nullptr), + XRTrackingSystem(nullptr), + DeviceIndex(0), + CurrentHandTrackingDataIndex(0), + Owner(InOwner) +{ +} + +FSGXRTracker::FImpl::~FImpl() = default; + +void FSGXRTracker::FImpl::BuildMotionSourceToKeypointMap() +{ + ensureAlwaysMsgf(IsInGameThread(), TEXT("Is not in the game thread!")); + + if (!MotionSourceToKeypointMap.IsEmpty()) + { + return; + } + + const bool bSupportLegacyControllerMotionSources = ShouldSupportLegacyControllerMotionSources(); + + // There is a motion source that corresponds to each hand keypoint of the form [Left|Right][Keypoint]. + // Build a map so we can quickly translate from motion source FName to hand bone EHandKeypoint value. + // We also have the option of using more specific motion sources of the form HandTracking[Left|Right][Keypoint]. + // This is useful if one wishes to use hand tracking and controllers simultaneously. + // We also may support more generic legacy motion sources, by default we do support this. + + const FName& Left(GetLeftHandTrackingMotionSourceName()); + const FName& Right(GetRightHandTrackingMotionSourceName()); + + for (int32 KeypointIndex = 0; KeypointIndex < EHandKeypointCount; ++KeypointIndex) + { + const EHandKeypoint EnumValue = static_cast(KeypointIndex); + const FName EnumName{GetHandKeypointEnumName(KeypointIndex)}; + const FString EnumString{EnumName.ToString()}; + + FName LeftName(Left.ToString() + EnumString); + FName RightName(Right.ToString() + EnumString); + MotionSourceToKeypointMap.Add(MoveTemp(LeftName), FSGMotionSourceInfo(EnumValue, true)); + MotionSourceToKeypointMap.Add(MoveTemp(RightName), FSGMotionSourceInfo(EnumValue, false)); + } + + if (bSupportLegacyControllerMotionSources) + { + const FName& LeftLegacyControllerHandTrackingMotionSourceName{ + GetLegacyControllerLeftHandTrackingMotionSourceName()}; + const FName& RightLegacyControllerHandTrackingMotionSourceName{ + GetLegacyControllerRightHandTrackingMotionSourceName()}; + MotionSourceToKeypointMap.Add( + LeftLegacyControllerHandTrackingMotionSourceName, FSGMotionSourceInfo(EHandKeypoint::Wrist, true)); + MotionSourceToKeypointMap.Add( + RightLegacyControllerHandTrackingMotionSourceName, FSGMotionSourceInfo(EHandKeypoint::Wrist, false)); + } + + const FSGWristTrackingSettings& WristTrackingSettings{GetWristTrackingSettings()}; + const FName& LeftHandSGMotionSourceName{WristTrackingSettings.LeftHandMotionSource}; + const FName& RightHandSGMotionSourceName{WristTrackingSettings.RightHandMotionSource}; + + MotionSourceToKeypointMap.Add( + LeftHandSGMotionSourceName, FSGMotionSourceInfo(EHandKeypoint::Wrist, true)); + MotionSourceToKeypointMap.Add( + RightHandSGMotionSourceName, FSGMotionSourceInfo(EHandKeypoint::Wrist, false)); +} + +bool FSGXRTracker::FImpl::CanOutputTrackingData(const EControllerHand Hand) const +{ + const bool bFallbackToHandTrackingIfNoGloveDetected = ShouldFallbackToHandTrackingIfNoGloveDetected(); + + const bool bIsHandTrackingAvailable = bHandTrackingAvailable; + + bool bGloveConnected = false; + if (Hand == EControllerHand::Left) + { + bGloveConnected = IsLeftGloveConnected(); + } + else if (Hand == EControllerHand::Right) + { + bGloveConnected = IsRightGloveConnected(); + } + + const bool bCanOutputTrackingData = + bGloveConnected || (bFallbackToHandTrackingIfNoGloveDetected && bIsHandTrackingAvailable); + + return bCanOutputTrackingData; +} + +bool FSGXRTracker::FImpl::UpdateXRHandTrackingData( + FSGXRHandState& OutHandState, const XrHandJointsLocateInfoEXT& LocateInfo) const +{ + if (!ensureAlwaysMsgf(XRTrackingSystem, TEXT("Invalid XR tracking system!"))) + { + return false; + } + + const float WorldToMetersScale = XRTrackingSystem->GetWorldToMetersScale(); + + XR_ENSURE(XRLocateHandJointsEXT(OutHandState.HandTracker, &LocateInfo, &OutHandState.Locations)); + + OutHandState.bTracked = OutHandState.Locations.isActive == XR_TRUE; + OutHandState.bHasReceivedJointPoses |= OutHandState.bTracked; + if (!OutHandState.bTracked) + { + return false; + } + + static_assert( + XR_HAND_JOINT_PALM_EXT == 0 && XR_HAND_JOINT_LITTLE_TIP_EXT == XR_HAND_JOINT_COUNT_EXT - 1, + "XrHandJointEXT enum is not as assumed for the following loop!"); + + for (int32 j = 0; j < XR_HAND_JOINT_COUNT_EXT; ++j) + { + const XrHandJointLocationEXT& JointLocation{OutHandState.JointLocations[j]}; + const XrPosef& Pose{JointLocation.pose}; + FTransform Transform{ToFTransform(Pose, WorldToMetersScale)}; + OutHandState.KeypointTransforms[j] = MoveTemp(Transform); + OutHandState.Radii[j] = JointLocation.radius * WorldToMetersScale; + // velocities would go here + } + + return true; +} + +FName FSGXRTracker::FImpl::GetTargetOpenXRPositionalTrackingProviderName() const +{ + const FSGWristTrackingSettings& WristTrackingSettings{GetWristTrackingSettings()}; + + ESGOpenXRPositionalTrackingProvider PositionalTrackingProvider = + WristTrackingSettings.OpenXRPositionalTrackingProvider; + + if (PositionalTrackingProvider == ESGOpenXRPositionalTrackingProvider::None) + { + const bool bIsAHtcViveDevice = FSGHMDTracker::IsAHtcViveDevice(); + if (bIsAHtcViveDevice) + { +#if PLATFORM_ANDROID + PositionalTrackingProvider = ESGOpenXRPositionalTrackingProvider::OpenXRViveWristTracker; +#else /* PLATFORM_ANDROID */ + // TODO + // Revisit this later! + // For now only `Emulate VIVE Wrist Tracker as VIVE Tracker` option in VBE works on Windows + // const bool bIsViveOpenXRPluginLoaded = FSGPluginUtils::IsViveOpenXRPluginAvailable(); + // if (bIsViveOpenXRPluginLoaded) + // { + // if (WristTrackingSettings.TrackingHardware == ESGPositionalTrackingHardware::ViveFocus3WristTracker) + // { + // PositionalTrackingProvider = ESGOpenXRPositionalTrackingProvider::OpenXRViveWristTracker; + // } + // else + // { + // PositionalTrackingProvider = ESGOpenXRPositionalTrackingProvider::OpenXRViveTracker; + // } + // } + // else + // { + // PositionalTrackingProvider = ESGOpenXRPositionalTrackingProvider::OpenXRViveTracker; + // } + PositionalTrackingProvider = ESGOpenXRPositionalTrackingProvider::OpenXRViveTracker; +#endif /* PLATFORM_ANDROID */ + } + else + { + PositionalTrackingProvider = ESGOpenXRPositionalTrackingProvider::OpenXR; + } + } + + const FName PositionalTrackingProviderName{ + GetOpenXRPositionalTrackingProviderEnumName(PositionalTrackingProvider) + }; + return PositionalTrackingProviderName; +} + +bool FSGXRTracker::FImpl::GetControllerTransform( + const FName MotionSource, const float WorldToMetersScale, + FTransform& OutTransform, bool& bOutMotionSourceHandTracking) const +{ + const FSGMotionSourceInfo* KeyPointInfoPtr{MotionSourceToKeypointMap.Find(MotionSource)}; + if (!KeyPointInfoPtr) + { + return false; + } + + const bool bRight = !KeyPointInfoPtr->Value; + const bool bGlovePresent = + (bRight && IsRightGloveConnected()) || (!bRight && IsLeftGloveConnected()); + const bool bFallbackToHandTrackingIfNoGloveDetected = ShouldFallbackToHandTrackingIfNoGloveDetected(); + + if (!bGlovePresent && !bFallbackToHandTrackingIfNoGloveDetected) + { + return false; + } + + const FSGWristTrackingSettings& WristTrackingSettings{GetWristTrackingSettings()}; + const FName& PositionalTrackingHardwareMotionSource{ + bRight + ? WristTrackingSettings.RightHandMotionSource + : WristTrackingSettings.LeftHandMotionSource + }; + + bool bTracked = false; + + if (MotionSource == PositionalTrackingHardwareMotionSource) + { + const FName TargetPositionalTrackingProviderName{ + GetTargetOpenXRPositionalTrackingProviderName() + }; + + const TArray MotionControllers{ + IModularFeatures::Get().GetModularFeatureImplementations( + IMotionController::GetModularFeatureName()) + }; + + for (const IMotionController* MotionController: MotionControllers) + { + if (!MotionController) + { + continue; + } + + const ETrackingStatus TrackingStatus = MotionController->GetControllerTrackingStatus( + DeviceIndex, PositionalTrackingHardwareMotionSource); + if (TrackingStatus == ETrackingStatus::NotTracked) + { + continue; + } + + const FName DeviceTypeName{MotionController->GetMotionControllerDeviceTypeName()}; + if (DeviceTypeName != TargetPositionalTrackingProviderName) + { + continue; + } + + FRotator Orientation; + FVector Position; + const bool bGotTransform = MotionController->GetControllerOrientationAndPosition( + DeviceIndex, PositionalTrackingHardwareMotionSource, + Orientation, Position, WorldToMetersScale); + if (bGotTransform) + { + OutTransform = FTransform{Orientation, Position}; + bOutMotionSourceHandTracking = false; + bTracked = true; + break; + } + } + } + + if (!bTracked && bFallbackToHandTrackingIfNoGloveDetected) + { + const FSGXRHandState& HandState{bRight ? Owner->GetRightHandState() : Owner->GetLeftHandState()}; + if (!HandState.bHasReceivedJointPoses) + { + return false; + } + + const EHandKeypoint KeyPoint = KeyPointInfoPtr->Key; + const FTransform& ControllerTransform{HandState.GetTransform(KeyPoint)}; + OutTransform = ControllerTransform; + bOutMotionSourceHandTracking = true; + bTracked = HandState.bTracked; + } + + return bTracked; +} + +bool FSGXRTracker::FImpl::GetWristTransform(const bool bRight, FTransform& OutTransform) const +{ + const FSGWristTrackingSettings& WristTrackingSettings{GetWristTrackingSettings()}; + const FName& MotionSource{ + bRight + ? WristTrackingSettings.RightHandMotionSource + : WristTrackingSettings.LeftHandMotionSource + }; + + if (!ensureAlwaysMsgf(XRTrackingSystem, TEXT("Invalid XR tracking system!"))) + { + return false; + } + const float WorldToMetersScale = XRTrackingSystem->GetWorldToMetersScale(); + + bool bMotionSourceHandTracking = false; + FTransform ControllerTransform; + const bool bGotTransform = GetControllerTransform( + MotionSource, WorldToMetersScale, ControllerTransform, bMotionSourceHandTracking); + + if (bGotTransform) + { + if (bMotionSourceHandTracking) + { + OutTransform = MoveTemp(ControllerTransform); + } + else + { + const ESGPositionalTrackingHardware TrackingHardware = GetPositionalTrackingHardware(); + if (TrackingHardware == ESGPositionalTrackingHardware::Custom) + { + if (bRight) + { + ControllerTransform.SetRotation( + (ControllerTransform.GetRotation().Rotator() + + WristTrackingSettings.TrackingHardwareRotationOffsetRightHand).Quaternion()); + ControllerTransform.SetLocation( + ControllerTransform.GetLocation() + + WristTrackingSettings.TrackingHardwareLocationOffsetRightHand); + } + else + { + ControllerTransform.SetRotation( + (ControllerTransform.GetRotation().Rotator() + + WristTrackingSettings.TrackingHardwareRotationOffsetLeftHand).Quaternion()); + ControllerTransform.SetLocation( + ControllerTransform.GetLocation() + + WristTrackingSettings.TrackingHardwareLocationOffsetLeftHand); + } + } + + const USGHapticGlove* Glove{GetGlove(bRight)}; + if (!IsValid(Glove)) + { + return false; + } + + FVector WristLocation; + FRotator WristRotation; + Glove->GetWristLocation( + ControllerTransform.GetLocation(), + ControllerTransform.GetRotation().Rotator(), + TrackingHardware, + WristLocation, WristRotation); + + OutTransform = FTransform{MoveTemp(WristRotation), MoveTemp(WristLocation)}; + } + } + + return bGotTransform; +} + +bool FSGXRTracker::FImpl::UpdateSGJointData( + FSGXRHandState& OutHandState, const EHandKeypoint Joint, + const FTransform& JointTransform, const FTransform& WristTransform) const +{ + if (!ensureAlwaysMsgf(XRTrackingSystem, TEXT("Invalid XR tracking system!"))) + { + return false; + } + + const float WorldToMetersScale = XRTrackingSystem->GetWorldToMetersScale(); + + const int32 JointIndex = static_cast(Joint); + + const FQuat WristRotation{WristTransform.GetRotation()}; + const FVector WristLocation{WristTransform.GetLocation()}; + const FQuat JointRotation{JointTransform.GetRotation()}; + const FVector JointLocation{JointTransform.GetLocation()}; + + FTransform Transform{ + WristRotation * JointRotation, + WristLocation + (WristRotation * JointLocation) + }; + + OutHandState.KeypointTransforms[JointIndex] = MoveTemp(Transform); + OutHandState.Radii[JointIndex] = 0.01f * WorldToMetersScale; + + return true; +} + +bool FSGXRTracker::FImpl::UpdateSGWristJointData( + FSGXRHandState& OutHandState, const FTransform& WristTransform) const +{ + if (!ensureAlwaysMsgf(XRTrackingSystem, TEXT("Invalid XR tracking system!"))) + { + return false; + } + + const float WorldToMetersScale = XRTrackingSystem->GetWorldToMetersScale(); + + static constexpr EHandKeypoint Joint = EHandKeypoint::Wrist; + static constexpr int32 JointIndex = static_cast(Joint); + + OutHandState.KeypointTransforms[JointIndex] = WristTransform; + OutHandState.Radii[JointIndex] = 0.01f * WorldToMetersScale; + + return true; +} + +bool FSGXRTracker::FImpl::UpdateSGPalmJointData( + FSGXRHandState& OutHandState, const bool bRight, const FTransform& WristTransform) const +{ + if (!ensureAlwaysMsgf(XRTrackingSystem, TEXT("Invalid XR tracking system!"))) + { + return false; + } + + FTransform JointTransform{GetMeshWristChildBoneRefTransform(bRight, EHandKeypoint::Palm)}; + + if (!UpdateSGJointData(OutHandState, EHandKeypoint::Palm, + MoveTemp(JointTransform), WristTransform)) + { + return false; + } + + return true; +} + +bool FSGXRTracker::FImpl::UpdateSGThumbJointData( + FSGXRHandState& OutHandState, + const TArray>& JointLocations, const TArray>& JointRotations, + const FTransform& WristTransform) const +{ + static constexpr int32 ThumbFingerIndex = 0; + static constexpr int32 ThumbMetacarpalJointIndex = 0; + static constexpr int32 ThumbProximalJointIndex = 1; + static constexpr int32 ThumbDistalJointIndex = 2; + static constexpr int32 ThumbTipJointIndex = 3; + + FTransform ThumbMetacarpalTransform{ + JointRotations[ThumbFingerIndex][ThumbMetacarpalJointIndex], + JointLocations[ThumbFingerIndex][ThumbMetacarpalJointIndex] + }; + FTransform ThumbProximalTransform{ + JointRotations[ThumbFingerIndex][ThumbProximalJointIndex], + JointLocations[ThumbFingerIndex][ThumbProximalJointIndex] + }; + FTransform ThumbDistalTransform{ + JointRotations[ThumbFingerIndex][ThumbDistalJointIndex], + JointLocations[ThumbFingerIndex][ThumbDistalJointIndex] + }; + FTransform ThumbTipTransform{ + JointRotations[ThumbFingerIndex][ThumbTipJointIndex], + JointLocations[ThumbFingerIndex][ThumbTipJointIndex] + }; + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::ThumbMetacarpal, + MoveTemp(ThumbMetacarpalTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::ThumbProximal, + MoveTemp(ThumbProximalTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::ThumbDistal, + MoveTemp(ThumbDistalTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::ThumbTip, + MoveTemp(ThumbTipTransform), WristTransform)) + { + return false; + } + + return true; +} + +bool FSGXRTracker::FImpl::UpdateSGIndexJointData( + FSGXRHandState& OutHandState, const bool bRight, + const TArray>& JointLocations, const TArray>& JointRotations, + const FTransform& WristTransform) const +{ + static constexpr int32 IndexFingerIndex = 1; + + static constexpr int32 IndexProximalJointIndex = 0; + static constexpr int32 IndexIntermediateJointIndex = 1; + static constexpr int32 IndexDistalJointIndex = 2; + static constexpr int32 IndexTipJointIndex = 3; + + FTransform IndexMetacarpalTransform{ + GetMeshWristChildBoneRefTransform(bRight, EHandKeypoint::IndexMetacarpal) + }; + FTransform IndexProximalTransform{ + JointRotations[IndexFingerIndex][IndexProximalJointIndex], + JointLocations[IndexFingerIndex][IndexProximalJointIndex] + }; + FTransform IndexIntermediateTransform{ + JointRotations[IndexFingerIndex][IndexIntermediateJointIndex], + JointLocations[IndexFingerIndex][IndexIntermediateJointIndex] + }; + FTransform IndexDistalTransform{ + JointRotations[IndexFingerIndex][IndexDistalJointIndex], + JointLocations[IndexFingerIndex][IndexDistalJointIndex] + }; + FTransform IndexTipTransform{ + JointRotations[IndexFingerIndex][IndexTipJointIndex], + JointLocations[IndexFingerIndex][IndexTipJointIndex] + }; + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::IndexMetacarpal, + MoveTemp(IndexMetacarpalTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::IndexProximal, + MoveTemp(IndexProximalTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::IndexIntermediate, + MoveTemp(IndexIntermediateTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::IndexDistal, + MoveTemp(IndexDistalTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::IndexTip, + MoveTemp(IndexTipTransform), WristTransform)) + { + return false; + } + + return true; +} + +bool FSGXRTracker::FImpl::UpdateSGMiddleJointData( + FSGXRHandState& OutHandState, const bool bRight, + const TArray>& JointLocations, const TArray>& JointRotations, + const FTransform& WristTransform) const +{ + static constexpr int32 MiddleFingerMiddle = 2; + + static constexpr int32 MiddleProximalJointMiddle = 0; + static constexpr int32 MiddleIntermediateJointMiddle = 1; + static constexpr int32 MiddleDistalJointMiddle = 2; + static constexpr int32 MiddleTipJointMiddle = 3; + + FTransform MiddleMetacarpalTransform{ + GetMeshWristChildBoneRefTransform(bRight, EHandKeypoint::MiddleMetacarpal) + }; + FTransform MiddleProximalTransform{ + JointRotations[MiddleFingerMiddle][MiddleProximalJointMiddle], + JointLocations[MiddleFingerMiddle][MiddleProximalJointMiddle] + }; + FTransform MiddleIntermediateTransform{ + JointRotations[MiddleFingerMiddle][MiddleIntermediateJointMiddle], + JointLocations[MiddleFingerMiddle][MiddleIntermediateJointMiddle] + }; + FTransform MiddleDistalTransform{ + JointRotations[MiddleFingerMiddle][MiddleDistalJointMiddle], + JointLocations[MiddleFingerMiddle][MiddleDistalJointMiddle] + }; + FTransform MiddleTipTransform{ + JointRotations[MiddleFingerMiddle][MiddleTipJointMiddle], + JointLocations[MiddleFingerMiddle][MiddleTipJointMiddle] + }; + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::MiddleMetacarpal, + MoveTemp(MiddleMetacarpalTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::MiddleProximal, + MoveTemp(MiddleProximalTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::MiddleIntermediate, + MoveTemp(MiddleIntermediateTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::MiddleDistal, + MoveTemp(MiddleDistalTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::MiddleTip, + MoveTemp(MiddleTipTransform), WristTransform)) + { + return false; + } + + return true; +} + +bool FSGXRTracker::FImpl::UpdateSGRingJointData( + FSGXRHandState& OutHandState, const bool bRight, + const TArray>& JointLocations, const TArray>& JointRotations, + const FTransform& WristTransform) const +{ + static constexpr int32 RingFingerRing = 3; + + static constexpr int32 RingProximalJointRing = 0; + static constexpr int32 RingIntermediateJointRing = 1; + static constexpr int32 RingDistalJointRing = 2; + static constexpr int32 RingTipJointRing = 3; + + FTransform RingMetacarpalTransform{ + GetMeshWristChildBoneRefTransform(bRight, EHandKeypoint::RingMetacarpal) + }; + FTransform RingProximalTransform{ + JointRotations[RingFingerRing][RingProximalJointRing], + JointLocations[RingFingerRing][RingProximalJointRing] + }; + FTransform RingIntermediateTransform{ + JointRotations[RingFingerRing][RingIntermediateJointRing], + JointLocations[RingFingerRing][RingIntermediateJointRing] + }; + FTransform RingDistalTransform{ + JointRotations[RingFingerRing][RingDistalJointRing], + JointLocations[RingFingerRing][RingDistalJointRing] + }; + FTransform RingTipTransform{ + JointRotations[RingFingerRing][RingTipJointRing], + JointLocations[RingFingerRing][RingTipJointRing] + }; + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::RingMetacarpal, + MoveTemp(RingMetacarpalTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::RingProximal, + MoveTemp(RingProximalTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::RingIntermediate, + MoveTemp(RingIntermediateTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::RingDistal, + MoveTemp(RingDistalTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::RingTip, + MoveTemp(RingTipTransform), WristTransform)) + { + return false; + } + + return true; +} + +bool FSGXRTracker::FImpl::UpdateSGLittleJointData( + FSGXRHandState& OutHandState, const bool bRight, + const TArray>& JointLocations, const TArray>& JointRotations, + const FTransform& WristTransform) const +{ + static constexpr int32 LittleFingerLittle = 4; + + static constexpr int32 LittleProximalJointLittle = 0; + static constexpr int32 LittleIntermediateJointLittle = 1; + static constexpr int32 LittleDistalJointLittle = 2; + static constexpr int32 LittleTipJointLittle = 3; + + FTransform LittleMetacarpalTransform{ + GetMeshWristChildBoneRefTransform(bRight, EHandKeypoint::LittleMetacarpal) + }; + FTransform LittleProximalTransform{ + JointRotations[LittleFingerLittle][LittleProximalJointLittle], + JointLocations[LittleFingerLittle][LittleProximalJointLittle] + }; + FTransform LittleIntermediateTransform{ + JointRotations[LittleFingerLittle][LittleIntermediateJointLittle], + JointLocations[LittleFingerLittle][LittleIntermediateJointLittle] + }; + FTransform LittleDistalTransform{ + JointRotations[LittleFingerLittle][LittleDistalJointLittle], + JointLocations[LittleFingerLittle][LittleDistalJointLittle] + }; + FTransform LittleTipTransform{ + JointRotations[LittleFingerLittle][LittleTipJointLittle], + JointLocations[LittleFingerLittle][LittleTipJointLittle] + }; + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::LittleMetacarpal, + MoveTemp(LittleMetacarpalTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::LittleProximal, + MoveTemp(LittleProximalTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::LittleIntermediate, + MoveTemp(LittleIntermediateTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::LittleDistal, + MoveTemp(LittleDistalTransform), WristTransform)) + { + return false; + } + + if (!UpdateSGJointData( + OutHandState, EHandKeypoint::LittleTip, + MoveTemp(LittleTipTransform), WristTransform)) + { + return false; + } + + return true; +} + +bool FSGXRTracker::FImpl::UpdateSGHandState(const bool bRight, FSGXRHandState& OutHandState) const +{ + const USGHandPose* HandPose{GetHandPose(bRight)}; + if (!IsValid(HandPose)) + { + return false; + } + + OutHandState.bHasReceivedJointPoses = true; + OutHandState.bTracked = true; + + const TArray> JointLocations{HandPose->GetJointPositions()}; + const TArray> JointRotations{HandPose->GetJointRotationsQ()}; + + FTransform WristTransform; + const bool bGotWristTransform = GetWristTransform(bRight, WristTransform); + + /// NOTE + // Even if we fail to get the wrist transform, the SenseGlove data needs to make it to the FXRMotionControllerData! + // So, we just ignore the bGotWristTransform results! Otherwise, even if bFallbackToHandTrackingIfNoGloveDetected + // is disabled it will output the hand-tracking data. + (void) bGotWristTransform; + + if (!UpdateSGWristJointData(OutHandState, WristTransform)) + { + return false; + } + + if (!UpdateSGPalmJointData(OutHandState, bRight, WristTransform)) + { + return false; + } + + if (!UpdateSGThumbJointData(OutHandState, + JointLocations, JointRotations, + WristTransform)) + { + return false; + } + + if (!UpdateSGIndexJointData(OutHandState, bRight, + JointLocations, JointRotations, + WristTransform)) + { + return false; + } + + if (!UpdateSGMiddleJointData(OutHandState, bRight, + JointLocations, JointRotations, + WristTransform)) + { + return false; + } + + if (!UpdateSGRingJointData(OutHandState, bRight, + JointLocations, JointRotations, + WristTransform)) + { + return false; + } + + if (!UpdateSGLittleJointData(OutHandState, bRight, + JointLocations, JointRotations, + WristTransform)) + { + return false; + } + + return true; +} + +void FSGXRTracker::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SenseGloveTracking.cpp b/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SenseGloveTracking.cpp new file mode 100644 index 0000000..c6843fe --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SenseGloveTracking.cpp @@ -0,0 +1,42 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveTracking.h" + +#include "Modules/ModuleManager.h" + +#include "SenseGloveTrackingModule.h" + +IMPLEMENT_MODULE(FSenseGloveTrackingModule, SenseGloveTracking) \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SenseGloveTracking.h b/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SenseGloveTracking.h new file mode 100644 index 0000000..a30ce66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SenseGloveTracking.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SenseGloveTrackingModule.cpp b/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SenseGloveTrackingModule.cpp new file mode 100644 index 0000000..1eb838c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SenseGloveTrackingModule.cpp @@ -0,0 +1,183 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveTrackingModule.h" + +#include "Framework/Application/SlateApplication.h" + +#include "SGLog/SGLog.h" +#include "SGTracking/SGXRTracker.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveTrackingModule" + +struct FSenseGloveTrackingModule::FImpl +{ + /************************ + * Member variables + ************************/ + + TSharedPtr InputDevice; + + /************************ + * Owner object + ************************/ + + FSenseGloveTrackingModule* Owner; + + /************************ + * Constructor / Destructor + ************************/ + + explicit FImpl(FSenseGloveTrackingModule* InOwner); + ~FImpl(); + + /************************ + * Default copy constructor & copy assignment operator + ************************/ + + FImpl(const FImpl& Rhs) = default; + FImpl& operator=(const FImpl& Rhs) = default; +}; + + +FSenseGloveTrackingModule::FSenseGloveTrackingModule() + : IInputDeviceModule(), + Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) +{ +} + +FSenseGloveTrackingModule::FSenseGloveTrackingModule(const FSenseGloveTrackingModule& Rhs) + : IInputDeviceModule(Rhs), + Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) +{ + Pimpl->Owner = this; +} + +FSenseGloveTrackingModule::FSenseGloveTrackingModule(FSenseGloveTrackingModule&& Rhs) SG_NOEXCEPT = default; + +FSenseGloveTrackingModule::~FSenseGloveTrackingModule() = default; + +FSenseGloveTrackingModule& FSenseGloveTrackingModule::operator=(const FSenseGloveTrackingModule& Rhs) +{ + IInputDeviceModule::operator=(Rhs); + *Pimpl = *Rhs.Pimpl; + Pimpl->Owner = this; + return *this; +} + +FSenseGloveTrackingModule& FSenseGloveTrackingModule::operator=(FSenseGloveTrackingModule&& Rhs) SG_NOEXCEPT = default; + +void FSenseGloveTrackingModule::StartupModule() +{ + SGLOG("Starting up SenseGloveTracking module..."); + + IInputDeviceModule::StartupModule(); + + /// HACK! + // Generic Application might not be instantiated at this point so we create the input device with a dummy message + // handler. When the Generic Application creates the input device it passes a valid message handler to it which is + // further on used for all the controller events. This hack fixes issues caused by using a custom input device + // before the Generic Application has instantiated it. Eg. within BeginPlay(). + // This also fixes the warnings that pop up on the custom input keys when the blueprint loads. Those warnings are + // caused because Unreal loads the Blueprints before the input device has been instantiated and has added its keys, + // thus leading Unreal to believe that those keys don't exist. This hack causes an earlier instantiation of the + // input device, and consequently, the custom keys. + TSharedPtr DummyMessageHandler(new FGenericApplicationMessageHandler()); + CreateInputDevice(DummyMessageHandler.ToSharedRef()); +} + +void FSenseGloveTrackingModule::PreUnloadCallback() +{ + SGLOG("Unloading SenseGloveTracking module..."); + + IInputDeviceModule::PreUnloadCallback(); +} + +void FSenseGloveTrackingModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveTracking module has succeeded!"); + + IInputDeviceModule::PostLoadCallback(); +} + +void FSenseGloveTrackingModule::ShutdownModule() +{ + SGLOG("Shutting down SenseGloveTracking module..."); + + IInputDeviceModule::ShutdownModule(); +} + +TSharedPtr FSenseGloveTrackingModule::CreateInputDevice( + const TSharedRef& InMessageHandler) +{ + SGLOG("Creating the SenseGloveTracking input device..."); + + if (!Pimpl->InputDevice.IsValid()) + { + TSharedPtr HandTrackingInputDevice(new FSGXRTracker(InMessageHandler)); + Pimpl->InputDevice = HandTrackingInputDevice; + } + else + { + Pimpl->InputDevice.Get()->SetMessageHandler(InMessageHandler); + } + + return Pimpl->InputDevice; +} + +TSharedPtr FSenseGloveTrackingModule::GetInputDevice() +{ + if (!Pimpl->InputDevice.IsValid()) + { + CreateInputDevice(FSlateApplication::Get().GetPlatformApplication()->GetMessageHandler()); + } + + return Pimpl->InputDevice; +} + +FSenseGloveTrackingModule::FImpl::FImpl(FSenseGloveTrackingModule* InOwner) + : InputDevice(nullptr), + Owner(InOwner) +{ +} + +FSenseGloveTrackingModule::FImpl::~FImpl() = default; + +void FSenseGloveTrackingModule::FImplDeleter::operator()(const FImpl* P) const +{ + delete P; +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SenseGloveTrackingModule.h b/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SenseGloveTrackingModule.h new file mode 100644 index 0000000..f07535e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTracking/Private/SenseGloveTrackingModule.h @@ -0,0 +1,116 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "IInputDeviceModule.h" +#include "Templates/UniquePtr.h" + +#include "SGBuildHacks/SGPlatform.h" + +#define LOCTEXT_NAMESPACE "SenseGloveTracking" + +class FSenseGloveTrackingModule : public IInputDeviceModule +{ +public: + static FORCEINLINE FSenseGloveTrackingModule& Get() + { + return FModuleManager::LoadModuleChecked("SenseGloveTracking"); + } + + static FORCEINLINE bool IsAvailable() + { + return FModuleManager::Get().IsModuleLoaded("SenseGloveTracking"); + } + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +public: + /** + * The default constructor. + */ + FSenseGloveTrackingModule(); + +public: + /** + * The copy constructor. + */ + FSenseGloveTrackingModule(const FSenseGloveTrackingModule& Rhs); + + /** + * The move constructor. + */ + FSenseGloveTrackingModule(FSenseGloveTrackingModule&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSenseGloveTrackingModule() override; + +public: + /** + * The copy assignment operator. + */ + FSenseGloveTrackingModule& operator=(const FSenseGloveTrackingModule& Rhs); + + /** + * The move assignment operator. + */ + FSenseGloveTrackingModule& operator=(FSenseGloveTrackingModule&& Rhs) SG_NOEXCEPT; + +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; + +public: + virtual TSharedPtr CreateInputDevice( + const TSharedRef& InMessageHandler) override; + + virtual TSharedPtr GetInputDevice(); +}; + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTracking/Public/SGTracking/SGGloveTracker.h b/Plugins/SenseGlove/Source/SenseGloveTracking/Public/SGTracking/SGGloveTracker.h new file mode 100644 index 0000000..af19bfb --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTracking/Public/SGTracking/SGGloveTracker.h @@ -0,0 +1,117 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Subsystems/WorldSubsystem.h" +#include "Templates/UniquePtr.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +#include "SGCore/SGHapticGlove.h" + +#include "SGGloveTracker.generated.h" + +UCLASS() +class SENSEGLOVETRACKING_API USGGloveTracker : public UWorldSubsystem +{ + GENERATED_BODY() + +public: + static USGGloveTracker* GetInstance(const UObject* WorldContextObject = nullptr); + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +private: + UPROPERTY(Transient) + USGHapticGlove* LeftGlove; + + UPROPERTY(Transient) + USGHapticGlove* RightGlove; + +private: + USGGloveTracker(); + +public: + FORCEINLINE USGHapticGlove* GetGlove(const bool bRight) const + { + return bRight ? RightGlove : LeftGlove; + } + + FORCEINLINE USGHapticGlove* GetLeftGlove() const + { + return LeftGlove; + } + + FORCEINLINE USGHapticGlove* GetRightGlove() const + { + return RightGlove; + } + + FORCEINLINE bool IsGloveConnected(const bool bRight) const + { + return IsValid(GetGlove(bRight)); + } + + FORCEINLINE bool IsLeftGloveConnected() const + { + return IsValid(GetLeftGlove()); + } + + FORCEINLINE bool IsRightGloveConnected() const + { + return IsValid(GetRightGlove()); + } + + FORCEINLINE bool IsAnyGloveConnected() const + { + return IsLeftGloveConnected() || IsRightGloveConnected(); + } + +public: + virtual bool ShouldCreateSubsystem(UObject* Outer) const override; + + virtual void Initialize(FSubsystemCollectionBase& Collection) override; + virtual void Deinitialize() override; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTracking/Public/SGTracking/SGHMDTracker.h b/Plugins/SenseGlove/Source/SenseGloveTracking/Public/SGTracking/SGHMDTracker.h new file mode 100644 index 0000000..7d2000d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTracking/Public/SGTracking/SGHMDTracker.h @@ -0,0 +1,109 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" +#include "UObject/NameTypes.h" +#include "UObject/ObjectMacros.h" + +#include "SGTypes/SGTrackingTypes.h" + +#include "SGHMDTracker.generated.h" + +/** + * + */ +USTRUCT() +struct SENSEGLOVETRACKING_API FSGHMDTracker +{ + GENERATED_BODY() + +public: + static FName GetDeviceName(); + + /** + * Checks whether the HMD device is Meta Quest 2, or not. + */ + static bool IsMetaQuest2(); + + /** + * Checks whether the HMD device is Meta Quest Pro, or not. + */ + static bool IsMetaQuestPro(); + + /** + * Checks whether the HMD device is Meta Quest 3, or not. + */ + static bool IsMetaQuest3(); + + FORCEINLINE static bool IsAMetaQuestDevice() + { + return IsMetaQuest2() || IsMetaQuestPro() || IsMetaQuest3(); + } + + /** + * Checks whether the HMD device is HTC VIVE Pro, or not. + */ + static bool IsHtcVivePro(); + + /** + * Checks whether the HMD device is HTC VIVE Focus 3, or not. + * + * @remark At the moment, VIVE Focus 3 cannot be distinguished from VIVE XR Elite, so when IsHtcViveFocus3 returns + * true, IsHtcViveXRElite will return true as well; thus we cannot know for sure which headset we are running on. + */ + static bool IsHtcViveFocus3(); + + /** + * Checks whether the HMD device is HTC VIVE XR Elite, or not. + * + * @remark At the moment, VIVE Focus 3 cannot be distinguished from VIVE XR Elite, so when IsHtcViveXRElite returns + * true, IsHtcViveFocus3 will return true as well; thus we cannot know for sure which headset we are running on. + */ + static bool IsHtcViveXRElite(); + + /** + * Checks whether the HMD device is HTC VIVE Focus Vision, or not. + */ + static bool IsHtcViveFocusVision(); + + FORCEINLINE static bool IsAHtcViveDevice() + { + return IsHtcVivePro() || IsHtcViveFocus3() || IsHtcViveXRElite() || IsHtcViveFocusVision(); + } + + static ESGHeadMountedDisplayDevice GetDeviceType(); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTracking/Public/SGTracking/SGXRHandState.h b/Plugins/SenseGlove/Source/SenseGloveTracking/Public/SGTracking/SGXRHandState.h new file mode 100644 index 0000000..6bbdfd8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTracking/Public/SGTracking/SGXRHandState.h @@ -0,0 +1,72 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HeadMountedDisplayTypes.h" +#include "IOpenXRExtensionPlugin.h" +#include "Math/MathFwd.h" +#include "Templates/UnrealTemplate.h" + +struct SENSEGLOVETRACKING_API FSGXRHandState final : public FNoncopyable +{ +public: + XrHandTrackerEXT HandTracker; + + XrHandJointLocationEXT JointLocations[XR_HAND_JOINT_COUNT_EXT]; + XrHandJointVelocityEXT JointVelocities[XR_HAND_JOINT_COUNT_EXT]; + + XrHandJointVelocitiesEXT Velocities; + XrHandJointLocationsEXT Locations; + + // Transforms are cached in Unreal Tracking Space. + FTransform KeypointTransforms[EHandKeypointCount]; + + float Radii[EHandKeypointCount]; + + // true if this hand has ever been tracked, and therefore its poses are valid. + bool bHasReceivedJointPoses; + + // true if tracked right now. + bool bTracked; + +public: + FSGXRHandState(); + virtual ~FSGXRHandState(); + +public: + bool GetTransform(EHandKeypoint Keypoint, FTransform& OutTransform) const; + const FTransform& GetTransform(EHandKeypoint Keypoint) const; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTracking/Public/SGTracking/SGXRTracker.h b/Plugins/SenseGlove/Source/SenseGloveTracking/Public/SGTracking/SGXRTracker.h new file mode 100644 index 0000000..4c7aca1 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTracking/Public/SGTracking/SGXRTracker.h @@ -0,0 +1,185 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HeadMountedDisplayTypes.h" +#include "IHandTracker.h" +#include "IInputDevice.h" +#include "IOpenXRExtensionPlugin.h" +#include "Math/MathFwd.h" +#include "Runtime/Launch/Resources/Version.h" +#include "Templates/UniquePtr.h" +#include "UObject/NameTypes.h" +#include "XRMotionControllerBase.h" + +#include "SGBuildHacks/SGPlatform.h" + +struct SENSEGLOVETRACKING_API FSGXRHandState; + +class SENSEGLOVETRACKING_API FSGXRTracker final : public IOpenXRExtensionPlugin, + public IInputDevice, + public FXRMotionControllerBase, + public IHandTracker +{ +public: + static bool GetMotionControllerData( + UObject* WorldContextObject, + EControllerHand Hand, + FXRMotionControllerData& OutMotionControllerData); + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + static bool GetMotionControllerState( + UObject* WorldContextObject, + EXRSpaceType XRSpaceType, EControllerHand Hand, EXRControllerPoseType XRControllerPoseType, + FXRMotionControllerState& OutMotionControllerState); + static bool GetHandTrackingState( + UObject* WorldContextObject, + EXRSpaceType XRSpaceType, EControllerHand Hand, + FXRHandTrackingState& OutHandTrackingState); +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + +private: + struct FImpl; + + struct FImplDeleter + { + void operator()(const FImpl* P) const; + }; + + TUniquePtr Pimpl; + FImplDeleter PimplDeleter; + +private: + FSGXRTracker() = delete; + +public: + FSGXRTracker(const TSharedRef& InMessageHandler); + +public: + /** + * The copy constructor. + */ + FSGXRTracker(const FSGXRTracker& Rhs) = delete; + + /** + * The move constructor. + */ + FSGXRTracker(FSGXRTracker&& Rhs) SG_NOEXCEPT; + +public: + /** + * The destructor. + */ + virtual ~FSGXRTracker() override; + +public: + /** + * The copy assignment operator. + */ + FSGXRTracker& operator=(const FSGXRTracker& Rhs) = delete; + + /** + * The move assignment operator. + */ + FSGXRTracker& operator=(FSGXRTracker&& Rhs) SG_NOEXCEPT; + +public: + bool IsHandTrackingSupportedByDevice() const; + + const FSGXRHandState& GetLeftHandState() const; + const FSGXRHandState& GetRightHandState() const; + +public: + // The IOpenXRExtensionPlugin interface. + + virtual FString GetDisplayName() override; + virtual bool GetRequiredExtensions(TArray& OutExtensions) override; + virtual const void* OnGetSystem(XrInstance InInstance, const void* InNext) override; + virtual const void* OnCreateSession(XrInstance InInstance, XrSystemId InSystem, const void* InNext) override; + virtual const void* OnBeginSession(XrSession InSession, const void* InNext) override; + virtual void UpdateDeviceLocations(XrSession InSession, XrTime DisplayTime, XrSpace TrackingSpace) override; + +public: + // The IMotionController interface. + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 3 + virtual bool GetControllerOrientationAndPosition(const int32 ControllerIndex, const FName MotionSource, + FRotator& OutOrientation, FVector& OutPosition, + float WorldToMetersScale) const override; + virtual ETrackingStatus GetControllerTrackingStatus(const int32 ControllerIndex, + const FName MotionSource) const override; +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 3 */ + virtual bool GetControllerOrientationAndPosition(const int32 ControllerIndex, const EControllerHand DeviceHand, + FRotator& OutOrientation, FVector& OutPosition, + float WorldToMetersScale) const override; + virtual ETrackingStatus GetControllerTrackingStatus(const int32 ControllerIndex, + const EControllerHand DeviceHand) const override; +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 3 */ + virtual FName GetMotionControllerDeviceTypeName() const override; + virtual void EnumerateSources(TArray& SourcesOut) const override; + +public: + // The IInputDevice interface. + + virtual void Tick(float DeltaTime) override; + virtual void SendControllerEvents() override; + virtual void SetMessageHandler(const TSharedRef& InMessageHandler) override; + virtual bool Exec(UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& Ar) override; + virtual void SetChannelValue(int32 ControllerId, FForceFeedbackChannelType ChannelType, float Value) override; + virtual void SetChannelValues(int32 ControllerId, const FForceFeedbackValues& Values) override; + virtual bool SupportsForceFeedback(int32 ControllerId) override; + virtual bool IsGamepadAttached() const override; + +public: + // The IHandTracker interface. + + virtual FName GetHandTrackerDeviceTypeName() const override; + virtual bool IsHandTrackingStateValid() const override; + virtual bool GetKeypointState( + EControllerHand Hand, + EHandKeypoint Keypoint, FTransform& OutTransform, float& OutRadius) const override; + +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + virtual bool GetAllKeypointStates( + EControllerHand Hand, + TArray& OutPositions, TArray& OutRotations, TArray& OutRadii, + bool& OutIsTracked) const override; +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + virtual bool GetAllKeypointStates( + EControllerHand Hand, + TArray& OutPositions, TArray& OutRotations, TArray& OutRadii) const override; +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTracking/SenseGloveTracking.Build.cs b/Plugins/SenseGlove/Source/SenseGloveTracking/SenseGloveTracking.Build.cs new file mode 100644 index 0000000..44764c2 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTracking/SenseGloveTracking.Build.cs @@ -0,0 +1,108 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using System.IO; +using UnrealBuildTool; + +public class SenseGloveTracking : ModuleRules +{ + public SenseGloveTracking(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "ApplicationCore", + "Core", + "CoreUObject", + "Engine", + "HeadMountedDisplay", + "InputCore", + "InputDevice", + "OpenXRHMD", + "OpenXRInput", + // NOTE + // Only UE 5.3+ provides the XRBase plugin. +#if UE_5_3_OR_LATER + "XRBase", +#else + "OpenXR", +#endif + "Slate", + "SlateCore", + } + ); + +#if ! UE_5_4_OR_LATER + string OpenXRHMDPrivateIncludeDir = Path.GetFullPath(Target.RelativeEnginePath); + OpenXRHMDPrivateIncludeDir = Path.Combine(OpenXRHMDPrivateIncludeDir, "Plugins"); + OpenXRHMDPrivateIncludeDir = Path.Combine(OpenXRHMDPrivateIncludeDir, "Runtime"); + OpenXRHMDPrivateIncludeDir = Path.Combine(OpenXRHMDPrivateIncludeDir, "OpenXR"); + OpenXRHMDPrivateIncludeDir = Path.Combine(OpenXRHMDPrivateIncludeDir, "Source"); + OpenXRHMDPrivateIncludeDir = Path.Combine(OpenXRHMDPrivateIncludeDir, "OpenXRHMD"); + OpenXRHMDPrivateIncludeDir = Path.Combine(OpenXRHMDPrivateIncludeDir, "Private"); + + PrivateIncludePaths.AddRange( + new string[] + { + OpenXRHMDPrivateIncludeDir, + } + ); +#endif + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveBackend", + "SenseGloveCore", + "SenseGloveLog", + "SenseGloveSettings", + "SenseGloveTypes", + "SenseGloveUtils", + } + ); + + PrivateIncludePathModuleNames.AddRange( + new string[] + { + "SenseGloveBuildHacks", + } + ); + + AddEngineThirdPartyPrivateStaticDependencies(Target, "OpenXR"); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SGTrackingKismet/SGGloveTrackerKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SGTrackingKismet/SGGloveTrackerKismetLibrary.cpp new file mode 100644 index 0000000..2057ebd --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SGTrackingKismet/SGGloveTrackerKismetLibrary.cpp @@ -0,0 +1,79 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGTrackingKismet/SGGloveTrackerKismetLibrary.h" + +#include "SGCore/SGHapticGlove.h" +#include "SGTracking/SGGloveTracker.h" + +USGGloveTracker* USGGloveTrackerKismetLibrary::GetInstance(UObject* WorldContextObject) +{ + return USGGloveTracker::GetInstance(WorldContextObject); +} + +USGHapticGlove* USGGloveTrackerKismetLibrary::GetGlove(const USGGloveTracker* GloveTracker, const bool bRight) +{ + return GloveTracker->GetGlove(bRight); +} + +USGHapticGlove* USGGloveTrackerKismetLibrary::GetLeftGlove(const USGGloveTracker* GloveTracker) +{ + return GloveTracker->GetLeftGlove(); +} + +USGHapticGlove* USGGloveTrackerKismetLibrary::GetRightGlove(const USGGloveTracker* GloveTracker) +{ + return GloveTracker->GetRightGlove(); +} + +bool USGGloveTrackerKismetLibrary::IsGloveConnected(const USGGloveTracker* GloveTracker, const bool bRight) +{ + return GloveTracker->IsGloveConnected(bRight); +} + +bool USGGloveTrackerKismetLibrary::IsLeftGloveConnected(const USGGloveTracker* GloveTracker) +{ + return GloveTracker->IsLeftGloveConnected(); +} + +bool USGGloveTrackerKismetLibrary::IsRightGloveConnected(const USGGloveTracker* GloveTracker) +{ + return GloveTracker->IsRightGloveConnected(); +} + +bool USGGloveTrackerKismetLibrary::IsAnyGloveConnected(const USGGloveTracker* GloveTracker) +{ + return GloveTracker->IsAnyGloveConnected(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SGTrackingKismet/SGHMDTrackerKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SGTrackingKismet/SGHMDTrackerKismetLibrary.cpp new file mode 100644 index 0000000..3874c89 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SGTrackingKismet/SGHMDTrackerKismetLibrary.cpp @@ -0,0 +1,78 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGTrackingKismet/SGHMDTrackerKismetLibrary.h" + +#include "SGTracking/SGHMDTracker.h" + +FName USGHMDTrackerKismetLibrary::GetDeviceName() +{ + return FSGHMDTracker::GetDeviceName(); +} + +bool USGHMDTrackerKismetLibrary::IsMetaQuest2() +{ + return FSGHMDTracker::IsMetaQuest2(); +} + +bool USGHMDTrackerKismetLibrary::IsMetaQuestPro() +{ + return FSGHMDTracker::IsMetaQuestPro(); +} + +bool USGHMDTrackerKismetLibrary::IsMetaQuest3() +{ + return FSGHMDTracker::IsMetaQuest3(); +} + +bool USGHMDTrackerKismetLibrary::IsHtcVivePro() +{ + return FSGHMDTracker::IsHtcVivePro(); +} + +bool USGHMDTrackerKismetLibrary::IsHtcViveFocus3() +{ + return FSGHMDTracker::IsHtcViveFocus3(); +} + +bool USGHMDTrackerKismetLibrary::IsHtcViveXRElite() +{ + return FSGHMDTracker::IsHtcViveXRElite(); +} + +ESGHeadMountedDisplayDevice USGHMDTrackerKismetLibrary::GetDeviceType() +{ + return FSGHMDTracker::GetDeviceType(); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SGTrackingKismet/SGXRTrackerKismetLibrary.cpp b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SGTrackingKismet/SGXRTrackerKismetLibrary.cpp new file mode 100644 index 0000000..b5cf88a --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SGTrackingKismet/SGXRTrackerKismetLibrary.cpp @@ -0,0 +1,48 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGTrackingKismet/SGXRTrackerKismetLibrary.h" + +#include "UObject/Object.h" + +#include "SGTracking/SGXRTracker.h" + +bool USGXRTrackerKismetLibrary::GetMotionControllerData( + UObject* WorldContextObject, const EControllerHand Hand, FXRMotionControllerData& OutMotionControllerData) +{ + PRAGMA_DISABLE_DEPRECATION_WARNINGS + return FSGXRTracker::GetMotionControllerData(WorldContextObject, Hand, OutMotionControllerData); + PRAGMA_ENABLE_DEPRECATION_WARNINGS +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SenseGloveTrackingKismet.cpp b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SenseGloveTrackingKismet.cpp new file mode 100644 index 0000000..72fc04b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SenseGloveTrackingKismet.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveTrackingKismet.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveTrackingKismetModule.h" + +IMPLEMENT_MODULE(FSenseGloveTrackingKismetModule, SenseGloveTrackingKismet) diff --git a/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SenseGloveTrackingKismet.h b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SenseGloveTrackingKismet.h new file mode 100644 index 0000000..a30ce66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SenseGloveTrackingKismet.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SenseGloveTrackingKismetModule.cpp b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SenseGloveTrackingKismetModule.cpp new file mode 100644 index 0000000..ff45ac5 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SenseGloveTrackingKismetModule.cpp @@ -0,0 +1,62 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveTrackingKismetModule.h" + +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveTrackingKismetModule" + +void FSenseGloveTrackingKismetModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveTrackingKismet module..."); +} + +void FSenseGloveTrackingKismetModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveTrackingKismet module..."); +} + +void FSenseGloveTrackingKismetModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveTrackingKismet module has succeeded!"); +} + +void FSenseGloveTrackingKismetModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveTrackingKismet module..."); +} + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SenseGloveTrackingKismetModule.h b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SenseGloveTrackingKismetModule.h new file mode 100644 index 0000000..ce1a942 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Private/SenseGloveTrackingKismetModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveTrackingKismet" + +class FSenseGloveTrackingKismetModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Public/SGTrackingKismet/SGGloveTrackerKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Public/SGTrackingKismet/SGGloveTrackerKismetLibrary.h new file mode 100644 index 0000000..cb2650d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Public/SGTrackingKismet/SGGloveTrackerKismetLibrary.h @@ -0,0 +1,75 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "SGKismet/SGBlueprintFunctionLibrary.h" + +#include "SGGloveTrackerKismetLibrary.generated.h" + +class USGGloveTracker; +class USGHapticGlove; + +UCLASS(meta=(ScriptName = "SenseGloveTrackerKismetLibrary")) +class SENSEGLOVETRACKINGKISMET_API USGGloveTrackerKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | Glove Tracker", + meta=(WorldContext="WorldContextObject")) + static USGGloveTracker* GetInstance(UObject* WorldContextObject); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Tracking | Glove Tracker") + static USGHapticGlove* GetGlove(const USGGloveTracker* GloveTracker, const bool bRight); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Tracking | Glove Tracker") + static USGHapticGlove* GetLeftGlove(const USGGloveTracker* GloveTracker); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Tracking | Glove Tracker") + static USGHapticGlove* GetRightGlove(const USGGloveTracker* GloveTracker); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Tracking | Glove Tracker") + static bool IsGloveConnected(const USGGloveTracker* GloveTracker, const bool bRight); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Tracking | Glove Tracker") + static bool IsLeftGloveConnected(const USGGloveTracker* GloveTracker); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Tracking | Glove Tracker") + static bool IsRightGloveConnected(const USGGloveTracker* GloveTracker); + + UFUNCTION(BlueprintPure, Category="SenseGlove | Tracking | Glove Tracker") + static bool IsAnyGloveConnected(const USGGloveTracker* GloveTracker); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Public/SGTrackingKismet/SGHMDTrackerKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Public/SGTrackingKismet/SGHMDTrackerKismetLibrary.h new file mode 100644 index 0000000..02e6c21 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Public/SGTrackingKismet/SGHMDTrackerKismetLibrary.h @@ -0,0 +1,98 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "UObject/NameTypes.h" + +#include "SGKismet/SGBlueprintFunctionLibrary.h" +#include "SGTypes/SGTrackingTypes.h" + +#include "SGHMDTrackerKismetLibrary.generated.h" + +UCLASS(meta=(ScriptName = "SenseGloveHMDTrackerKismetLibrary")) +class SENSEGLOVETRACKINGKISMET_API USGHMDTrackerKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | HMD Tracker") + static FName GetDeviceName(); + + /** + * Checks whether the HMD device is Meta Quest 2, or not. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | HMD Tracker") + static bool IsMetaQuest2(); + + /** + * Checks whether the HMD device is Meta Quest Pro, or not. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | HMD Tracker") + static bool IsMetaQuestPro(); + + /** + * Checks whether the HMD device is Meta Quest 3, or not. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | HMD Tracker") + static bool IsMetaQuest3(); + + /** + * Checks whether the HMD device is HTC VIVE Pro, or not. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | HMD Tracker") + static bool IsHtcVivePro(); + + /** + * Checks whether the HMD device is HTC VIVE Focus 3, or not. + * + * @remark At the moment, VIVE Focus 3 cannot be distinguished from VIVE XR Elite, so when IsHtcViveFocus3 returns + * true, IsHtcViveXRElite will return true as well; thus we cannot know for sure which headset we are running on. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | HMD Tracker") + static bool IsHtcViveFocus3(); + + /** + * Checks whether the HMD device is HTC VIVE XR Elite, or not. + * + * @remark At the moment, VIVE Focus 3 cannot be distinguished from VIVE XR Elite, so when IsHtcViveXRElite returns + * true, IsHtcViveFocus3 will return true as well; thus we cannot know for sure which headset we are running on. + */ + UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | HMD Tracker") + static bool IsHtcViveXRElite(); + + UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | HMD Tracker") + static ESGHeadMountedDisplayDevice GetDeviceType(); +}; diff --git a/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Public/SGTrackingKismet/SGXRTrackerKismetLibrary.h b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Public/SGTrackingKismet/SGXRTrackerKismetLibrary.h new file mode 100644 index 0000000..94b3a9d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/Public/SGTrackingKismet/SGXRTrackerKismetLibrary.h @@ -0,0 +1,60 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HeadMountedDisplayTypes.h" +#include "InputCoreTypes.h" +#include "UObject/ObjectMacros.h" + +#include "SGKismet/SGBlueprintFunctionLibrary.h" + +#include "SGXRTrackerKismetLibrary.generated.h" + +class UObject; + +UCLASS(meta=(ScriptName = "SenseGloveXRTrackerKismetLibrary")) +class SENSEGLOVETRACKINGKISMET_API USGXRTrackerKismetLibrary final : public USGBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, Category="SenseGlove | Tracking | XR Tracker", + meta=(WorldContext="WorldContextObject")) + static bool GetMotionControllerData( + UObject* WorldContextObject, + EControllerHand Hand, + FXRMotionControllerData& OutMotionControllerData); +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/SenseGloveTrackingKismet.Build.cs b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/SenseGloveTrackingKismet.Build.cs new file mode 100644 index 0000000..1ea98ed --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTrackingKismet/SenseGloveTrackingKismet.Build.cs @@ -0,0 +1,76 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGloveTrackingKismet : ModuleRules +{ + public SenseGloveTrackingKismet(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + "HeadMountedDisplay", + "InputCore", + "InputDevice", + "OpenXRHMD", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveCore", + "SenseGloveLog", + "SenseGloveKismet", + "SenseGloveTracking", + "SenseGloveTypes", + } + ); + + PrivateIncludePathModuleNames.AddRange( + new string[] + { + "SenseGloveBuildHacks", + } + ); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGCoreTypes.cpp b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGCoreTypes.cpp new file mode 100644 index 0000000..eb6dac2 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGCoreTypes.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGTypes/SGCoreTypes.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGDebugTypes.cpp b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGDebugTypes.cpp new file mode 100644 index 0000000..5c708ad --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGDebugTypes.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGTypes/SGDebugTypes.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGFloatArray.cpp b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGFloatArray.cpp new file mode 100644 index 0000000..64a423b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGFloatArray.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGTypes/SGFloatArray.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGNameArray.cpp b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGNameArray.cpp new file mode 100644 index 0000000..07fb65b --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGNameArray.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGTypes/SGNameArray.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGQuatArray.cpp b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGQuatArray.cpp new file mode 100644 index 0000000..e38458c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGQuatArray.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGTypes/SGQuatArray.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGRotatorArray.cpp b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGRotatorArray.cpp new file mode 100644 index 0000000..ccfba21 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGRotatorArray.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGTypes/SGRotatorArray.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGTrackingTypes.cpp b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGTrackingTypes.cpp new file mode 100644 index 0000000..246219e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGTrackingTypes.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGTypes/SGTrackingTypes.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGTypes.cpp b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGTypes.cpp new file mode 100644 index 0000000..0e9740f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGTypes.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGTypes/SGTypes.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGVectorArray.cpp b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGVectorArray.cpp new file mode 100644 index 0000000..0decc2c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SGTypes/SGVectorArray.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGTypes/SGVectorArray.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SenseGloveTypes.cpp b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SenseGloveTypes.cpp new file mode 100644 index 0000000..3b9681c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SenseGloveTypes.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveTypes.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveTypesModule.h" + +IMPLEMENT_MODULE(FSenseGloveTypesModule, SenseGloveTypes) diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SenseGloveTypes.h b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SenseGloveTypes.h new file mode 100644 index 0000000..ab121d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SenseGloveTypes.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SenseGloveTypesModule.cpp b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SenseGloveTypesModule.cpp new file mode 100644 index 0000000..e957353 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SenseGloveTypesModule.cpp @@ -0,0 +1,61 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveTypesModule.h" +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveTypesModule" + +void FSenseGloveTypesModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveTypes module..."); +} + +void FSenseGloveTypesModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveTypes module..."); +} + +void FSenseGloveTypesModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveTypes module has succeeded!"); +} + +void FSenseGloveTypesModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveTypes module..."); +} + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SenseGloveTypesModule.h b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SenseGloveTypesModule.h new file mode 100644 index 0000000..4ba8a68 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Private/SenseGloveTypesModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveTypes" + +class FSenseGloveTypesModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGCoreTypes.h b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGCoreTypes.h new file mode 100644 index 0000000..7fe1867 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGCoreTypes.h @@ -0,0 +1,665 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" +#include "UObject/ObjectMacros.h" + +UENUM(BlueprintType) +enum class ESGBackendType : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* Back-end info comes from shared memory on the device. */ + SharedMemory UMETA(DisplayName = "Shared Memory"), +}; + +/* Connection type of this device, as detected by the SGConnect library. */ +UENUM(BlueprintType) +enum class ESGConnectionType : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* Could not determine which connection type this SGDevice is using, most likely because it is disconnected. */ + Unknown UMETA(DisplayName = "Unknown"), + + /* USB Serial communication. */ + Serial UMETA(DisplayName = "Serial"), + + /* A bluetooth connection that creates up to two Serial Ports. */ + BluetoothSerial UMETA(DisplayName = "Bluetooth Serial"), + + /* Bluetooth Connection Via Android/Java SDK. */ + BluetoothAndroid UMETA(DisplayName = "Bluetooth Android"), +}; + +/** + * Used to access specific positions from the CV output, which is an array of Vect3D positions. + * @remarks Declared in CVHandOutput.cs because these enums are used to index the jointPositions array in that class. + */ +UENUM(BlueprintType) +enum class ESGCVHandPoints : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* The position of the Wrist as determined by the CV Model. */ + Wrist UMETA(DisplayName = "Wrist"), + + /* The position of the Thumb CMC Joint as determined by the CV Model. */ + ThumbCmc UMETA(DisplayName = "Thumb CMC"), + + /* The position of the Thumb MCP Joint as determined by the CV Model. */ + ThumbMcp UMETA(DisplayName = "Thumb MCP"), + + /* The position of the Thumb IP Joint as determined by the CV Model. */ + ThumbIp UMETA(DisplayName = "Thumb IP"), + + /* The position of the Thumb tip as determined by the CV Model. */ + ThumbTip UMETA(DisplayName = "Thumb Tip"), + + /* The position of the Index MCP Joint as determined by the CV Model. */ + IndexMcp UMETA(DisplayName = "Indexx MCP"), + + /* The position of the Index PIP Joint as determined by the CV Model. */ + IndexPip UMETA(DisplayName = "Index PIP"), + + /* The position of the Index DIP Joint as determined by the CV Model. */ + IndexDip UMETA(DisplayName = "Index DIP"), + + /* The position of the Index fingertip as determined by the CV Model. */ + IndexTip UMETA(DisplayName = "Index Tip"), + + /* The position of the Middle MCP Joint as determined by the CV Model. */ + MiddleMcp UMETA(DisplayName = "Middle MCP"), + + /* The position of the Middle PIP Joint as determined by the CV Model. */ + MiddlePip UMETA(DisplayName = "Middle PIP"), + + /* The position of the Middle DIP Joint as determined by the CV Model. */ + MiddleDip UMETA(DisplayName = "Middle DIP"), + + /* The position of the Middle fingertip as determined by the CV Model. */ + MiddleTip UMETA(DisplayName = "Middle Tip"), + + /* The position of the Ring MCP Joint as determined by the CV Model. */ + RingMcp UMETA(DisplayName = "Ring MCP"), + + /* The position of the Ring PIP Joint as determined by the CV Model. */ + RingPip UMETA(DisplayName = "Ring PIP"), + + /* The position of the Ring DIP Joint as determined by the CV Model. */ + RingDip UMETA(DisplayName = "Ring DIP"), + + /* The position of the Ring fingertip as determined by the CV Model. */ + RingTip UMETA(DisplayName = "Rint Tip"), + + /* The position of the Pinky MCP Joint as determined by the CV Model. */ + PinkyMcp UMETA(DisplayName = "Pinky MCP"), + + /* The position of the Pinky PIP Joint as determined by the CV Model. */ + PinkyPip UMETA(DisplayName = "Pinky PIP"), + + /* The position of the Pinky DIP Joint as determined by the CV Model. */ + PinkyDip UMETA(DisplayName = "Pinky DIP"), + + /* The position of the Pinky fingertip as determined by the CV Model. */ + PinkyTip UMETA(DisplayName = "Pinky Tip"), + + /* Utility enumerator to check if an array contains enough values. */ + All UMETA(DisplayName = "All"), +}; + +/* How much of the CV tracking is being used. Used by other APIs. */ +UENUM(BlueprintType) +enum class ESGCVTrackingDepth : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* No computer-vision is enabled. */ + Disabled UMETA(DisplayName = "Disabled"), + + /* Use CV only for the wrist position/rotation. */ + WristOnly UMETA(DisplayName = "Wrist Only"), + + /* Use CV for both the wrist location and Hand Position. */ + WristAndHandPose UMETA(DisplayName = "Wrist and Hand Pose"), +}; + +/* Specific devices within the SGCore library. */ +UENUM(BlueprintType) +enum class ESGDeviceType : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* This device is not recognized by the Sense Glove API. */ + Unknown UMETA(DisplayName = "Unknown"), + + /* A Device that is in development, with direct access to sensor data and commands. */ + BetaDevice UMETA(DisplayName = "Beta Device"), + + /* An exoskeleton glove that provides force- and haptic feedback. */ + SenseGlove UMETA(DisplayName = "Sense Glove"), + + /* A soft glove with basic tracking, as well as force- and Haptic Feedback. */ + Nova UMETA(DisplayName = "Nova"), + + /* A soft glove with basic tracking, as well as force- and Haptic Feedback. */ + Nova2 UMETA(DisplayName = "Nova 2"), +}; + +/* One of the fingers on the hand. */ +UENUM(BlueprintType) +enum class ESGFinger : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* Responsible for our evolutionary success! */ + Thumb UMETA(DisplayName = "Thumb"), + + /* Used to point at what you want. */ + Index UMETA(DisplayName = "Index"), + + /* On its own, this one is used to indicate frustration. */ + Middle UMETA(DisplayName = "Middle"), + + /* If you like it then you should have put a ___ on it. */ + Ring UMETA(DisplayName = "Ring"), + + /* The little finger. */ + Pinky UMETA(DisplayName = "Pinky"), +}; + +/* Anatomical movements of the finger joints. */ +UENUM(BlueprintType) +enum class ESGFingerMovement : uint8 +{ + None UMETA(DisplayName = "None"), + + /* Flexion of the first finger joint. */ + McpFlexion UMETA(DisplayName = "MCP Flexion"), + + /* Abduction of the first finger joint. */ + McpAbduction UMETA(DisplayName = "MCP Abduction"), + + /* Flexion of the second finger joint. */ + PipFlexion UMETA(DisplayName = "PIP Flexion"), + + /* Flexion of the third finger joint. */ + DipFlexion UMETA(DisplayName = "DIP Flexion"), +}; + +/* How this Sense Glove converts sensor data into a HandPose. */ +UENUM(BlueprintType) +enum class ESGFingerSolver : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* Hand angles are interpolated based on the total flexion / abduction of the exoskeleton. */ + Interpolation UMETA(DisplayName = "Interpolation"), +}; + +/* Different types of Haptic Channels - with different behaviours. */ +UENUM(BlueprintType) +enum class ESGHapticChannelType : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /** + * This type of haptic channel can be constantly overridden. SGConnect will only send a command if a change occurs. + * Ideal for Force-Feedback. + */ + StreamingChannel UMETA(DisplayName = "Streaming Channel"), + + /* These commands must be sent once, after their queue is cleared. */ + FireAndForgetChannel UMETA(DisplayName = "Fire and Forget Channel"), +}; + +/* The Calibration State of this Glove. */ +UENUM(BlueprintType) +enum class ESGHapticGloveCalibrationState : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* No idea what the calibrationState of this glove is... */ + Unknown UMETA(DisplayName = "Unknown"), + + /* One or more sensors still need to move... */ + MoveFingers UMETA(DisplayName = "Move Fingers"), + + /* All sensors have moved. */ + AllSensorsMoved UMETA(DisplayName = "All Sensors Moved"), + + /* Calibration is locked in. Done collecting Data. */ + CalibrationLocked UMETA(DisplayName = "Calibration Locked"), +}; + +/* All of the locations supported by the SenseGlove API. */ +UENUM(BlueprintType) +enum class ESGHapticLocation : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* Unknown location. Calling haptic function(s) with this parameter will not play anything. */ + Unknown UMETA(DisplayName = "Unknown"), + + /* Fingertip of the Thumb. */ + ThumbTip UMETA(DisplayName = "Thumb Tip"), + + /* Fingertip of the Index Finger. */ + IndexTip UMETA(DisplayName = "Index Tip"), + + /* Fingertip of the Middle Finger. */ + MiddleTip UMETA(DisplayName = "Middle Tip"), + + /* Fingertip of the Ring Finger. */ + RingTip UMETA(DisplayName = "Ring Tip"), + + /* Fingertip of the Pinky Finger. */ + PinkyTip UMETA(DisplayName = "Pinky Tip"), + + /* Vibration on the hand palm, close to the index finger. */ + PalmIndexSide UMETA(DisplayName = "Palm Index Side"), + + /* Vibration on the hand palm close to the pinky finger. */ + PalmPinkySide UMETA(DisplayName = "Palm Pinky Side"), + + /* Play this Haptic Effect on the whole hand. For General Hand Feedback. */ + WholeHand UMETA(DisplayName = "Whole Hand"), +}; + +/* Indices to access DeviceList data in Shared Memory. */ +UENUM(BlueprintType) +enum class ESGListFormat : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + Connected UMETA(DisplayName = "Connected"), + PpsGot UMETA(DisplayName = "PPS Got"), + DeviceType UMETA(DisplayName = "Device Type"), + CString UMETA(DisplayName = "C String"), + Address UMETA(DisplayName = "Address"), + ConnectType UMETA(DisplayName = "Connect Type"), + PpsSent UMETA(DisplayName = "PPS Sent"), + All UMETA(DisplayName = "All"), +}; + +/* State of the Nova's sensor Normalization. */ +UENUM(BlueprintType) +enum class ESGNormalizationState : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* Unable to retrieve the state out of our Sensor Data :( */ + Unknown UMETA(DisplayName = "Unknown"), + + /* Developer has asked the glove to send raw data. */ + SendingRawData UMETA(DisplayName = "Sending Raw Data"), + + /* The glove is currently normalizing, but the fingers haven't moved enough. */ + Normalizing_MoveFingers UMETA(DisplayName = "Normalizing: Move Fingers"), + + /* Fires when all fingers have moved enough and you _could_ stop normalization + /// collection. */ + Normalizing_AwaitConfirm UMETA(DisplayName = "Normalizing: Await Confirm"), + + /* Normalization is completed. */ + NormalizationFinished UMETA(DisplayName = "Normalization Finished"), +}; + +/* Used to access a sensor Movement of the Nova_SensorData class. */ +UENUM(BlueprintType) +enum class ESGNovaSensorLocation : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* Sideways motion; finger splay, moving the thumb away from the hand palm. */ + Abduction UMETA(DisplayName = "Abduction"), + + /* Flexion of any sensor. */ + Flexion UMETA(DisplayName = "Flexion"), +}; + +/* Used to access a sensor Movement of the Nova_SensorData class. */ +UENUM(BlueprintType) +enum class ESGNova2SensorLocation : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* Sideways motion; finger splay, moving the thumb away from the hand palm. */ + Abduction UMETA(DisplayName = "Abduction"), + + /* Flexion of any sensor close to the thumb. */ + FlexionProximal UMETA(DisplayName = "Flexion Proximal"), + + /* flexion of any sensor further from the hub. */ + FlexionDistal UMETA(DisplayName = "Flexion Distal"), +}; + +/* Which vibration motors to send vibrations to. */ +UENUM(BlueprintType) +enum class ESGNova2VibroMotor : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* Not sure which motor this is meant for. */ + Unknown UMETA(DisplayName = "Unknown"), + + /* LRA Vibration Motor that is located on the thumb fingertip. */ + ThumbFingertip UMETA(DisplayName = "Thumb Fingertip"), + + /* LRA Vibration Motor that is located on the index fingertip. */ + IndexFingertip UMETA(DisplayName = "Index Fingertip"), + + /* LRA Vibration Motor that is located on the hand palm, roughly at the Index MCP joint. */ + PalmIndexSide UMETA(DisplayName = "Palm Index Side"), + + /* LRA Vibration Motor that is located on the hand palm, roughly at the Pinky MCP joint. */ + PalmPinkySide UMETA(DisplayName = "Palm Pinky Side"), +}; + +/* Order of values as they come in from the Nova. */ +UENUM(BlueprintType) +enum class ESGNovaCVar : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + ConstOpen UMETA(DisplayName = "Const Open"), + ID UMETA(DisplayName = "ID"), + GloveVersion UMETA(DisplayName = "Glove Version"), + FirmwareVersion UMETA(DisplayName = "Firmware Version"), + LeftRight UMETA(DisplayName = "Left Right"), + Functions UMETA(DisplayName = "Functions"), + ImuCorrection UMETA(DisplayName = "IMU Correction"), + + /* Utility value used in iteration / checking lengths. */ + AllC UMETA(DisplayName = "All C"), +}; + +/* Sensor data blocks. */ +UENUM(BlueprintType) +enum class ESGNovaData : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + Sensors UMETA(DisplayName = "Sensors"), + Imu UMETA(DisplayName = "IMU"), + All UMETA(DisplayName = "All"), +}; + +/* Which vibration motors to send vibrations to. */ +UENUM(BlueprintType) +enum class ESGNovaVibroMotor : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* Not sure which motor to send this to. */ + Unknown UMETA(DisplayName = "Unknown"), + + /* Vibration motor located at the back of the hand. A.k.a. "The Thumper". */ + BackOfHand UMETA(DisplayName = "Back of Hand"), + + /* Vibration motor located at the tip of the thumb. */ + ThumbTip UMETA(DisplayName = "Thumb Tip"), + + /* Vibration motor located at the tip of the index finger. */ + IndexFingertip UMETA(DisplayName = "Index Fingertip"), +}; + +/* Tracking Hardware used for positional tracking. */ +UENUM(BlueprintType) +enum class ESGPositionalTrackingHardware : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* Custom tracking hardware, we don't apply any offsets. */ + Custom UMETA(DisplayName = "Custom"), + + /* HTC VIVE Tracker (v1.0 or v2.0). */ + ViveTracker UMETA(DisplayName = "VIVE Tracker"), + + /* Touch controller for Oculus Quest 2. */ + Quest2Controller UMETA(DisplayName = "Quest 2 Controller"), + + /* Wrist tracker for the VIVE Focus 3. */ + ViveFocus3WristTracker UMETA(DisplayName = "VIVE Focus 3 Wrist Tracker"), + + /* Oculus Touch Controller that comes with the Meta Quest Pro. */ + QuestProController UMETA(DisplayName = "Quest Pro Controller"), + + /* Oculus Quest 3 Controller. */ + Quest3Controller UMETA(DisplayName = "Quest 3 Controller"), +}; + +/* Indices to access Sensor Data in Shared Memory. */ +UENUM(BlueprintType) +enum class ESGSensorFormat : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + Sensors UMETA(DisplayName = "Sensors"), +}; + +/* Sense Glove C string Variables, enumerated for our convenience. */ +UENUM(BlueprintType) +enum class ESGSenseGloveCVar : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + ID UMETA(DisplayName = "ID"), + GloveVersion UMETA(DisplayName = "Glove Version"), + FirmwareVersion UMETA(DisplayName = "Firmware Version"), + LeftRight UMETA(DisplayName = "Left Right"), + Functions UMETA(DisplayName = "Functions"), + GlovePos UMETA(DisplayName = "Glove Pos"), + + /* All gloves have functionality up to this point. */ + GloveLengths UMETA(DisplayName = "Glove Lengths"), + + NumberOfSensors UMETA(DisplayName = "Number Of Sensors"), + ImuCorrection UMETA(DisplayName = "IMU Correction"), + + /* Utility value used in iteration / checking lengths. */ + AllC UMETA(DisplayName = "All C"), +}; + +/* Sense Glove sensor string Variables, enumerated for our convenience. */ +UENUM(BlueprintType) +enum class ESGSenseGloveSVar : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* Real-time error */ + RealtimeError UMETA(DisplayName = "Real-time Error"), + + FingerSensors UMETA(DisplayName = "Finger Sensors"), + + ImuData UMETA(DisplayName = "IMU Data"), + + /* Watchdog error. */ + WatchdogError UMETA(DisplayName = "Watchdog Error"), + + /* Semaphore error */ + SemaphoreError UMETA(DisplayName = "Semaphore Error"), + + /* Utility value used in iteration / checking lengths. */ + AllS UMETA(DisplayName = "All S"), +}; + +/* A command to activate the SenseGlove Thumper module, which is responsible for wrist feedback. */ +UENUM(BlueprintType) +enum class ESGSenseGloveThumperCommand : uint8 +{ + /* None. */ + None UMETA(DisplayName = "None"), + + /* Turn off the thumper effects. */ + TurnOff UMETA(DisplayName = "Turn Off"), + + /* A 5-seconds long, constant vibration. */ + CueGameOver UMETA(DisplayName = "Cue Game Over"), + + /* A double-click at 100% intensity. */ + ButtonDouble100 UMETA(DisplayName = "Button Double 100"), + + /* A double click at 60% intensity. */ + ButtonDouble60 UMETA(DisplayName = "Button Double 60"), + + /* Simulates an impact of the hand at 100% intensity. */ + ImpactThump100 UMETA(DisplayName = "Impact Thump 100"), + + /* Simulates an impact of the hand at 30% intensity. */ + ImpactThump30 UMETA(DisplayName = "Impact Thump 30"), + + /* Simulates an sharp impact of the hand at 10% intensity. */ + ImpactThump10 UMETA(DisplayName = "Impact Thump 10"), + + /* A light vibration to cue the user that an object it picked up. 100% intensity. */ + ObjectGrasp100 UMETA(DisplayName = "Object Grasp 100"), + + /* A light vibration to cue the user that an object it picked up. 60% intensity. */ + ObjectGrasp60 UMETA(DisplayName = "Object Grasp 60"), + + /* A light vibration to cue the user that an object it picked up. 30% intensity. */ + ObjectGrasp30 UMETA(DisplayName = "Object Grasp 30"), +}; + +/* The way handPoses are smoothed in this class. */ +UENUM(BlueprintType) +enum class ESGSmoothingMethod : uint8 +{ + /** + * None. You'll always get the latest pose received. No performance increase, but might result in a "stop-motion" + * effect on lower frame-rates. + */ + None UMETA(DisplayName = "None"), + + /** + * Pretend you're one sample behind, and interpolate along the exact paths. More accurate, but we will lag 1 frame + * behind. + */ + InterpolateBehind UMETA(DisplayName = "Interpolated Behind"), + + /** + * Take the last two handPoses and estimate the current values based on extrapolation. Is perceived as "faster", + * but is more likely to overshoot during sudden changes in direction. + */ + ExtrapolateAhead UMETA(DisplayName = "Extraplate Ahead"), +}; + +/* Anatomical movements of the thumb joints. */ +UENUM(BlueprintType) +enum class ESGThumbMovement : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* Pronation/Supination of the first finger joint. */ + CmcTwist UMETA(DisplayName = "CMC Twist"), + + /* Flexion of the first finger joint. */ + CmcFlexion UMETA(DisplayName = "CMC Flexion"), + + /* Abduction of the first finger joint. */ + CmcAbduction UMETA(DisplayName = "CMC Abduction"), + + /* Flexion of the second thumb joint. */ + McpFlexion UMETA(DisplayName = "MCP Flexion"), + + /* Flexion of the third thumb joint. */ + IpFlexion UMETA(DisplayName = "IP Flexion"), +}; + +/* How this Sense Glove converts sensor data into a HandPose. */ +UENUM(BlueprintType) +enum class ESGThumbSolver : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* Hand angles are interpolated based on the total flexion / abduction of the exoskeleton. */ + Interpolation UMETA(DisplayName = "Interpolation"), +}; + +/* Waveform type for an advanced Buzz Command. */ +UENUM(BlueprintType) +enum class ESGWaveformType : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* We're not sure what type of Waveform to use. */ + Unknown UMETA(DisplayName = "Unknown"), + + /* Smooth sine wave. */ + Sine UMETA(DisplayName = "Sine"), + + /* Can shift duty Cycle. */ + Square UMETA(DisplayName = "Square"), + + /* Inverse of SawDown. */ + SawUp UMETA(DisplayName = "Saw Up"), + + /* Inverse of SawUp. */ + SawDown UMETA(DisplayName = "Saw Down"), + + /* Triangle waveform. */ + Triangle UMETA(DisplayName = "Triangle"), + + /* A random, noisy signal. */ + Noise UMETA(DisplayName = "Noise"), +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGDebugTypes.h b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGDebugTypes.h new file mode 100644 index 0000000..46e36f9 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGDebugTypes.h @@ -0,0 +1,56 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreTypes.h" +#include "HAL/Platform.h" +#include "UObject/ObjectMacros.h" + +/** + * Determines the debug virtual hand drawing mode. + */ +UENUM(BlueprintType) +enum class ESGDebugVirtualHandDrawingMode : uint8 +{ + /** Do not draw any debug virtual hands. */ + None UMETA(DisplayName = "None"), + + /** Draw a debug virtual hand with cubic joints. */ + CubicJoints UMETA(DisplayName = "Cubic Joints"), + + /** Draw a debug virtual hand with gizmo joints. */ + GizmoJoints UMETA(DisplayName = "Gizmo Joints"), +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGFloatArray.h b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGFloatArray.h new file mode 100644 index 0000000..ba848a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGFloatArray.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "UObject/ObjectMacros.h" + +#include "SGFloatArray.generated.h" + +USTRUCT(BlueprintType) +struct SENSEGLOVETYPES_API FSGFloatArray +{ + GENERATED_BODY() + +public: + UPROPERTY(EditAnywhere, Category="SenseGlove | Types | Nested Arrays", BlueprintReadWrite) + TArray FloatArray; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGNameArray.h b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGNameArray.h new file mode 100644 index 0000000..6370e09 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGNameArray.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "UObject/NameTypes.h" + +#include "SGNameArray.generated.h" + +USTRUCT(BlueprintType) +struct SENSEGLOVETYPES_API FSGNameArray +{ + GENERATED_BODY() + +public: + UPROPERTY(EditAnywhere, Category="SenseGlove | Types | Nested Arrays", BlueprintReadWrite) + TArray NameArray; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGQuatArray.h b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGQuatArray.h new file mode 100644 index 0000000..4abc159 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGQuatArray.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Math/Quat.h" + +#include "SGQuatArray.generated.h" + +USTRUCT(BlueprintType) +struct SENSEGLOVETYPES_API FSGQuatArray +{ + GENERATED_BODY() + +public: + UPROPERTY(EditAnywhere, Category="SenseGlove | Types | Nested Arrays", BlueprintReadWrite) + TArray QuatArray; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGRotatorArray.h b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGRotatorArray.h new file mode 100644 index 0000000..12977b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGRotatorArray.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Containers/Array.h" +#include "Math/Rotator.h" + +#include "SGRotatorArray.generated.h" + +USTRUCT(BlueprintType) +struct SENSEGLOVETYPES_API FSGRotatorArray +{ + GENERATED_BODY() + +public: + UPROPERTY(EditAnywhere, Category="SenseGlove | Types | Nested Arrays", BlueprintReadWrite) + TArray RotatorArray; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGTrackingTypes.h b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGTrackingTypes.h new file mode 100644 index 0000000..16a7dae --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGTrackingTypes.h @@ -0,0 +1,134 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" +#include "UObject/ObjectMacros.h" + +/** + * The Head-mounted Display device enum to determine the HMD device type. + */ +UENUM(BlueprintType) +enum class ESGHeadMountedDisplayDevice : uint8 +{ + /* The default none value. */ + None UMETA(DisplayName = "None"), + + /* The Meta Quest 2 HMD. */ + MetaQuest2 UMETA(DisplayName = "Meta Quest 2"), + + /* The Meta Quest Pro HMD. */ + MetaQuestPro UMETA(DisplayName = "Meta Quest Pro"), + + /* The Meta Quest 3 HMD. */ + MetaQuest3 UMETA(DisplayName = "Meta Quest 3"), + + /* The HTC VIVE Pro HMD. */ + HtcVivePro UMETA(DisplayName = "HTC VIVE Pro"), + + /* The HTC VIVE Focus 3 HMD. */ + HtcViveFocus3 UMETA(DisplayName = "HTC VIVE Focus 3"), + + /* The HTC VIVE XR Elite HMD. */ + HtcViveXRElite UMETA(DisplayName = "HTC VIVE XR Elite"), + + /* The HTC VIVE Focus 3 HMD. */ + HtcViveFocusVision UMETA(DisplayName = "HTC VIVE Focus Vision"), +}; + +/* OpenXR provider for the positional tracking hardware. */ +UENUM(BlueprintType) +enum class ESGOpenXRPositionalTrackingProvider : uint8 +{ + /* The default none value. Setting to 'None' will fall back to auto-detection. */ + None UMETA(DisplayName = "None"), + + /** + * OpenXR: + * - Quest 2 Controller + * - Quest Pro Controller + * - Quest 3 Controller + */ + OpenXR UMETA(DisplayName = "OpenXR"), + + /** + * OpenXRViveTracker: + * - PCVR: + * - VIVE Tracker + * - VIVE Focus 3 Wrist Tracker + * - Ultimate Tracker + */ + OpenXRViveTracker UMETA(DisplayName = "OpenXRViveTracker"), + + /** + * OpenXRViveWristTracker: + * - Standalone: + * - VIVE Focus 3 Wrist Tracker + */ + OpenXRViveWristTracker UMETA(DisplayName = "OpenXRViveWristTracker"), + + /** + * OpenXRXrTracker: + * - Standalone: + * - Ultimate Tracker + */ + OpenXRXrTracker UMETA(DisplayName = "OpenXRXrTracker"), +}; + +/* + * The HTC VIVE HMD detection priority for HTC devices that we cannot distinguish. + */ +UENUM(BlueprintType) +enum class ESGViveHMDDetectionPriority : uint8 +{ + /* First try to detect HTC VIVE Focus Vision, then XR Elite, and then Focus 3. */ + FocusVision_XRElite_Focus3 UMETA(DisplayName = "Focus Vision (1st), XR Elite (2nd), Focus3 (3rd)"), + + /* First try to detect HTC VIVE Focus Vision, then Focus 3, and then XR Elite. */ + FocusVision_Focus3_XRElite UMETA(DisplayName = "Focus Vision (1st), Focus3 (2nd), XR Elite (3rd)"), + + /* First try to detect HTC VIVE XR Elite, then Focus Vision, and then Focus 3. */ + XRElite_FocusVision_Focus3 UMETA(DisplayName = "XR Elite (1st), Focus Vision (2nd), Focus3 (3rd)"), + + /* First try to detect HTC VIVE XR Elite, then Focus 3, and then Focus Vision. */ + XRElite_Focus3_FocusVision UMETA(DisplayName = "XR Elite (1st), Focus3 (2nd), Focus Vision (3rd)"), + + /* First try to detect HTC VIVE Focus 3, then Focus Vision, and then XR Elite. */ + Focus3_FocusVision_XRElite UMETA(DisplayName = "Focus3 (1st), Focus Vision (2nd), XR Elite (3rd)"), + + /* First try to detect HTC VIVE Focus 3, then XR Elite, and then Focus Vision. */ + Focus3_XRElite_FocusVision UMETA(DisplayName = "Focus3 (1st), XR Elite (2nd), Focus Vision (3rd)"), +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGTypes.h b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGTypes.h new file mode 100644 index 0000000..057afb8 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGTypes.h @@ -0,0 +1,59 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" +#include "UObject/ObjectMacros.h" + +/** + * The engine scalability settings. + */ +UENUM(BlueprintType) +enum class ESGEngineScalabilitySettings : uint8 +{ + Low = 0 UMETA(DisplayName = "Low"), + Medium = 1 UMETA(DisplayName = "Medium"), + High = 2 UMETA(DisplayName = "High"), + Epic = 3 UMETA(DisplayName = "Epic"), + Cinematic = 4 UMETA(DisplayName = "Cinematic"), + + /** + * This will be used for benchmarking purpose. Then it should set the engine scalability settings to one of the + * other levels. + */ + Auto = 254 UMETA(DisplayName = "Auto"), + Custom = 255 UMETA(DisplayName = "Custom"), +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGVectorArray.h b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGVectorArray.h new file mode 100644 index 0000000..7ca7147 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/Public/SGTypes/SGVectorArray.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "HAL/Platform.h" +#include "Math/Vector.h" + +#include "SGVectorArray.generated.h" + +USTRUCT(BlueprintType) +struct SENSEGLOVETYPES_API FSGVectorArray +{ + GENERATED_BODY() + +public: + UPROPERTY(EditAnywhere, Category="SenseGlove | Types | Nested Arrays", BlueprintReadWrite) + TArray VectorArray; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveTypes/SenseGloveTypes.Build.cs b/Plugins/SenseGlove/Source/SenseGloveTypes/SenseGloveTypes.Build.cs new file mode 100644 index 0000000..88b8419 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveTypes/SenseGloveTypes.Build.cs @@ -0,0 +1,61 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGloveTypes : ModuleRules +{ + public SenseGloveTypes(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveLog", + } + ); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGAngles.cpp b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGAngles.cpp new file mode 100644 index 0000000..49c8237 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGAngles.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGUtils/SGAngles.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGArrayUtils.cpp b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGArrayUtils.cpp new file mode 100644 index 0000000..4b4394f --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGArrayUtils.cpp @@ -0,0 +1,140 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGUtils/SGArrayUtils.h" + +#include "SGUtils/SGUnits.h" + +TArray FSGArrayUtils::QuatsToRotators(const TArray& QuatsArray) +{ + TArray RotatorsArray; + + for (const FQuat& Quat: QuatsArray) + { + FRotator Rotator{Quat.Rotator()}; + RotatorsArray.Add(MoveTemp(Rotator)); + } + + return RotatorsArray; +} + +TArray> FSGArrayUtils::QuatsToRotators(const TArray>& QuatsNestedArray) +{ + TArray> RotatorsNestedArray; + + for (const TArray& InnerQuatsArray: QuatsNestedArray) + { + TArray InnerRotatorsArray{QuatsToRotators(InnerQuatsArray)}; + RotatorsNestedArray.Add(MoveTemp(InnerRotatorsArray)); + } + + return RotatorsNestedArray; +} + +TArray FSGArrayUtils::RotatorsToQuats(const TArray& RotatorsArray) +{ + TArray QuatsArray; + + for (const FRotator& Rotator: RotatorsArray) + { + FQuat Quat{Rotator.Quaternion()}; + QuatsArray.Add(MoveTemp(Quat)); + } + + return QuatsArray; +} + +TArray> FSGArrayUtils::RotatorsToQuats(const TArray>& RotatorsNestedArray) +{ + TArray> QuatsNestedArray; + + for (const TArray& RotatorsInnerArray: RotatorsNestedArray) + { + TArray InnerQuatsArray{RotatorsToQuats(RotatorsInnerArray)}; + QuatsNestedArray.Add(MoveTemp(InnerQuatsArray)); + } + + return QuatsNestedArray; +} + +TArray FSGArrayUtils::FromMillimeters(const std::vector& Vector) +{ + TArray Array; + + for (const float Value: Vector) + { + Array.Add(FSGUnits::MillimetersToCentimeters(Value)); + } + + return Array; +} + +TArray> FSGArrayUtils::FromMillimeters(const std::vector>& NestedVector) +{ + TArray> NestedArray; + + for (const std::vector& InnerVector: NestedVector) + { + TArray InnerArray{FromMillimeters(InnerVector)}; + NestedArray.Add(MoveTemp(InnerArray)); + } + + return NestedArray; +} + +std::vector FSGArrayUtils::ToMillimeters(const TArray& Array) +{ + std::vector Vector; + + for (const float Value: Array) + { + Vector.emplace_back(FSGUnits::CentimetersToMillimeters(Value)); + } + + return Vector; +} + +std::vector> FSGArrayUtils::ToMillimeters(const TArray>& NestedArray) +{ + std::vector> NestedVector; + + for (const TArray& InnerArray: NestedArray) + { + std::vector InnerVector{ToMillimeters(InnerArray)}; + NestedVector.emplace_back(MoveTemp(InnerVector)); + } + + return NestedVector; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGEditorUtils.cpp b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGEditorUtils.cpp new file mode 100644 index 0000000..269d2a4 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGEditorUtils.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGUtils/SGEditorUtils.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGEngineUtils.cpp b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGEngineUtils.cpp new file mode 100644 index 0000000..0f37750 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGEngineUtils.cpp @@ -0,0 +1,119 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGUtils/SGEngineUtils.h" + +#include "CoreGlobals.h" +#if WITH_EDITOR +#include "Editor.h" +#endif /* WITH_EDITOR */ +#include "Engine/Engine.h" +#include "Engine/GameViewportClient.h" +#include "Engine/World.h" +#include "Runtime/Launch/Resources/Version.h" +#include "Subsystems/EngineSubsystem.h" + +UWorld* FSGEngineUtils::GetWorld() +{ + UWorld* World{nullptr}; + +#if WITH_EDITOR + if (GIsEditor) + { + if (IsValid(GEditor)) + { + { + const bool bIsPIE = +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + UE::GetPlayInEditorID() +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + GPlayInEditorID +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + != -1; + const int32 WorldPIEInstance = bIsPIE + ? +#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 + UE::GetPlayInEditorID() +#else /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + GPlayInEditorID +#endif /* ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 */ + : 1; + const FWorldContext* WorldContext{GEditor->GetPIEWorldContext(WorldPIEInstance)}; + if (WorldContext) + { + World = WorldContext->World(); + } + } + + if (!IsValid(World) && IsInGameThread() && !(GEditor->PlayWorld || GIsPlayInEditorWorld)) + { + World = GEditor->GetEditorWorldContext(false).World(); + } + } + + if (!IsValid(World) && IsValid(GEngine)) + { + const UGameViewportClient* Viewport{GEngine->GameViewport}; + if (IsValid(Viewport)) + { + World = Viewport->GetWorld(); + } + } + } + else + { + if (IsValid(GEngine)) + { + World = GEngine->GetCurrentPlayWorld(nullptr); + } + } +#else /* WITH_EDITOR */ + if (IsValid(GEngine)) + { + World = GEngine->GetCurrentPlayWorld(nullptr); + } +#endif /* WITH_EDITOR */ + + if (!IsValid(World) && IsValid(GEngine)) + { + UEngineSubsystem* EngineSubsystem{GEngine->GetEngineSubsystem()}; + if (IsValid(EngineSubsystem)) + { + World = EngineSubsystem->GetWorld(); + } + } + + return World; +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGPluginUtils.cpp b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGPluginUtils.cpp new file mode 100644 index 0000000..895d685 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGPluginUtils.cpp @@ -0,0 +1,54 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGUtils/SGPluginUtils.h" + +#include "Interfaces/IPluginManager.h" +#include "Modules/ModuleManager.h" + +bool FSGPluginUtils::IsPluginEnabled(const FString& PluginName) +{ + TSharedPtr Plugin{IPluginManager::Get().FindPlugin(*PluginName)}; + if (Plugin.IsValid()) + { + return Plugin->IsEnabled(); + } + return false; +} + +bool FSGPluginUtils::IsModuleLoaded(const FString& ModuleName) +{ + return FModuleManager::Get().IsModuleLoaded(FName{*ModuleName}); +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGUnits.cpp b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGUnits.cpp new file mode 100644 index 0000000..1cb0895 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SGUtils/SGUnits.cpp @@ -0,0 +1,36 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SGUtils/SGUnits.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SenseGloveUtils.cpp b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SenseGloveUtils.cpp new file mode 100644 index 0000000..b497146 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SenseGloveUtils.cpp @@ -0,0 +1,40 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveUtils.h" +#include "Modules/ModuleManager.h" +#include "SenseGloveUtilsModule.h" + +IMPLEMENT_MODULE(FSenseGloveUtilsModule, SenseGloveUtils) \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SenseGloveUtils.h b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SenseGloveUtils.h new file mode 100644 index 0000000..a30ce66 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SenseGloveUtils.h @@ -0,0 +1,38 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "CoreMinimal.h" \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SenseGloveUtilsModule.cpp b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SenseGloveUtilsModule.cpp new file mode 100644 index 0000000..0addebe --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SenseGloveUtilsModule.cpp @@ -0,0 +1,61 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#include "SenseGloveUtilsModule.h" +#include "SGLog/SGLog.h" + +#define LOCTEXT_NAMESPACE "FSenseGloveUtilsModule" + +void FSenseGloveUtilsModule::StartupModule() +{ + SGLOG("Starting up the SenseGloveUtils module..."); +} + +void FSenseGloveUtilsModule::PreUnloadCallback() +{ + SGLOG("Unloading the SenseGloveUtils module..."); +} + +void FSenseGloveUtilsModule::PostLoadCallback() +{ + SGLOG("Loading of SenseGloveUtils module has succeeded!"); +} + +void FSenseGloveUtilsModule::ShutdownModule() +{ + SGLOG("Shutting down the SenseGloveUtils module..."); +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SenseGloveUtilsModule.h b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SenseGloveUtilsModule.h new file mode 100644 index 0000000..3757850 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveUtils/Private/SenseGloveUtilsModule.h @@ -0,0 +1,51 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Modules/ModuleInterface.h" + +#define LOCTEXT_NAMESPACE "SenseGloveUtils" + +class FSenseGloveUtilsModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void PreUnloadCallback() override; + virtual void PostLoadCallback() override; + virtual void ShutdownModule() override; +}; + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGAngles.h b/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGAngles.h new file mode 100644 index 0000000..87f014d --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGAngles.h @@ -0,0 +1,129 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED To THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ToRT OR OTHERWISE, ARISING From, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Math/Vector.h" + +#include "SGTypes/SGCoreTypes.h" + +class SENSEGLOVEUTILS_API FSGAngles final +{ +public: + static FORCEINLINE float TransformToSenseGlove(const float Degrees) + { + return FMath::DegreesToRadians(Degrees); + } + + static FORCEINLINE float TransformToSenseGlove(const int32 Movement, const float Direction) + { + // 0 = twist, 1 = flexion/extension, 2 = abduction + return FMath::DegreesToRadians(Movement != 1 ? -Direction : Direction); + } + + static FORCEINLINE FVector TransformToSenseGlove(const FVector& Vector) + { + return FMath::DegreesToRadians(FVector(-Vector.X, Vector.Y, -Vector.Z)); + } + + template + static FORCEINLINE V TransformToSenseGlove(const FVector& Vector) + { + return FMath::DegreesToRadians(V(-Vector.X, Vector.Y, -Vector.Z)); + } + + static FORCEINLINE float TransformToUnreal(const float Radians) + { + return FMath::RadiansToDegrees(Radians); + } + + static FORCEINLINE constexpr float TransformToUnreal(const int32 Movement, const float Direction) + { + /// TODO + /// values require validation. + + // 0 = twist, 1 = flexion/extension, 2 = abduction + return Movement != 1 ? -Direction : Direction; + } + + static FORCEINLINE constexpr float TransformToUnreal(const ESGFingerMovement Movement, const float Direction) + { + ensureAlwaysMsgf(Movement != ESGFingerMovement::None, TEXT("none is not a valid value!")); + + /// TODO + /// values require validation. + + // 0 = twist, 1 = flexion/extension, 2 = abduction + /// TODO + /// Which flexions should be ignored? + return (Movement != ESGFingerMovement::McpFlexion && Movement != ESGFingerMovement::PipFlexion && Movement != + ESGFingerMovement::PipFlexion) + ? -Direction + : Direction; + } + + static FORCEINLINE float TransformToUnreal(const ESGThumbMovement Movement, const float Direction) + { + ensureAlwaysMsgf(Movement != ESGThumbMovement::None, TEXT("none is not a valid value!")); + + /// TODO + /// values require validation. + + // 0 = twist, 1 = flexion/extension, 2 = abduction + /// TODO + /// Which flexions should be ignored? + return FMath::RadiansToDegrees( + Movement != ESGThumbMovement::CmcFlexion + && Movement != ESGThumbMovement::McpFlexion + && Movement != ESGThumbMovement::IpFlexion + ? -Direction + : Direction); + } + + static FORCEINLINE FVector TransformToUnreal(const FVector& Vector) + { + return FMath::RadiansToDegrees(FVector(-Vector.X, Vector.Y, -Vector.Z)); + } + + template + static FORCEINLINE FVector TransformToUnreal(const V& Vector) + { + return FMath::RadiansToDegrees(FVector(-Vector.GetX(), Vector.GetY(), -Vector.GetZ())); + } + +public: + FSGAngles() = delete; + virtual ~FSGAngles() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGArrayUtils.h b/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGArrayUtils.h new file mode 100644 index 0000000..ad6d879 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGArrayUtils.h @@ -0,0 +1,799 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED To THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ToRT OR OTHERWISE, ARISING From, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include +#include + +#include "SGAngles.h" +#include "Containers/Array.h" +#include "Containers/StringConv.h" +#include "Math/Quat.h" +#include "Math/Rotator.h" +#include "Math/Vector.h" +#include "Templates/UnrealTemplate.h" + +#include "SGUtils/SGUnits.h" + +class SENSEGLOVEUTILS_API FSGArrayUtils final +{ +public: + template + static FORCEINLINE TArray FromStdVector(const std::vector& Vector) + { + const TArray Array{&Vector[0], StaticCast(Vector.size())}; + return Array; + } + + /// NOTE + /// std::vector is a non-conforming container. Since it packs booleans to be stored in one bit, + /// it cannot provide a bool reference. Thus, FSGArrayUtils::FromStdVector() cannot be used. + /// Hence, the specialization. + static TArray FromStdVector(const std::vector& Vector) + { + TArray Array; + Array.Reserve(Vector.size()); + + for (const bool bValue: Vector) + { + Array.Add(bValue); + } + + return Array; + } + + static TArray FromStdVector(const std::vector& Vector) + { + TArray Array; + Array.Reserve(Vector.size()); + + for (const std::string& StdString: Vector) + { + FString String{UTF8_TO_TCHAR(StdString.c_str())}; + Array.Add(MoveTemp(String)); + } + + return Array; + } + + template + static TArray> FromStdVector(const std::vector>& NestedVector) + { + TArray> NestedArray; + NestedArray.Reserve(NestedVector.size()); + + for (const std::vector& InnerVector: NestedVector) + { + TArray InnerArray{FromStdVector(InnerVector)}; + NestedArray.Add(MoveTemp(InnerArray)); + } + + return NestedArray; + } + + template + static TArray FromStdVector(const std::vector& Vector) + { + TArray Array; + Array.Reserve(Vector.size()); + + for (const T1& T1Element: Vector) + { + T2 T2Element(T1Element); + Array.Add(MoveTemp(T2Element)); + } + + return Array; + } + + template + static TArray> FromStdVector(const std::vector>& NestedVector) + { + TArray> NestedArray; + NestedArray.Reserve(NestedVector.size()); + + for (const std::vector& InnerVector: NestedVector) + { + TArray InnerArray{FromStdVector(InnerVector)}; + NestedArray.Add(MoveTemp(InnerArray)); + } + + return NestedArray; + } + + template + static TArray FromStdVector(const std::vector& Vector) + { + TArray Array; + Array.Reserve(Vector.size()); + + for (const T1& T1Element: Vector) + { + IntermediateImpl ImplElement(T1Element); + T2 T2Element((ImplElement.*ToT2TypeMethod)()); + Array.Add(MoveTemp(T2Element)); + } + + return Array; + } + + template + static TArray> FromStdVector(const std::vector>& NestedVector) + { + TArray> NestedArray; + NestedArray.Reserve(NestedVector.size()); + + for (const std::vector& InnerVector: NestedVector) + { + TArray InnerArray{FromStdVector(InnerVector)}; + NestedArray.Add(MoveTemp(InnerArray)); + } + + return NestedArray; + } + + template + static FORCEINLINE std::vector ToStdVector(const TArray& Array) + { + std::vector Vector(&Array[0], &Array[0] + Array.Num()); + return Vector; + } + + static std::vector ToStdVector(const TArray& Array) + { + std::vector Vector; + Vector.reserve(Array.Num()); + + for (const FString& String: Array) + { + std::string StdString{TCHAR_TO_UTF8(*String)}; + Vector.emplace_back(MoveTemp(StdString)); + } + + return Vector; + } + + template + static std::vector> ToStdVector(const TArray>& NestedArray) + { + std::vector> NestedVector; + NestedVector.reserve(NestedArray.Num()); + + for (const TArray& InnerArray: NestedArray) + { + std::vector InnerVector{ToStdVector(InnerArray)}; + NestedVector.emplace_back(MoveTemp(InnerVector)); + } + + return NestedVector; + } + + template + static std::vector ToStdVector(const TArray& Array) + { + std::vector Vector; + Vector.reserve(Array.Num()); + + for (const T1& T1Element: Array) + { + T2 T2Element((T1Element.*ToUnderlyingTypeMethod)()); + Vector.emplace_back(MoveTemp(T2Element)); + } + + return Vector; + } + + template + static std::vector> ToStdVector(const TArray>& NestedArray) + { + std::vector> NestedVector; + NestedVector.reserve(NestedArray.Num()); + + for (const TArray& InnerArray: NestedArray) + { + std::vector InnerVector{ToStdVector(InnerArray)}; + NestedVector.emplace_back(MoveTemp(InnerVector)); + } + + return NestedVector; + } + + template + static std::vector ToStdVector(const TArray& Array) + { + std::vector Vector; + Vector.reserve(Array.Num()); + + for (const T1& T1Element: Array) + { + IntermediateImpl ImplElement(T1Element); + T2 T2Element((ImplElement.*ToUnderlyingTypeMethod)()); + Vector.emplace_back(MoveTemp(T2Element)); + } + + return Vector; + } + + template + static std::vector> ToStdVector(const TArray>& NestedArray) + { + std::vector> NestedVector; + NestedVector.reserve(NestedArray.Num()); + + for (const TArray& InnerArray: NestedArray) + { + std::vector InnerVector{ToStdVector(InnerArray)}; + NestedVector.emplace_back(MoveTemp(InnerVector)); + } + + return NestedVector; + } + + template + static TArray FromImplType(const TArray& ImplArray) + { + TArray Array; + Array.Reserve(ImplArray.Num()); + + for (const T1& T1Element: ImplArray) + { + T2 T2Element(T1Element); + Array.Add(MoveTemp(T2Element)); + } + + return Array; + } + + template + static TArray FromImplType(UObject* Outer, const TArray& ImplArray) + { + TArray Array; + Array.Reserve(ImplArray.Num()); + + for (const T1& T1Element: ImplArray) + { + T2* T2Element(NewObjectMethod(Outer, T1Element)); + Array.Add(MoveTemp(T2Element)); + } + + return Array; + } + + template + static TArray> FromImplType(const TArray>& NestedImplArray) + { + TArray> NestedArray; + NestedArray.Reserve(NestedImplArray.Num()); + + for (const TArray& InnerImplArray: NestedImplArray) + { + TArray InnerArray{FromImplType(InnerImplArray)}; + NestedArray.Add(MoveTemp(InnerArray)); + } + + return NestedArray; + } + + template + static TArray> FromImplType(UObject* Outer, const TArray>& NestedImplArray) + { + TArray> NestedArray; + NestedArray.Reserve(NestedImplArray.Num()); + + for (const TArray& InnerImplArray: NestedImplArray) + { + TArray InnerArray{FromImplType(Outer, InnerImplArray)}; + NestedArray.Add(MoveTemp(InnerArray)); + } + + return NestedArray; + } + + template + static TArray FromImplType(const TArray>& NestedImplArray) + { + TArray NestedBPArray; + NestedBPArray.Reserve(NestedImplArray.Num()); + + for (const TArray& InnerImplArray: NestedImplArray) + { + TArray InnerArray{FromImplType(InnerImplArray)}; + S InnerArrayContainer{MoveTemp(InnerArray)}; + NestedBPArray.Add(MoveTemp(InnerArrayContainer)); + } + + return NestedBPArray; + } + + template + static TArray FromImplType(UObject* Outer, const TArray>& NestedImplArray) + { + TArray NestedArray; + NestedArray.Reserve(NestedImplArray.Num()); + + for (const TArray& InnerImplArray: NestedImplArray) + { + TArray InnerArray{FromImplType(Outer, InnerImplArray)}; + S InnerArrayContainer{MoveTemp(InnerArray)}; + NestedArray.Add(MoveTemp(InnerArrayContainer)); + } + + return NestedArray; + } + + template + static TArray FromImplType(const TArray>& NestedImplArray) + { + TArray NestedArray; + NestedArray.Reserve(NestedImplArray.Num()); + + for (const TArray& InnerImplArray: NestedImplArray) + { + TArray InnerArray{FromImplType(InnerImplArray)}; + S InnerArrayContainer{MoveTemp(InnerArray)}; + NestedArray.Add(MoveTemp(InnerArrayContainer)); + } + + return NestedArray; + } + + template + static TArray ToImplType(const TArray& Array) + { + TArray ImplArray; + ImplArray.Reserve(Array.Num()); + + for (const T1& T1Element: Array) + { + T2 T2Element((T1Element.*ToUnderlyingTypeMethod)()); + ImplArray.Add(MoveTemp(T2Element)); + } + + return ImplArray; + } + + template + static TArray ToImplType(const TArray& Array) + { + TArray ImplArray; + ImplArray.Reserve(Array.Num()); + + for (const T1* T1Element: Array) + { + T2 T2Element((T1Element->*ToUnderlyingTypeMethod)()); + ImplArray.Add(MoveTemp(T2Element)); + } + + return ImplArray; + } + + template + static TArray> ToImplType(const TArray>& Array) + { + TArray> ImplArray; + ImplArray.Reserve(Array.Num()); + + for (const TArray& InnerArray: Array) + { + TArray InnerImplArray{ToImplType(InnerArray)}; + ImplArray.Add(MoveTemp(InnerImplArray)); + } + + return ImplArray; + } + + template + static TArray> ToImplType(const TArray>& NestedArray) + { + TArray> NestedImplArray; + NestedImplArray.Reserve(NestedArray.Num()); + + for (const TArray& InnerArray: NestedArray) + { + TArray InnerImplArray{ToImplType(InnerArray)}; + NestedImplArray.Add(MoveTemp(InnerImplArray)); + } + + return NestedImplArray; + } + + template S::* + InnerArray> + static TArray> ToImplType(const TArray& NestedArray) + { + TArray> NestedImplArray; + NestedImplArray.Reserve(NestedArray.Num()); + + for (const S& InnerArrayContainer: NestedArray) + { + TArray InnerImplArray{ToImplType(InnerArrayContainer.*InnerArray)}; + NestedImplArray.Add(MoveTemp(InnerImplArray)); + } + + return NestedImplArray; + } + + template S::* + InnerArray> + static TArray> ToImplType(const TArray& NestedArray) + { + TArray> NestedImplArray; + NestedImplArray.Reserve(NestedArray.Num()); + + for (const S& InnerArrayContainer: NestedArray) + { + TArray InnerImplArray{ToImplType(InnerArrayContainer.*InnerArray)}; + NestedImplArray.Add(MoveTemp(InnerImplArray)); + } + + return NestedImplArray; + } + + template S::*InnerArray> + static TArray> FromNestedBPArray(const TArray& NestedBPArray) + { + TArray> NestedArray; + NestedArray.Reserve(NestedBPArray.Num()); + + for (const S& InnerBPArrayContainer: NestedBPArray) + { + NestedArray.Add(InnerBPArrayContainer.*InnerArray); + } + + return NestedArray; + } + + template + static TArray ToNestedBPArray(const TArray>& NestedArray) + { + TArray NestedBPArray; + NestedBPArray.Reserve(NestedArray.Num()); + + for (const TArray& InnerArray: NestedArray) + { + S InnerBPArrayContainer{InnerArray}; + NestedBPArray.Add(MoveTemp(InnerBPArrayContainer)); + } + + return NestedBPArray; + } + + template + static TArray ToNestedBPArray(const TArray>& NestedArray) + { + TArray NestedBPArray; + NestedBPArray.Reserve(NestedArray.Num()); + + for (const TArray& InnerArray: NestedArray) + { + S InnerBPArrayContainer{InnerArray}; + NestedBPArray.Add(MoveTemp(InnerBPArrayContainer)); + } + + return NestedBPArray; + } + + static TArray QuatsToRotators(const TArray& QuatsArray); + static TArray> QuatsToRotators(const TArray>& QuatsArray); + + template S::*InnerArray> + static TArray> QuatsToRotators(const TArray& QuatsNestedArray) + { + TArray> RotatorsNestedArray; + RotatorsNestedArray.Reserve(QuatsNestedArray.Num()); + + for (const S& QuatsInnerBPArrayContainer: QuatsNestedArray) + { + RotatorsNestedArray.Add(QuatsToRotators(QuatsInnerBPArrayContainer.*InnerArray)); + } + + return RotatorsNestedArray; + } + + template + static TArray QuatsToRotators(const TArray>& QuatsNestedArray) + { + TArray RotatorsNestedBPArray; + RotatorsNestedBPArray.Reserve(QuatsNestedArray.Num()); + + for (const TArray& QuatsInnerArray: QuatsNestedArray) + { + S RotatorsInnerBPArrayContainer{QuatsToRotators(QuatsInnerArray)}; + RotatorsNestedBPArray.Add(MoveTemp(RotatorsInnerBPArrayContainer)); + } + + return RotatorsNestedBPArray; + } + + template Q::*InnerArray> + static TArray QuatsToRotators(const TArray& QuatsNestedArray) + { + TArray RotatorsNestedBPArray; + RotatorsNestedBPArray.Reserve(QuatsNestedArray.Num()); + + for (const Q& QuatsInnerArrayContainer: QuatsNestedArray) + { + R RotatorsInnerBPArrayContainer{QuatsToRotators(QuatsInnerArrayContainer.*InnerArray)}; + RotatorsNestedBPArray.Add(MoveTemp(RotatorsInnerBPArrayContainer)); + } + + return RotatorsNestedBPArray; + } + + static TArray RotatorsToQuats(const TArray& RotatorsNestedArray); + static TArray> RotatorsToQuats(const TArray>& RotatorsNestedArray); + + template S::*InnerArray> + static TArray> RotatorsToQuats(const TArray& RotatorsNestedArray) + { + TArray> QuatsNestedArray; + QuatsNestedArray.Reserve(RotatorsNestedArray.Num()); + + for (const S& RotatorsInnerBPArrayContainer: RotatorsNestedArray) + { + QuatsNestedArray.Add(RotatorsToQuats(RotatorsInnerBPArrayContainer.*InnerArray)); + } + + return QuatsNestedArray; + } + + template + static TArray RotatorsToQuats(const TArray>& RotatorsNestedArray) + { + TArray QuatsNestedBPArray; + QuatsNestedBPArray.Reserve(RotatorsNestedArray.Num()); + + for (const TArray& RotatorsInnerArray: RotatorsNestedArray) + { + S QuatsInnerBPArrayContainer{RotatorsToQuats(RotatorsInnerArray)}; + QuatsNestedBPArray.Add(MoveTemp(QuatsInnerBPArrayContainer)); + } + + return QuatsNestedBPArray; + } + + template Q::*InnerArray> + static TArray RotatorsToQuats(const TArray& RotatorsNestedArray) + { + TArray QuatsNestedBPArray; + QuatsNestedBPArray.Reserve(RotatorsNestedArray.Num()); + + for (const Q& RotatorsInnerArrayContainer: RotatorsNestedArray) + { + R QuatsInnerBPArrayContainer{RotatorsToQuats(RotatorsInnerArrayContainer.*InnerArray)}; + QuatsNestedBPArray.Add(MoveTemp(QuatsInnerBPArrayContainer)); + } + + return QuatsNestedBPArray; + } + + static TArray FromMillimeters(const std::vector& Vector); + static TArray> FromMillimeters(const std::vector>& NestedVector); + + template + static TArray FromMillimeters(const std::vector& Vector) + { + TArray Array; + Array.Reserve(Vector.size()); + + for (const V3D& Value: Vector) + { + Array.Add(FSGUnits::MillimetersToCentimeters(Value)); + } + + return Array; + } + + template + static TArray> FromMillimeters(const std::vector>& NestedVector) + { + TArray> NestedArray; + NestedArray.Reserve(NestedVector.size()); + + for (const std::vector& InnerVector: NestedVector) + { + TArray InnerArray{FromMillimeters(InnerVector)}; + NestedArray.Add(MoveTemp(InnerArray)); + } + + return NestedArray; + } + + static std::vector ToMillimeters(const TArray& Array); + static std::vector> ToMillimeters(const TArray>& NestedArray); + + template S::*InnerArray> + static std::vector> ToMillimeters(const TArray& NestedBPArray) + { + std::vector> NestedVector; + NestedVector.reserve(NestedBPArray.Num()); + + for (const S& InnerBPArrayContainer: NestedBPArray) + { + std::vector InnerVector{ToMillimeters(InnerBPArrayContainer.*InnerArray)}; + NestedVector.emplace_back(MoveTemp(InnerVector)); + } + + return NestedVector; + } + + template + static std::vector ToMillimeters(const TArray& Array) + { + std::vector Vector; + Vector.reserve(Array.Num()); + + for (const FVector& Value: Array) + { + Vector.emplace_back(FSGUnits::CentimetersToMillimeters(Value)); + } + + return Vector; + } + + template + static std::vector> ToMillimeters(const TArray>& NestedArray) + { + std::vector> NestedVector; + NestedVector.reserve(NestedArray.Num()); + + for (const TArray& InnerArray: NestedArray) + { + std::vector InnerVector{ToMillimeters(InnerArray)}; + NestedVector.emplace_back(MoveTemp(InnerVector)); + } + + return NestedVector; + } + + static std::vector ToSenseGloveAngles(const TArray& Array) + { + std::vector Vector; + Vector.reserve(Array.Num()); + + for (const float Value: Array) + { + Vector.emplace_back(FSGAngles::TransformToSenseGlove(Value)); + } + + return Vector; + } + + static std::vector> ToSenseGloveAngles(const TArray>& NestedArray) + { + std::vector> NestedVector; + NestedVector.reserve(NestedArray.Num()); + + for (const TArray& InnerArray: NestedArray) + { + std::vector InnerVector{ToSenseGloveAngles(InnerArray)}; + NestedVector.emplace_back(MoveTemp(InnerVector)); + } + + return NestedVector; + } + + template + static std::vector ToSenseGloveAngles(const TArray& Array) + { + std::vector Vector; + Vector.reserve(Array.Num()); + + for (const FVector& Value: Array) + { + Vector.emplace_back(FSGAngles::TransformToSenseGlove(Value)); + } + + return Vector; + } + + template + static std::vector> ToSenseGloveAngles(const TArray>& NestedArray) + { + std::vector> NestedVector; + NestedVector.reserve(NestedArray.Num()); + + for (const TArray& InnerArray: NestedArray) + { + std::vector InnerVector{ToSenseGloveAngles(InnerArray)}; + NestedVector.emplace_back(MoveTemp(InnerVector)); + } + + return NestedVector; + } + + static TArray FromSenseGloveAngles(const std::vector& Vector) + { + TArray Array; + Array.Reserve(Vector.size()); + + for (const float Value: Vector) + { + Array.Add(FSGAngles::TransformToUnreal(Value)); + } + + return Array; + } + + static TArray> FromSenseGloveAngles(const std::vector>& NestedVector) + { + TArray> NestedArray; + NestedArray.Reserve(NestedVector.size()); + + for (const std::vector& InnerVector: NestedVector) + { + TArray InnerArray{FromSenseGloveAngles(InnerVector)}; + NestedArray.Add(MoveTemp(InnerArray)); + } + + return NestedArray; + } + + template + static TArray FromSenseGloveAngles(const std::vector& Vector) + { + TArray Array; + Array.Reserve(Vector.size()); + + for (const V3D& Value: Vector) + { + Array.Add(FSGAngles::TransformToUnreal(Value)); + } + + return Array; + } + + template + static TArray> FromSenseGloveAngles(const std::vector>& NestedVector) + { + TArray> NestedArray; + NestedArray.Reserve(NestedVector.size()); + + for (const std::vector& InnerVector: NestedVector) + { + TArray InnerArray{FromSenseGloveAngles(InnerVector)}; + NestedArray.Add(MoveTemp(InnerArray)); + } + + return NestedArray; + } + +public: + FSGArrayUtils() = delete; + virtual ~FSGArrayUtils() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGEditorUtils.h b/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGEditorUtils.h new file mode 100644 index 0000000..48a1ebe --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGEditorUtils.h @@ -0,0 +1,43 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED To THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ToRT OR OTHERWISE, ARISING From, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +class SENSEGLOVEUTILS_API FSGEditorUtils final +{ +public: + FSGEditorUtils() = delete; + virtual ~FSGEditorUtils() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGEngineUtils.h b/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGEngineUtils.h new file mode 100644 index 0000000..888cb1e --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGEngineUtils.h @@ -0,0 +1,48 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED To THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ToRT OR OTHERWISE, ARISING From, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +class UWorld; + +class SENSEGLOVEUTILS_API FSGEngineUtils final +{ +public: + static UWorld* GetWorld(); + +public: + FSGEngineUtils() = delete; + virtual ~FSGEngineUtils() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGPluginUtils.h b/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGPluginUtils.h new file mode 100644 index 0000000..ab32991 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGPluginUtils.h @@ -0,0 +1,82 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED To THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ToRT OR OTHERWISE, ARISING From, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +class SENSEGLOVEUTILS_API FSGPluginUtils final +{ +public: + static bool IsPluginEnabled(const FString& PluginName); + static bool IsModuleLoaded(const FString& ModuleName); + + static FORCENOINLINE bool IsPluginAvailable(const FString& PluginName, const FString& ModuleName) + { + return IsPluginEnabled(*PluginName) && IsModuleLoaded(ModuleName); + } + + FORCENOINLINE static bool IsMetaXRPluginEnabled() + { + return IsPluginEnabled(TEXT("OculusXR")); + } + + FORCENOINLINE static bool IsMetaXRPluginLoaded() + { + return IsModuleLoaded(TEXT("OculusXRHMD")); + } + + FORCENOINLINE static bool IsMetaXRPluginAvailable() + { + return IsMetaXRPluginEnabled() && IsMetaXRPluginLoaded(); + } + + FORCENOINLINE static bool IsViveOpenXRPluginEnabled() + { + return IsPluginEnabled(TEXT("ViveOpenXR")); + } + + FORCENOINLINE static bool IsViveOpenXRPluginLoaded() + { + return IsModuleLoaded(TEXT("ViveOpenXRCommon")); + } + + FORCENOINLINE static bool IsViveOpenXRPluginAvailable() + { + return IsViveOpenXRPluginEnabled() && IsViveOpenXRPluginLoaded(); + } + +public: + FSGPluginUtils() = delete; + virtual ~FSGPluginUtils() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGUnits.h b/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGUnits.h new file mode 100644 index 0000000..083fb0c --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveUtils/Public/SGUtils/SGUnits.h @@ -0,0 +1,78 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED To THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ToRT OR OTHERWISE, ARISING From, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +#pragma once + +#include "Math/Vector.h" + +class SENSEGLOVEUTILS_API FSGUnits final +{ +public: + static FORCEINLINE constexpr float CentimetersToMillimetersMultiplier() + { + return 10.0f; + } + + static FORCEINLINE constexpr float MillimetersToCentimetersMultiplier() + { + return 0.1f; + } + + static FORCEINLINE float CentimetersToMillimeters(const float Value) + { + return Value * CentimetersToMillimetersMultiplier(); + } + + template + static FORCEINLINE V3D CentimetersToMillimeters(const FVector& Vector) + { + return V3DImpl(Vector * CentimetersToMillimetersMultiplier()).ToVect3D(); + } + + static FORCEINLINE float MillimetersToCentimeters(const float Value) + { + return Value * MillimetersToCentimetersMultiplier(); + } + + template + static FORCEINLINE FVector MillimetersToCentimeters(const V3D& Vect3D) + { + return V3DImpl(Vect3D).ToFVector() * MillimetersToCentimetersMultiplier(); + } + +public: + FSGUnits() = delete; + virtual ~FSGUnits() = delete; +}; \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/SenseGloveUtils/SenseGloveUtils.Build.cs b/Plugins/SenseGlove/Source/SenseGloveUtils/SenseGloveUtils.Build.cs new file mode 100644 index 0000000..a29b0b0 --- /dev/null +++ b/Plugins/SenseGlove/Source/SenseGloveUtils/SenseGloveUtils.Build.cs @@ -0,0 +1,73 @@ +/** + * @file + * + * @author Mamadou Babaei + * + * @section LICENSE + * + * (The MIT License) + * + * Copyright (c) 2020 - 2025 SenseGlove + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @section DESCRIPTION + * + * + */ + + +using System; +using UnrealBuildTool; + +public class SenseGloveUtils : ModuleRules +{ + public SenseGloveUtils(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + "Projects", + } + ); + + if (Target.bBuildEditor) + { + PrivateDependencyModuleNames.AddRange( + new string[] + { + "UnrealEd", + } + ); + } + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SenseGloveLog", + "SenseGloveTypes", + } + ); + } +} \ No newline at end of file diff --git a/Plugins/SenseGlove/Source/ThirdParty/android/sgconnect.jar b/Plugins/SenseGlove/Source/ThirdParty/android/sgconnect.jar new file mode 100644 index 0000000..a795b2f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/android/sgconnect.jar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0518583cb00a2816e3e0c91c1a559d372d03e16975a9c73be9da623085ad7905 +size 41018 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/Android.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/Android.hpp new file mode 100644 index 0000000..8400844 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/Android.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83c730f7c6840f3c89628f9d691859100a713bae02c3d4d9a5bc6848b2870228 +size 1905 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/Connection.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/Connection.hpp new file mode 100644 index 0000000..b2e49c3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/Connection.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0cc329587b1b84bc915372e99c2ae69c0086aa209e4579df198f4115f2cdbe89 +size 5454 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/ConnectionData.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/ConnectionData.hpp new file mode 100644 index 0000000..8d5fa50 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/ConnectionData.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ba29fc7bc964566b4d6ed81dabe7958bdb60637126c36b4c15295ecfdc43c2d +size 2004 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/ConnectionFactory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/ConnectionFactory.hpp new file mode 100644 index 0000000..e5f5387 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/ConnectionFactory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98f0b93f34dc074a520bc1905e35707fe0650aaa658314697c0dee8fca0e29c1 +size 774 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/ConnectionTester.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/ConnectionTester.hpp new file mode 100644 index 0000000..e5b95bb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/ConnectionTester.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a10e3708aadaeeecf8be6d2d4288b10c9be086003d50143d7bb50694e84afb6 +size 1678 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/ConnectionsTracker.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/ConnectionsTracker.hpp new file mode 100644 index 0000000..5f8c17c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/ConnectionsTracker.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b89511e5d195aad4ce30a71e8f35567fd92224365406636c9ad25d0a46abc930 +size 2336 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/Debugger.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/Debugger.hpp new file mode 100644 index 0000000..5c0bb2d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/Debugger.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a00df260d32c5969308e06d757686ff20514f06cf8c74f4e733c22754dac3b5f +size 3183 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/DeviceScanner.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/DeviceScanner.hpp new file mode 100644 index 0000000..0ca4621 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/DeviceScanner.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a89852f2063e95ea654e76e27558ad12bb27b588c529b8a6870be83b1defb51 +size 2380 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/ExitCodes.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/ExitCodes.hpp new file mode 100644 index 0000000..762dab7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/ExitCodes.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ceef3991ddd7d2d7021304b473c68683abc58a18d0fea213c8529e405bccd1b5 +size 2460 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/HapticResponse.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/HapticResponse.hpp new file mode 100644 index 0000000..2a0f6de --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/HapticResponse.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:574644402011d5bb0eafe3cebaa1328425d58776770821161104263b2ff7f3dc +size 5435 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/IdResponse.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/IdResponse.hpp new file mode 100644 index 0000000..2d4ca30 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/IdResponse.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:27103bf30076604d42e0eb50fe0cded40ff3815a1f02da6429ed95f5f0778913 +size 2282 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/IpcCommand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/IpcCommand.hpp new file mode 100644 index 0000000..d5763b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/IpcCommand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90320eea0042af8cd6767386b537d87379d21627cc96fbbe806b33c09e1a4c84 +size 1967 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/NewSGDevice.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/NewSGDevice.hpp new file mode 100644 index 0000000..9463244 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/NewSGDevice.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5d8fa9b3be2a143ad3be884dedaea3aa33f6ac3cac5ea80f580235550db7b1b +size 1834 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/Platform.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/Platform.hpp new file mode 100644 index 0000000..135dbd5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/Platform.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:84cb61f7827f0e4831a48fc6904316f1ff98145980f8f136e2619dca0da11cd3 +size 5623 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/PortInfo.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/PortInfo.hpp new file mode 100644 index 0000000..f0c0564 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/PortInfo.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be7ac7eaf8db79f553b3d6b87399dc365c7e0992ddaed0878222e12204aff4c4 +size 2822 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/SGConnect.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/SGConnect.hpp new file mode 100644 index 0000000..29cf59c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/SGConnect.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b3b5bb2a2a660af01e474a6aeb0cc30c32b5158c7f4b8d6321edd269ef76e61 +size 9956 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/SGDevice.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/SGDevice.hpp new file mode 100644 index 0000000..b6fad10 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/SGDevice.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b8a3fa2c6bf0cb0702a6e84408e386a2b753e2ccfb0aac353a9f4460c1aba665 +size 3057 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/SerialConnection.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/SerialConnection.hpp new file mode 100644 index 0000000..d6459e8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/SerialConnection.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86e24978ba5dc81e75bbdd66ffe62875822bcee767b44ad5b2d8dfff7a0a3ae7 +size 2536 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/SerialPorts.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/SerialPorts.hpp new file mode 100644 index 0000000..39ad3f4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/SerialPorts.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76b79eb1a3c2ced6c555f118853488dbaa0b3279d0692cdbca9a2049ace6e90c +size 2310 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/SharedMem.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/SharedMem.hpp new file mode 100644 index 0000000..2aa9afa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/SharedMem.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f474e3e6cd7d693d8656b00f9316eb42321bd8ba79198a08dec1edfdf22c129 +size 3580 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/StringUtils.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/StringUtils.hpp new file mode 100644 index 0000000..61c4e90 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/StringUtils.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1067acebb96f59bb2842196b2e10e81a177a5e5d1d5a96a18dec8cabc4348a6 +size 1702 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/TestingState.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/TestingState.hpp new file mode 100644 index 0000000..20c4f45 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/TestingState.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:825ed593095d10c68e995597e61fa7c5e7e323df2dd03ac55c88130723fa9619 +size 1962 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/TransmissionMode.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/TransmissionMode.hpp new file mode 100644 index 0000000..3485252 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Connect/TransmissionMode.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:abf7a74183b53e66a7418a6141dbd5588c7429e1f6b946e5d2ecca8e506a338c +size 907 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Anatomy.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Anatomy.hpp new file mode 100644 index 0000000..e3ea59f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Anatomy.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c14d0cf9a8f73ff036f1b4dc361e3bc044067e172668220beea61fc58ddb52e6 +size 3368 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Android.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Android.hpp new file mode 100644 index 0000000..d893ce2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Android.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95f486ea273b2dbcc1db8bdded8a9cbdc848d20f22f82cae376f575ba9cb73a8 +size 2129 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/BasicHandModel.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/BasicHandModel.hpp new file mode 100644 index 0000000..723c7dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/BasicHandModel.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5b8348fa07db8cf9e9169691649f376f0d67086607ab7c37ca3708cdefec08b +size 7431 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/BetaDevice.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/BetaDevice.hpp new file mode 100644 index 0000000..6cea310 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/BetaDevice.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc4eea4985714e6e36ab4bf716b26fc93b4cc89367f40e40e4b5729b1ef7e93d +size 3636 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CVHandDataSmoother.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CVHandDataSmoother.hpp new file mode 100644 index 0000000..c82294a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CVHandDataSmoother.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5625a1a2f8d4c21b4a351a14f98b5f8b70b31ee2ac3d83d04c5e36af382681bb +size 6462 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CVHandLayer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CVHandLayer.hpp new file mode 100644 index 0000000..990aebb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CVHandLayer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b7fbfefc9174e39dc4f9179cc72a869db28b5af49b310d05f0fc9e6cad922b5 +size 5018 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CVHandTrackingData.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CVHandTrackingData.hpp new file mode 100644 index 0000000..0aa4d22 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CVHandTrackingData.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13b381e7f1f2387d74b77fb78b4773624af92ee396ec7098afd6ebcad52c2bdf +size 9305 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CVKinematics.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CVKinematics.hpp new file mode 100644 index 0000000..32d7407 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CVKinematics.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87a10e50f85ca0f6301bdfd0863dc6091f0d5de4c3454bb1e0be84bc3b69b3e7 +size 5515 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CVProcessedHandData.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CVProcessedHandData.hpp new file mode 100644 index 0000000..535e043 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CVProcessedHandData.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4220e679b1ee2278346961c65f1750ecfb17bc2e7e1a703d781417edf4b60fca +size 6133 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Communications.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Communications.hpp new file mode 100644 index 0000000..3ddfc2c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Communications.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9163cd53502cb725fd5dbcd3d937c08a9104d05d3ac414d7d72c4d8f6161865b +size 4141 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/ConnectionStatus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/ConnectionStatus.hpp new file mode 100644 index 0000000..c67d111 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/ConnectionStatus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:123cc71ad92e7055f7ecc0734aeadd296a6b7a315718349307493928eca0ae64 +size 3193 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CustomWaveform.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CustomWaveform.hpp new file mode 100644 index 0000000..ce44e51 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/CustomWaveform.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c435a57617a890e5250287ef0888005187a7daddb90f473e5ac3bd2e1b8724d +size 8343 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Debugger.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Debugger.hpp new file mode 100644 index 0000000..d8ea2f8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Debugger.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ba3ceb3dd0d05bf8985b382e5ad6962648cf73e3b39720c03dfe136d44cef82 +size 2386 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/DeviceList.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/DeviceList.hpp new file mode 100644 index 0000000..1f927ce --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/DeviceList.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4be0c78e0b2ce166e6ff7c96cae8037e39c45d9388d6ae13f735435dec3490a4 +size 4462 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/DeviceModel.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/DeviceModel.hpp new file mode 100644 index 0000000..302b134 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/DeviceModel.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83e390e924304143f4ef64bd4cdd6a18526ecdf74491480ad5f4d90dfc710c20 +size 3983 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/DeviceTypes.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/DeviceTypes.hpp new file mode 100644 index 0000000..3ac560f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/DeviceTypes.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90a2fed4f7500d4d4e8a9ab66f2fb6361f601f43bfb60e68173b6d337a91d2bf +size 1303 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/FileIO.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/FileIO.hpp new file mode 100644 index 0000000..2c876c7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/FileIO.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd4100045835761669bcdbf6af461a7b42ee4171f030781f428ebf78c06de78f +size 3595 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Fingers.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Fingers.hpp new file mode 100644 index 0000000..6f74e23 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Fingers.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5cc65a180b5749b68363ec4f6db38b6a3a65a40528ddb541b6008ce5f3e0ecb +size 2547 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/FloatUtils.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/FloatUtils.hpp new file mode 100644 index 0000000..1dad445 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/FloatUtils.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ffdf00d7e42c7279869f894f54d590e054cd169111c6b7034453e1d6003a3a6 +size 970 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/HandInterpolator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/HandInterpolator.hpp new file mode 100644 index 0000000..93fd543 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/HandInterpolator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4795c3004087f63a5de65f2620ea93bc23e841e5b418d1095dcca6bbdc0e984f +size 3456 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/HandLayer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/HandLayer.hpp new file mode 100644 index 0000000..25f1332 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/HandLayer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a64f2fcd219f4efe47154866398aace0ff862e4de9f175176209e87c67bb8035 +size 10188 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/HandPose.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/HandPose.hpp new file mode 100644 index 0000000..cc3e6ca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/HandPose.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f24cae8dff8ed91431f098acacc8a179b87b44c6b54448f693dbb0ba53d2970 +size 7750 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/HapticChannelInfo.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/HapticChannelInfo.hpp new file mode 100644 index 0000000..4c20b1c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/HapticChannelInfo.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:edf43c4d4e1fcbf56b659537ea6d5e13054085aeca668efcd318cbfaf48d3070 +size 5581 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/HapticGlove.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/HapticGlove.hpp new file mode 100644 index 0000000..ef269a5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/HapticGlove.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aef9423baa5d1a03064861b30dfea419d4329cf6cb7b1b29aa50ec95f657cc49 +size 13753 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/InterpolationSet.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/InterpolationSet.hpp new file mode 100644 index 0000000..35de5c8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/InterpolationSet.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a4aaa2d95c96d5ed565a2422bc1cdbce4ac505d0f1672e31f5c4860d939e2ad +size 3576 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/JointKinematics.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/JointKinematics.hpp new file mode 100644 index 0000000..3c3b1e7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/JointKinematics.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:448de29d2274053b1cc0e21a869451aedab87510e1b9f0bfb7777e3055664e5a +size 1616 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Library.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Library.hpp new file mode 100644 index 0000000..e3fb59b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Library.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3424f06b18a142c9d4387e98c9baae44230837f7e61329fb3132e569dca69aa1 +size 1538 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/MathDefines.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/MathDefines.hpp new file mode 100644 index 0000000..855fedc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/MathDefines.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9052e3ccb9d186279b9d5feeeba43d9ad16b12e5f088ca7752b4eb48afa83656 +size 955 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NormalizationState.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NormalizationState.hpp new file mode 100644 index 0000000..e584085 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NormalizationState.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff81d09a253cca18a6abb33664c132506b9607fba2d6fc086a3a92d469e2c248 +size 1218 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Nova2Glove.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Nova2Glove.hpp new file mode 100644 index 0000000..46036cb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Nova2Glove.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1186f38c4e2c4c500aea0693f30089ba769cedb9b8ca78d3340d96829c2632bd +size 21483 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Nova2GloveSensorData.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Nova2GloveSensorData.hpp new file mode 100644 index 0000000..90f86f7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Nova2GloveSensorData.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:68e027f9ffc01a1f2e96b6ebd25b06c82fa1cf53aab2349524df918f920370a7 +size 5406 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGlove.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGlove.hpp new file mode 100644 index 0000000..f7c2390 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGlove.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef2ee4d38bfa1e4894bc24d326574d3db4a98a27db6a84ff2d4f5c99a5718d08 +size 22864 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGloveHapticEncoder.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGloveHapticEncoder.hpp new file mode 100644 index 0000000..00c0638 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGloveHapticEncoder.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e0b0f97a9f9c90c7e25f3f3025c00318adde989c8ba42c7d6451242c4ad4c7b2 +size 4844 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGloveHapticStream.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGloveHapticStream.hpp new file mode 100644 index 0000000..165bb19 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGloveHapticStream.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aed1f374a112cacb924e8ac2b9b18460ba9bf7cf479c5750f82dc00a335f21e3 +size 5957 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGloveInfo.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGloveInfo.hpp new file mode 100644 index 0000000..30e1a5b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGloveInfo.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ac9b0ed4ac65e53194d9b384be85beb62afc28975c33ee15055d6cdfce2a4ee +size 4985 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGloveSensorData.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGloveSensorData.hpp new file mode 100644 index 0000000..26a22bd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGloveSensorData.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f83cf80009e498fbb15e5cf44f5ad58cacf720f7c1c7164fb26b9372a13ebcc7 +size 5821 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGloveVars.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGloveVars.hpp new file mode 100644 index 0000000..cdbaf85 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/NovaGloveVars.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5bb14e8da00dd17a931ba643df901ecc5fc4bbe2d2806433859003a461d9ef9 +size 1161 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/OnDiskCalibration.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/OnDiskCalibration.hpp new file mode 100644 index 0000000..22db767 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/OnDiskCalibration.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc3de15e7bd51993635ca7ebb426c5e57cbd51f8ee6493961b9ccc83b65b1494 +size 3586 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Platform.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Platform.hpp new file mode 100644 index 0000000..3f58ad6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Platform.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a97c899023860c8c0ce09347d1a77947594a0bd02682ed38129d6e8b5f5bd3aa +size 6247 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Quat.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Quat.hpp new file mode 100644 index 0000000..eda81a2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Quat.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f911c53932d50d4ac84ee26b8ab0d3cecb08953c75a7b4a45386ced2055a93d8 +size 5969 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SGDevice.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SGDevice.hpp new file mode 100644 index 0000000..19c1b53 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SGDevice.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c41c0322257543f4232df085d9919f701fd63dd5494349b506577c4810d7f330 +size 8577 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseCom.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseCom.hpp new file mode 100644 index 0000000..1502460 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseCom.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:524aba3fe803227a1515f30c60a055d9112aeb9d71812deb35d20965cb27298d +size 1572 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGlove.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGlove.hpp new file mode 100644 index 0000000..d9360e5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGlove.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e1b154a74ac1a2ce2f980b0df740d1ccbb638a2bbd077827fdb8e9243e825f26 +size 21299 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveHapticStream.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveHapticStream.hpp new file mode 100644 index 0000000..df569cc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveHapticStream.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b82b18484410855149dabeae6818bcd13d6c7d83cacdc3a7da85f901a021f08a +size 4450 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveInfo.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveInfo.hpp new file mode 100644 index 0000000..ecd075d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveInfo.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a28c84876798a4c86eddce9a8a0b98f3e84db0e94b4c4e51bcc58c0e229835d +size 5796 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGlovePose.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGlovePose.hpp new file mode 100644 index 0000000..0d9fb5e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGlovePose.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3813028c6338bab9efbd501755a05ff5d33170c2934427d147f3b91bd93489ef +size 4395 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveSensorData.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveSensorData.hpp new file mode 100644 index 0000000..4018ef8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveSensorData.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9503e5a316ec9f9ed4d475ed408a473df4ad6e3c5674256b5fc904f9167fc256 +size 3740 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveSensorNormalizer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveSensorNormalizer.hpp new file mode 100644 index 0000000..f4b82dc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveSensorNormalizer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ddf54bb466e827ab191e8a9093e9bdb99cc01b18b72c2efd3d2ee008823c6677 +size 2931 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveThumperCommand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveThumperCommand.hpp new file mode 100644 index 0000000..ca62665 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveThumperCommand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c04eb1d486bb35b1ecd2919721cdc45b5863531dfaa6b05f6e3df90bcfa1ba9 +size 1979 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveVars.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveVars.hpp new file mode 100644 index 0000000..bcd230a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SenseGloveVars.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e9b2925e3bea8bdc8e4e70af1008376f76c8029b7d3b2822012f2a68ce629053 +size 5483 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SensorNormalization.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SensorNormalization.hpp new file mode 100644 index 0000000..26d5564 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SensorNormalization.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b97ebecf780d7cd01ca8cfd1a7db3eba549d09efbe86717318c8dbb961163eb7 +size 4689 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Serializer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Serializer.hpp new file mode 100644 index 0000000..5c0db61 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Serializer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5eb46cc89021702599421149873279f9d2747c5340654a827bc837a8b9d574f +size 4790 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SharedMem.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SharedMem.hpp new file mode 100644 index 0000000..ef852a4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/SharedMem.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db530e1b564788c20e453f01fcda9a6c6e43250de976cedc6fd58f0e6b9008fc +size 2933 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/StringUtils.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/StringUtils.hpp new file mode 100644 index 0000000..6f2da3d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/StringUtils.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e9267345920ec2b89be4eef7112169d84e53edf4e0d63bfe8ea17f6b833a054 +size 3240 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/ThresholdCommand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/ThresholdCommand.hpp new file mode 100644 index 0000000..5d1b61d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/ThresholdCommand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:934ef42a51e4b60bef2e4cb7c1dd3eb87165d1f75c61d658307672d431735a45 +size 4152 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Tracking.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Tracking.hpp new file mode 100644 index 0000000..ecf2855 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Tracking.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58da217c880122a8cc48f10568dfe98a53544e8fe234b2cdb0653b6b12b08eb7 +size 12189 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Values.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Values.hpp new file mode 100644 index 0000000..a1aef10 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Values.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd6cd08bbdf4d917cd6a81eb06c1ca7aa4269ad1ede0eb99df05ba40341b16b5 +size 5877 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Vect3D.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Vect3D.hpp new file mode 100644 index 0000000..2303072 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/SenseGlove/Core/Vect3D.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:114ec89dd5b00ec17481e83c9794765384d230961eecf8349378da0dabb6a9dc +size 3990 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio.hpp new file mode 100644 index 0000000..e60df28 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dad14550ca7ff58d564d91edae9a8353cd0c2e97046d5f8944eca1cae24d42f6 +size 6232 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/associated_allocator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/associated_allocator.hpp new file mode 100644 index 0000000..5611e36 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/associated_allocator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e352e6e09acb8881fce05dffb8149a6e43e6692f440ecb5fb5a2d0a3f2812dda +size 3889 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/associated_executor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/associated_executor.hpp new file mode 100644 index 0000000..fa87a3b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/associated_executor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8af8992c0be5ae6ccd9a51e6cac267af228a301dd6bb213bbb076c021eee26d0 +size 4586 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/async_result.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/async_result.hpp new file mode 100644 index 0000000..e09f430 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/async_result.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3b8e3e636e8f5bb4b92855fddf0aa889d44949fc3a6ff6b975a7a5209a8231bd +size 8095 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_datagram_socket.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_datagram_socket.hpp new file mode 100644 index 0000000..6456e48 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_datagram_socket.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a50e88ba1e27879a312b13f0be5220998ef8e651eb55f716d170117e133adb13 +size 42006 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_deadline_timer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_deadline_timer.hpp new file mode 100644 index 0000000..f152c85 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_deadline_timer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b04442f7e643c1bfaa6feff331432d0bb2a1aafbb3c912a7acc1b372b0c5f4b0 +size 22508 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_io_object.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_io_object.hpp new file mode 100644 index 0000000..8fe6b4c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_io_object.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b6627d36aa1fc84965d6a77e73c903f34a04f3cc96e681758ccdbdd65f1b4ee7 +size 8096 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_raw_socket.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_raw_socket.hpp new file mode 100644 index 0000000..b01bb97 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_raw_socket.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:63f7fad264cd32d3e3f6609d96911ac61d1162232303c2a075c48f7f86c7870b +size 41590 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_seq_packet_socket.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_seq_packet_socket.hpp new file mode 100644 index 0000000..4cabd6e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_seq_packet_socket.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce931bd14b14c986023d9f807f82f045a38151063ca31034e8473849346e32af +size 24654 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_serial_port.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_serial_port.hpp new file mode 100644 index 0000000..113e846 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_serial_port.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d82cc5230e085257633d4fd4cbc53fa9676821c44647e59e4eb34ecae7b0cb49 +size 25209 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_signal_set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_signal_set.hpp new file mode 100644 index 0000000..870bc17 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_signal_set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ec13d6b939ef9f3f621d36ac8844ce86b73f8f81e6f08c896e9692e993a2e0e0 +size 13942 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_socket.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_socket.hpp new file mode 100644 index 0000000..5be5401 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_socket.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0aa4feab46c17b598896a60ccc6efb4f99e24358129b6b9508a48618d3b13cdc +size 61616 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_socket_acceptor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_socket_acceptor.hpp new file mode 100644 index 0000000..6c591fc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_socket_acceptor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41a3841205b0f17d2e214f63348582423551f3dc126b150ef09b599257b45ab4 +size 70860 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_socket_iostream.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_socket_iostream.hpp new file mode 100644 index 0000000..6e87817 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_socket_iostream.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e4893932b098ff65b27ce1c4fe189154925cfe6296733270200417e515028e9 +size 14458 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_socket_streambuf.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_socket_streambuf.hpp new file mode 100644 index 0000000..a11d9b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_socket_streambuf.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37bc612408a4eda8153b9b01a7da3a23114314f698894568b663cee62922ff07 +size 22750 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_stream_socket.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_stream_socket.hpp new file mode 100644 index 0000000..1eacdd0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_stream_socket.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:70334d6306f97c1f07a2cd3cad0c7160b368a868c2c17bd11ec275d1e15a7ab6 +size 37274 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_streambuf.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_streambuf.hpp new file mode 100644 index 0000000..578ed8d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_streambuf.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b3bbedf8f705ea5fcb906071954a2b0a9642a777007986bba92e8daa89661de1 +size 13714 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_streambuf_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_streambuf_fwd.hpp new file mode 100644 index 0000000..da70036 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_streambuf_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:31e3dfc5bbd49b77a7305542e2f4968da8b5c2159156cd88026986b7b10a2842 +size 920 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_waitable_timer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_waitable_timer.hpp new file mode 100644 index 0000000..a405210 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/basic_waitable_timer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e4bbe948e3001f537db384bcf967b3e29fa26a1c288fde5be47bc040f43e7c20 +size 25460 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/bind_executor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/bind_executor.hpp new file mode 100644 index 0000000..ece1b3c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/bind_executor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:759d4e62be557260b39c75d5ab523d6b8dc5ebec6af7bd377209a1f34e1d9858 +size 17248 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffer.hpp new file mode 100644 index 0000000..f23c435 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d75d955ca374582d5b8b46f68420f71d34d36748dd84a612cd552ba9b5c9b615 +size 69873 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_read_stream.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_read_stream.hpp new file mode 100644 index 0000000..1dfa9b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_read_stream.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a35dbff5610bd20f43459e5f60b9f828e4dbefa13a2a30babcaf0f05d547b014 +size 8269 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_read_stream_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_read_stream_fwd.hpp new file mode 100644 index 0000000..fa896d7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_read_stream_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d377064bb171db03386d99a3afe1c2cb073f9405db8cecb97e09d20c88c74bd +size 699 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_stream.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_stream.hpp new file mode 100644 index 0000000..d9420a5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_stream.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08bc09f9309e54db1582183e670c6f16aaa4e7a992eb1d9ef64dbac2518edf4d +size 8699 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_stream_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_stream_fwd.hpp new file mode 100644 index 0000000..f112b73 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_stream_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ea46531377bc2a35d76975b23102ec15f1a252c60a76972a05edbddc2cd36b2 +size 669 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_write_stream.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_write_stream.hpp new file mode 100644 index 0000000..0f183b3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_write_stream.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0292710a2c41c916c244e5f689abe09ea9ce2e8f49250fb097f071d199513c0b +size 7887 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_write_stream_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_write_stream_fwd.hpp new file mode 100644 index 0000000..092fc30 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffered_write_stream_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:816b0d8b42766e1569486658e4e8470a742c4294a9ecb09f332bd4a9ce7a7088 +size 705 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffers_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffers_iterator.hpp new file mode 100644 index 0000000..05f9c25 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/buffers_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e71a0abbd086a543bd75918aa56252fb3821eb60c9024027ae230f2f46f0c216 +size 14049 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/completion_condition.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/completion_condition.hpp new file mode 100644 index 0000000..12fdf59 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/completion_condition.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0cefe14897b477249b60f1a969c797706ac98f56b31ef65d473bf892e9e178c7 +size 5500 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/connect.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/connect.hpp new file mode 100644 index 0000000..d3fe4d3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/connect.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a221f42d0e89fa9e9b00bc6ede4956954beca27258b861277e65a7b7ac73e01 +size 42153 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/coroutine.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/coroutine.hpp new file mode 100644 index 0000000..6f95c03 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/coroutine.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8383099cdf26e9e0a86f818a72df5af32e4dc4b6e0f7e686e70c04633ce7154d +size 9896 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/datagram_socket_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/datagram_socket_service.hpp new file mode 100644 index 0000000..5cff4e6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/datagram_socket_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ddec72ae5e840f09fb3d15fe32c86b0ae86265aa3522f5f4f1909ac4a0b6df9b +size 15317 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/deadline_timer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/deadline_timer.hpp new file mode 100644 index 0000000..e3ced5d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/deadline_timer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62a4602586496d71aa319e0ef076e06ddf38033a8dfe5abe7ac98029da5e7dba +size 1138 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/deadline_timer_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/deadline_timer_service.hpp new file mode 100644 index 0000000..cc40956 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/deadline_timer_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:988968dd606f1fa04111ac4c8013f85551ac9a4bc0dff2ef9116d9680de13ae4 +size 5018 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/defer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/defer.hpp new file mode 100644 index 0000000..c2da3ae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/defer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e4b6ff148e153a9e836ab76117e2dac598571c8fbdbca8064fe58d9a3c4eb71 +size 3952 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/array.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/array.hpp new file mode 100644 index 0000000..938d411 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/array.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:160a2b1448a346a72d1de53c074fc331d0725226aa567bae85da6e17c4b6d565 +size 1001 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/array_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/array_fwd.hpp new file mode 100644 index 0000000..95a9f92 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/array_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ba1e36592072dbc07912563a90270cb493cb55713c94a201df5ff2825f7e58f +size 950 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/assert.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/assert.hpp new file mode 100644 index 0000000..56f1f70 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/assert.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d7ea6b9ecb65d1b347ea0fe6079e48ba35c5f3bf5ff6d50ac16505e407a194a +size 968 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/atomic_count.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/atomic_count.hpp new file mode 100644 index 0000000..91612c5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/atomic_count.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9497180bff29591ec59958330b1ae52c17e2768fbeffbbfd16ab9ddb80bccfd6 +size 1430 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/base_from_completion_cond.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/base_from_completion_cond.hpp new file mode 100644 index 0000000..4390fa5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/base_from_completion_cond.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:998429380b9456ec07906d10520eefa16b8699c05bb01df72a2c09b6ebe40bc2 +size 1742 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/bind_handler.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/bind_handler.hpp new file mode 100644 index 0000000..296c074 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/bind_handler.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2dce7d6ae28b2561a9f319db0f4deefb804e509e150cfebd25d38cd790e6773 +size 23840 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/buffer_resize_guard.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/buffer_resize_guard.hpp new file mode 100644 index 0000000..0179393 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/buffer_resize_guard.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:554d0bf89e03dcd972161738e7594272c78ef9fe570d4ac9914ef585ee5b17ca +size 1593 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/buffer_sequence_adapter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/buffer_sequence_adapter.hpp new file mode 100644 index 0000000..35a62a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/buffer_sequence_adapter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87ecdff6ac328ffa07c42614e9c82dedab43d8c933f5790e1ab267186f75e03f +size 12627 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/buffered_stream_storage.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/buffered_stream_storage.hpp new file mode 100644 index 0000000..aca1ccd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/buffered_stream_storage.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d5ee9d793db3a6857412b2c6baa6ff05cdd55fb65885e3111dbbcf827d26f2c +size 2987 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/call_stack.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/call_stack.hpp new file mode 100644 index 0000000..e7f23f5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/call_stack.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7dad1d34f072b024b0281dbac2d7b82ea1316f56426dbb72ea84d738a4c7c49 +size 3003 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/chrono.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/chrono.hpp new file mode 100644 index 0000000..5b27d74 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/chrono.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c0cb57c48d203f708a0a7075d58f6ba8f7f5636983d4910a4f7bfc0774a8418 +size 2081 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/chrono_time_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/chrono_time_traits.hpp new file mode 100644 index 0000000..92ac0dc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/chrono_time_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9f688d6d1dd1223e0cf061dea3641ab0bf82da9dcef207aaac4f9ad97edfcbf2 +size 4469 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/completion_handler.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/completion_handler.hpp new file mode 100644 index 0000000..5c5c1e3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/completion_handler.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5242a1f0ef357286ce68d2a4ad1855a84d9e29617eef4cd005486e883db63ca4 +size 2610 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/concurrency_hint.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/concurrency_hint.hpp new file mode 100644 index 0000000..15e5066 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/concurrency_hint.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99f885c9c53d708243d2b35f3ba9153d95e02d88bbb13b0ae0728c631a8d90d4 +size 4062 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/conditionally_enabled_event.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/conditionally_enabled_event.hpp new file mode 100644 index 0000000..8389f78 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/conditionally_enabled_event.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bdb815d80c452be2aead43979a7529a290238d65e42b59348dc5f2b14340ca2e +size 2879 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/conditionally_enabled_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/conditionally_enabled_mutex.hpp new file mode 100644 index 0000000..ac8ebe1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/conditionally_enabled_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e32c322cda4dd70f85b386986948459466758218c6163076f4fad06f8646c4cb +size 3126 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/config.hpp new file mode 100644 index 0000000..a98cb20 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66ece32592198eb21f4cfaa4b72311e720096185bd08778d0c36a874e0b77f34 +size 59955 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/consuming_buffers.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/consuming_buffers.hpp new file mode 100644 index 0000000..85d65eb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/consuming_buffers.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50a89224b444e3d909959320060125ca5fb455c6f23067b7f25d6aac81e6e182 +size 10631 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/cstddef.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/cstddef.hpp new file mode 100644 index 0000000..e10dfba --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/cstddef.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:876cdeffe77f012bc99b31f01c816ef6158d162d787403e1c5f5cce9bf6960e0 +size 816 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/cstdint.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/cstdint.hpp new file mode 100644 index 0000000..fbb6572 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/cstdint.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87dc5e2bdb80989d7f023e37a6b4a691dff4f46f0940ec14516a633ddc841a3c +size 1558 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/date_time_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/date_time_fwd.hpp new file mode 100644 index 0000000..ecad30d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/date_time_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98492de63b13922660523824db2322c071f514dbfdcdb216a2cbb5d2166519d8 +size 792 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/deadline_timer_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/deadline_timer_service.hpp new file mode 100644 index 0000000..c25bc88 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/deadline_timer_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7330f1d3cf6d31f8bfc5154e9287eb42c3b07e7efe7ce10220d1aa0c11dba578 +size 8674 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/dependent_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/dependent_type.hpp new file mode 100644 index 0000000..0999e8a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/dependent_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ef771d2bb68bac376d27be73f61ba7ccd6994f1061a4633236fde2785ccac61 +size 891 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/descriptor_ops.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/descriptor_ops.hpp new file mode 100644 index 0000000..34a1441 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/descriptor_ops.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bf38766b065a53a8479cc2d59fb1f0d6561d53ffade51270029152e1b32407fb +size 3643 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/descriptor_read_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/descriptor_read_op.hpp new file mode 100644 index 0000000..45d2413 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/descriptor_read_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c4243177a79cd7556a5aaadad0ecd75ac9b601121941aa052383e496faba609 +size 4098 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/descriptor_write_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/descriptor_write_op.hpp new file mode 100644 index 0000000..e30eef5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/descriptor_write_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9eb62956b2a6a078997460832dc377b3293e5432c042c8dc9f52a96402eb68da +size 4100 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/dev_poll_reactor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/dev_poll_reactor.hpp new file mode 100644 index 0000000..c3b34d9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/dev_poll_reactor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0e7312952b18efb3be627dd075509e289d7cf40d1481eda0024366a8ac3d982 +size 8039 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/epoll_reactor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/epoll_reactor.hpp new file mode 100644 index 0000000..3ed8443 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/epoll_reactor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:981322680338b452120492313c6a9883d548960a0a6d6e407f8147f1ee96e3f8 +size 9467 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/event.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/event.hpp new file mode 100644 index 0000000..d7fd566 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/event.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:84b80d9811f20a74f0114680bc57431590405c5deb1b52b308e80159ba9a70d4 +size 1364 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/eventfd_select_interrupter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/eventfd_select_interrupter.hpp new file mode 100644 index 0000000..c863a94 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/eventfd_select_interrupter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1649f80faa41d46831464dd6d58240582fdedbcae01c63a02754452dab03001 +size 2522 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/executor_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/executor_op.hpp new file mode 100644 index 0000000..b07c536 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/executor_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a15a6289809dcf8107e831b5e148663d383e22af95f947b36c48ad271aaec145 +size 2605 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/fd_set_adapter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/fd_set_adapter.hpp new file mode 100644 index 0000000..cbeeef5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/fd_set_adapter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b6a0dd954f7f5e1da83551d3d0e7a3cce21e706eeabc1b220d46a90952f95a83 +size 1064 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/fenced_block.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/fenced_block.hpp new file mode 100644 index 0000000..316d548 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/fenced_block.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b2e9924b8c053cb65c9a8d2db245c6b43060c6c3a2df5660c972c2e7c122f6e4 +size 3066 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/functional.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/functional.hpp new file mode 100644 index 0000000..80834af --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/functional.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9a015dbce56f33100805251d57d62f9d5f48e3dd32cd07f6d6ed70e311b3205 +size 1014 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/future.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/future.hpp new file mode 100644 index 0000000..73977a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/future.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a9d561ed561fdede561caa5507ddb7f05e5995fe1fbab8d50eee6b6e2ae3cdc +size 1241 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/gcc_arm_fenced_block.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/gcc_arm_fenced_block.hpp new file mode 100644 index 0000000..af55624 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/gcc_arm_fenced_block.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9820d74e631afcd97e10c2804a3347a9e967fa50f8348d1ca8a1afc1fb271ef1 +size 2238 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/gcc_hppa_fenced_block.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/gcc_hppa_fenced_block.hpp new file mode 100644 index 0000000..48df11a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/gcc_hppa_fenced_block.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96a45b8dd17c72bc7fead3d1ebc5c63d1cfba6f1c27176dc947bba1b8096e668 +size 1560 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/gcc_sync_fenced_block.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/gcc_sync_fenced_block.hpp new file mode 100644 index 0000000..45e809a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/gcc_sync_fenced_block.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cca5c98e2f917d1471cca9ff5d2df11606ac8450d5c9c4087d6b06ed57d618d5 +size 1679 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/gcc_x86_fenced_block.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/gcc_x86_fenced_block.hpp new file mode 100644 index 0000000..b9f9cce --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/gcc_x86_fenced_block.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d1df0cc58ed607d8513e7ec9cafa31fcbfd55345dbc0b788c678643c51b4e33 +size 2460 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/global.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/global.hpp new file mode 100644 index 0000000..6826364 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/global.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e60644ce6695f2cdd7a3e56238bb787a73b3a9707f545566b81b2d1dfb4103c7 +size 1397 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_alloc_helpers.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_alloc_helpers.hpp new file mode 100644 index 0000000..aae3f7c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_alloc_helpers.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ffd0ef584561f007238fa3216240ae0da74b06d3efb614982000a1f6afa9e6b +size 5985 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_cont_helpers.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_cont_helpers.hpp new file mode 100644 index 0000000..e368d67 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_cont_helpers.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39ad58c023ab0f7c24ef939a6b47f4bfc96fdb1f9f40eebbff2c1f8ece7d945e +size 1364 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_invoke_helpers.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_invoke_helpers.hpp new file mode 100644 index 0000000..448e651 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_invoke_helpers.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3b1f16b044a746fae92d9a48750ab27e89494b71e1d81a44112dad477d90f7f7 +size 1745 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_tracking.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_tracking.hpp new file mode 100644 index 0000000..ba92e37 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_tracking.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b6635d3ea6a3b0edb479cf62b8897148f2149665fec8796dc1156657f32fb1eb +size 8467 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_type_requirements.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_type_requirements.hpp new file mode 100644 index 0000000..d1240b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_type_requirements.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:43f3597f6f24d05bb56afe184cf34b31824b3163a6ff8b3610d7b2d29536d7d0 +size 20351 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_work.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_work.hpp new file mode 100644 index 0000000..5b84619 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/handler_work.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6982cb1410b661682761d62249ecd855254f012e58c440fcccaeacc47516bb48 +size 2760 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/hash_map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/hash_map.hpp new file mode 100644 index 0000000..c0fcaba --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/hash_map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c27e6a838fbcbb775a33003a11f18a719ff6c583c986f19f5d5e061370b3388d +size 8343 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/buffer_sequence_adapter.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/buffer_sequence_adapter.ipp new file mode 100644 index 0000000..1ffabfe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/buffer_sequence_adapter.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54e186978a31fb591dbc80a29fc847d16b49ae3f05cb8bc2d15be8a4f4a38004 +size 3096 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/descriptor_ops.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/descriptor_ops.ipp new file mode 100644 index 0000000..6333fb6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/descriptor_ops.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c615f63ea7619dc7efc839fa0c1336717d5ab2ba5beb7f7e73d35a07003f347 +size 11981 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/dev_poll_reactor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/dev_poll_reactor.hpp new file mode 100644 index 0000000..e747860 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/dev_poll_reactor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:419445ef5ebf54fc3c6866e60addb3026dc47d7dc47295d0ebc46b11d3064dd7 +size 2587 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/dev_poll_reactor.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/dev_poll_reactor.ipp new file mode 100644 index 0000000..f96b707 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/dev_poll_reactor.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c6901a8c21d8e2c640c66a76b89f4fee668ccb4f4e39f98d6c6ce99d9b659b9 +size 13138 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/epoll_reactor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/epoll_reactor.hpp new file mode 100644 index 0000000..faaae95 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/epoll_reactor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:690aac96d9d4af45700bf8cebf235c484dde571954f6926d30c73c93e991bb67 +size 2439 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/epoll_reactor.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/epoll_reactor.ipp new file mode 100644 index 0000000..1fd2879 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/epoll_reactor.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a2f0f856e9da4a8666134b6cfc676e007b272d1a09d4b0aabcfba7f9c93a994 +size 22372 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/eventfd_select_interrupter.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/eventfd_select_interrupter.ipp new file mode 100644 index 0000000..6a41351 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/eventfd_select_interrupter.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83ac0cf55b4addfd2cebb64d25e0bbe230d22d1ba5310a1590840029f59200ba +size 4615 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/handler_tracking.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/handler_tracking.ipp new file mode 100644 index 0000000..9dcf550 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/handler_tracking.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e0abe69ec2ee487ea3ec0dfb8b52383300650c810e8ad5f5c6e73d3c5fa0678 +size 10538 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/kqueue_reactor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/kqueue_reactor.hpp new file mode 100644 index 0000000..c7f6081 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/kqueue_reactor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34b8c963f7043a6fe35745bf430484ade7e85eb608c5421897715c2a1ab391ac +size 2590 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/kqueue_reactor.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/kqueue_reactor.ipp new file mode 100644 index 0000000..5b011cf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/kqueue_reactor.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a066a1888d78ea063617cd108cd80b6de87295f5545b8d51170c728a9d0a6837 +size 16955 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/null_event.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/null_event.ipp new file mode 100644 index 0000000..462670a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/null_event.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7531976a4beb1ff09eb74ea189be031c442feb3eff7bfc1b9fe7a0613c317677 +size 1906 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/pipe_select_interrupter.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/pipe_select_interrupter.ipp new file mode 100644 index 0000000..0a07bdb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/pipe_select_interrupter.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b31cd1d671aaaf5eed37705876a77e8df80081f8e31186796fa9b51cd65d4b23 +size 3145 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/posix_event.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/posix_event.ipp new file mode 100644 index 0000000..c1ea2bf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/posix_event.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39908cb7dddb19463ab3bad162bd62b8b87dcb4ea55cf5dc62538bd0fd95ae7c +size 1776 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/posix_mutex.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/posix_mutex.ipp new file mode 100644 index 0000000..6c82f38 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/posix_mutex.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e1970f17b355449fecded0e5090583f8aced8fc949fd608d935b8e903ead3596 +size 1235 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/posix_thread.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/posix_thread.ipp new file mode 100644 index 0000000..0acf596 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/posix_thread.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:029d65e8223716bc93dfe08bf077d7125e9d08748f481e963ce2bc03a0259e40 +size 1964 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/posix_tss_ptr.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/posix_tss_ptr.ipp new file mode 100644 index 0000000..d6a2f99 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/posix_tss_ptr.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78a9935d5d0d812f1d8c638d474b62412a045743b5797aa60115c3caf39fb6e5 +size 1261 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/reactive_descriptor_service.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/reactive_descriptor_service.ipp new file mode 100644 index 0000000..89bde21 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/reactive_descriptor_service.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c6c15d9a908480d7d76d30dd0b6264c865f4d3b573086ebc25bac48ca2534f9c +size 6363 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/reactive_serial_port_service.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/reactive_serial_port_service.ipp new file mode 100644 index 0000000..a8563f3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/reactive_serial_port_service.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28321382892375a5dc048a308115d1298fc27c2c3d1af6dbf16d18f23305b7fa +size 4291 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/reactive_socket_service_base.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/reactive_socket_service_base.ipp new file mode 100644 index 0000000..c9f08c6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/reactive_socket_service_base.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6dab7bfd63748448ecdf00251e0de564588758198989047d881ad35d2d6d5f80 +size 8821 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/resolver_service_base.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/resolver_service_base.ipp new file mode 100644 index 0000000..0336955 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/resolver_service_base.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60a5fdf552827f0aea639ad5cf12c8b4832ac9e2be2a7385e058faacd4749224 +size 4061 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/scheduler.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/scheduler.ipp new file mode 100644 index 0000000..a0e6ad1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/scheduler.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a478122e74c0289806c929a4dd8315adf60dfd7866494c96b9d327eb45b3fe6e +size 13987 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/select_reactor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/select_reactor.hpp new file mode 100644 index 0000000..c1d22bb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/select_reactor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd98397a05f5d0a511c652b89663f291b90dc696e49d6a0a9ffbea020a61534e +size 2985 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/select_reactor.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/select_reactor.ipp new file mode 100644 index 0000000..932ada3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/select_reactor.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0131577863058634316bcf1bdab8475f9934f1002004c182af9fb2aaa0e98a68 +size 9270 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/service_registry.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/service_registry.hpp new file mode 100644 index 0000000..2f18297 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/service_registry.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b94b81f8f730dda706f5ece9204549a7203a93235fa18f9f03c2797717cf34b9 +size 2652 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/service_registry.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/service_registry.ipp new file mode 100644 index 0000000..ea328cf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/service_registry.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37ea7e48949dee80ffd1a2689d9f4768c6ba55cb8359a717176e5694e60effaa +size 5462 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/signal_set_service.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/signal_set_service.ipp new file mode 100644 index 0000000..c7d2a83 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/signal_set_service.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46efcbde15aeb4c1d8744e80a1a5aaef6e02cdaa53e9fb7f4e2772684b141db8 +size 20378 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/socket_ops.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/socket_ops.ipp new file mode 100644 index 0000000..324cf6b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/socket_ops.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e5c95ea3181cf293681d48d1c8648ab6890a4223efcd63273d86bbf7ce90389 +size 103312 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/socket_select_interrupter.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/socket_select_interrupter.ipp new file mode 100644 index 0000000..c10a445 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/socket_select_interrupter.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3cf50439f90b59044f9177bfc3ff6f77f49923260550eb986d10a17ab21c2ed0 +size 5739 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/strand_executor_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/strand_executor_service.hpp new file mode 100644 index 0000000..b767cd4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/strand_executor_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1507dd3bced276878aa2fba23ea00158f0d842e1bd10f3dea8f4f7b019f256e +size 5816 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/strand_executor_service.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/strand_executor_service.ipp new file mode 100644 index 0000000..6b86d7e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/strand_executor_service.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:227885e8ee5e24f5743f6b81aefe007e5a32d04e394c928c0ebdd27418bc62e6 +size 3637 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/strand_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/strand_service.hpp new file mode 100644 index 0000000..065cbb7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/strand_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f9aac5f0228438ac9becdf4fa241b455f215285f2558fe784a5eb23c1ab90cde +size 3478 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/strand_service.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/strand_service.ipp new file mode 100644 index 0000000..8f75773 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/strand_service.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5fc0b3f9e56106b6f1f87b1dcab0735bce789d5cf485dc8a7b2eee8be0d93325 +size 4988 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/throw_error.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/throw_error.ipp new file mode 100644 index 0000000..8704ba5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/throw_error.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1928c4e62a4519d7b11d8fba471d0b53b3e876e68355fd50df356827d6240858 +size 1268 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/timer_queue_ptime.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/timer_queue_ptime.ipp new file mode 100644 index 0000000..d8fa5b2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/timer_queue_ptime.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:435ddc27cba9212f1679991da9c6d19267c293a19a5cd5034455dc1d2f2df15c +size 2410 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/timer_queue_set.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/timer_queue_set.ipp new file mode 100644 index 0000000..03ef690 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/timer_queue_set.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:725d1d1aa8ed2e3f3490c9f0a3c7a0dbc3eb659d8f5284ad2104eb57e37e356a +size 2317 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_event.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_event.ipp new file mode 100644 index 0000000..7be200b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_event.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d45daae237f8399b7103b8b071a7cfd81cc196da145e2a0420e019311e7bfa0 +size 2068 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_iocp_handle_service.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_iocp_handle_service.ipp new file mode 100644 index 0000000..88c9649 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_iocp_handle_service.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a99a796c57883937211d0b520a197644dc52d10552daa81a66d564c7a21cc254 +size 14344 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_iocp_io_context.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_iocp_io_context.hpp new file mode 100644 index 0000000..a7df63a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_iocp_io_context.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c3185a6b1cd7c6e63eba4829b0a11a595606ca0110e8726ac5aca6694f099bb +size 3026 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_iocp_io_context.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_iocp_io_context.ipp new file mode 100644 index 0000000..e9edbd1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_iocp_io_context.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e9e851dd96f096bba62e728b21f176cc065c9076c34dd5e0ae4c69ea7c951e4d +size 15594 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_iocp_serial_port_service.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_iocp_serial_port_service.ipp new file mode 100644 index 0000000..0aed497 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_iocp_serial_port_service.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb39b5312b22eaaccf69067975546e131df818a7d677cfd08bd84f9e0be9b9ae +size 5621 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_iocp_socket_service_base.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_iocp_socket_service_base.ipp new file mode 100644 index 0000000..b7e89b4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_iocp_socket_service_base.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:203f46643678e8a6758bfe5f1672eb56eecaa652649ce1599aa742b54dc2825a +size 24988 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_mutex.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_mutex.ipp new file mode 100644 index 0000000..0e6a7b3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_mutex.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d97a35bcb906230535137a5e2f3a6c1398a3ce5c13c5c5b59b7b62cda41fd71 +size 2213 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_object_handle_service.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_object_handle_service.ipp new file mode 100644 index 0000000..58332e5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_object_handle_service.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:911f0248c9eda43cf23ec549af58f6454438e5e30239febda4a30dcaff58f4e5 +size 12508 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_static_mutex.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_static_mutex.ipp new file mode 100644 index 0000000..19a5fb1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_static_mutex.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e011abb39c46c428265077336fa1d11fd658053919798bf0061b9d471f7d5b59 +size 3636 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_thread.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_thread.ipp new file mode 100644 index 0000000..b02079d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_thread.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:910321a0aa3a513b3b41ff946c252c5dffc12935cccfc277eaa94ec570b474f1 +size 4102 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_tss_ptr.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_tss_ptr.ipp new file mode 100644 index 0000000..6e0659d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/win_tss_ptr.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b5aea341bddf4cf3f5af7f7e972d2d6b9c0ff3e690e0e918b9ea5b5c1b2cf43 +size 1448 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/winrt_ssocket_service_base.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/winrt_ssocket_service_base.ipp new file mode 100644 index 0000000..ecd3c7c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/winrt_ssocket_service_base.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2d25f140b10dcc762c4cb5dca096585835131448cff526b4257d4b47ffe06b6 +size 17552 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/winrt_timer_scheduler.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/winrt_timer_scheduler.hpp new file mode 100644 index 0000000..c52f2ae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/winrt_timer_scheduler.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acff5b9de152a3e7e2a71490e6602a484d32154c23ece7841e480b1aff267e14 +size 2667 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/winrt_timer_scheduler.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/winrt_timer_scheduler.ipp new file mode 100644 index 0000000..538a72a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/winrt_timer_scheduler.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e772c4e3f92e0bfd42630a451364d82148f05fbe7db7d8119ce47c3c7889a5ec +size 2995 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/winsock_init.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/winsock_init.ipp new file mode 100644 index 0000000..a449651 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/impl/winsock_init.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:081f4c4175ac81ee4b3ce27b493b6e455260527ce581e7034265f913f306dec9 +size 2050 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/io_control.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/io_control.hpp new file mode 100644 index 0000000..b003f88 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/io_control.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96633171c8b44a0d68f1d7f9afd052c2b42dd33e7d12d56cdc34e849b4a25cca +size 1883 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/is_buffer_sequence.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/is_buffer_sequence.hpp new file mode 100644 index 0000000..315eff3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/is_buffer_sequence.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d4ee75ceb8b8d6fda3cb51245c34a960e03b3cbb20f3886e8776c7e604fba3f1 +size 6596 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/is_executor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/is_executor.hpp new file mode 100644 index 0000000..58e2013 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/is_executor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0cea7459803b58a41c8d7e3044f28533fee306035110ee5053b0edad8eb37f77 +size 3033 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/keyword_tss_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/keyword_tss_ptr.hpp new file mode 100644 index 0000000..e9e3541 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/keyword_tss_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c2f3373d43bfcb17aa2860cd6cc84f862b9ccd2b3506c07401787048ee931507 +size 1425 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/kqueue_reactor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/kqueue_reactor.hpp new file mode 100644 index 0000000..493d868 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/kqueue_reactor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd9be5ec34b51484899c85794c47ada822c6c3836e5be0047c576a4c3e138e31 +size 8277 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/limits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/limits.hpp new file mode 100644 index 0000000..52f5c31 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/limits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7c7934f7e04faaedb09dae84b87c15fd4b55fadcc71b78974f75f8e4467c417 +size 734 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/local_free_on_block_exit.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/local_free_on_block_exit.hpp new file mode 100644 index 0000000..1061984 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/local_free_on_block_exit.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9498506326999472feb1c06836108e989a2815c95a1055c08c465913cf0882d +size 1470 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/macos_fenced_block.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/macos_fenced_block.hpp new file mode 100644 index 0000000..7ab9c5a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/macos_fenced_block.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7042a9fe1215bcaa5e5a68a47c7327e330cc4a4722aa93e119ab3af53de82b2 +size 1380 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/memory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/memory.hpp new file mode 100644 index 0000000..20ded41 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/memory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ee10c6726c30b39c8365b65ea3aa05ed04f6894f6f2d4f4bd9bab7e9ed435a5 +size 2019 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/mutex.hpp new file mode 100644 index 0000000..f2ee67b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:762278d4eb8f2d004071a04ed0aee9b33a3009d8831064233d15a2737deed7f9 +size 1351 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/noncopyable.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/noncopyable.hpp new file mode 100644 index 0000000..7ca1dfe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/noncopyable.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b67760ea76346dbb5e08586042013323f003785073e6863b88de6530105d645 +size 1000 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_event.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_event.hpp new file mode 100644 index 0000000..82fe350 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_event.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c408992c79d9eac27f562e2f501c91a35c1bd03d642463ebd4e2c170ec7717f2 +size 2045 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_fenced_block.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_fenced_block.hpp new file mode 100644 index 0000000..daa90ac --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_fenced_block.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01505376bf724aec479e45343c544117b805d380dea4522633c222453f6b6cdb +size 1044 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_global.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_global.hpp new file mode 100644 index 0000000..ef2fec9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_global.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e463ec37cc78eb19626753040fc154c4bdd848f614f78e192eae7da742ff9649 +size 1295 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_mutex.hpp new file mode 100644 index 0000000..038187a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0477f08f25b858570f94c32baab8c8636e994a6252c24838fa852d97d48fc86 +size 1255 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_reactor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_reactor.hpp new file mode 100644 index 0000000..5a20055 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_reactor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eda399cc81b0a3f15ad061a0393b4ed7e1606f8ed887f4d0982d6145a1550428 +size 1563 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_signal_blocker.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_signal_blocker.hpp new file mode 100644 index 0000000..ae97ff7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_signal_blocker.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e9098cfdf48d6387f3b5fd1bc10ee59840e397a321890bed3c3d61ee8ae96ac +size 1627 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_socket_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_socket_service.hpp new file mode 100644 index 0000000..f44678a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_socket_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:63fd3ac97319fab8cbb8b039f5adcd8e1514b3de09e3f21279fb87b3deb38604 +size 16545 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_static_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_static_mutex.hpp new file mode 100644 index 0000000..b848efc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_static_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0a420bc41243fc4936c87801144d33927016d65d3e700529e868d5fa0b62b12 +size 1259 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_thread.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_thread.hpp new file mode 100644 index 0000000..53a442e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_thread.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de8136a6db0518122d97f243ea13b8e45e11ac9be1b3c73eeeb99f3943c7a73b +size 1442 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_tss_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_tss_ptr.hpp new file mode 100644 index 0000000..95005f9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/null_tss_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e740f325fd66cd2002a3084d6a80ad6400175491e28f0c3accc1f828c7470a0 +size 1272 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/object_pool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/object_pool.hpp new file mode 100644 index 0000000..da6f6d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/object_pool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9ac8678879817b5409579357a89fa6112daabe06483d5ddb4bd790a8ce2e752 +size 3500 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/old_win_sdk_compat.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/old_win_sdk_compat.hpp new file mode 100644 index 0000000..0e8837f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/old_win_sdk_compat.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:68bf6319aafb0ab8724db103e7a5194aab45f191a91afcb45942536cd21767c8 +size 4478 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/op_queue.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/op_queue.hpp new file mode 100644 index 0000000..f6ae82a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/op_queue.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b43c38d36897962c431b5ccb406185c238594c9bf8ba6e61c72194ea0d7e294 +size 3313 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/operation.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/operation.hpp new file mode 100644 index 0000000..874fe82 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/operation.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d4a8e0a90a9d91829ab694361299e2e10f35b1bcc2d2b8194f859e86b7fb323 +size 963 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/pipe_select_interrupter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/pipe_select_interrupter.hpp new file mode 100644 index 0000000..861e041 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/pipe_select_interrupter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4bf8bce2b5112c26873889254dfe7b8e96b4722a3b0103c0b266dd7f25b707bc +size 2601 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/pop_options.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/pop_options.hpp new file mode 100644 index 0000000..fac207d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/pop_options.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a26e10e684101d4badfc62fb6e05ec36d8bcb08d6206a3990cf39a771d2e0f3a +size 2577 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_event.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_event.hpp new file mode 100644 index 0000000..c04a8ba --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_event.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8038d8ca76a6620283b33a1532f654d59b6de8ff26790d6f2e474ee448846e7 +size 4182 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_fd_set_adapter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_fd_set_adapter.hpp new file mode 100644 index 0000000..c2d8152 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_fd_set_adapter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd1d92681b8b5ac8a29284bbdee08a86aec41fd155875639c0dac0fb8b2a389b +size 2992 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_global.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_global.hpp new file mode 100644 index 0000000..f365dde --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_global.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6921e597374317d7dbd939efad96e80d5fc3806423ad1f834f9c4b7bfaf46e9f +size 1807 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_mutex.hpp new file mode 100644 index 0000000..cb7c835 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dbea4786ef8d85e0e4eb9399b2167cef025573c8c9cca66aaae4989b0396f460 +size 1685 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_signal_blocker.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_signal_blocker.hpp new file mode 100644 index 0000000..8df1999 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_signal_blocker.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7de47be836117003368e3e6e2fb8c931532130663ef76cea37ee4873c4c3612 +size 1975 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_static_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_static_mutex.hpp new file mode 100644 index 0000000..e0d397f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_static_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0ab47579aeb2ccfe327c503bd3930fc79292018c5cf4fdd65cc340ae6c1ef7e +size 1467 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_thread.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_thread.hpp new file mode 100644 index 0000000..94ed6e2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_thread.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61e94bf73cf002cef50f3af4f9f6fecadb0213239a4ca7eef36639cc9051714d +size 2187 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_tss_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_tss_ptr.hpp new file mode 100644 index 0000000..ee08e63 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/posix_tss_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a66843339903548a0d0a094dd23291f56d26f1387c353b7ca2772b4be1e790e5 +size 1800 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/push_options.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/push_options.hpp new file mode 100644 index 0000000..6b39ed6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/push_options.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e69d196ad62bbfed3e013806ebc3f6829cdb52d7989552bb3f79b15beea5f35f +size 4224 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_descriptor_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_descriptor_service.hpp new file mode 100644 index 0000000..14fbd6b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_descriptor_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c562b3f05d5343c9b98c95095a56a33504451468082ba61efbd9bfc0289ab717 +size 13402 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_null_buffers_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_null_buffers_op.hpp new file mode 100644 index 0000000..dcb6956 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_null_buffers_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e56ab8a02437079aa8bd4391b94e53e9629fb9acaaacc0304cd8fcd7920b3451 +size 2923 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_serial_port_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_serial_port_service.hpp new file mode 100644 index 0000000..65ddb7e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_serial_port_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e8f749814ebfeeb8114abc5f7e13254e65c9ceae5cf96d921e0a5675b6d39084 +size 8177 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_accept_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_accept_op.hpp new file mode 100644 index 0000000..a13f104 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_accept_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30ad229e3c52c390d49d7454da20ae8ea2edbf9ee3c584bfc25ee3c5935aa5f0 +size 7321 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_connect_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_connect_op.hpp new file mode 100644 index 0000000..9d9c8cd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_connect_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:06fcc764657249ba5206c1093ffcab8f6e78f706a3c07fe16cc8ab4434dbe636 +size 3554 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_recv_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_recv_op.hpp new file mode 100644 index 0000000..1f0f428 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_recv_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bf7fa101924c66aa9a3621bce4eccd724ef01ef3ea9a02d4843fede183919f08 +size 4512 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_recvfrom_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_recvfrom_op.hpp new file mode 100644 index 0000000..633c560 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_recvfrom_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34a07dbd6353b10a36c49cd34f4facbfdf333e4e91b1bda5fa1a12f81107759f +size 4733 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_recvmsg_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_recvmsg_op.hpp new file mode 100644 index 0000000..3f3bd94 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_recvmsg_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3a7a1eb6d9b36d19b754d254600c9ebcaf3fbb7d6556a532967082ebf831095d +size 4484 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_send_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_send_op.hpp new file mode 100644 index 0000000..b638ffb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_send_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b23f002481150ab1bf8dd21e2b9ca9526c9e9713420fa01b7ef114fdd7a6388c +size 4457 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_sendto_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_sendto_op.hpp new file mode 100644 index 0000000..e5b6dc8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_sendto_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:308ff82940137d6c970eb49ae5d92cbafb6f8fcce43f35ba039f6dfa5a1f373e +size 4432 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_service.hpp new file mode 100644 index 0000000..d93c4ad --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26343bee66eb42422df17202c557270007b4d8b790ffaa8ca0f72f719fdc84e2 +size 18269 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_service_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_service_base.hpp new file mode 100644 index 0000000..1831010 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_socket_service_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7958ebcf6ee028149eb42bfcac2e163e234ef97556194e6658daeae38cae2bb5 +size 18465 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_wait_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_wait_op.hpp new file mode 100644 index 0000000..1c9f8e5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactive_wait_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c5f66c4c1bd4228854ea2c14cfa162ad62a594414fa110a0997a77b3387f85d +size 2776 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactor.hpp new file mode 100644 index 0000000..78e59e8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2653de9b06f66e978f670a9d4872c088aa95dbfab4673b0ff68d7b980cdb337a +size 1003 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactor_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactor_fwd.hpp new file mode 100644 index 0000000..5cbc239 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactor_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce703c076bfceab4fe53528444e7b894b5a2b576b02ee06b8b700f10f1ab2083 +size 1155 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactor_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactor_op.hpp new file mode 100644 index 0000000..dbe4c76 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactor_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5fb3879ce982139752778893c6b680126e7aa9c8c34491d82f18684920c4029 +size 1689 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactor_op_queue.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactor_op_queue.hpp new file mode 100644 index 0000000..c9cc676 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/reactor_op_queue.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7df2d757883bbf636430cb9912229737427fac6621f8d3db51ed06b3550dfc63 +size 4979 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/recycling_allocator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/recycling_allocator.hpp new file mode 100644 index 0000000..325881c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/recycling_allocator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98910af74e8aba26ff0389d77fb383f78e125c82424a7f7ebf78bb68d0893451 +size 2265 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/regex_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/regex_fwd.hpp new file mode 100644 index 0000000..c3b3be6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/regex_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07a714670336891220fa8ebd332e78092a10d1457093633576e64935d647d134 +size 846 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/resolve_endpoint_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/resolve_endpoint_op.hpp new file mode 100644 index 0000000..02faaf2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/resolve_endpoint_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aae0f9759cbe29e69de297c2faa50fbdede36f42d58380397c780b91f5e6a597 +size 4327 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/resolve_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/resolve_op.hpp new file mode 100644 index 0000000..fd8772c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/resolve_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e2e69fc76e9723ec83736f096d2abd20bb46f517c27cdde77f6b032703b15967 +size 1090 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/resolve_query_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/resolve_query_op.hpp new file mode 100644 index 0000000..e28d431 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/resolve_query_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0adc1f589d12081a1180e74cd517d0de4fc1a54510f989a86605e11a99b3ee3 +size 4525 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/resolver_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/resolver_service.hpp new file mode 100644 index 0000000..d206ed4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/resolver_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df2a6be94c78b7ec5de727c03aa3d5104d179bd86a92f0611b3976bd58d20475 +size 4685 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/resolver_service_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/resolver_service_base.hpp new file mode 100644 index 0000000..8217f7f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/resolver_service_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa187d2f2472886a8bc62fb9e41ef3a32c4b181aaf7ccb3a7929712b1e513547 +size 4363 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/scheduler.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/scheduler.hpp new file mode 100644 index 0000000..787b752 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/scheduler.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86fb8d506514871740412ac91fe0fe21f02700d4a2ce13260ee644fa255b7915 +size 6889 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/scheduler_operation.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/scheduler_operation.hpp new file mode 100644 index 0000000..d037fa3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/scheduler_operation.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:678d6b1fcb0ee20f2c3a7d300cb8a74d4082a211d6b52b29c51708c3c8279b7d +size 1922 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/scheduler_thread_info.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/scheduler_thread_info.hpp new file mode 100644 index 0000000..e04cfb3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/scheduler_thread_info.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7d406acc70c3777d7af18c238762c1116b7690d7f41b297e410f80e2a33b14e +size 1079 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/scoped_lock.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/scoped_lock.hpp new file mode 100644 index 0000000..6c979ca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/scoped_lock.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ae28679d3434c29929b02744650190b780883d086f54fab2f28f01a268c8c1e +size 1942 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/scoped_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/scoped_ptr.hpp new file mode 100644 index 0000000..f4d29f9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/scoped_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1abf14af75fcbd2935bffbf5578baf9c44657a536b245f723da123d006d5f3d +size 1448 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/select_interrupter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/select_interrupter.hpp new file mode 100644 index 0000000..9b67be3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/select_interrupter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:80e944ceb28f98434e86e07dfe888ab1aed37e617176f3a49db4dbd1a94b2a5b +size 1426 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/select_reactor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/select_reactor.hpp new file mode 100644 index 0000000..2f36bb0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/select_reactor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c9e7220dae6a79dee806e39dd52111e3d613f35df30472eeadb7a6c1199cd378 +size 8813 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/service_registry.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/service_registry.hpp new file mode 100644 index 0000000..8a36bc6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/service_registry.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0ec76748aae87d617c0bf89fb5762d3cd4d82e37c68fb6115c4c2b36852907e +size 5645 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/signal_blocker.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/signal_blocker.hpp new file mode 100644 index 0000000..e0347a8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/signal_blocker.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4fdcebc8be95fd4c92e88b2ce44336dd3541aabfead2162c782830144069d91 +size 1382 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/signal_handler.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/signal_handler.hpp new file mode 100644 index 0000000..6d51bd0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/signal_handler.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5584d576a6c9afc540c671031d82128c7625e9b220bb5fa94bcad666bd01be5 +size 2765 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/signal_init.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/signal_init.hpp new file mode 100644 index 0000000..78d5927 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/signal_init.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d6a2a6d637ffb079c12bda4d45f51b1af8d3b01f85a60c4776ea088448e7132 +size 1070 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/signal_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/signal_op.hpp new file mode 100644 index 0000000..3281016 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/signal_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4103884a9db9abe2bd7e3bac6b4c7e7859d5e84e935352769ad467b537fc4f94 +size 1146 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/signal_set_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/signal_set_service.hpp new file mode 100644 index 0000000..5569813 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/signal_set_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14703ab36342438651a22b9621a377c05a596d0b8d3a3ba5a85a8d9d9a7a7b9e +size 6588 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/socket_holder.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/socket_holder.hpp new file mode 100644 index 0000000..336753b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/socket_holder.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:129ae88c4acac7228b8ee5514400a84b7922fe88ba1e04b8eb22d88d51ffb986 +size 2148 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/socket_ops.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/socket_ops.hpp new file mode 100644 index 0000000..8868af4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/socket_ops.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2522fea39af9f389896011cde2adca05991f9c639f62882da56cfd4b25708f25 +size 11828 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/socket_option.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/socket_option.hpp new file mode 100644 index 0000000..c18be6f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/socket_option.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8161d5674a4010b6005b6751352902245491957b87502f0143506b522efd71bf +size 6410 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/socket_select_interrupter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/socket_select_interrupter.hpp new file mode 100644 index 0000000..b6afd80 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/socket_select_interrupter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81ac3eaa25f11edf101e26f7deb03da3110ecdbf7895391309d0fa9453e7cc3b +size 2618 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/socket_types.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/socket_types.hpp new file mode 100644 index 0000000..c455de1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/socket_types.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37b29fb54ccb865cc3667bf6d1aa1d8deef063aac98262e6a5acba718eeac1a6 +size 16173 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/solaris_fenced_block.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/solaris_fenced_block.hpp new file mode 100644 index 0000000..1e974f8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/solaris_fenced_block.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f71d24b1f3dfcef03fdce219d3274641e328a701610a0ba0fefd4f22cd860eb +size 1338 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/static_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/static_mutex.hpp new file mode 100644 index 0000000..23f8437 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/static_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c6225ed7dd28b5a93c1b938f1de60f41fb54a7af30d189713518aa44f2db1ec2 +size 1745 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_event.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_event.hpp new file mode 100644 index 0000000..5630779 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_event.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e13bb9b2d1d9960bc66d4a01377de01b0ded62642213d6ef6acc787939bd1d28 +size 3728 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_fenced_block.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_fenced_block.hpp new file mode 100644 index 0000000..84d4cc3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_fenced_block.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48cf0e90eab1dec6ddecca727cfebcd7b9e638a26874e345ccb6bc4a79f6e6be +size 1408 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_global.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_global.hpp new file mode 100644 index 0000000..093e50b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_global.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da092fab7f9093ea6c6445ba3b27c9e55128d44b3ef373297f467073f628d51e +size 1568 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_mutex.hpp new file mode 100644 index 0000000..981a72c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49fad314848f1b644acd56848a4ebf246de7f9c1a1f5453c0c0014df5fc046cc +size 1404 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_static_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_static_mutex.hpp new file mode 100644 index 0000000..82e048d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_static_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:69bedc8390c52cf71afb6fe6274f89ea692b3407451559ba7b9dd478273a4504 +size 1586 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_thread.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_thread.hpp new file mode 100644 index 0000000..046b28f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/std_thread.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e1e3d70025f5eb3615c4f4e6f6d507b39a112e9d8abe3bf7a61eb7c9faf8b1d +size 1425 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/strand_executor_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/strand_executor_service.hpp new file mode 100644 index 0000000..e0fc3cc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/strand_executor_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6fc80f2c0dfe52965115eab9a00e51dfdc1d8353e324922b2108f55be4cd757b +size 5015 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/strand_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/strand_service.hpp new file mode 100644 index 0000000..fd32207 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/strand_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29341ec61f2b811bd36f27ca858f2b55f76288ae4128999e6205b27a9898d7df +size 4811 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/string_view.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/string_view.hpp new file mode 100644 index 0000000..e7b1464 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/string_view.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95457b89a3d6655a11a37220a3ea5b5c724be81e150915539eb4f4bc791e07ed +size 1574 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/thread.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/thread.hpp new file mode 100644 index 0000000..a7786d1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/thread.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9277c1199fa44fb09ba56c2abb743e4e14fb062729a0601b209f14a0f2f3eee3 +size 1658 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/thread_context.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/thread_context.hpp new file mode 100644 index 0000000..a819616 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/thread_context.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6762729b444057c389dd82f7f92feb6678cb11d2f5757b3e2574fadc9642eda0 +size 1135 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/thread_group.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/thread_group.hpp new file mode 100644 index 0000000..b29cebd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/thread_group.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d62106a52c11bdcb09e2aa8a35d1a9a454ddadaebacc64ed899d4a0027f8b053 +size 1901 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/thread_info_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/thread_info_base.hpp new file mode 100644 index 0000000..03d09b8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/thread_info_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acbc1827390656513f54c335063d9cb777d0650c01720e421eb93116674e6a9a +size 3095 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/throw_error.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/throw_error.hpp new file mode 100644 index 0000000..7cbc9ce --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/throw_error.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:93184285a2920f25f94008e960ff45156730e626e997a1143a94d7793e336733 +size 1377 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/throw_exception.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/throw_exception.hpp new file mode 100644 index 0000000..b763611 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/throw_exception.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:567027051197e12e08a9dc03517ccddc66ed298623e20c5274cfd83e3a602717 +size 1512 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_queue.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_queue.hpp new file mode 100644 index 0000000..fcde3f5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_queue.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04a92cddc3b58662d497999a27af6f089b2e3fc52756930b15658c7a1208f7ca +size 9873 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_queue_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_queue_base.hpp new file mode 100644 index 0000000..27ed138 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_queue_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:160ab4341e1b2d50177f346ba7fe43073499c12beb6632b3472a0d8b18eca995 +size 1754 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_queue_ptime.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_queue_ptime.hpp new file mode 100644 index 0000000..cea2e0a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_queue_ptime.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e633f63849ed6df00289af000566bb5d95bc21fcd04be2f423a91e5fa10cddc7 +size 3132 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_queue_set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_queue_set.hpp new file mode 100644 index 0000000..8573f3e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_queue_set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd3ab29422c2a48a51b01715b4dc2035229f50eddce6d57a57b215e5cced0f08 +size 1805 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_scheduler.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_scheduler.hpp new file mode 100644 index 0000000..d52a5f1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_scheduler.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7e294e9dbda06b95a6bcc055806dcb24cc2a154520a3be677e9ee1ae3b7c690e +size 1157 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_scheduler_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_scheduler_fwd.hpp new file mode 100644 index 0000000..046b01c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/timer_scheduler_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9655df419c406b427d38db49ecfc9b971c070bda519e319d645bc586cadf33b9 +size 1225 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/tss_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/tss_ptr.hpp new file mode 100644 index 0000000..b830e5e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/tss_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1783dca827adc6dad1948d09e9356e5b81328e7785132a9b8bf46462112cc46d +size 1883 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/type_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/type_traits.hpp new file mode 100644 index 0000000..b832572 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/type_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81149d082102b1619a71493c4ba31624535717e44eeff724c42afc497e0a8fc0 +size 2746 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/variadic_templates.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/variadic_templates.hpp new file mode 100644 index 0000000..5a0733e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/variadic_templates.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b3bfc75ea923ab378a7c4fc990e7e69ef1edf0309a41bd3387ba5fbe412f8ad +size 4528 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/wait_handler.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/wait_handler.hpp new file mode 100644 index 0000000..a56579a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/wait_handler.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0b2510d6ff0652a018b73bdb9382e5c79790e37ae093b2869d66848fe46c711 +size 2643 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/wait_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/wait_op.hpp new file mode 100644 index 0000000..fcf6911 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/wait_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de2ba94c8fd940e00cb1097e45b8530107cdf4952f836081b4eeef5f36da1448 +size 1021 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_event.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_event.hpp new file mode 100644 index 0000000..23b4c41 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_event.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f234349477d033e64294e1c2272f6e8da40fce00dd1fd2f47b0a570f6a5a2e9 +size 3596 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_fd_set_adapter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_fd_set_adapter.hpp new file mode 100644 index 0000000..a846024 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_fd_set_adapter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fda7ed1dca38c382d8471621b2e18776cc85d76bd335fd0a16eb41b03a471578 +size 3911 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_fenced_block.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_fenced_block.hpp new file mode 100644 index 0000000..2af4ab6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_fenced_block.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:449f35f728927d4d4ba098ca3972124ed8a1361c7caabba3fa0e153a57309d3b +size 2138 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_global.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_global.hpp new file mode 100644 index 0000000..ffa9eaa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_global.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4326d64ea4d853ead8a891c2753c1de8c98edee7c227f458d94a7f1949f1356 +size 1823 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_handle_read_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_handle_read_op.hpp new file mode 100644 index 0000000..eaa5822 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_handle_read_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cdf4c9a9047b170f207331154187e434305034c2cfc482db65a3c6181edeb616 +size 3689 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_handle_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_handle_service.hpp new file mode 100644 index 0000000..8456bba --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_handle_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f5cc6c988536837ad6cef362e037a387267a258ee8283164a5804917356bc17 +size 12356 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_handle_write_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_handle_write_op.hpp new file mode 100644 index 0000000..0faba8d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_handle_write_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:050375a8210731bf74fd7a4a4fb21210211f3cc918f89b0bf6cb160427e22441 +size 3484 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_io_context.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_io_context.hpp new file mode 100644 index 0000000..484aef0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_io_context.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a887684ca04873e9cde919aafd54226d9c1df02ba5018fc44d8373b0dc494c48 +size 11293 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_null_buffers_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_null_buffers_op.hpp new file mode 100644 index 0000000..0cbbd92 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_null_buffers_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f7654939397009a9fc199bfb92147311dc540e73241b075a5d7261fc0ba5a0b +size 3850 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_operation.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_operation.hpp new file mode 100644 index 0000000..16fa70e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_operation.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d6969bec7a2226db3061fa310680c255d722cc391ab8a6d133ae25cc9ae4592 +size 2187 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_overlapped_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_overlapped_op.hpp new file mode 100644 index 0000000..9c1c4aa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_overlapped_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98f7fdcd47ae4d20dd98572e5787399b3f264036bf5e1dbd1d6ed6ae574b2091 +size 2918 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_overlapped_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_overlapped_ptr.hpp new file mode 100644 index 0000000..2d19b3e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_overlapped_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0f4d8cd2abbd0afa9bf52fd817be6c8de971d9ea2fccf64997cffc2cd4c70ba +size 3561 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_serial_port_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_serial_port_service.hpp new file mode 100644 index 0000000..8202ef3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_serial_port_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bf4469088d254ce43cddefc1f1aa71238f709112ba030f3bd4c8dcf3dc525460 +size 7848 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_accept_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_accept_op.hpp new file mode 100644 index 0000000..a9342ac --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_accept_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f10aab18b460d197b69e28bd51257b2792557afccd73900e33e0a57e2b4ec654 +size 9676 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_connect_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_connect_op.hpp new file mode 100644 index 0000000..571dfcf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_connect_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f98301ef1adf3e679f0acc45dbbfd611ff049590a3f1f430e0eeca3b586edd8 +size 3835 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_recv_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_recv_op.hpp new file mode 100644 index 0000000..9e385db --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_recv_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b13de30ace488f64262fc869f05d1b1613f00c2b2374ac1d92f94b7709a241c +size 3958 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_recvfrom_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_recvfrom_op.hpp new file mode 100644 index 0000000..3e0d647 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_recvfrom_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8538901831792383ed246c64c94153d98fdea6696a858ab84f61e17e1a24cf5f +size 4116 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_recvmsg_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_recvmsg_op.hpp new file mode 100644 index 0000000..acc2a28 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_recvmsg_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79334e9adab359b29c803a19bce4fed09266a9e046d36a8e7ec7dd03e7c9d5bb +size 3937 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_send_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_send_op.hpp new file mode 100644 index 0000000..aeb9a7e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_send_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:522a003daf6c68da503c14749c0567c49f413aa333e77dae1e86a9c495e85ad2 +size 3701 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_service.hpp new file mode 100644 index 0000000..2f236f4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f95ab08dbb3af7fe18f341202fe97b87c5ff9bb75b90da419ecd9b3699bff80 +size 20585 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_service_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_service_base.hpp new file mode 100644 index 0000000..50ebb57 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_socket_service_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1de9b20eec883e09f4a42351d7074cbf10ae75a4a1c5329fc5f1ad9a1da115b +size 22970 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_thread_info.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_thread_info.hpp new file mode 100644 index 0000000..fd11fa2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_thread_info.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8757a76df82b24733b37e8faf7caf5e125281de247127afdc662fd65d656bb0b +size 903 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_wait_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_wait_op.hpp new file mode 100644 index 0000000..61f0f72 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_iocp_wait_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e28640c50c829aa4a8062030a78d52ac9b82b3d3f5e5d23eff395bee8f85a07 +size 3711 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_mutex.hpp new file mode 100644 index 0000000..18405ed --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9881d335171e72da5d16a814726f1f71b0432e1e92bbd70399612795ce111400 +size 1832 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_object_handle_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_object_handle_service.hpp new file mode 100644 index 0000000..7447b93 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_object_handle_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96619f6ff6e1f1ecbbf2deb121219f63537d6921fcef5849c67fd88cd06fb066 +size 5991 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_static_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_static_mutex.hpp new file mode 100644 index 0000000..b302422 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_static_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea162c53713c8fe9f3f354f4a5ae8c60fcdabdda9b03fb6dcb9ced41b9a091ae +size 1937 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_thread.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_thread.hpp new file mode 100644 index 0000000..151c2ba --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_thread.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5da25470ee00115bc15732d2b8300f8d13777a37f28e812192639f8de26d601 +size 3233 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_tss_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_tss_ptr.hpp new file mode 100644 index 0000000..92d849e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/win_tss_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:027351323e075b51bbb4cf75f579bc195e2964cb72876a8e69e8c421c667b5fa +size 1744 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winapp_thread.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winapp_thread.hpp new file mode 100644 index 0000000..4c78c62 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winapp_thread.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df88b9b348ec91207daa1f83252c90a0c13dc8ecb428782eb3e43f4d2ab4a50c +size 2740 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/wince_thread.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/wince_thread.hpp new file mode 100644 index 0000000..6bad7f7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/wince_thread.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a9330e36ec552fd2376174739bf6b057c1790b6d5fda2bcffc7c25eb87706a8 +size 2683 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_async_manager.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_async_manager.hpp new file mode 100644 index 0000000..f6a68f7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_async_manager.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c2f02eaa8e8c37a467703b2385624d1830165aa09dcff8334d6c607b9c0840df +size 8700 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_async_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_async_op.hpp new file mode 100644 index 0000000..cdebd5f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_async_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04b1d6bd54a98c9cbc75a2d43950b61326bf42aef5c6aa9e39f552f9c10d0078 +size 1487 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_resolve_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_resolve_op.hpp new file mode 100644 index 0000000..afd78e8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_resolve_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a7fd049a17949996d69be978d7ffcad3e8f26a70c8e7d4e998ed15b5c0ba7bd4 +size 3784 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_resolver_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_resolver_service.hpp new file mode 100644 index 0000000..c33ec11 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_resolver_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8571d956ea0ac4f98b5508e0052d2b63a57ad17471f657ab4f6168ec8d915483 +size 5746 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_socket_connect_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_socket_connect_op.hpp new file mode 100644 index 0000000..dd8baaa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_socket_connect_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c71da19c487253fea8777ce75ed35e22de6a2a8efeab6fc8cbc19f49a8c05ea9 +size 2965 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_socket_recv_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_socket_recv_op.hpp new file mode 100644 index 0000000..2879335 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_socket_recv_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:84f0385bb94a35ce2578286652e923897643d8f89bcd0e78d268213973b4678a +size 3764 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_socket_send_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_socket_send_op.hpp new file mode 100644 index 0000000..3a34fed --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_socket_send_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb7ebe5416c9329a3283463e9bbca847740b74baa929deb54c0df302170bd7b1 +size 3399 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_ssocket_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_ssocket_service.hpp new file mode 100644 index 0000000..555e029 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_ssocket_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0525c18869c3de8f89c61ff19b386135ae7f4025e4ac1e9b871a9b0da7496e7f +size 7089 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_ssocket_service_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_ssocket_service_base.hpp new file mode 100644 index 0000000..62fd60c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_ssocket_service_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:12e5c1cd470783f0be3dce2028ddc99489948eaa7c33a667bbcad4c12064c0eb +size 12560 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_timer_scheduler.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_timer_scheduler.hpp new file mode 100644 index 0000000..776d4da --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_timer_scheduler.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2008908bd8882a5c4d13afe6b6d94e48428683049640df1c36d6967e3f5679f +size 4511 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_utils.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_utils.hpp new file mode 100644 index 0000000..78905ee --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winrt_utils.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:640ef16c0cf47062f071ab23637a2e6d3751ae0bbebbdb717d0f956faedb5d80 +size 2760 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winsock_init.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winsock_init.hpp new file mode 100644 index 0000000..d0c8cbc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/winsock_init.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:63f1f7dc67a733908855a135025e3aee04ff5dcdfc8ef7750a9a84123476b50e +size 3232 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/work_dispatcher.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/work_dispatcher.hpp new file mode 100644 index 0000000..4ff4f34 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/work_dispatcher.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:593d3454031d55d415a0f3f2e42a1530260a483e68c4576197e400150e006fd1 +size 1929 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/wrapped_handler.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/wrapped_handler.hpp new file mode 100644 index 0000000..4e90d86 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/detail/wrapped_handler.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b853d7f308c42c5c754df3ebc6d198a1802c0142c5c54c18c556bcfdad3239d +size 8334 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/dispatch.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/dispatch.hpp new file mode 100644 index 0000000..60493e7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/dispatch.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f02de1b3a86abcd3eb6b94e2342601fbcf4c010bc414368357382d342ffd2fff +size 3997 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/error.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/error.hpp new file mode 100644 index 0000000..a78d1c4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/error.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:baa0e11510425b18acc67872e2c418d81623e6100958f22568444c5237222aba +size 10351 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/execution_context.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/execution_context.hpp new file mode 100644 index 0000000..ccb5d1b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/execution_context.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e14bfddcc202437cb659405c666fa9093b81ee958addac171658f40255b5e28e +size 14333 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/executor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/executor.hpp new file mode 100644 index 0000000..f89bc41 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/executor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:131ed030b7701fd32bbb00762ac82e723b80532911ea42968b1d405f674ba66f +size 10297 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/executor_work_guard.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/executor_work_guard.hpp new file mode 100644 index 0000000..733e454 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/executor_work_guard.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e5bddb1ec2b137b07255c945b88b168a7be362fc8003318e60951aebc8f21ea6 +size 5133 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental.hpp new file mode 100644 index 0000000..c0259de --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:245d8dd777c1a59a97752137ecad2230d8591a93b709e4ddc133b86227e8f483 +size 656 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/co_spawn.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/co_spawn.hpp new file mode 100644 index 0000000..6a81f03 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/co_spawn.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d2458fda0e9d12b5c6597ed32688cccb1e646db6c3bd82fd37f4bf3709a3e9d +size 6380 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/detached.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/detached.hpp new file mode 100644 index 0000000..ac46276 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/detached.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9fcdefa1caea5197033dede92a721728e623fbf476f3478344356096e664b25e +size 1826 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/impl/co_spawn.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/impl/co_spawn.hpp new file mode 100644 index 0000000..fdf8cd9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/impl/co_spawn.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc9869211858b73eb3d3debdbe1c1faef44fdf975a730a1253f1972d5b00ebaa +size 20232 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/impl/detached.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/impl/detached.hpp new file mode 100644 index 0000000..5f37f0f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/impl/detached.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:20caf730d7400d2a87a8b4567617580e1ea2dcdf5be2563397f22738f1282342 +size 2128 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/impl/redirect_error.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/impl/redirect_error.hpp new file mode 100644 index 0000000..d043f90 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/impl/redirect_error.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8d4876b1637b67e716211d19efe02db8d4f5c44683ab56350a91bf5e42c3795 +size 8588 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/redirect_error.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/redirect_error.hpp new file mode 100644 index 0000000..803993b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/experimental/redirect_error.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b051c51392c0bb980506ddddfd2698e932975873c8132a0e22f930f59079f085 +size 2046 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/basic_endpoint.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/basic_endpoint.hpp new file mode 100644 index 0000000..5863d78 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/basic_endpoint.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2f1822a6dc08e182b8f423402f79a7154b6952a80db8f5c593ba90a2e55c72b +size 4824 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/datagram_protocol.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/datagram_protocol.hpp new file mode 100644 index 0000000..e4ff5c2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/datagram_protocol.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f8d444b89360703332b71284a947d6ffdedf0201513930a645e897796f9e7be +size 3290 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/detail/endpoint.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/detail/endpoint.hpp new file mode 100644 index 0000000..3f12577 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/detail/endpoint.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed92caff8cebc4dc3180e14af7f7b1e31cbd3baa7f9096349daf4a0602c93c26 +size 3359 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/detail/impl/endpoint.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/detail/impl/endpoint.ipp new file mode 100644 index 0000000..6a088c9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/detail/impl/endpoint.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0973171b6da3051ac86e7d8b3eedbcd8759c995a96c7a36f5ff942ad158f221b +size 2846 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/raw_protocol.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/raw_protocol.hpp new file mode 100644 index 0000000..7aa2d07 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/raw_protocol.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de0781c2e14c29c4ca2f4d0351449873e09b1135315439f1fe50ab5bdba0d6f0 +size 3150 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/seq_packet_protocol.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/seq_packet_protocol.hpp new file mode 100644 index 0000000..c8d10b9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/seq_packet_protocol.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c5d06ad85fd296a4543107f7ac9643b0dc477b30f8b7dee8ccff409c957aa47 +size 3236 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/stream_protocol.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/stream_protocol.hpp new file mode 100644 index 0000000..3d75abb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/generic/stream_protocol.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ceb76a6660d5e70d25e8dc9e3d5c9d063a109c73aab48c73949575a13a05dfb5 +size 3463 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/handler_alloc_hook.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/handler_alloc_hook.hpp new file mode 100644 index 0000000..084a2a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/handler_alloc_hook.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:560e2460c5db4c122574053ee37e62a238ca2cafd41c204f59c692568da7fccb +size 2516 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/handler_continuation_hook.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/handler_continuation_hook.hpp new file mode 100644 index 0000000..e1b40de --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/handler_continuation_hook.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67f9ae57a708be2ffc606334214a35062c9802536d2f1da0169848537b5144fe +size 1474 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/handler_invoke_hook.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/handler_invoke_hook.hpp new file mode 100644 index 0000000..ea8fa2c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/handler_invoke_hook.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:909232f25d5fbaa668f0d685ed0172e20ebdd5517e85c45624719e369ed9f4c8 +size 2750 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/handler_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/handler_type.hpp new file mode 100644 index 0000000..cd8bbc3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/handler_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b55cf8c79ee0d892648bc0d8a8836f7f4340f0a1b549fa30a64f0998ee8ca463 +size 1608 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/high_resolution_timer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/high_resolution_timer.hpp new file mode 100644 index 0000000..333efc8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/high_resolution_timer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aef7a84a54d5c1764b10ca15dc61d73b20047eed3a9049d0f58d4fd0e10b1448 +size 1394 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/buffered_read_stream.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/buffered_read_stream.hpp new file mode 100644 index 0000000..fc6da66 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/buffered_read_stream.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a84d5d302790a9b04dcee06dba9e444405d33433b7e95ac1f36bd4595aa6a53c +size 13410 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/buffered_write_stream.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/buffered_write_stream.hpp new file mode 100644 index 0000000..94a8dbc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/buffered_write_stream.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c539ec32e1cbafab25ee990f956db06c0e4e2616eb6b97c3aade2e69ec9fb74e +size 12977 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/connect.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/connect.hpp new file mode 100644 index 0000000..6757dfc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/connect.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:804ccfb625482e4fd775f381d924d2963c1739e71c19f5113bd630a6f10b1dfb +size 30400 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/defer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/defer.hpp new file mode 100644 index 0000000..16c2b34 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/defer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02648fb36045315a6cd3985da79616a1a5b908e4efea0d532a6dc8532f75ba9a +size 2454 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/dispatch.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/dispatch.hpp new file mode 100644 index 0000000..f7e6a2e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/dispatch.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19e27ec1faf56e4c13daa2d10b51ff1da007d61fb8297f13356304ef6047c618 +size 2496 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/error.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/error.ipp new file mode 100644 index 0000000..268641d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/error.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7026e0ff4b9d134d412cd5160c5e2face30c88876429925290e562799cbccee1 +size 3070 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/execution_context.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/execution_context.hpp new file mode 100644 index 0000000..5fc767a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/execution_context.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e59a04360ad5038bcf336bb1b211407fce3fb349f12b6c6bb7b937e2b4e6acc +size 3248 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/execution_context.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/execution_context.ipp new file mode 100644 index 0000000..497c33a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/execution_context.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca346c4d55aed1d4411db83613daa33311d6cbe0f36a61ad9a6ba052f7eb9e58 +size 1801 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/executor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/executor.hpp new file mode 100644 index 0000000..57f004d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/executor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da2519b35e8e2ee8cd2a36bb7847e544c60257a3e6091524fbb4595f0c77d91f +size 8425 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/executor.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/executor.ipp new file mode 100644 index 0000000..234424e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/executor.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f84b90cd80745837a3fcf01ba9324bc65893f242554bfd0766f52b75a8f5b667 +size 911 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/handler_alloc_hook.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/handler_alloc_hook.ipp new file mode 100644 index 0000000..f05cf50 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/handler_alloc_hook.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2408d51873fe153d2ad407ac9659c1c58345fce73283e13c3290dfe8f3c8c45d +size 1690 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/io_context.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/io_context.hpp new file mode 100644 index 0000000..fc5f9cd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/io_context.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1bca79c36df175a4e53eea7ab79b6d822ebf71e977ae67643afff0205a9fffd3 +size 10171 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/io_context.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/io_context.ipp new file mode 100644 index 0000000..82bfd3b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/io_context.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:65572c45c5b7cd1f5f6a513c04c9b44547e3a5a63f9fa9422afba8be4a249ae8 +size 4084 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/post.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/post.hpp new file mode 100644 index 0000000..0ee6ffe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/post.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ce4a0c5ffffff7ac857b49d9e0480681d3206aa687b93e2c3f21e9d25daf41e +size 2443 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/read.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/read.hpp new file mode 100644 index 0000000..aaf8490 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/read.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:932008cb54ed84513c5d05590301a5b8b7d122b6c6b1c797536e8cc83bd3985e +size 26056 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/read_at.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/read_at.hpp new file mode 100644 index 0000000..d34ed09 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/read_at.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a80572cee8b10da3656f3592697f4d61fb051bd0dd5ac01b602ee4169668c474 +size 24102 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/read_until.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/read_until.hpp new file mode 100644 index 0000000..1fafea3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/read_until.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d94f0e2368503868fd078b65ccca8aee8da44ea822d227b77ff78eae338ae557 +size 50549 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/serial_port_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/serial_port_base.hpp new file mode 100644 index 0000000..68040ba --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/serial_port_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b93d39624f4d87526100a15305a5aa9113250ba331028c47ecd31e38f5a0342 +size 1375 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/serial_port_base.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/serial_port_base.ipp new file mode 100644 index 0000000..bfeea4e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/serial_port_base.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:398142e389a4c8c988efc05afd1a3a44d77c9de10cb0eaa32d1dbf93c474bbcc +size 13327 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/spawn.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/spawn.hpp new file mode 100644 index 0000000..284deb6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/spawn.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1dc5a82c6e2922931b19909c441031c4c6ddf6d34617f2d2c8cb5d63a095d885 +size 15788 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/src.cpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/src.cpp new file mode 100644 index 0000000..a30182d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/src.cpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:027311c78ceb4d1900592cedcf91f929ad84b25698772815d06bed068271ed37 +size 712 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/src.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/src.hpp new file mode 100644 index 0000000..9891175 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/src.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b921421712371a4c630582c874b6a79ee7b3ec26d32c803500e1e6c72b9f7ae +size 3661 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/system_context.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/system_context.hpp new file mode 100644 index 0000000..6b309ea --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/system_context.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bdc959173817e9f5f4f182387244294563850d3a4083d4103eaff7f13b6c5755 +size 875 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/system_context.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/system_context.ipp new file mode 100644 index 0000000..e2d34ee --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/system_context.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbe223cd3aa3421cc05a8bf7f79e385ef275664e0f7c3e6b7521be89ebd28a5e +size 1591 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/system_executor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/system_executor.hpp new file mode 100644 index 0000000..9e7a3b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/system_executor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:80123ef4002039fb1c1c3e1e9fe643ff2404d3e34c088a12d387a210654c28fc +size 2727 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/thread_pool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/thread_pool.hpp new file mode 100644 index 0000000..a7a1fae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/thread_pool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:35f9f9682866f4de33447eeee09ebc69b07b71a60cc4200b8dd54c243b1d929c +size 3836 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/thread_pool.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/thread_pool.ipp new file mode 100644 index 0000000..9a9ca3f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/thread_pool.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d11820ab27f8cc2eb0c6d633a2f6d1f1ae325c3e831cd206dde503e8cacdeea +size 1630 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/use_future.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/use_future.hpp new file mode 100644 index 0000000..a3aed95 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/use_future.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd5301f2b0f81aa854d9265fa5ebde565d49c247ad43e5d8ffe417bfd3199be8 +size 25304 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/write.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/write.hpp new file mode 100644 index 0000000..2eba656 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/write.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:269222cfc0fdd661418411fa64b921f281231957bcee343f0bb8b2ab974d8640 +size 24231 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/write_at.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/write_at.hpp new file mode 100644 index 0000000..f35ae00 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/impl/write_at.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e883994ddfcd223e2031d7c1516172e8d084a9db49335fd0e461baed0fcf4308 +size 20882 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/io_context.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/io_context.hpp new file mode 100644 index 0000000..4a03dcd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/io_context.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ace12ef70142c92895b0112a33dfc5d97c50e16b35596419d7989c8a9d39457 +size 33264 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/io_context_strand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/io_context_strand.hpp new file mode 100644 index 0000000..2c12625 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/io_context_strand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d507cdd9d5a67e5bd7c10b9ff9e61bedc678ebecf0fec69d762112166d1a643 +size 13970 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/io_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/io_service.hpp new file mode 100644 index 0000000..d3c4a05 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/io_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05d43932fad7c13d57944f0db0599e75431eadc23877e5af0da933273d5e81d2 +size 861 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/io_service_strand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/io_service_strand.hpp new file mode 100644 index 0000000..abef986 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/io_service_strand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:740d721453207bea19bb53f2145766e17499975a04279760f93a53735471ab76 +size 575 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address.hpp new file mode 100644 index 0000000..1ef8494 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1ae8a83875a8293f95e03288a66089670ffb050ea03fa4998619a7778833ddb +size 7806 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v4.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v4.hpp new file mode 100644 index 0000000..0fc9097 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v4.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3b8a0f0edeb67a741c01cd9999f968772972f91c469f570909de73907e8eb32 +size 9621 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v4_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v4_iterator.hpp new file mode 100644 index 0000000..1495626 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v4_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e659f9c99c997f9f26f763edc04c26d27ed22a7e8617471e20cfc5fdd0471a56 +size 4260 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v4_range.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v4_range.hpp new file mode 100644 index 0000000..8e5019e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v4_range.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:634e6a10d612672160badf5f4daf6dbe7de3b9b4bc8f1779e39b4ca3a27433c7 +size 3392 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v6.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v6.hpp new file mode 100644 index 0000000..070e951 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v6.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be66f84f8f6c0d0b9c78da49a30c51819093bc07c1d61e05ed6f90afab0ceab6 +size 9943 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v6_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v6_iterator.hpp new file mode 100644 index 0000000..19db191 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v6_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:909280f4144b87cbba1d689ae4a05968464fa8f345e204c84f0bd03f12058601 +size 4602 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v6_range.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v6_range.hpp new file mode 100644 index 0000000..70c8219 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/address_v6_range.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb2e51865a750cc7f970a0c14822f64357d083e1d71829e21e8b6a3f36a7c0f6 +size 3335 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/bad_address_cast.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/bad_address_cast.hpp new file mode 100644 index 0000000..59ca681 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/bad_address_cast.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a537a290eb8cc79c20a333bc52dc8adb7c53bb6edf47d7f7628d46d23711aaac +size 1317 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_endpoint.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_endpoint.hpp new file mode 100644 index 0000000..b821443 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_endpoint.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e16fbc31d9c938fa29e3f9c29f75a6245b3b34a35083f4250af5859fc55c5b51 +size 7008 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_resolver.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_resolver.hpp new file mode 100644 index 0000000..c14538e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_resolver.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5893909a41f2c2edbdbc348fceadabfc3a9778410eae379bcc96a2ac28fbac7a +size 44973 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_resolver_entry.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_resolver_entry.hpp new file mode 100644 index 0000000..e43f3a2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_resolver_entry.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:817b5b8501da73242c5e4c0f643f5d0674f39de89e22f2bd5bb667e4dd2fca0a +size 3020 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_resolver_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_resolver_iterator.hpp new file mode 100644 index 0000000..a5ced5e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_resolver_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed8b2d7ef1403f664e3370155324dc745988227670d4f58a63b37367c70524cb +size 5154 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_resolver_query.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_resolver_query.hpp new file mode 100644 index 0000000..32f71f2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_resolver_query.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea98bc2724ca2716db822ad8d554abe1a7f729e61a928ddcddb1655c1f1b3fe1 +size 9356 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_resolver_results.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_resolver_results.hpp new file mode 100644 index 0000000..1a41e0b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/basic_resolver_results.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2732bdecc6b106dcf1e2ac5ac21a3cc2aad35d6656d7b493f5e50e43c9d0f5f0 +size 9749 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/detail/endpoint.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/detail/endpoint.hpp new file mode 100644 index 0000000..2ea4a6e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/detail/endpoint.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d596c6b8cdad52afbf03a5f6f24a06784b0e9d02c16d014a5b51e6d8c21f63b +size 3767 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/detail/impl/endpoint.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/detail/impl/endpoint.ipp new file mode 100644 index 0000000..0782ce1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/detail/impl/endpoint.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:12d9d27d00dda12cba1f5dcdd02e980db6cd69b89599f0234537fb1c06106767 +size 5670 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/detail/socket_option.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/detail/socket_option.hpp new file mode 100644 index 0000000..d624276 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/detail/socket_option.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c62eb2ce9b64345f6fd8da7afbc267e237c62f0eae9972fc3854e509ffd994e7 +size 14206 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/host_name.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/host_name.hpp new file mode 100644 index 0000000..d7d5e44 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/host_name.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5bc63f753dcf320196077f0771713dcb9f03bedb78a86833225580ce10b51577 +size 1106 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/icmp.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/icmp.hpp new file mode 100644 index 0000000..dd9c53d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/icmp.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de48e868cf93da48510fe65ad55b67147f58318bcf209d6fcfe830bc1ffb4ddd +size 2745 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address.hpp new file mode 100644 index 0000000..6a3c595 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef96c7203c2c98f3023a61fdd03eb660401756765b325cce077791830a522b92 +size 1641 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address.ipp new file mode 100644 index 0000000..c24a61c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e2e1c764a86ccc309e6c2e460f036a3b23976b2dd8b3e010a1ec48f14f609637 +size 5307 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address_v4.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address_v4.hpp new file mode 100644 index 0000000..5642e2e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address_v4.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1b05b2874beba8d0ae3c45e76a628834844120681467ae2e8e3b19a9408d6b7 +size 1695 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address_v4.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address_v4.ipp new file mode 100644 index 0000000..e272eba --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address_v4.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fec7f5663e125790acf43f184ff8a8924161aebae569787d74f38364372564ac +size 5479 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address_v6.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address_v6.hpp new file mode 100644 index 0000000..fd46fdd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address_v6.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed4e419c897db68dce6664eb49baa71682caec0e69ff253ad90ea2b44a6cc9e8 +size 1695 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address_v6.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address_v6.ipp new file mode 100644 index 0000000..3dda495 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/address_v6.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4cf5ac7da3d90753d1f796d3c374de28a3f3f4ce082e2aa20aa00789b41b94e6 +size 9941 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/basic_endpoint.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/basic_endpoint.hpp new file mode 100644 index 0000000..8ff7a17 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/basic_endpoint.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ceaf18cb3f79c64359e1f826d984cfdb9cb4856e17f05efc3a7c280047c7d71 +size 1227 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/host_name.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/host_name.ipp new file mode 100644 index 0000000..b0edcea --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/host_name.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0144ef48a3f082ab9f4a45234cfb7bb52ac567914eb349154af1d571d99cf84b +size 1426 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/network_v4.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/network_v4.hpp new file mode 100644 index 0000000..24d1e77 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/network_v4.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78954e2d43659e33abde368bb68f6a5160f8cbf8906e51567dae0e38a279c1ab +size 1484 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/network_v4.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/network_v4.ipp new file mode 100644 index 0000000..aecc726 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/network_v4.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:026e2d4de233900343b36bd1c104ecedc350f22ad9b7a9f1e5eae54d85ccaa0d +size 5619 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/network_v6.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/network_v6.hpp new file mode 100644 index 0000000..2407477 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/network_v6.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90128aeff354db1121426e26a866ade6a3f0190ad190a3056f9549524b77370a +size 1409 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/network_v6.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/network_v6.ipp new file mode 100644 index 0000000..f989f3d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/impl/network_v6.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:235079f8fde220d14bb9b0c8318bf96471839c399acaae770c18b6a2f97f8ff6 +size 4961 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/multicast.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/multicast.hpp new file mode 100644 index 0000000..df73304 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/multicast.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79961573d1f72e8e495a8866d49159c7224f9e4c31cde25fa9f343347945ffc4 +size 5503 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/network_v4.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/network_v4.hpp new file mode 100644 index 0000000..d02d3be --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/network_v4.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:693999f0ba5a341d081d81f6379ea49d96b35e2173778b25dcd88804e0aa96aa +size 7283 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/network_v6.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/network_v6.hpp new file mode 100644 index 0000000..3c7c06d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/network_v6.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7d83f4fc6fe2f5e5f5fd2ed93c01b2c35a90906e6b6f27cadca73dac2a48d69 +size 6500 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/resolver_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/resolver_base.hpp new file mode 100644 index 0000000..c87f905 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/resolver_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3b8e04c8cd661c170e1a1c860031db233ab0de1b78246a3842b1a95a4fed07de +size 3772 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/resolver_query_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/resolver_query_base.hpp new file mode 100644 index 0000000..4d1ace8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/resolver_query_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17d1be625382e3d52753963618b09ebfc2aad48a59217c6d2b78c16756a647a7 +size 1169 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/resolver_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/resolver_service.hpp new file mode 100644 index 0000000..57cde38 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/resolver_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e2c1ecfd6df37e67c9071ad2ad6e6c91b6fb4580f5e85769a0de9d6b1d18f571 +size 5904 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/tcp.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/tcp.hpp new file mode 100644 index 0000000..df69ff5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/tcp.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a9f69a13f5d4b3a5578506989fcbb10f6e1e7b9a1b63f9692c6c80b9491da534 +size 3810 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/udp.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/udp.hpp new file mode 100644 index 0000000..c4e642e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/udp.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a278a7e948d92e8dcd908a0fc1dd243e18a61444f042064e619c764ddfb5fcb +size 2540 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/unicast.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/unicast.hpp new file mode 100644 index 0000000..72447ee --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/unicast.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73002b553b3e40b76e5ca0bec0d4d7d292fb1d656db7ac866da8224eadd1f2c6 +size 1787 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/v6_only.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/v6_only.hpp new file mode 100644 index 0000000..26cd5b2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ip/v6_only.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce7c43d538dec4b00eeaafc486449fd6d919a87df3a6d0adc7834d0d2abb371f +size 1811 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/is_executor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/is_executor.hpp new file mode 100644 index 0000000..db98dec --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/is_executor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4642a7c28a21dc9a1a9b8f1d794e2fcf95b4802ce42b97e415bdd294183c3a61 +size 1306 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/is_read_buffered.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/is_read_buffered.hpp new file mode 100644 index 0000000..be1a489 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/is_read_buffered.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5801a804e7f3224e279183f23dcbe2c2baebb05b885b592120080ac4b46b55a2 +size 1646 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/is_write_buffered.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/is_write_buffered.hpp new file mode 100644 index 0000000..29f89e1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/is_write_buffered.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c70135e9f8db384995dd34b4fc8df249acb1196bbefc9ae86f78ddd656e4b2c +size 1667 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/basic_endpoint.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/basic_endpoint.hpp new file mode 100644 index 0000000..9bcda4a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/basic_endpoint.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07fcfacee85c741a92f85ee153de26d14d64b7dcc643b3eb6489f0d4a3212cd1 +size 5716 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/connect_pair.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/connect_pair.hpp new file mode 100644 index 0000000..3b72749 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/connect_pair.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e04aeec377ea5ddb5a4b76c991a99e0efe804346c49a8ad8f88646165d2a54d4 +size 3515 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/datagram_protocol.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/datagram_protocol.hpp new file mode 100644 index 0000000..76ffc95 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/datagram_protocol.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:194e2e306d432e5f44caf5c5932985f27fb91bbcd276d53b2d60b2da614bfdda +size 1990 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/detail/endpoint.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/detail/endpoint.hpp new file mode 100644 index 0000000..0e4f6c3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/detail/endpoint.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f46c4572a363e45ef131430ba9dc31b6b9f7eb47e8892a9c5f3c8ea0561549d +size 3564 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/detail/impl/endpoint.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/detail/impl/endpoint.ipp new file mode 100644 index 0000000..f918385 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/detail/impl/endpoint.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:784fb7ddf36d7e06ae3acc2a244954634c026bdd9cabdd778ff881160f13b144 +size 3320 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/stream_protocol.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/stream_protocol.hpp new file mode 100644 index 0000000..1275f03 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/local/stream_protocol.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3a44ead6ff8f0822f0265c261b1708d1762106489a84b2a13097128b761e635 +size 2335 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/packaged_task.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/packaged_task.hpp new file mode 100644 index 0000000..1fa668e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/packaged_task.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74317a2903dbc5e993d0bf926fd34f88b4adf2f41be1089328fcf573b8703f72 +size 3358 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/placeholders.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/placeholders.hpp new file mode 100644 index 0000000..40b3942 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/placeholders.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e8f59912eb21394e7a59b0510098cce186fd01cfe3791f5c963ddd16f762496 +size 4146 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/basic_descriptor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/basic_descriptor.hpp new file mode 100644 index 0000000..d52c963 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/basic_descriptor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5335a1d978d265c7fafbdba08cb8e0a212f6abe291c85097bb18d289fe189b2d +size 20466 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/basic_stream_descriptor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/basic_stream_descriptor.hpp new file mode 100644 index 0000000..7111ee5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/basic_stream_descriptor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c6738de29d25de7fa3388899e2f62a2ea6176e17fc5d7d3bd6faeed945da905 +size 14316 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/descriptor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/descriptor.hpp new file mode 100644 index 0000000..0e85394 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/descriptor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7002eeec5966af0e8f9eee1a4a288566bfccadcf89e51271ebd3b049adbf3897 +size 22357 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/descriptor_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/descriptor_base.hpp new file mode 100644 index 0000000..75007ca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/descriptor_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7cf9dd85e7c8b3cfccb9b9a06492c773263fc3a3415629b79dc968f58bea5d3c +size 2370 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/stream_descriptor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/stream_descriptor.hpp new file mode 100644 index 0000000..731d586 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/stream_descriptor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c57d4e81bbe0f090c397e2454f066d6a9f90df5486a95f0f08f9dd054294ab8e +size 13985 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/stream_descriptor_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/stream_descriptor_service.hpp new file mode 100644 index 0000000..91dbde7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/posix/stream_descriptor_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e626bd2b574f2a3d78af4dc47eda81cccc481c262b26c8f2b683249ea72bfb92 +size 8816 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/post.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/post.hpp new file mode 100644 index 0000000..1bcffa0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/post.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4329b3b0800d3d87f1bb5c1f51197a9515febd65c323d11add3507b6572a8421 +size 3938 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/raw_socket_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/raw_socket_service.hpp new file mode 100644 index 0000000..c38625c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/raw_socket_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75594b3abdc58d6c6aa2d1d47c1a41336156bb12ee6b0cce6b76b870c9b88a34 +size 15181 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/read.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/read.hpp new file mode 100644 index 0000000..9e18628 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/read.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66ebcc6a8237b95811767ec799e726096a05b6a0f66a31a169bb08af5bd47ad2 +size 38935 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/read_at.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/read_at.hpp new file mode 100644 index 0000000..f21721c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/read_at.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1fccf23cf7f0869e87ca2f1104ce9efa450c9fece2d26bf7dcf1f2988c82b950 +size 26510 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/read_until.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/read_until.hpp new file mode 100644 index 0000000..eaa08d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/read_until.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48862844a4ac2c096d032a19cb44e97f02377adbdd4bba85bbc6cd6ee29a8d27 +size 75209 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/seq_packet_socket_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/seq_packet_socket_service.hpp new file mode 100644 index 0000000..2cb7ae8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/seq_packet_socket_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa15d57b6c03d284c10cb0d4e9f3306c9d36e0c3013f6e5cb2516b91138d9105 +size 13489 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/serial_port.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/serial_port.hpp new file mode 100644 index 0000000..f54325d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/serial_port.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98de02d7379c32792c715579a241b4f19d790500fdcac36dc4357903c7366e33 +size 27711 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/serial_port_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/serial_port_base.hpp new file mode 100644 index 0000000..201f2d7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/serial_port_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8dfbd5c1391c6aa207014acdf1b86ce5383156bb9a9cd62f8e01d734c95b9804 +size 4975 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/serial_port_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/serial_port_service.hpp new file mode 100644 index 0000000..49a2243 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/serial_port_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c827629f8e7f5504bb1740b20b71dcbe35aad37fc8f271c2a5c4911f86e658a6 +size 7586 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/signal_set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/signal_set.hpp new file mode 100644 index 0000000..4970fe9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/signal_set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:938f8d39da7a28a7daf937016221844b3c9561091f35b4977ffa1d3f25cf95a3 +size 15900 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/signal_set_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/signal_set_service.hpp new file mode 100644 index 0000000..6336a11 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/signal_set_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:231ff32be7d7c59c2992c85642af4e24b9bb5e9f88ea81922c49998b7d14fb3b +size 3968 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/socket_acceptor_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/socket_acceptor_service.hpp new file mode 100644 index 0000000..43a3720 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/socket_acceptor_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:624706c38efeb26f24f19c826af21406e46787f74e383530161e234f892074de +size 12093 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/socket_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/socket_base.hpp new file mode 100644 index 0000000..1deb883 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/socket_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2a3e7520ac45eca3bc4c08257914681c0908b2b08959a45e3594c8caa0ae99f +size 15962 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/spawn.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/spawn.hpp new file mode 100644 index 0000000..26a01d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/spawn.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ffd1d7c66de2aae0a6baff85d864a1274f58b280f2e7f65834d7968365cd8908 +size 11556 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl.hpp new file mode 100644 index 0000000..530062d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:72bfb0942f5caa3d6ff4dad2a7fc5a2cd0f906bfd620ce2a4066e0ff7d9fe2e9 +size 795 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/context.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/context.hpp new file mode 100644 index 0000000..4c1098f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/context.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca3ab65dbe10885fc8d3adc0a3cff6e697fb0816e445430d4249f1b50d5e3b6c +size 26624 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/context_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/context_base.hpp new file mode 100644 index 0000000..18b577a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/context_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:25db549bbe8bb1c9cbd21a2570f8a7166c89a8488af0b2104b455fa6df14dd97 +size 5437 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/buffered_handshake_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/buffered_handshake_op.hpp new file mode 100644 index 0000000..d4dcd4c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/buffered_handshake_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2580cbcebfa28f014adb4c2b897da0dc372e82ea5ca692cbdb194aeefb8e3dc2 +size 3275 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/engine.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/engine.hpp new file mode 100644 index 0000000..84165f1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/engine.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b54f2331a87154fac972bd309c3b3603b59b721e58dccafaf7ecac3f556921dc +size 5852 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/handshake_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/handshake_op.hpp new file mode 100644 index 0000000..512573f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/handshake_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f0aee6ab4760366967c6b9bb974574843fa4187dc6cf399b8b0f55ab95dd758 +size 1410 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/impl/engine.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/impl/engine.ipp new file mode 100644 index 0000000..4e023ca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/impl/engine.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9cd5bfdd4962e34f7f00fba7056835e7a61b74b1b5592ae90b244e17a6be63a4 +size 8413 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/impl/openssl_init.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/impl/openssl_init.ipp new file mode 100644 index 0000000..fa4400c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/impl/openssl_init.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4576aa1a186819d859a77deb4c88b00ab77d4acd636cdcff4cb54d42c29b0518 +size 5401 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/io.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/io.hpp new file mode 100644 index 0000000..5a49334 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/io.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef104030aec2f664091ef94724fe460930ff60612d7b26f26209122d41a6a540 +size 11692 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/openssl_init.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/openssl_init.hpp new file mode 100644 index 0000000..9486024 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/openssl_init.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:572a66b06054f551a97d172ce334d48f6726189e4e3ead817f267126d8702158 +size 3059 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/openssl_types.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/openssl_types.hpp new file mode 100644 index 0000000..34df581 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/openssl_types.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4712c62bcf5f4cb325748f17c182850c53e699a4710a501e026865748c1e86a0 +size 904 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/password_callback.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/password_callback.hpp new file mode 100644 index 0000000..6708dd1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/password_callback.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:abe1f9bda2a1421a673da68bc2defe24cb7dec90bd5201f6473bc9a1f2c784fd +size 1512 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/read_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/read_op.hpp new file mode 100644 index 0000000..d71705e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/read_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de61ee61dc57775f31dbc35247ce83edb62d67812c37f127268b546d976ce045 +size 1677 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/shutdown_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/shutdown_op.hpp new file mode 100644 index 0000000..952f889 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/shutdown_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:219051fb00397f06617a3bac21f11fd8a1edd830d9a9ba28255098736c5405d1 +size 1273 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/stream_core.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/stream_core.hpp new file mode 100644 index 0000000..3440987 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/stream_core.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b412fe905737046182f56e78da5caa8bf8f8df4a46fedbc134e788e8f7c2e273 +size 4134 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/verify_callback.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/verify_callback.hpp new file mode 100644 index 0000000..1808a02 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/verify_callback.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a46fcc3a676358edb5ee9fc24aaa2e2d8e7d322f2f8c7382503b1e9b9538b4c +size 1392 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/write_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/write_op.hpp new file mode 100644 index 0000000..64cd29e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/detail/write_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:beff61c5f4ca7bb1e464c69b760e0778d21818d065f3cb4ce47d7562ec989e51 +size 1673 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/error.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/error.hpp new file mode 100644 index 0000000..5e586fe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/error.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cfb76db60b80b6ba8b05b2da78c81641e1d42ee77777634680b4faff48383dcc +size 2687 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/impl/context.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/impl/context.hpp new file mode 100644 index 0000000..fc73ae7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/impl/context.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afde58c52015dfa62533bd5d3a5bbfb1cd0c5145c36249065284ef4a9c5d4dd7 +size 1953 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/impl/context.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/impl/context.ipp new file mode 100644 index 0000000..67a667e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/impl/context.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c3bb2ab44844aecdd11730dec1fdf414167838316ef0317d4287781f73ade612 +size 34027 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/impl/error.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/impl/error.ipp new file mode 100644 index 0000000..e0762d2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/impl/error.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d5a8a3900b8f50c5b29cd2fd5fc4738a40e49c8c084e65ad30268b215b38351 +size 2121 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/impl/rfc2818_verification.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/impl/rfc2818_verification.ipp new file mode 100644 index 0000000..5b74f70 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/impl/rfc2818_verification.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:028f19f31d4170831b9ff47cfe249b8e7ac32a64f35f15d3dad5cb5bd7964a51 +size 4753 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/impl/src.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/impl/src.hpp new file mode 100644 index 0000000..c9c9daf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/impl/src.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e1445166ad0fe1b8ba389ae347f3ebff66bb0a4b59d763c8004e5274a56e6945 +size 832 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/rfc2818_verification.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/rfc2818_verification.hpp new file mode 100644 index 0000000..b09cd41 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/rfc2818_verification.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2430456dd28fb6a9cdc12efd195f58e3dc2dd586a4b2767e51e48ecc8366175a +size 2854 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/stream.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/stream.hpp new file mode 100644 index 0000000..48dd365 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/stream.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dff19d7da7532713b37568303bdb2b876044fd13f85721be1430f7411311e70a +size 26723 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/stream_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/stream_base.hpp new file mode 100644 index 0000000..e52ca74 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/stream_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9693789496a1b3f7fd110a765df743d123250fde7cf042ee5fbf58c6172a4cc4 +size 1224 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/verify_context.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/verify_context.hpp new file mode 100644 index 0000000..59a2022 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/verify_context.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d1368845a0393d1a831f36144fa86cfb60c03aed6e592937c581d9c0d301af2 +size 1745 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/verify_mode.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/verify_mode.hpp new file mode 100644 index 0000000..920ede8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ssl/verify_mode.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4da539e4faae73b099b49744ee7bf03b00ba5800fd0b2a1466fb653a70e56346 +size 1758 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/steady_timer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/steady_timer.hpp new file mode 100644 index 0000000..f97001f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/steady_timer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:09e97b40fac7a2e1fcee8294af930795092b3a874578ed4e34d247a740f6ab73 +size 1306 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/strand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/strand.hpp new file mode 100644 index 0000000..448e9d3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/strand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3877818734dbc699317e929fb44248e3caf6e3f627c50305bed13d5c571a7dd9 +size 8947 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/stream_socket_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/stream_socket_service.hpp new file mode 100644 index 0000000..4c10419 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/stream_socket_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d1b40058ef27c7b5ec9c496fc502a1b3d27eee6ca30d68d3f2e73876ac26ff5 +size 13145 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/streambuf.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/streambuf.hpp new file mode 100644 index 0000000..37ba65f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/streambuf.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9dda58d4e8da8527f3224ecfba296055f5aec3036af1386a290f921c8034b34 +size 826 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/system_context.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/system_context.hpp new file mode 100644 index 0000000..8ce947b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/system_context.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2911d8c3e5f35c39e35373ecaa4de7731d113cfebe52ef8ec8796daf00ce38f8 +size 2166 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/system_executor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/system_executor.hpp new file mode 100644 index 0000000..ddf7c06 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/system_executor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c226892076a2282ad2c6b019837b715eb86142c31c91ceab5a13e8a62675be90 +size 4390 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/system_timer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/system_timer.hpp new file mode 100644 index 0000000..fb1ccac --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/system_timer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40ef5f6018157c4eb087fb8bbfa862808db4d8ffcc38422e355737e46ff1b33e +size 1306 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/thread_pool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/thread_pool.hpp new file mode 100644 index 0000000..e04fd6a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/thread_pool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0a541a4dc05285a3dbe9efa4641f9db317bc60a931f1c31d394967b93fdfb4b5 +size 7449 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/time_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/time_traits.hpp new file mode 100644 index 0000000..3181c91 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/time_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91ad4e0a41a42d656b4c09da7b1bafb50bc6aee724ed7a8bdbe72c9fae38a4e0 +size 2281 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/buffer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/buffer.hpp new file mode 100644 index 0000000..e9bcd9d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/buffer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92010a61c2cb299ecfd3ca88dc2d3b4c9c5fadf0f7050f32a95256719057ca4a +size 671 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/executor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/executor.hpp new file mode 100644 index 0000000..951515d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/executor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95315500977f69c2b393b75348ef77b43076d72da0310f6e983f7683f01b8d48 +size 1125 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/internet.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/internet.hpp new file mode 100644 index 0000000..d09ab4d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/internet.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f91d7191014d874c3edd49bc4d2da9a5be3bd83dda5413f293eeb8caf1f487a +size 1393 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/io_context.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/io_context.hpp new file mode 100644 index 0000000..a37471e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/io_context.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e4aea9c89b65b53d3275d8c863efc0c42aaf6b2a13feaa0b8c1756311f74702 +size 548 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/net.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/net.hpp new file mode 100644 index 0000000..79af345 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/net.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99fc28ce0060d1dad8ab068ab7e1a3e01f7c6e7c0f24643de2a5f967274cc25a +size 735 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/netfwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/netfwd.hpp new file mode 100644 index 0000000..1099ea5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/netfwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7dc63ff0371577c59c69865286e7ed06ecd94c4d72a0db5542c02be15f01fd6 +size 5123 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/socket.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/socket.hpp new file mode 100644 index 0000000..2f3579a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/socket.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2fcc64f241bb09615b9e043780c8d61b8eb980f9debfe70c203fbe31b81a2a7 +size 841 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/timer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/timer.hpp new file mode 100644 index 0000000..96fd924 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/ts/timer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f2940128369a6f667c6602f61f6802f54ffad8fa9b803807c0f3ef08cfb1b09 +size 738 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/unyield.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/unyield.hpp new file mode 100644 index 0000000..ec4c028 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/unyield.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05cec70bb2caa62252bea38b5c9c9da8f82264911d816b13fb387dbbae1afedb +size 381 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/use_future.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/use_future.hpp new file mode 100644 index 0000000..1fa3417 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/use_future.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0efbcad95c823020605bfc4dda17f6905b8409e5d25d4343d228be3da02e9637 +size 4820 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/uses_executor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/uses_executor.hpp new file mode 100644 index 0000000..a5bd963 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/uses_executor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:988440437a206491d44593f2a7a12f20ba9951b4c572db2934c71d36c0f47d36 +size 2348 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/version.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/version.hpp new file mode 100644 index 0000000..5c090d6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/version.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:679f696421f7dd798971f860534910ca693fd9dac5ae6973d0fd8c04b284410b +size 686 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/wait_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/wait_traits.hpp new file mode 100644 index 0000000..07fbd64 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/wait_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e8195e154d3fe6fb41d7000da5dabd4e02b8a2719d9dd1f5393f6356244930a7 +size 1451 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/waitable_timer_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/waitable_timer_service.hpp new file mode 100644 index 0000000..443771d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/waitable_timer_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4fd732196bd673628019983bb0a0155b67971caf8b4b08f5a6f4be12bcf388d +size 6346 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/basic_handle.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/basic_handle.hpp new file mode 100644 index 0000000..91d711c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/basic_handle.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9c449c77722603d514f2c738c694b3c99ec2dec4714c886c8eba8ae4702c482 +size 8810 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/basic_object_handle.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/basic_object_handle.hpp new file mode 100644 index 0000000..191e9e5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/basic_object_handle.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2fea66ca2dbb1547743b9d1f3ea75e0050a671b4d1451ba3d6110ecd885fc766 +size 6353 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/basic_random_access_handle.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/basic_random_access_handle.hpp new file mode 100644 index 0000000..9fae87b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/basic_random_access_handle.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6017f7e39c8f0bb20ea214dab5f630193fe6931dfa0bd5a9fc364261ba9fc70a +size 15013 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/basic_stream_handle.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/basic_stream_handle.hpp new file mode 100644 index 0000000..af151bb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/basic_stream_handle.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30e1f06f36cf78c331db0ad459d95f13f1404caec3a85c75508ce5cc517dd835 +size 14005 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/object_handle.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/object_handle.hpp new file mode 100644 index 0000000..bc4e09e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/object_handle.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c3528d08d93e565cddf05444b6593ca82623ef5bd952ac1aeb0564cc29163eb +size 12870 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/object_handle_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/object_handle_service.hpp new file mode 100644 index 0000000..d2cb780 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/object_handle_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5cc1f72a8a48cf99033679c9a34b236fcbefb922d08354a40f408e182878a300 +size 5349 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/overlapped_handle.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/overlapped_handle.hpp new file mode 100644 index 0000000..d8b0b9b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/overlapped_handle.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64f0ebdc050ca6bbbeffe4b73bd472038405a753b372f0c4125af7588b5d929b +size 10888 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/overlapped_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/overlapped_ptr.hpp new file mode 100644 index 0000000..cc76ea3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/overlapped_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d790c15bb8ad8ce973c742522e7e6e5ee6be2fd2dddfde32fb4614e5c0c15719 +size 2959 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/random_access_handle.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/random_access_handle.hpp new file mode 100644 index 0000000..55bd039 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/random_access_handle.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ae1f571a0918b0b8fd5fcb7f8d9db16bf5a2912ae6ba93dcadea52053316f70 +size 14811 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/random_access_handle_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/random_access_handle_service.hpp new file mode 100644 index 0000000..71f694e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/random_access_handle_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54f3d602c856f4086dc68810f157912dbf05f0f8b343f3e0bf6c1eb5c101b81d +size 6796 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/stream_handle.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/stream_handle.hpp new file mode 100644 index 0000000..a925fff --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/stream_handle.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cbfb1581002a24ac9778b6234d276c27e989ec3d117e5e5474569a2a97330e8 +size 13860 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/stream_handle_service.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/stream_handle_service.hpp new file mode 100644 index 0000000..fdb292b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/windows/stream_handle_service.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e22f0da024ae451fac13f7791632c5265012553c26bd8a6c6eaeb65e4e89a40 +size 6391 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/write.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/write.hpp new file mode 100644 index 0000000..3d29525 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/write.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8121f2c0dbd7a962a183ddd6956b8a6b083976279c5c148433d54ea399d91911 +size 38694 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/write_at.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/write_at.hpp new file mode 100644 index 0000000..b4676ca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/write_at.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85c2d4434e994f6178bc0805fe1da40110531ce9a2b0b0d40bb4d0f3f4c5c2d6 +size 28250 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/yield.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/yield.hpp new file mode 100644 index 0000000..a3af2b8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/asio/yield.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83be779e6c7a0e51559c632e5e50fc5f73fdb4a351ca8df7266f2f386cdba485 +size 482 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/assert.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/assert.hpp new file mode 100644 index 0000000..f14b4df --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/assert.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bbedf7669fec61d273084e1165bdf766636bf427d0ce5e9fed378b23445969e +size 2625 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind.hpp new file mode 100644 index 0000000..9ac42c7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7442708211608a9390f8a8bcbe1b6008370998f67c1e0198f2d68225e0cd0387 +size 936 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/apply.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/apply.hpp new file mode 100644 index 0000000..722b63a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/apply.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3f545bcefda3d8f2dcb7302b3971c3e685b35c6d14b90dab5a56c6982b9eaeb +size 2402 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/arg.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/arg.hpp new file mode 100644 index 0000000..1821c60 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/arg.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dcb9eb3acf810e8079dfb3e4c7665b8f80e1cc98ac5a7b763fb1d8ff09f04a47 +size 1314 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/bind.hpp new file mode 100644 index 0000000..a7f6323 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8930aaf6257441ae0a43693e7f3cfe2360c2926a40c55f055d6f445fbc816c90 +size 81476 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/bind_cc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/bind_cc.hpp new file mode 100644 index 0000000..51c7d02 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/bind_cc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba98f81705e1e9633fc3ecc97bd94cd6c195d1695d69c2e4d4f25c47cd065eda +size 6508 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/bind_mf2_cc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/bind_mf2_cc.hpp new file mode 100644 index 0000000..82c46be --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/bind_mf2_cc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73218349eb9ff4fa1b2d715093c6bc3d19e3ee555fcb404fc566b45d1433964a +size 11338 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/bind_mf_cc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/bind_mf_cc.hpp new file mode 100644 index 0000000..bda8469 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/bind_mf_cc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc07c077db3f655b49d08b991056c0c857e01041cd5861e2afbd645d1ccd3bbe +size 23475 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/bind_template.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/bind_template.hpp new file mode 100644 index 0000000..4879567 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/bind_template.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2defabb1fd59d8ff0db963d5be9edc88c4067a43e93a1e809a9871c51f700ed4 +size 14071 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/make_adaptable.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/make_adaptable.hpp new file mode 100644 index 0000000..03ab040 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/make_adaptable.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e65ae5b80733e6b0876abf81d5b6409a7c3efb2acc4dfb4bdad33ad1dac70735 +size 3164 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/mem_fn.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/mem_fn.hpp new file mode 100644 index 0000000..58d6ecc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/mem_fn.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7e131c07d7bda3064b4ead6d06de823dcac2a8340fffa69bc7841b0438758dc +size 7049 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/mem_fn_cc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/mem_fn_cc.hpp new file mode 100644 index 0000000..4ac9b6d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/mem_fn_cc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac135d8d682b5e01e76f4c552996aa2eed247eec4ae8c3fcf0ddd1960f02f22c +size 4804 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/mem_fn_template.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/mem_fn_template.hpp new file mode 100644 index 0000000..8c621fe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/mem_fn_template.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dbe25c55983f9b0f6d695a7044aab9e2f2c74f9804a0883e679350db3667bb8a +size 26529 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/mem_fn_vw.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/mem_fn_vw.hpp new file mode 100644 index 0000000..8bcb7e5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/mem_fn_vw.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9311b08120e2ae2c1d980ed338db29fb60257cdbb26780cfd32797164f1a157 +size 7952 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/placeholders.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/placeholders.hpp new file mode 100644 index 0000000..193a076 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/placeholders.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ca918e6c9bebbf79006b2923220e045a06a6caaf7b83ed3572660aa6eecce70 +size 1725 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/protect.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/protect.hpp new file mode 100644 index 0000000..561f13a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/protect.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3372f3a9494d06ad0f6963183ecbcf7351857267348b1ae4ccc97b354f9b2b21 +size 9704 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/storage.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/storage.hpp new file mode 100644 index 0000000..b77336e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/bind/storage.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e0a84447240d765578227aee29572ff8ec9388b203ccf27ff7f824fb1f8ac02 +size 13372 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/cerrno.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/cerrno.hpp new file mode 100644 index 0000000..4bf5985 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/cerrno.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c098a406619f7cd75cd5638191be32e3837a5a6692cf9bab1bf2403617eb9b59 +size 4187 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/checked_delete.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/checked_delete.hpp new file mode 100644 index 0000000..22c30d7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/checked_delete.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c33aaa806a5b166366b487f1ef9d332216a926db4c5f83b68d9449ad5301f6f +size 414 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config.hpp new file mode 100644 index 0000000..569d474 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:373206390d20aa5bb9e2628eb08543399d73b853af7bfc5f1d2bd9a00bc07593 +size 2216 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi/borland_prefix.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi/borland_prefix.hpp new file mode 100644 index 0000000..453f12f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi/borland_prefix.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9bcb32c03327907d1a79f1a687d1e889f048f89a02f01c9306ffccd270ccd53a +size 1002 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi/borland_suffix.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi/borland_suffix.hpp new file mode 100644 index 0000000..952b524 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi/borland_suffix.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ddf73eec710e6a40e5649e70ff0f5ee262b92648ab5b1ab2abb563a5fb6bc556 +size 280 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi/msvc_prefix.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi/msvc_prefix.hpp new file mode 100644 index 0000000..4b10fa7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi/msvc_prefix.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0846f71a84d25120bd54ae29095b33af1e9691f162a3a81d518b044a76037613 +size 819 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi/msvc_suffix.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi/msvc_suffix.hpp new file mode 100644 index 0000000..ce5a06d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi/msvc_suffix.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e401a3cc760fde65b6ff0681094eaab365a5716632d8526d4847e98f842927ac +size 252 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi_prefix.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi_prefix.hpp new file mode 100644 index 0000000..5bed52f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi_prefix.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7cab389037c481b96573401da49f75d2309e6df2947f3c63db396ff5d2a04cff +size 698 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi_suffix.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi_suffix.hpp new file mode 100644 index 0000000..ba176b4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/abi_suffix.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f301ea93528e4dbf8cada69033f4cda44920ec5f82f6bc4f1e87d88b60cfeea +size 781 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/auto_link.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/auto_link.hpp new file mode 100644 index 0000000..30ca396 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/auto_link.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e73dcbbd0d807c16747233ddf769380816eb69f3c8f2fec9dc2bdded7bebd783 +size 16377 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/borland.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/borland.hpp new file mode 100644 index 0000000..7fb7361 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/borland.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf4d58509f668b53f1bc61b854f2828d5e5dac8ad8847a0c0f460b34f93fcf4f +size 10611 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/clang.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/clang.hpp new file mode 100644 index 0000000..b16fffb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/clang.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a223c63d52a40dde9b4a30cdad596406cc9ef6a7d48859776df761998ff84a82 +size 9409 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/codegear.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/codegear.hpp new file mode 100644 index 0000000..c2f0af9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/codegear.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:89ad51ee112993c90a3dd26d1d99f5fcd852f4ca7cba48cc5da381b053422119 +size 7802 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/comeau.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/comeau.hpp new file mode 100644 index 0000000..1b9fbbe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/comeau.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:710f475254cdce46a9409b53a618f241267f91fd4ff66b24796b4ea596044227 +size 1638 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/common_edg.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/common_edg.hpp new file mode 100644 index 0000000..b8aae6f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/common_edg.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a02c301cedd3a5b169253f184c419f2051379b0f16afa7d1840495e4be1873e6 +size 5247 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/compaq_cxx.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/compaq_cxx.hpp new file mode 100644 index 0000000..ffa7557 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/compaq_cxx.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5db1c8909dfc9e25ccaca4b205c4def731e3565a73e7529c7ceb31b98f255203 +size 501 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/cray.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/cray.hpp new file mode 100644 index 0000000..a793ed2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/cray.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4e4c3d6fecb6d9c7b177a007cc25d61758e56e900fe325f4e860c6561ed302f +size 15285 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/diab.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/diab.hpp new file mode 100644 index 0000000..c98a05d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/diab.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b60af9eae596c5c9b8e26cfaa82d91f8e1024e442d91dbf8245be373de43ed9c +size 909 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/digitalmars.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/digitalmars.hpp new file mode 100644 index 0000000..64e044d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/digitalmars.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a27e82f571ce92696730536998566452e87df1ad2b06e05fd5961f286ca9321 +size 4521 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/gcc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/gcc.hpp new file mode 100644 index 0000000..992f2dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/gcc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b93e55d7f13c181e3526f3484283a86c54fac45a7f1025dec9a96a074028e765 +size 11572 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/gcc_xml.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/gcc_xml.hpp new file mode 100644 index 0000000..2d3cf3b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/gcc_xml.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6159362de2881f4230008c9e543aeb119ac53e121354057160c4b2ac453f591 +size 3967 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/greenhills.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/greenhills.hpp new file mode 100644 index 0000000..46dce08 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/greenhills.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2fa76a673c90ac4dfa2868f87c6fdd42601c1ff69bd4a1aae14dbd374dd49714 +size 822 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/hp_acc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/hp_acc.hpp new file mode 100644 index 0000000..3f9e397 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/hp_acc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0614cef2999442685ce759bb10724749b56935302dc6410f880309f6c35fe1e +size 4927 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/intel.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/intel.hpp new file mode 100644 index 0000000..fce44dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/intel.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18b2ae5c32a57321ca00780ff8171b4568599b389c0e712c4cda3dbfbe09ec2c +size 22218 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/kai.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/kai.hpp new file mode 100644 index 0000000..c3f33bd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/kai.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a92aed2cecd022d9c1321a47929ae0b518c6e502396df8b70042d90a653e306 +size 1030 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/metrowerks.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/metrowerks.hpp new file mode 100644 index 0000000..b29ea6f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/metrowerks.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba43cb6b143e9a15881c0d721824d6e706d3b60de574ef996a14cd8c61b8bcaa +size 6303 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/mpw.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/mpw.hpp new file mode 100644 index 0000000..7eacaf1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/mpw.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce5a90d5581b5d500db988db6e7786b990712fa137038ceb4e8aa1f1547ea5a1 +size 4706 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/nvcc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/nvcc.hpp new file mode 100644 index 0000000..a66fe65 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/nvcc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d6e949ad18b5c1391cc87ed1aaf8224943ac3d6ff650d3312d23ebde698ef54 +size 2042 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/pathscale.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/pathscale.hpp new file mode 100644 index 0000000..629c59a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/pathscale.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dcd0f45be8c30a8337203db437e22a2355a1032d30e0b59ea4108e6089d611f5 +size 5045 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/pgi.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/pgi.hpp new file mode 100644 index 0000000..4250fac --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/pgi.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0545c8d13c7680d2b46308794b54196f76b86625c475dd0ff809ebe8b8724bb4 +size 770 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/sgi_mipspro.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/sgi_mipspro.hpp new file mode 100644 index 0000000..2256ccc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/sgi_mipspro.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0911c1cf0f124ba79239bd9ee73bc1a78c529e9f99186dc2820c0c33e64097ca +size 774 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/sunpro_cc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/sunpro_cc.hpp new file mode 100644 index 0000000..2531069 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/sunpro_cc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bceea851fe07e3702d8aac9df57d0b6dee85f76ac4b756315a80c6ec49a6818c +size 7350 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/vacpp.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/vacpp.hpp new file mode 100644 index 0000000..5c52870 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/vacpp.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8ae704d51ce15c16b33e5d698ddbe2d9073c8fc743a4aad7cdb1dca85fa8a99 +size 6044 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/visualc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/visualc.hpp new file mode 100644 index 0000000..311b862 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/visualc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:194b0a6ad4592bc913df06312279702b16b35dc54f43175a5de0836fdf3fb3e3 +size 11612 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/xlcpp.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/xlcpp.hpp new file mode 100644 index 0000000..cdb5a23 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/xlcpp.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b01eabb78ac1bc3c293ea62a7c7a383365e0d5aa1de79645623f2240f5dc914f +size 7768 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/xlcpp_zos.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/xlcpp_zos.hpp new file mode 100644 index 0000000..3b1c9b8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/compiler/xlcpp_zos.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e6fdd6a4368ba3dc9ec0aede9cefb5056d83728522bb2d896fd943c14b51449 +size 4879 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/detail/posix_features.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/detail/posix_features.hpp new file mode 100644 index 0000000..cc7cb8d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/detail/posix_features.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bba105d0af558c09307941fe64ce5ce9d775990b96684708adf4a9a92070fc0a +size 3736 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/detail/select_compiler_config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/detail/select_compiler_config.hpp new file mode 100644 index 0000000..8102469 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/detail/select_compiler_config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92fec7679b77bf4defdbb0ef661a63c2a32470a88bddca82b66e4b48eb788879 +size 5329 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/detail/select_platform_config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/detail/select_platform_config.hpp new file mode 100644 index 0000000..4d0a9a2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/detail/select_platform_config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f2107ebb83c115963be6ec3a63dacc89ef644538b639babad64d720e391b9e3 +size 4479 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/detail/select_stdlib_config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/detail/select_stdlib_config.hpp new file mode 100644 index 0000000..c168e79 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/detail/select_stdlib_config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:866b014d24f2a1ef38eb648496d700384ecb4c3a414d6c2f4a5b9071a515fc1c +size 4090 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/detail/suffix.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/detail/suffix.hpp new file mode 100644 index 0000000..c63bec9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/detail/suffix.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d71fa9b920caf20305158579f3eb45e2021a6c25eb042615e0663639dfe41800 +size 37297 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/header_deprecated.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/header_deprecated.hpp new file mode 100644 index 0000000..6666313 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/header_deprecated.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f65fdd80185ee4999beb94248ff133db9875ac8e44349ca77a20a7ed375c0815 +size 813 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/helper_macros.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/helper_macros.hpp new file mode 100644 index 0000000..ec27035 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/helper_macros.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ecf739b9b06545ebb0d691e8207cf7b70a5d42d7cb378d5d5502c0c96eefafc2 +size 1120 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/no_tr1/cmath.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/no_tr1/cmath.hpp new file mode 100644 index 0000000..54fdf23 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/no_tr1/cmath.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:88333f68b514da159a18b2aac33be864f279ce4efc215c3f8425baf2c9ea1fa4 +size 838 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/no_tr1/complex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/no_tr1/complex.hpp new file mode 100644 index 0000000..3929495 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/no_tr1/complex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c91b0824f8f22581547c364626decc91d94092518be46aa5ed473046565ac0dd +size 854 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/no_tr1/functional.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/no_tr1/functional.hpp new file mode 100644 index 0000000..e7ab900 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/no_tr1/functional.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa14f93ad82f3ef4d5be7107e388f4636e057cc056602527ae82319bd6d91949 +size 878 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/no_tr1/memory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/no_tr1/memory.hpp new file mode 100644 index 0000000..7955654 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/no_tr1/memory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0be3cb94459966b29df1a4c36d4bf7bc18d57d2a06a433c12e1ed60ec29851c +size 846 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/no_tr1/utility.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/no_tr1/utility.hpp new file mode 100644 index 0000000..7f033c0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/no_tr1/utility.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2f768cf5c0a2800fb8bee3bd521e1e77feb1ca8dc7120d3fed4c7b2a70cacde +size 854 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/aix.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/aix.hpp new file mode 100644 index 0000000..2b77a21 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/aix.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:202780bd2c63a581860b273d439c27aebf5380ec6ef88c3ae6f45fe5498ea7f4 +size 888 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/amigaos.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/amigaos.hpp new file mode 100644 index 0000000..e45417d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/amigaos.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:281591f1f79e5560b06fbc5671ed86596e10c0ecd02215f3c5e12c101165ea0b +size 442 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/beos.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/beos.hpp new file mode 100644 index 0000000..f3b1da9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/beos.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bfb4c40d6a696aafc3068e0613768b4ca3bd914dfda24677afe87e6eed39bfd +size 600 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/bsd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/bsd.hpp new file mode 100644 index 0000000..2bfc0fe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/bsd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb1eb62f358321c2c555a893329e6b2943e3626323173760e4818c43e923d1f9 +size 2505 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/cloudabi.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/cloudabi.hpp new file mode 100644 index 0000000..614a862 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/cloudabi.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e9c3693c4033f2625f90185806c9a7be6bffb1982fbbf48adddd565fa2e09680 +size 530 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/cray.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/cray.hpp new file mode 100644 index 0000000..e2922b0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/cray.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4cdb37d8dfc102a686fdff50aaa77641aebd5e674dd617c73c405748ffb94b24 +size 456 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/cygwin.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/cygwin.hpp new file mode 100644 index 0000000..d97d86b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/cygwin.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2851dd3e823b55e73cf894d2976354d7a7326072b2fec81c18a9ed58e27ec1f1 +size 1767 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/haiku.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/haiku.hpp new file mode 100644 index 0000000..9db3e2a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/haiku.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e66f4725bfa196668a3252964ed5468c81dbd1006a733c49edd4f87f0e7fd4c +size 807 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/hpux.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/hpux.hpp new file mode 100644 index 0000000..a447d8e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/hpux.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e1ada36b46783f7a3f336b8d060a38cd519e9701cc606c958fcc202e8e4f4ce +size 2484 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/irix.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/irix.hpp new file mode 100644 index 0000000..61e3002 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/irix.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ea7e1e081993ed5aa631acf35b69146193f6285624011872fdc861d12274115 +size 796 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/linux.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/linux.hpp new file mode 100644 index 0000000..e6a54b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/linux.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f508f04c0fe1e1dab43a5c5cb287bb5514b58f63ea3d4705d3aafea528be2341 +size 2850 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/macos.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/macos.hpp new file mode 100644 index 0000000..ad8e5bd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/macos.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5f923845074c86a3abfb0b5fee1e5795646e92274f722291f6e2a1e6e4d7b0d +size 2350 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/qnxnto.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/qnxnto.hpp new file mode 100644 index 0000000..1755871 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/qnxnto.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a994c5204414f356008d0cbb491bb1215f24adac65f71ea62e8f1641b5741482 +size 773 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/solaris.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/solaris.hpp new file mode 100644 index 0000000..a2bdf6f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/solaris.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da27516af05fb2bc561fcc06e293202524b22c962eb9c077646fa7a592afcac3 +size 841 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/symbian.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/symbian.hpp new file mode 100644 index 0000000..956f9f6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/symbian.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:301de8231e5be4e9bbb812e7142235c15d6b8b31b05c3b5c55944e898f059e9c +size 2621 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/vms.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/vms.hpp new file mode 100644 index 0000000..52dab7e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/vms.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e479c2501ba061a46720795cbc7845137c12a081df6325d58b9ffe7317ca00a1 +size 749 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/vxworks.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/vxworks.hpp new file mode 100644 index 0000000..ddabc1e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/vxworks.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03a1c29f99985989d7315a2ac1a84fa2722211876b0bc61691c39912910f8d40 +size 15342 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/win32.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/win32.hpp new file mode 100644 index 0000000..3400dc9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/win32.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eaa82c93bc49969f4e91edd333e1068bb4aeeb97c9a3dcdf51c0f8dab05dc225 +size 2718 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/zos.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/zos.hpp new file mode 100644 index 0000000..584ed16 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/platform/zos.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:108f3d2d0c14c98e258b6bb012119edc5c0f954981f4836f019f563e7ec4e729 +size 789 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/pragma_message.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/pragma_message.hpp new file mode 100644 index 0000000..bd4e822 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/pragma_message.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1951b59b8db3e8bf1e02c622605c7f45067dc3ce86eee8fba00f656099c64ab9 +size 1019 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/requires_threads.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/requires_threads.hpp new file mode 100644 index 0000000..f6bba02 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/requires_threads.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff5b6b123e00b032d58d5f0c2daa299d99036618d9c90260cb4c7693d05a985c +size 3507 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/dinkumware.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/dinkumware.hpp new file mode 100644 index 0000000..8c5f051 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/dinkumware.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c12e2ab06e2357239c62b4472221a8113f59c4abf4121fc553770665bb30cdff +size 9354 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/libcomo.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/libcomo.hpp new file mode 100644 index 0000000..efa5fbf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/libcomo.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c524987d9cfec1e22e892dd9f5d463a0c443e8d2240e2c0b4ad8cf26ac7c7f7a +size 2791 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/libcpp.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/libcpp.hpp new file mode 100644 index 0000000..522f6cc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/libcpp.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17f7c3e0fcdf40e865c1ebe0cb1927d179fca9a198076e3dd371a1c2fbddb3b1 +size 4929 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/libstdcpp3.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/libstdcpp3.hpp new file mode 100644 index 0000000..fe65898 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/libstdcpp3.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1dbfe1e377b1b9c16f95bbfefe7519b96732645cfa5a8c257757a396d7c4d10 +size 12239 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/modena.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/modena.hpp new file mode 100644 index 0000000..d749948 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/modena.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db7f6ae87e7ef379a1f6319b2598bd177ed9b88ac0ff35a5247cd6274f4067b0 +size 2196 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/msl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/msl.hpp new file mode 100644 index 0000000..1576609 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/msl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42674ff55c138e6e8957fac8d03e461f5d2626da6d627ecd52f06849563500ba +size 2797 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/roguewave.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/roguewave.hpp new file mode 100644 index 0000000..fd17fc1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/roguewave.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e5cf1bfc3827462eecb0f5959d6bb823f6fa2fcbec102a72a399e54fed43be50 +size 6219 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/sgi.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/sgi.hpp new file mode 100644 index 0000000..4c1fcb1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/sgi.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f45d99aab0c0e9027965b14fa9b6abf441da4804ae239e98addadf4788371724 +size 5022 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/stlport.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/stlport.hpp new file mode 100644 index 0000000..46bcecb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/stlport.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:275e8b37848ab6d82d9da164e466868f19136892ce5eff5d466bdd3719dac5d9 +size 8532 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/vacpp.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/vacpp.hpp new file mode 100644 index 0000000..488e3af --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/vacpp.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:153464bd14987f2d0b7d5317084571446bc164961b6b560053e39a43a62ea096 +size 2355 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/xlcpp_zos.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/xlcpp_zos.hpp new file mode 100644 index 0000000..d08b48c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/stdlib/xlcpp_zos.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3918664637dba3e454425906964c1bf56ce5ac2e33beab01e0ec6f62eda3a438 +size 1926 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/user.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/user.hpp new file mode 100644 index 0000000..280acd6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/user.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3031f2d4cd6ab3b9f7f8a17a0b2acd3947a9ede21ecb18a16104b2f2b68d2cb3 +size 5367 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/warning_disable.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/warning_disable.hpp new file mode 100644 index 0000000..fdcc86d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/warning_disable.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51afb69aa2a3907b10d253ed93d000cee51f88cd6ff1bc7ca23a3296997e7453 +size 1820 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/workaround.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/workaround.hpp new file mode 100644 index 0000000..6c55d78 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/config/workaround.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:31d4fd91e3ed1c01cdb49d1bc6dda8cbfd071c323da15bf40c2b58b9371ca48a +size 7558 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/adaptive_pool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/adaptive_pool.hpp new file mode 100644 index 0000000..cca1253 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/adaptive_pool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca36797be3bf6fad249895a55362b3dfc83fd877751190c8150640464c2b83b1 +size 23207 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/allocator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/allocator.hpp new file mode 100644 index 0000000..630cfd0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/allocator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b8ccb5b89731743f872bba30fd11ab752668718535d3c5de0966628a2cd68bd0 +size 13809 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/allocator_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/allocator_traits.hpp new file mode 100644 index 0000000..92724a4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/allocator_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b998cb2d659b71ae2e9a547c65f6fa5687a03a8feca8f3fa96cdd54d5b4b6b37 +size 23213 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/container_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/container_fwd.hpp new file mode 100644 index 0000000..0281479 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/container_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9009f31dc938d3eec09bd43576fc0ad97d4a47cca7e0e24c85edbc68e00045ea +size 7795 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/deque.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/deque.hpp new file mode 100644 index 0000000..68282b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/deque.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d2c67577f8c7b7adf0dc86427c4245434f8b7292e39dec75b03e435b9c0cef8 +size 81807 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/adaptive_node_pool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/adaptive_node_pool.hpp new file mode 100644 index 0000000..d82a0e3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/adaptive_node_pool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8dc59b370749d2bb6463a578b92eaa1562408a4e66d41fd8c47643152019c26 +size 5569 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/adaptive_node_pool_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/adaptive_node_pool_impl.hpp new file mode 100644 index 0000000..e3e0147 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/adaptive_node_pool_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba25f2342be0cdfae1861ec460a349401e63ced4fe8a9fad321460a7f5f17de9 +size 54088 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/addressof.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/addressof.hpp new file mode 100644 index 0000000..1bfe281 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/addressof.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85817e83cca948b15bd4294c04d36a0c9f06d3aacf8868b48edea274064dbc7d +size 1063 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/advanced_insert_int.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/advanced_insert_int.hpp new file mode 100644 index 0000000..c800e42 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/advanced_insert_int.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d371daa953cb5de31d88f2ded295cb4509618f83356bc22acd34e0fcc73893c0 +size 17544 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/algorithm.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/algorithm.hpp new file mode 100644 index 0000000..79c91dc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/algorithm.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3a67332a18f057c2ae6d001f0b692124243722f691d6e21b58ee04c518bd342 +size 3880 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/alloc_helpers.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/alloc_helpers.hpp new file mode 100644 index 0000000..adb5fbd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/alloc_helpers.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:00da1b4240cda3358a8acae0e737c807e6208a2cedc11732961e520400be8d0a +size 1741 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/alloc_lib.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/alloc_lib.h new file mode 100644 index 0000000..e8414a9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/alloc_lib.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ae7c2f57ce10dd5b64c543d1af5901f43f78acd35894c7a42b7fa07d210f3fa +size 11710 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/allocation_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/allocation_type.hpp new file mode 100644 index 0000000..02171fb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/allocation_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81611e89ed54d9deb3fd03c648e6f58e45fca65410f1a846cd422d4b562d8a1d +size 2017 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/allocator_version_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/allocator_version_traits.hpp new file mode 100644 index 0000000..18d89ed --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/allocator_version_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c7b05ab60fa46ecdd75a29ba82721c5c044e2f2fc94006651f707043d71418b +size 5632 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/auto_link.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/auto_link.hpp new file mode 100644 index 0000000..162ad59 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/auto_link.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7e711211ac22c58b18ccd0dac1f8b6c21556f86e3009d4611e6bded25f45ee7d +size 1657 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/block_list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/block_list.hpp new file mode 100644 index 0000000..97db143 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/block_list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98ced842d2e57aaa2de002ab8de4cab28718aff2073a943435e43b525a64727a +size 4122 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/block_slist.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/block_slist.hpp new file mode 100644 index 0000000..1c1e676 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/block_slist.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c5269d48993dc4adda3918c359ab9d0582b63318976f2ece7d39676e2c0dc9e +size 4426 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/compare_functors.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/compare_functors.hpp new file mode 100644 index 0000000..d0fc330 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/compare_functors.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85c4cb4b05632f26006d2636f3b458eacbb9035ad7be5a7f4dff931778a3079e +size 4013 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/config_begin.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/config_begin.hpp new file mode 100644 index 0000000..879771d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/config_begin.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74c930a9e23bf0ea690f43ec8a12b5c9f80109186beae33ad4951e52aa3ee342 +size 3637 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/config_end.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/config_end.hpp new file mode 100644 index 0000000..7408b2b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/config_end.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f35bfe1070009b6dd95b4d76bd60399fc0ba4fcfd462709851499949b552c227 +size 480 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/construct_in_place.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/construct_in_place.hpp new file mode 100644 index 0000000..82522ba --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/construct_in_place.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ea864816752e399d90e5c9cb4e2c13fb6a11aa7178eb757455f29548e03edaf +size 2952 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/container_or_allocator_rebind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/container_or_allocator_rebind.hpp new file mode 100644 index 0000000..16c169c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/container_or_allocator_rebind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66997726c38ca95f813219bae7e424eb85511cb257a8cdbd3c6bd32528aeadaf +size 1619 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/container_rebind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/container_rebind.hpp new file mode 100644 index 0000000..7c0714c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/container_rebind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9f83bbda90c8997cb1733dc098f06b999779a70895575394a3ca9501e6cd61ac +size 10824 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/copy_move_algo.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/copy_move_algo.hpp new file mode 100644 index 0000000..9526559 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/copy_move_algo.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c98d1df5921f3da2eac74c77efcbcb6d2e012a8a4bc2c3b0779d5360b47c1e3a +size 38467 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/destroyers.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/destroyers.hpp new file mode 100644 index 0000000..b712fb3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/destroyers.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b11fae41fd6bb4f7704509d6773d5e0262ac00654564663fbb64a30e096f703 +size 9338 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/dispatch_uses_allocator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/dispatch_uses_allocator.hpp new file mode 100644 index 0000000..7a44b2e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/dispatch_uses_allocator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14a9c0c060eee5ee84b2df807466e790196aa27d6703be91cfb28f6c7ca50511 +size 19485 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/dlmalloc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/dlmalloc.hpp new file mode 100644 index 0000000..80ce5dc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/dlmalloc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a808c9bf7add5c4505769d257180cb1b477805f53fa52bf066c6aecbc7569092 +size 3444 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/flat_tree.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/flat_tree.hpp new file mode 100644 index 0000000..8bcb47f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/flat_tree.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6672e0a6a94771f9a947aee6a326a17d380643b18beae44124195eec8649f26e +size 61462 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/function_detector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/function_detector.hpp new file mode 100644 index 0000000..6c64031 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/function_detector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c695281459d1ce9a54e8d6023733dbd1e87564cd18a3f7220452daf91c3017b +size 3558 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/is_container.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/is_container.hpp new file mode 100644 index 0000000..d2b1ba1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/is_container.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a05957392014db9799a58c034d9883d14d553c0fc645ec961beb203b8b88127 +size 2132 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/is_contiguous_container.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/is_contiguous_container.hpp new file mode 100644 index 0000000..fdd327a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/is_contiguous_container.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fba30670ef4a0028c5dfc13b7ba4ef96279190bec3df7e7eb2c2e7f904c26d04 +size 1712 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/is_sorted.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/is_sorted.hpp new file mode 100644 index 0000000..f580304 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/is_sorted.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78082cc7f00dc3b8ed73d601352b4f456c136532bc19f1e8af4190395a61daea +size 1465 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/iterator.hpp new file mode 100644 index 0000000..280ec30 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae697e6b82b585d1fd6569ca744851e78504073f39ed3e9a952248150b22bde1 +size 2590 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/iterator_to_raw_pointer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/iterator_to_raw_pointer.hpp new file mode 100644 index 0000000..a29e8eb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/iterator_to_raw_pointer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:758d0974971f187b130aa6ddea90c633932daa7d0ea3b1065988f37fb89611f7 +size 971 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/iterators.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/iterators.hpp new file mode 100644 index 0000000..4e741b5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/iterators.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95c5fb1a97f0e6151c8040a87cbfc4956a47ed9fa846c91fd7040ce898da6bcc +size 26063 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/math_functions.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/math_functions.hpp new file mode 100644 index 0000000..1b87904 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/math_functions.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d71c4698133616580d723198f54e1ba1c28680a557a857f4dc7f6d713c5b97a +size 3872 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/min_max.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/min_max.hpp new file mode 100644 index 0000000..9ed8b1d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/min_max.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46047136eeeba6892fb4d92ae362e2be20bd8b74e08abde37cc1602f5fbd5e6f +size 997 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/minimal_char_traits_header.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/minimal_char_traits_header.hpp new file mode 100644 index 0000000..14e625a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/minimal_char_traits_header.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a34e6549640689dacfd8f82d945bf97eeb29a729a1c309bf6533f85b7efef9db +size 1057 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/mpl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/mpl.hpp new file mode 100644 index 0000000..87e6e87 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/mpl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d5693b121b9473db400f9ff80707bd1a4d9e9ee791ea9b08e8e35d3810e2dc3 +size 3778 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/multiallocation_chain.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/multiallocation_chain.hpp new file mode 100644 index 0000000..50e738f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/multiallocation_chain.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e97a150a94b8527c4a4b03e688f4f98d539c80b3f8eb6190b2d98d7860aeb438 +size 10317 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/mutex.hpp new file mode 100644 index 0000000..0b9752b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:679965f26776637b748d894e0dc65b0128b74bb52fdcdb0c61bff10622a2b5d4 +size 8665 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/next_capacity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/next_capacity.hpp new file mode 100644 index 0000000..4c88ed0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/next_capacity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4f30acc17dfe1c3002c330e6e4f3fe95502a170d835d3bde535d24a538581de +size 2140 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/node_alloc_holder.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/node_alloc_holder.hpp new file mode 100644 index 0000000..4ee716a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/node_alloc_holder.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db4ba31d3048d7abf5ee895cc3bb37d9219f36f79b541e217e15c08ca135038e +size 17651 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/node_pool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/node_pool.hpp new file mode 100644 index 0000000..ef83160 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/node_pool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e773146c9ecf45ec8c2fb7545ac48614b034e026505d736820acaf4653fc12fa +size 4808 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/node_pool_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/node_pool_impl.hpp new file mode 100644 index 0000000..b6e3015 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/node_pool_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5dda6d7bcd7a4b0a9f57107bd1a6232b64a035597a48c3072837b66a0ebc82ee +size 13171 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/pair.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/pair.hpp new file mode 100644 index 0000000..e801ac7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/pair.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07e6392d7dfaea04181f38720abc3615f3d5d6eba8f27cfa0fd7c68dac7ca243 +size 19046 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/pair_key_mapped_of_value.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/pair_key_mapped_of_value.hpp new file mode 100644 index 0000000..285f879 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/pair_key_mapped_of_value.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b48b142f084d7d3b1693f5d03a6e9bb4857ca178cc697e2b1fe06c38041a3b99 +size 1466 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/placement_new.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/placement_new.hpp new file mode 100644 index 0000000..c7dd114 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/placement_new.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:624e2da323c21b01142e31388403c071cf915950d91b59bc82167ab75b017735 +size 914 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/pool_common.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/pool_common.hpp new file mode 100644 index 0000000..1afcbe3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/pool_common.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d440b96963a29471b32fce299ea92240cc5e26bf534739a66bed15f92499d2c9 +size 1606 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/pool_common_alloc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/pool_common_alloc.hpp new file mode 100644 index 0000000..d21f4e6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/pool_common_alloc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ad2d8210ddf586c70070242e02991540b8f3fc1acc25c825714a1b4066daa92 +size 2730 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/pool_resource.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/pool_resource.hpp new file mode 100644 index 0000000..b0fdbd0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/pool_resource.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f47ef05e5ea1eef48a77c54aac3e52a6eccfbf9ceff3b7569e90db3a13c67d13 +size 7744 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/singleton.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/singleton.hpp new file mode 100644 index 0000000..981e6ed --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/singleton.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3928673e1293f043baa56dac6c38cf7e0bed2f7df6873483c83824aab97ff1af +size 4465 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/std_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/std_fwd.hpp new file mode 100644 index 0000000..7d309b1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/std_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c6d541b8c82a29fbcecfeb4b54be889570f2c71f02341bf4b8eb1d64b52f6129 +size 1450 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/thread_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/thread_mutex.hpp new file mode 100644 index 0000000..dfba990 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/thread_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e43787e0469c55afe74bed268a252e36b2cd5989c4921cd079ec5559d1fd3c52 +size 4440 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/transform_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/transform_iterator.hpp new file mode 100644 index 0000000..5ce7fe8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/transform_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c2a3a41bfaa0db0d95cfb75482cdd74784d5dd0beb658b3c84476b525b428cf +size 5103 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/tree.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/tree.hpp new file mode 100644 index 0000000..a589a06 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/tree.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff65d82e5390e8e3e9f10cbcec5845e8fe4be9d28ac075f1f0ef70a5520e04a4 +size 55865 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/type_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/type_traits.hpp new file mode 100644 index 0000000..864d566 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/type_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3cb5197331c9251167b68db1432d84ba52cfae40b2e5b623c0ecac5c42a67bb7 +size 2714 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/value_functors.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/value_functors.hpp new file mode 100644 index 0000000..2ae16f6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/value_functors.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ae0b73aa647084c393425f9f6680887e6b646edad42aac89f7b744023fe85e0 +size 1026 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/value_init.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/value_init.hpp new file mode 100644 index 0000000..0664574 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/value_init.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:69f9bd16f6ec8e0b9709d5cda5c81fc46452603e6c678dd538e6c0fbc43d5baa +size 1135 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/variadic_templates_tools.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/variadic_templates_tools.hpp new file mode 100644 index 0000000..093002c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/variadic_templates_tools.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30189e4df53bc5ff1dcb896b27c1e9afa19494d5097d40dceddfffcb9572c9d8 +size 4959 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/version_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/version_type.hpp new file mode 100644 index 0000000..1a7cca1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/version_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6d791962ad165a84a0f118cbcdf1f40ebc707ae50e4e4f03b9dee1f1c7ff74bc +size 2650 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/workaround.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/workaround.hpp new file mode 100644 index 0000000..bc5ad39 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/detail/workaround.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c96dc9894a16f739a88345b5264a705c753e5c2e407befb1a2be2e580f0c781a +size 4360 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/flat_map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/flat_map.hpp new file mode 100644 index 0000000..abfd02a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/flat_map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9aaf36bca6fdf621d5fea4eb88f85fbbc8d7daae19484e809504e458ccec06c6 +size 135185 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/flat_set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/flat_set.hpp new file mode 100644 index 0000000..6e7db73 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/flat_set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a7c50d7443926c10f583f8d96af9d70352aa3fb33d676e0061dd1b889b2075a8 +size 84437 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/list.hpp new file mode 100644 index 0000000..c33cc5d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2932e201900557ee62074169eb67151b10ec074dcc2573c5ccc7c977e94a6b2b +size 57410 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/map.hpp new file mode 100644 index 0000000..675dfc5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:babba37700734440739685c6a5674b25493a228954f0bf9a80851c8b234925d6 +size 103614 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/new_allocator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/new_allocator.hpp new file mode 100644 index 0000000..d23c13e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/new_allocator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c51ea38764fdd8e1c9b2e9950b02262489c1c65efeec27c7a7ebeb3054212f2 +size 5779 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/node_allocator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/node_allocator.hpp new file mode 100644 index 0000000..90244c7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/node_allocator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0559380f399711515d9b6a9562b181c50f13a9c8cb759564eb8df239ab8e1948 +size 12485 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/node_handle.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/node_handle.hpp new file mode 100644 index 0000000..1c6d04c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/node_handle.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b0e33149324e8fd37dcc7dd67e025f56347bfce0adcc710a8873eabf38e55e4 +size 15448 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/options.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/options.hpp new file mode 100644 index 0000000..6c923b5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/options.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:959fe941344d0895d4f971b212de5f7f84350ee97483ddd72d2e5cb4788e3e6d +size 9054 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/deque.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/deque.hpp new file mode 100644 index 0000000..12eb6b2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/deque.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c84b9bd31b180b49b59797f79cf27ab3e241596316fca3ce4c7fd1be49cead71 +size 1160 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/flat_map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/flat_map.hpp new file mode 100644 index 0000000..9df3443 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/flat_map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81e151eb16824c8cb7337b06f8d69e8fd57759913b2e87662b595cbf8fae8ace +size 1883 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/flat_set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/flat_set.hpp new file mode 100644 index 0000000..ed53096 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/flat_set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e5545422237dc7908dabf6d8a6567cc4ee2f6e1c601275fc6d2ae872837f021 +size 1719 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/global_resource.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/global_resource.hpp new file mode 100644 index 0000000..99bc5dc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/global_resource.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:572cc0465577b9c726cf983bdf1dd50206b8b4a86ddf9837b5725a7cfeb8f723 +size 2733 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/list.hpp new file mode 100644 index 0000000..b0a0e7d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b517bf3972e964569806a899f41dca6314049369f4decbd4b1dd700ea3aa3f21 +size 1153 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/map.hpp new file mode 100644 index 0000000..9832cf7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:617314d31645256f4274ae8d4f927858e2658faea6c4c86000c80262b4a0b3af +size 1992 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/memory_resource.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/memory_resource.hpp new file mode 100644 index 0000000..a1760fe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/memory_resource.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03465f4d5cb6e2f4e078ac5f8454887d1655a1f3d813353d241e23dacf9b578a +size 4047 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/monotonic_buffer_resource.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/monotonic_buffer_resource.hpp new file mode 100644 index 0000000..5dd3ad2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/monotonic_buffer_resource.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:209fdb451925db3c21838ec6f1ead15aca3b675cb6bbe325fb9aacec8d9e25be +size 8172 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/polymorphic_allocator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/polymorphic_allocator.hpp new file mode 100644 index 0000000..ea3329a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/polymorphic_allocator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46a68512287b0d237d5f07de05f9dfbe384cfec41e38fa1a41fa0b1717d81ebe +size 6189 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/pool_options.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/pool_options.hpp new file mode 100644 index 0000000..22b74c9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/pool_options.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f8525dcffff4f7a89745453eb6252d807b37b21bfb8919e62e5be3263a18ff9c +size 2083 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/resource_adaptor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/resource_adaptor.hpp new file mode 100644 index 0000000..f3d6012 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/resource_adaptor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e44d4d6acf7ebc7de0d2a4ca1266fedb279dbd6b0aaea5cc34e5fdf533c6b393 +size 7106 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/set.hpp new file mode 100644 index 0000000..724c0f4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e48645929e7b95e859822f002841acecbbb9613b75524a6f8356d4adc57272fe +size 1820 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/slist.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/slist.hpp new file mode 100644 index 0000000..8892420 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/slist.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82ed1aeafbb1a55dd1f106877f63dcbc01d404c759b7ec009c21b69dc0bec219 +size 1161 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/small_vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/small_vector.hpp new file mode 100644 index 0000000..3a8544a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/small_vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a50c69e5a22c8767ccf005e6826249ebdb80b05d20f18ec8e2a6ce9722ebd56e +size 1259 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/stable_vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/stable_vector.hpp new file mode 100644 index 0000000..e77fa6a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/stable_vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d35304a610c0a425c275923ba8cf2f453590e5f2abc89a909f7dc2807676d011 +size 1232 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/string.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/string.hpp new file mode 100644 index 0000000..c020bb5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/string.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:653a19c4302f866bc3d9f53d203000777b42b633ace6d071253eadad13bb9ce4 +size 1423 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/synchronized_pool_resource.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/synchronized_pool_resource.hpp new file mode 100644 index 0000000..29cc894 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/synchronized_pool_resource.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c3260484b730afcdfb042679570afcb7a0398e2f5647a1d2d6e62ff37bc64d0 +size 6111 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/unsynchronized_pool_resource.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/unsynchronized_pool_resource.hpp new file mode 100644 index 0000000..84c2601 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/unsynchronized_pool_resource.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:188429bdca7e6224e2297d4c322bd8aacefbd78789e64eac5eb642f27894ca42 +size 8568 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/vector.hpp new file mode 100644 index 0000000..56e42f0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/pmr/vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:331eb4eb5266c349bd8feab278634abf367c6c763ea015ceefd965b951d38516 +size 1169 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/scoped_allocator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/scoped_allocator.hpp new file mode 100644 index 0000000..4670bb1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/scoped_allocator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:196dfa0350e2fbf576462f15749c88e973f1aa72c8b3f643982bb0c2fb40b6dd +size 37015 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/scoped_allocator_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/scoped_allocator_fwd.hpp new file mode 100644 index 0000000..57d6f36 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/scoped_allocator_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f05c469dbff10c113be2986dcb448cd857a8f0bcb6d5b3ae9ccd46a0aa76d242 +size 2164 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/set.hpp new file mode 100644 index 0000000..5b8f20b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42743033f4cd7c3050c60db083fc83cc3769bf736706be7254085cf93c62b048 +size 71786 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/slist.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/slist.hpp new file mode 100644 index 0000000..59a59d4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/slist.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7af48ec021a5d2114edf79faa803768c87ef54c31e4cc23639f70cce0a1eaab +size 68707 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/small_vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/small_vector.hpp new file mode 100644 index 0000000..480f2c5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/small_vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:162eb86c7b91da734287e06cfaf27c76616345719ef868ccba0409e9a5bdd49c +size 29769 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/stable_vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/stable_vector.hpp new file mode 100644 index 0000000..27d7cb2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/stable_vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1a7238bdd6e6bbfd4a94fce4f138e48d0ddef577eaaafc4ff69116a72be324db +size 81300 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/static_vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/static_vector.hpp new file mode 100644 index 0000000..b4793f2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/static_vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:572abb6546da20d732a528a81312b8452b9ef0b09986e79981e85460fb1aef07 +size 41483 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/string.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/string.hpp new file mode 100644 index 0000000..7eb15ad --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/string.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b35c46542bb1d7a36ddac6840dec5f9df242b451719973cca86353c76f3a50ce +size 128107 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/throw_exception.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/throw_exception.hpp new file mode 100644 index 0000000..9488d6a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/throw_exception.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:765da2d552f6ee07b49687b523d6f9e0823cbd68cd8b68d84274ca8983fb468e +size 6617 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/uses_allocator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/uses_allocator.hpp new file mode 100644 index 0000000..9e694b1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/uses_allocator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74301a9e236dcced388e0dafae3cd8b73841e1fa8270b1ceb6dbfc2472ebaac4 +size 7514 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/uses_allocator_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/uses_allocator_fwd.hpp new file mode 100644 index 0000000..604ea41 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/uses_allocator_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e10f25e2777a0d866180e6a2d97add1f976ddb1e4e2e7c67be04ac34c90fb013 +size 2540 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/vector.hpp new file mode 100644 index 0000000..93db681 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container/vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1a9a7b829da31de7602533d5416e0409f3f256629b4cf8c0b0599cf5ca08d527 +size 138814 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/detail/float_functions.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/detail/float_functions.hpp new file mode 100644 index 0000000..87b20fc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/detail/float_functions.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:38f198d979b179803048865a8dfb14d02abf327cfdf65e6897af2a04132fffca +size 13683 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/detail/hash_float.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/detail/hash_float.hpp new file mode 100644 index 0000000..4f054e8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/detail/hash_float.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e2f8606b8f1c8efcb339291f5a52431e861c7d825a08d978f5f623b7aed0aec2 +size 8079 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/detail/limits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/detail/limits.hpp new file mode 100644 index 0000000..41ad1fe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/detail/limits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b863c3d936d76bfa33c45ba20a781285fbad604c6279ac858946e53e6db737e8 +size 1691 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/extensions.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/extensions.hpp new file mode 100644 index 0000000..fa519e7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/extensions.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2659b8b59d8ceec444374e4c74c5720165354dac66ad34f8f0a39db2ef4a5ba8 +size 11603 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/hash.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/hash.hpp new file mode 100644 index 0000000..58b5110 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/hash.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18fe6add07eef55ecaca4200b7db763e92cb6f4c2b43db64ea7f0b4cb86186fb +size 22598 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/hash_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/hash_fwd.hpp new file mode 100644 index 0000000..4af5008 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/container_hash/hash_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:93bcc6f92f328d5a55c7a351cacdd0f0a6ccd4eb98ebd9c2d1e1ab3fbac2b36d +size 971 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/addressof.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/addressof.hpp new file mode 100644 index 0000000..f32aaf3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/addressof.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:643323576b2aa61127f9aff6c01542975d997cfac46c2a97e9d3f4954853b83b +size 6149 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/checked_delete.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/checked_delete.hpp new file mode 100644 index 0000000..c1f78aa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/checked_delete.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e25321ad09aa981c0b0732158aef56702508d779b4c96a72397d970e6fc1d6f +size 1588 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/demangle.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/demangle.hpp new file mode 100644 index 0000000..e2a6fd6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/demangle.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:310bfea5659a54a79f0421132b5d7fcf5e79f846788775e64beae700c01f5413 +size 3034 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/empty_value.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/empty_value.hpp new file mode 100644 index 0000000..32106b5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/empty_value.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:482d4e37868c9b3fa4b95fdef7a0689dab3841d43f3c1cb5b683265d7349d72b +size 2997 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/enable_if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/enable_if.hpp new file mode 100644 index 0000000..1d8cc07 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/enable_if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4aefa20fb7a5d673ee4023e693ca74738dd84ffd5a4c248ddc06c1df812229e +size 3315 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/exchange.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/exchange.hpp new file mode 100644 index 0000000..77c67e3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/exchange.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:010dbad20301588498082a5d26121cf7f53c51f948f92fa9097e17319d520b28 +size 911 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/explicit_operator_bool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/explicit_operator_bool.hpp new file mode 100644 index 0000000..7affa3e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/explicit_operator_bool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4328e10b18731c5a01feb82e692d6e3d61418d37958cd6ef66c55e1676070c3f +size 5354 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/ignore_unused.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/ignore_unused.hpp new file mode 100644 index 0000000..3680e6e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/ignore_unused.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:091ae9d42706a5ba1cafd9546f080927a5e6b8dc3dc7c10f26410525708a342e +size 1976 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/is_same.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/is_same.hpp new file mode 100644 index 0000000..225d464 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/is_same.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:686586c5a596d4819c71fc970dfd4400f21cc55909743ca1e0f58d43fc87869b +size 793 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/lightweight_test.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/lightweight_test.hpp new file mode 100644 index 0000000..e26e48e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/lightweight_test.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91e714a355defe1fe684f9b63ed20a5f82ca82a79b045c7e5902275c6839f3ef +size 15544 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/lightweight_test_trait.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/lightweight_test_trait.hpp new file mode 100644 index 0000000..e71e5e4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/lightweight_test_trait.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:960cce021dc6403dac6c19a8aabe0a62af951a4848d4da0640acffbce929be26 +size 1613 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/no_exceptions_support.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/no_exceptions_support.hpp new file mode 100644 index 0000000..b28de20 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/no_exceptions_support.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b612e534d0b9405c3c7d206eb10282557590a8c6e289f508bd7fbff58eb123f +size 1390 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/noncopyable.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/noncopyable.hpp new file mode 100644 index 0000000..bb55b81 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/noncopyable.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37177e9d1a542014397f53f01495f00937c502cf5f8454db1d035c4021cab20e +size 1911 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/null_deleter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/null_deleter.hpp new file mode 100644 index 0000000..c196216 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/null_deleter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29ba0a5afd6f04d18edbb97c5cc72cb5d8b06f4901862774552a335a9a64c818 +size 1232 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/pointer_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/pointer_traits.hpp new file mode 100644 index 0000000..7947845 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/pointer_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b043faee0d6d221cedb9bbd7cf229ba94a205147d4af21877b3b5da715514225 +size 5053 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/quick_exit.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/quick_exit.hpp new file mode 100644 index 0000000..acb89a2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/quick_exit.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0de8f085851cc50221306337dd5b2be3ce20cc5817274bde84c92c40a9a76dd3 +size 1097 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/ref.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/ref.hpp new file mode 100644 index 0000000..935919f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/ref.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34d9a961c758fbd24b0ce724ecc3d520dfd8e35c1eb2877a3e679224b6c503e1 +size 5972 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/scoped_enum.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/scoped_enum.hpp new file mode 100644 index 0000000..8cbb2de --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/scoped_enum.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c923e0d3cfa3d28f7269c636cd7866cb54c6c8787757bbdfb72ac207e49d9b61 +size 7880 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/swap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/swap.hpp new file mode 100644 index 0000000..ab3cc35 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/swap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e46d8300864b19397cfad6b4b988c840825659130996488102a5a75be2bf4244 +size 2044 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/typeinfo.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/typeinfo.hpp new file mode 100644 index 0000000..a93c897 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/typeinfo.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b197390b6e5fa52c32ccced47f0132c67d5e6d7b27e4132a770f2f262af37f12 +size 3099 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/underlying_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/underlying_type.hpp new file mode 100644 index 0000000..53874e6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/core/underlying_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47a7e72f96110bb7e961f1979ed9032c641fe26553775d7bf60205f89e1f1c25 +size 2205 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/cstdint.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/cstdint.hpp new file mode 100644 index 0000000..b89cdab --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/cstdint.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85d2640e28b15a56508f65b9406e64e7042265cc9a55f20bd341b5d657d60185 +size 18473 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/current_function.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/current_function.hpp new file mode 100644 index 0000000..ab20b4c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/current_function.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3289f8a267ae81c452b9dda40391ea0778c027771eaa90b7af2284e8e3a7a17e +size 1701 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time.hpp new file mode 100644 index 0000000..78e505a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5973bcb349ac07a42d883201b177bb7da778157f11982d4e706b2b6c29f435b8 +size 540 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/adjust_functors.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/adjust_functors.hpp new file mode 100644 index 0000000..d53a819 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/adjust_functors.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:31851a1c7ed0a952cbeec86b45bd8ec0ae37c4b1090b99b001c4fca9ef73ea64 +size 5467 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/c_local_time_adjustor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/c_local_time_adjustor.hpp new file mode 100644 index 0000000..25838d6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/c_local_time_adjustor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:258565a0a5e4bc5e912eb9e89f26c68973fb152cc08eca965a2aee4bbe7d81cb +size 2631 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/c_time.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/c_time.hpp new file mode 100644 index 0000000..63c8f5e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/c_time.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9f9615c5283919867707c997c2de710c6f94eb00fb6230a461f85c879bbb5a9a +size 4288 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/compiler_config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/compiler_config.hpp new file mode 100644 index 0000000..af490bb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/compiler_config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21410b1960858ac3c7fbcb7c4ef11583ec6a95a822fe70ff98acb8dd268767db +size 6327 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/constrained_value.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/constrained_value.hpp new file mode 100644 index 0000000..a02e31c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/constrained_value.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46d1a0955478a2790397f603fb72a785692ee8f6e866b4deb0ff8018395a6c3a +size 4025 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date.hpp new file mode 100644 index 0000000..7fb7550 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82c2ad7a595250e588dae3b8edef727684f57a13c3cb6c09318589ca71327d87 +size 6905 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_clock_device.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_clock_device.hpp new file mode 100644 index 0000000..f6efa3e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_clock_device.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13d55167b7b349282fa5ff8950a8f659a2f124d0dbe457b3984572e824e2cd6a +size 2299 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_defs.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_defs.hpp new file mode 100644 index 0000000..c6b1393 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_defs.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6e32066c662aaf8c9fe93b908676b2b75c6b4daaed6898be5824739283a5259 +size 701 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_duration.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_duration.hpp new file mode 100644 index 0000000..a5748e3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_duration.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c20b51691d1e18bee689b456d1454008319f227b9c31d424d602608dc88bacb9 +size 4510 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_duration_types.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_duration_types.hpp new file mode 100644 index 0000000..d581089 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_duration_types.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:abc44f224030c5e2028ea034e66290f4250e6821d63a86f263ab755a950a0bc8 +size 8243 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_facet.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_facet.hpp new file mode 100644 index 0000000..bd75eca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_facet.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae3b4688b9285dd19365d7273705978ebaf59cad555fc25b38af111c79b80dbb +size 29307 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_format_simple.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_format_simple.hpp new file mode 100644 index 0000000..9b351d7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_format_simple.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54f2045755444bf66d9b790724ac3bc1bc4eeb3de842695ad95013283cb1c4b0 +size 3128 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_formatting.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_formatting.hpp new file mode 100644 index 0000000..df61a7a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_formatting.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90e2399a826f825bcfb0645c551cd3daff201d0ccf63df3311f03712344b3c42 +size 4208 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_formatting_limited.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_formatting_limited.hpp new file mode 100644 index 0000000..4019228 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_formatting_limited.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8456598970a28a1e9c665f778052a76493e46e1a5384393afb788bbeb9535cd0 +size 3461 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_formatting_locales.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_formatting_locales.hpp new file mode 100644 index 0000000..6d97fe7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_formatting_locales.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64a572ef7978032622d869d6055016061a88b9379a37aaf5197d403f0cbd908e +size 6748 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_generator_formatter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_generator_formatter.hpp new file mode 100644 index 0000000..073c4da --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_generator_formatter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58ee6e9b80bf6f6d1f86e3e07061c1d363af4d7e9e3e39e47889338d10dfd4b9 +size 11715 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_generator_parser.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_generator_parser.hpp new file mode 100644 index 0000000..9a0f4f6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_generator_parser.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ed55fd956de6e6dd362bee41ce5b21fc3e8326631ae017287aaec6f62c738e2 +size 13064 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_generators.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_generators.hpp new file mode 100644 index 0000000..241b548 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_generators.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a054891f0881965708c9f3f565d476ce2cf834db5a0854eb9ac5031f5fae4183 +size 16156 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_iterator.hpp new file mode 100644 index 0000000..fdac4ea --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e169e910a7d5f2c5ad23a85b04db17136a701071ed56dbbff9544b0c3275492 +size 3305 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_names_put.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_names_put.hpp new file mode 100644 index 0000000..d6e2796 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_names_put.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7bae080a8e0db02188cc42c782e264324d41271341257449b87d7cb3c93a0bb +size 10754 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_parsing.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_parsing.hpp new file mode 100644 index 0000000..abd1710 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/date_parsing.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2004b64c2d2b0c6f1f9d3aa80d1d2c06d72bd8e8650358219337e06e1df5b27b +size 11784 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/dst_rules.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/dst_rules.hpp new file mode 100644 index 0000000..99daf9a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/dst_rules.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:320526d0e30b6a050a3bfcac54cabb4505d4507b2e0e6a2057cd14aeb2f64be0 +size 15505 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/dst_transition_generators.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/dst_transition_generators.hpp new file mode 100644 index 0000000..ffa6d2a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/dst_transition_generators.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0450f3a83c3e83755a6e0a9d34ddf8006d7f50283e3ca95af3d35690f0a4311f +size 2275 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/filetime_functions.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/filetime_functions.hpp new file mode 100644 index 0000000..3a8d3c4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/filetime_functions.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:38285d82bd47b2e017dad7556770f61e261fd3f78fbd80c292d9086007a873aa +size 3163 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/format_date_parser.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/format_date_parser.hpp new file mode 100644 index 0000000..9f8d222 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/format_date_parser.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fcb9de62184af7f47233f6b672e69c910808fa622c24b5c33402419be73668d5 +size 24153 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/conversion.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/conversion.hpp new file mode 100644 index 0000000..c494d58 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/conversion.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e969d78894c065b76a3a7b49ddde85a8d8cdf7c42048bddcbe957e7804e99008 +size 2067 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/formatters.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/formatters.hpp new file mode 100644 index 0000000..a84066c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/formatters.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7329f13482203c62780e0ab9a0bd8fe9cea69361ef95e4490f076122d3611ce +size 5627 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/formatters_limited.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/formatters_limited.hpp new file mode 100644 index 0000000..2d2054a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/formatters_limited.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d62a9048c3d6e16329a2e71734d15b15def2c0e145e85eaea5f0f919c983960 +size 2746 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_calendar.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_calendar.hpp new file mode 100644 index 0000000..e402b0a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_calendar.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e9506577b519976af0a3fff0e8779eb725625ff50bb81c7fc25094992c96da47 +size 1588 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_date.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_date.hpp new file mode 100644 index 0000000..ab4ce89 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_date.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:532297dd97a6ade09da0dbf75bacd44130f5e2f591b3f2d11bc2dc67d9e372f1 +size 4517 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_day.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_day.hpp new file mode 100644 index 0000000..ec04646 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_day.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:25e987120333af63aeac2bba07ee56b54efbb199c0c0d8cea3095b5d9e2d088b +size 1832 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_day_of_year.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_day_of_year.hpp new file mode 100644 index 0000000..93fb651 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_day_of_year.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:893c436c51fa71996b6654deca0761ba6e8df65b85d887bae7c7e0c2337b45f8 +size 1094 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_duration.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_duration.hpp new file mode 100644 index 0000000..adfd5d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_duration.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6abcabbcc34a24ac06b809b32ee2c0f4fe73f93dca0a0bd86f826267a4ec36fd +size 3919 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_duration_types.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_duration_types.hpp new file mode 100644 index 0000000..701abaa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_duration_types.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e0c78a508ce20d5da5ddd0b4ec7f7bb13777e24f7efd5736116dbad0eccfeaf +size 1413 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_facet.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_facet.hpp new file mode 100644 index 0000000..a410474 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_facet.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ff825c8a9a1ca337a3402822ab400addf2cabb02fe441255dbc4fa3c5abbe5f +size 13225 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_month.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_month.hpp new file mode 100644 index 0000000..ec40b75 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_month.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b506c3ded4675d1b207d9d8acaf4abd934b03491238a90a77ca53f0a4ef4ee49 +size 3449 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_serialize.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_serialize.hpp new file mode 100644 index 0000000..238d8b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_serialize.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b600c2c77a6aaee3047bcf7f2ccb93a8148aa2dc5a7446014123d6339c03f8a +size 19711 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_weekday.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_weekday.hpp new file mode 100644 index 0000000..1adcabd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_weekday.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9dc951357533666ada1cf44b77c3b9b1bd404bcac33629fdeb45a0e9c5b950dd +size 1892 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_year.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_year.hpp new file mode 100644 index 0000000..f858da0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_year.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3682daa0f4ec1ebdbcfd76e1b97beca5a262ba67c793534e10cb01416118ed79 +size 1630 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_ymd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_ymd.hpp new file mode 100644 index 0000000..f6e02c8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/greg_ymd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1771bb4bf7fa2c9429f27d630d24addccd50218bc70423285b994a98dc18bc5a +size 857 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/gregorian.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/gregorian.hpp new file mode 100644 index 0000000..3f03b97 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/gregorian.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1214658bea4d9808808d3e225b943dcd43c989d8cecf403e5defdc2acd9d95d +size 1163 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/gregorian_io.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/gregorian_io.hpp new file mode 100644 index 0000000..1657dfa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/gregorian_io.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f170b718c37f77803c3af54b2a0eaee0f4ab60d89ffd76fd41eff673d8b23116 +size 28585 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/gregorian_types.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/gregorian_types.hpp new file mode 100644 index 0000000..8223d7a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/gregorian_types.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4bcef06b45abf99432752a3339a70377214798d7af09333af2ba5a8cbb663d2a +size 3631 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/parsers.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/parsers.hpp new file mode 100644 index 0000000..9bd0db2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian/parsers.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c4e3d8b0f5b28db420256b3f3bb3b034493c1fb3ef43a6054d4893db141c54b +size 3594 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian_calendar.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian_calendar.hpp new file mode 100644 index 0000000..003805b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian_calendar.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77f88d8dc7997345799423b4439f59d1d5299ce380cd3d7b7fac63921ff2c32a +size 2544 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian_calendar.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian_calendar.ipp new file mode 100644 index 0000000..9ff1a31 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/gregorian_calendar.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd4c7b335ba02e048c4cabcaeb8254c5c78a4c8ca95fd52e648719f4f17f42ea +size 7969 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/int_adapter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/int_adapter.hpp new file mode 100644 index 0000000..3b8cf0c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/int_adapter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15e40654ba5e1d3dfad18c560f1546888e3d2d51217ad8c8e7b5111c701364c5 +size 13552 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/iso_format.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/iso_format.hpp new file mode 100644 index 0000000..7edb88c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/iso_format.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:575e7a4ff7917693210d013dc6f4a7b5f9f6ed4e6102a72dfbc92e0d58c3afa9 +size 5640 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/conversion.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/conversion.hpp new file mode 100644 index 0000000..c1f964f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/conversion.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0c44c46c8630f5687dc17e7c7f1350fd0a5e85da25904523657d9f10973e771 +size 863 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/custom_time_zone.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/custom_time_zone.hpp new file mode 100644 index 0000000..7d378e0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/custom_time_zone.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c43a05cdb6ec0b18f6efbebca58dafa66506a8d231360cf18010b40d074f443a +size 6279 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/date_duration_operators.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/date_duration_operators.hpp new file mode 100644 index 0000000..93800f0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/date_duration_operators.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d881a3010dfe4087c691cc8fdaa2f4052a5896bb5cedda9fcd4c491274ce554 +size 4282 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/dst_transition_day_rules.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/dst_transition_day_rules.hpp new file mode 100644 index 0000000..06e3aa9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/dst_transition_day_rules.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08089af0dad8c7212646d394cf0d1a357c02ce15e4502e60630aa783ebcd55b4 +size 2638 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/local_date_time.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/local_date_time.hpp new file mode 100644 index 0000000..6a8f65f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/local_date_time.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51c0fc0edf4ba88412c18fdcbb6272a7aa516428407a9a19ff729aeece5a0243 +size 19914 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/local_time.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/local_time.hpp new file mode 100644 index 0000000..a94fe4d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/local_time.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5da700d67733e74ed6c05cb751a5c5680b8690e333f95ea97aa4e0d76272f1e1 +size 911 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/local_time_io.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/local_time_io.hpp new file mode 100644 index 0000000..16119dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/local_time_io.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:36ea3fecf2bd8c2ab87afead6c70687d818903f0608f7a8f239aef8774459b31 +size 7001 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/local_time_types.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/local_time_types.hpp new file mode 100644 index 0000000..1a8ad00 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/local_time_types.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:846162ee7403dbfbb7dee722c27f52c6280d1389178ff12da3a8d429ee83632e +size 1957 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/posix_time_zone.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/posix_time_zone.hpp new file mode 100644 index 0000000..7bfb778 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/posix_time_zone.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f5c65e79e32f09e8a07687ab839b80d1b88d4d04969f05b90b0f6964c76905c +size 18179 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/tz_database.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/tz_database.hpp new file mode 100644 index 0000000..f67ea8e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time/tz_database.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7cf5cfed850b7ed153c8338a0173ff28e2b3108681e3cdd88b88a426943471f8 +size 1044 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time_adjustor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time_adjustor.hpp new file mode 100644 index 0000000..26f1efa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_time_adjustor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8cc7101014480462359bf1babf29f3cd5835e0b055828e914408acc40b0cbb49 +size 8578 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_timezone_defs.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_timezone_defs.hpp new file mode 100644 index 0000000..d55f781 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/local_timezone_defs.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a897f6e00db5b61e55d317aca3f68ad4cbaba1fc6d06672cc18ccb65d798310 +size 7618 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/locale_config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/locale_config.hpp new file mode 100644 index 0000000..cf49c1d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/locale_config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aaf3df750edb54d2b517d0b6c8056533401d30823d6ccad734cd3e008dcd0a1b +size 1204 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/microsec_time_clock.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/microsec_time_clock.hpp new file mode 100644 index 0000000..0a060c6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/microsec_time_clock.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51afe4a30061be7d51053d2217f06e03a3d0475d83b724a39fddd7f029a1db74 +size 6257 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/parse_format_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/parse_format_base.hpp new file mode 100644 index 0000000..c066f16 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/parse_format_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b34b51527656fb1347b1d97130808daa118d26ce87591ed0757c2802ff7437b +size 961 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/period.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/period.hpp new file mode 100644 index 0000000..627e41f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/period.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbde2892f2c09817ca32d9852b64e34e694b0bbb70936ea4a62a902e8dca764a +size 11069 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/period_formatter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/period_formatter.hpp new file mode 100644 index 0000000..be86308 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/period_formatter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a086f31bf78a1dca3fd11833c7b4ba464b8b8e7fabf125eca55a2b7ca199aa4e +size 7216 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/period_parser.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/period_parser.hpp new file mode 100644 index 0000000..4fdfba4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/period_parser.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75a0425bef0c9bfdb20fcb864a8d5204a9cbc2576150ff30a94c2180df23b40e +size 8022 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/conversion.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/conversion.hpp new file mode 100644 index 0000000..b21a25c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/conversion.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19ecc8e1ddd8d358477de2f22fe8094f8f46e446dd4389de01d66063721a4987 +size 3391 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/date_duration_operators.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/date_duration_operators.hpp new file mode 100644 index 0000000..d0618bc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/date_duration_operators.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26b0a57f64b28a27648622d046bf8ab7961467449cbaf3ff6a42fef5a9aeef7a +size 3730 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time.hpp new file mode 100644 index 0000000..22f5c8d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34137e920ef44d6f7ebe62b51c74ebf37fb4a3f469d25d36683f142ff668d4f8 +size 1250 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_config.hpp new file mode 100644 index 0000000..c3ce870 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:72adeb89f412867c33b9e5da016a80d4830c5a6b2cff89f89a64f5332feecc9b +size 5948 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_duration.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_duration.hpp new file mode 100644 index 0000000..85660b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_duration.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:351fc7e675046f77b45446559b3722ac17ad709b83e4ae3aaa8cf4b819ed513c +size 2769 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_io.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_io.hpp new file mode 100644 index 0000000..f6b6c4b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_io.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ee9170b6bede5822cefe353210cffdecfb58c94c0056026ddfcfaa469cad385 +size 9233 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_legacy_io.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_legacy_io.hpp new file mode 100644 index 0000000..bafc3e8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_legacy_io.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32a60630628875121fefbf735484d3f8c312a7e4253b730d56f4f5cd3c84b29b +size 4640 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_system.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_system.hpp new file mode 100644 index 0000000..e816ecb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_system.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef0a43e1a0e93e2b709420ffd5048fe9cb24c36f42c36d0b7ddfee724ca1fc01 +size 1154 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_types.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_types.hpp new file mode 100644 index 0000000..06da376 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/posix_time_types.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e720aa5af0a1ced8a64579a3a5ff4cfb90838ae6413d543dca74f59ebb7c2fb4 +size 1798 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/ptime.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/ptime.hpp new file mode 100644 index 0000000..e4f1a3f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/ptime.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5ea6995328fd8c26d27f6ab013e09769cdf440e6cd599b3f5689a275889e18c +size 2143 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/time_formatters.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/time_formatters.hpp new file mode 100644 index 0000000..0ad94a7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/time_formatters.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d34478c620f0651ad11bd2b9900f401e2ffc8b18e42cb9e7278a034b054001d3 +size 9300 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/time_formatters_limited.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/time_formatters_limited.hpp new file mode 100644 index 0000000..3103894 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/time_formatters_limited.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61329e533e54183f15753ac72ca491ab553a4597f5c817705d397d0487ae2f31 +size 5988 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/time_parsers.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/time_parsers.hpp new file mode 100644 index 0000000..23f4b8d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/time_parsers.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01dd2569f9e36ddfd10c2dd350c5dff7c4516bda57c1da8044d7ec42aa9174bc +size 1384 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/time_period.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/time_period.hpp new file mode 100644 index 0000000..44750a7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/time_period.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5cf187c92b23661debf994b73e9ad0dc47c414284ad4ef6e4547051430c8b156 +size 690 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/time_serialize.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/time_serialize.hpp new file mode 100644 index 0000000..c4555f1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/posix_time/time_serialize.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e9f2f28910e0e312629f8ea924fe4431a3da6b5e3b3d00ae32661aba91bc677 +size 9067 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/special_defs.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/special_defs.hpp new file mode 100644 index 0000000..5b1e1dc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/special_defs.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e60e7b693dc42d405e5287ad2007c0451963c798ae2dd92f80fcb78d5d8f17c +size 633 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/special_values_formatter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/special_values_formatter.hpp new file mode 100644 index 0000000..a294a07 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/special_values_formatter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eab0cca5dee40bb0c3977e4688bcf9a66397219923f053a8c27dc8da43df803d +size 3637 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/special_values_parser.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/special_values_parser.hpp new file mode 100644 index 0000000..139e2a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/special_values_parser.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:feb4a8ba30926d446dd205e9925155d5d812b99ac51f651c6f259bae635d9ce2 +size 6296 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/string_convert.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/string_convert.hpp new file mode 100644 index 0000000..531b277 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/string_convert.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1b7a9cd7756d05168150b740b27dddfb152badfff4fd70fdb2c3b787fef7296 +size 1002 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/string_parse_tree.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/string_parse_tree.hpp new file mode 100644 index 0000000..0291921 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/string_parse_tree.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:294a84fbf3dd9bc5eefcb372d740e0adb24d173c7bde8467c70ebb19ba3d44ec +size 8397 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/strings_from_facet.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/strings_from_facet.hpp new file mode 100644 index 0000000..27c222c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/strings_from_facet.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d79aef90303f28a21831db5330636b6c2e606dd9ef0e6bd780dfb89730efd0a +size 4456 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time.hpp new file mode 100644 index 0000000..e0040f2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c32f5de81e684f650161a47505b374816fc2c4ce8e6a8218478996fe5fbd2423 +size 6261 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_clock.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_clock.hpp new file mode 100644 index 0000000..7639508 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_clock.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05d28d4731ef2087af7ea08cc7d71cc99934a0cd6ef37792d5ff09f850118caf +size 2245 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_defs.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_defs.hpp new file mode 100644 index 0000000..b15ef25 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_defs.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7b7ee0bd6c015d4f62b8a75891299ce9bc2b364474e98e8cb26ab982e3ed414 +size 942 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_duration.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_duration.hpp new file mode 100644 index 0000000..240e0dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_duration.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f96a30c485a756a5ed30b77e06e3fc568bd81c034f513431e38d98015d776578 +size 9619 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_facet.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_facet.hpp new file mode 100644 index 0000000..bc20278 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_facet.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:598804789646de8c3114e6c11b6b5e3dd6b99f7112fb80360729df1729b260f3 +size 58976 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_formatting_streams.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_formatting_streams.hpp new file mode 100644 index 0000000..8665d5e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_formatting_streams.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3b3020371d76c64e262d150b21ee3d94dd3d17f8285eeef8f4329a1e726cb8b6 +size 3752 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_iterator.hpp new file mode 100644 index 0000000..b4930d8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f1fd1676da75940dcb1e499b035d6b31ba3bb3cd149d17854eba7769b25761dc +size 1438 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_parsing.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_parsing.hpp new file mode 100644 index 0000000..3c17fde --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_parsing.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:412e34e03a58eaf5fe6b5f85a9e8f3cd06fd46f7102d5755104731a4171db456 +size 11854 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_resolution_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_resolution_traits.hpp new file mode 100644 index 0000000..1a522fb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_resolution_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18b4534e09a33ba616d52ccf378f01cf4d47d14356ffd15a334d5af08a676c43 +size 6364 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_system_counted.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_system_counted.hpp new file mode 100644 index 0000000..3ee433e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_system_counted.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:695cef3b0f1e2ac39e043cc5a9be3d05d5ed6606ad94e812a757639e926a5c0f +size 8441 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_system_split.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_system_split.hpp new file mode 100644 index 0000000..4daeadc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_system_split.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:553897efc9659072d0cb74e6a9146dcc56bad4581adf85f60c8b7d541fdb79d7 +size 7795 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_zone_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_zone_base.hpp new file mode 100644 index 0000000..0372fe4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_zone_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d43c4bd562b051592f1abdc3037d7a6b58a87abe9a5cc3e8038e4e8bdee5cdb +size 3710 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_zone_names.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_zone_names.hpp new file mode 100644 index 0000000..37a2ff5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/time_zone_names.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d756a1c7241212d3676b26105e4f34e0e289783ce386a0b47a173f39aa3cd4a +size 3101 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/tz_db_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/tz_db_base.hpp new file mode 100644 index 0000000..97df1a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/tz_db_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1cee6199b6b5c6fb3b7961f7766738e6446a7aba368a362007993d333ba891e3 +size 15950 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/wrapping_int.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/wrapping_int.hpp new file mode 100644 index 0000000..d859309 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/wrapping_int.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e0dd673bf4a70bda3f1c16ce830e393b39af0036703e49f555d0b415ab46346 +size 5508 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/year_month_day.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/year_month_day.hpp new file mode 100644 index 0000000..387032e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/date_time/year_month_day.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba3540087870f6c8dc9ab9cdd48b5a4d7254a992c3a3762fc5d0f1c478837461 +size 1333 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/algorithm.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/algorithm.hpp new file mode 100644 index 0000000..16f474d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/algorithm.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:976ed0f5ee1552f8d37eff0b650e271211b35081ccff9a7ab39156cb7fa3d01a +size 2960 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/allocator_utilities.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/allocator_utilities.hpp new file mode 100644 index 0000000..428752f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/allocator_utilities.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86d53dbbbeb9fdf88fa3b132b017ae3cd31836d623013fb4a1b879272819d83e +size 4792 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/atomic_count.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/atomic_count.hpp new file mode 100644 index 0000000..ca90f54 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/atomic_count.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21e4599d95ecdb73147ed2a580e950de649119b6342ae8137733845eb4df7aae +size 618 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/basic_pointerbuf.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/basic_pointerbuf.hpp new file mode 100644 index 0000000..3a39ed6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/basic_pointerbuf.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c7feca71b630a9c768f178507630fe7ea539788270963a2365ccac4c28fb37f +size 4425 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/binary_search.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/binary_search.hpp new file mode 100644 index 0000000..32963ae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/binary_search.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d955f53e843e5e5b332083d73f6bd8b8471be79d19454a2354e8e7e4a25676d9 +size 6358 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/bitmask.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/bitmask.hpp new file mode 100644 index 0000000..28f057c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/bitmask.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd17654c91580081408d358c0c83a2d4a6d34362b009cd620aecb1c603e05d6e +size 3033 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/call_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/call_traits.hpp new file mode 100644 index 0000000..c6dd2a8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/call_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60399c9aee599b10f6a1e93acd9ceaf061ff6abb7770f18f2e32b2d0d5889bd8 +size 4322 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/catch_exceptions.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/catch_exceptions.hpp new file mode 100644 index 0000000..72a982d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/catch_exceptions.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53d42570100e9b74caeb9d380786176310eaf6231e6e0deddb70056e840c4e82 +size 5644 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/compressed_pair.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/compressed_pair.hpp new file mode 100644 index 0000000..3c7ea7c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/compressed_pair.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d4ee16a2881189010ac17202551cb3e3dda582449aa7a9295e8a44f4cc77c300 +size 17002 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/container_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/container_fwd.hpp new file mode 100644 index 0000000..ea0371c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/container_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5865c63f8a83daad0747aed35dc5b036f200d2844c9cccd53d805b17a83f5ada +size 5160 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/endian.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/endian.hpp new file mode 100644 index 0000000..5dad19b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/endian.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86701f68f842417a8e887ef6868b09eaa68e9519ed2ecd0f3ccb558743cbe5da +size 364 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/fenv.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/fenv.hpp new file mode 100644 index 0000000..0349579 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/fenv.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:433a938c63e22681fe03b2220ba342289c36b89926d5836511595b27cbe4a2dd +size 3206 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/has_default_constructor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/has_default_constructor.hpp new file mode 100644 index 0000000..653ff3e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/has_default_constructor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:645f2a64387bfde7e31b97a09df13a6566752d3d28bb5beb7a82e2cda55fe7b1 +size 935 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/identifier.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/identifier.hpp new file mode 100644 index 0000000..960b93c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/identifier.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28318c5a65122b31542612eef2f11e0b6b6e68d26d3954c39aea41e6e85cfaab +size 3178 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/indirect_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/indirect_traits.hpp new file mode 100644 index 0000000..d98c4e5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/indirect_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10629648828b55d799bb03bca2bcfa203b76993dde571c43bbf77739f96299f2 +size 4423 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/interlocked.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/interlocked.hpp new file mode 100644 index 0000000..6d42050 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/interlocked.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afa500324f550dabf1beb9ba6a83269778d0e50fcb076e3130bded65ee999ec1 +size 8907 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/is_incrementable.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/is_incrementable.hpp new file mode 100644 index 0000000..6f1a109 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/is_incrementable.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44ad465d065f7b81faae5a13d133d1739fdec6ef3fffebfe29cee15fda7ad51c +size 3071 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/is_sorted.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/is_sorted.hpp new file mode 100644 index 0000000..7e44754 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/is_sorted.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02cdbe1a5149f8c45bdf989f7e0273dcc858e53b001961eb4cdafe3fba282618 +size 1464 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/is_xxx.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/is_xxx.hpp new file mode 100644 index 0000000..cba5103 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/is_xxx.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b234852437ea2dae5472f1985d58485faeade9b310052024ac430b954f40755 +size 1250 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/iterator.hpp new file mode 100644 index 0000000..20881b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b9993e0c49c30c8bfe4d09b1ad3a045943013d2f2e688fdf21e9fe6b4027543 +size 1068 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lcast_precision.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lcast_precision.hpp new file mode 100644 index 0000000..8d9214f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lcast_precision.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b8407e48a437166db6b905fa78d1317af9c5589012f7cc0df9c26384b64e38fa +size 6089 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lightweight_main.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lightweight_main.hpp new file mode 100644 index 0000000..9ee5320 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lightweight_main.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a7c84f48874707850915234489fcb4fd947ad679c02dfa891b1c6073f025c25 +size 1226 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lightweight_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lightweight_mutex.hpp new file mode 100644 index 0000000..f80005c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lightweight_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0889c1d4383014f4c1d4b399b10aa48d9947fc50608dacba28f751c56667cc67 +size 630 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lightweight_test.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lightweight_test.hpp new file mode 100644 index 0000000..0e3beeb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lightweight_test.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e20f75a9ec1966e0282e51641d064d0351b0da81d4328e08e238cb5126f3a823 +size 436 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lightweight_test_report.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lightweight_test_report.hpp new file mode 100644 index 0000000..eaa500c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lightweight_test_report.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5cacffcc87fd88da49b8cd0ee2815ffca5ff238137cfd893e7c0da3451e86640 +size 2223 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lightweight_thread.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lightweight_thread.hpp new file mode 100644 index 0000000..892a3b1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/lightweight_thread.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3bd2a9165de74bc01431fcc584dc5595e03ac2d1c941d0a9e37d7f35ba3e756e +size 3412 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/named_template_params.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/named_template_params.hpp new file mode 100644 index 0000000..c3adfe8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/named_template_params.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42a3f77ad31176a3e9433169d5a30d40c9f02eab2911cdf522434834cc6f18f7 +size 6090 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/no_exceptions_support.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/no_exceptions_support.hpp new file mode 100644 index 0000000..f50a232 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/no_exceptions_support.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:923b11128f5132839e7a320c9a56c9a5985885ec2682dd51a26c00ded2396f2c +size 456 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/numeric_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/numeric_traits.hpp new file mode 100644 index 0000000..a4a61f9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/numeric_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b43af6d1f7e9f237f4a21bd07a045861a2be0679319492745b888f8490685a5d +size 5473 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/ob_compressed_pair.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/ob_compressed_pair.hpp new file mode 100644 index 0000000..dca5e30 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/ob_compressed_pair.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:baaab0b90d8aa661ac54811a284c18392e1b57dd84653d9a77266140692c0df2 +size 16399 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/quick_allocator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/quick_allocator.hpp new file mode 100644 index 0000000..c88605e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/quick_allocator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55e168afa917d086929d2a9b975fa28f6da034b7d89db7bb3bfa8ad83286e7ac +size 606 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/reference_content.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/reference_content.hpp new file mode 100644 index 0000000..695178d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/reference_content.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:729862548f026865e374c9df1eaeb7524c992d68baf5d45af7bf1f6b54b4ec1c +size 2443 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/scoped_enum_emulation.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/scoped_enum_emulation.hpp new file mode 100644 index 0000000..3a5d29e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/scoped_enum_emulation.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:738641b0d11878f83645d85b5a72b3357de5b9040c664138cedafb116ebf9fcc +size 437 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/select_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/select_type.hpp new file mode 100644 index 0000000..a5b4dfe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/select_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:983d9862b3b45e5a213140521c24a33c928fc4cbc297013fb7130b78b7a0aa32 +size 1130 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/sp_typeinfo.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/sp_typeinfo.hpp new file mode 100644 index 0000000..2ead394 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/sp_typeinfo.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c2ed76e073cd899a2375dbd270994e2ad07ed32da690e12198cf4e327e623cb6 +size 755 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/templated_streams.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/templated_streams.hpp new file mode 100644 index 0000000..d4b2817 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/templated_streams.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:515459aa9b62b0cd8fee8fa901df26cb423166328b0217a1166c6476ee7da575 +size 2242 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/utf8_codecvt_facet.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/utf8_codecvt_facet.hpp new file mode 100644 index 0000000..9b1e88e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/utf8_codecvt_facet.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da81df69b429bd1d31f7c7cd449570555a11b7cec011f66876e03201abe59866 +size 7726 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/utf8_codecvt_facet.ipp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/utf8_codecvt_facet.ipp new file mode 100644 index 0000000..6dcb5f5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/utf8_codecvt_facet.ipp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b2fc6b7ba19a83a6de665fb4475869ec3372d044ce8a1cee0cdb906646353af +size 9560 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/access_rights.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/access_rights.hpp new file mode 100644 index 0000000..7c22534 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/access_rights.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbc4465aa9da6fde41aa58231d317fc5258bb6a5ab94ccad73b396794b697b66 +size 525 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/apc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/apc.hpp new file mode 100644 index 0000000..6248cb5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/apc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f2124b4787cf692e3fc121066a1da2dede0203a5b29813627f2859e59373853 +size 475 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/basic_types.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/basic_types.hpp new file mode 100644 index 0000000..b018826 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/basic_types.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7ebe425dbdfe971df31f0e01f800cd2fc4dbc16f3ce6ca128da527172b80ce8 +size 515 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/bcrypt.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/bcrypt.hpp new file mode 100644 index 0000000..702f77e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/bcrypt.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a74668a720375819c2b97a3f8287946e11d08d8fe6269ea7e249f14754619f61 +size 493 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/character_code_conversion.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/character_code_conversion.hpp new file mode 100644 index 0000000..839cba7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/character_code_conversion.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc53578e9cecfb3ba65ccec4f68d187f996ec5c1295bec319ed4791543b4455a +size 585 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/condition_variable.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/condition_variable.hpp new file mode 100644 index 0000000..8c514a8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/condition_variable.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:24bf06cf7fe55796cfa022d4af61411eb73d5a7d3298e5d264fc081253210a25 +size 654 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/config.hpp new file mode 100644 index 0000000..5a8efa1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:315556578f72bd289cb9b5f06c586c663870d0096a2190249d0cd1faaf873ec7 +size 457 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/critical_section.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/critical_section.hpp new file mode 100644 index 0000000..75aac4f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/critical_section.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8d3c8eb8527cbb3ed6d23ae046d799b84932159794eb7b8a07e8dee421da1fe +size 540 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/crypt.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/crypt.hpp new file mode 100644 index 0000000..6dbf287 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/crypt.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f3a5a70a91bde2ec5eafecebbb1c26367f90646f9187d977de4e75a5c2f1696 +size 485 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/dbghelp.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/dbghelp.hpp new file mode 100644 index 0000000..d40ebee --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/dbghelp.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d88a4fb3e5fb5de41b347fd1782b53211490fa911a71865ab76a65f68ee5293d +size 495 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/debugapi.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/debugapi.hpp new file mode 100644 index 0000000..aef48f9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/debugapi.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed667194b5257c31fb5699c5865b11ea7a33e24745c7a9d4fa248f7d504a72e6 +size 500 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/detail/deprecated_namespace.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/detail/deprecated_namespace.hpp new file mode 100644 index 0000000..366c8d5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/detail/deprecated_namespace.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40410f67af3513578474fa04ada5c30ea62b384ff06b3b9a53cf6dd7a9be6f36 +size 714 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/directory_management.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/directory_management.hpp new file mode 100644 index 0000000..a058dbb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/directory_management.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f676b76a78108f3e09c044fc46a3e6ee19f8bd6a0601eb14c921955051a87e3 +size 560 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/dll.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/dll.hpp new file mode 100644 index 0000000..4271f01 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/dll.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb3a0729ca76dad40f984f49f12e0cb312b785950d0c19c8c7cad90ba5f6198d +size 475 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/environment.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/environment.hpp new file mode 100644 index 0000000..c60f420 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/environment.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c41b70241b1c26ffc48e37c33f1e144b95529a16e87093b6a4df185fec3af639 +size 518 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/error_codes.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/error_codes.hpp new file mode 100644 index 0000000..e285150 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/error_codes.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5cc6a1db79b1e94693c5a64c0675a6cd88980a340a1ee449085f4c5690726fb +size 518 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/error_handling.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/error_handling.hpp new file mode 100644 index 0000000..1fa043c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/error_handling.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7533316843f8f3222d809e84ac2fc40959dcf16508e308cfa4e0f7a985d0cb5 +size 530 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/event.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/event.hpp new file mode 100644 index 0000000..11d081a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/event.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41b84e5e6061b0cca925e13d35f127657a23173a3bcfa277051689692e003359 +size 488 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/file_management.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/file_management.hpp new file mode 100644 index 0000000..9a54fed --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/file_management.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:690403490a9b17310c70e03a01804ed99bd5191bebaca4d0fd76b051ab954b6b +size 535 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/file_mapping.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/file_mapping.hpp new file mode 100644 index 0000000..cbb670e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/file_mapping.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:118250fb16e8e915238db1bf0d69e3b0447987ab93920b5fdda26e064af501a8 +size 520 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_current_process.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_current_process.hpp new file mode 100644 index 0000000..60d51e1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_current_process.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f8ee35f983cffbdcb00f6b6b3eba7c6e9498f679bb6584ba945f7884b22b0a4 +size 555 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_current_process_id.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_current_process_id.hpp new file mode 100644 index 0000000..fe4f0e6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_current_process_id.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aef3b74ca147a518db6574d2b841f02c7a4766c084be587f9f3fe5752983e542 +size 570 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_current_thread.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_current_thread.hpp new file mode 100644 index 0000000..40bb129 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_current_thread.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1371550116848274c95d826a95bccd7e29330ff8cdd88d71975ee11c25db64f0 +size 550 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_current_thread_id.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_current_thread_id.hpp new file mode 100644 index 0000000..2ed3187 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_current_thread_id.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2e933198420e32b4447b9410c4a9a3f3745957848e833abbb9286e4bc8d012b +size 565 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_last_error.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_last_error.hpp new file mode 100644 index 0000000..c29a920 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_last_error.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03981df2b80a2dab93d31fe206536ca124140916a89e9f04f985571bf36f6d4e +size 530 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_process_times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_process_times.hpp new file mode 100644 index 0000000..3e9268d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_process_times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c3c79b723ef4acd812760158dd075a6a916c92948b63d967e229566506c2a468 +size 545 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_system_directory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_system_directory.hpp new file mode 100644 index 0000000..1f652e1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_system_directory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:998fc56deb9a4abd6924f55ab5399b05bd23fa6421b06f595e919922b7c0dbd0 +size 563 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_thread_times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_thread_times.hpp new file mode 100644 index 0000000..75a1fcc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/get_thread_times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96e5a7d6be15e188f089ae2583e41c80ff0e397a56670b35884ff47d80c3f88f +size 540 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/handle_info.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/handle_info.hpp new file mode 100644 index 0000000..25bd997 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/handle_info.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3a8414e4152c87838c2ed151206d9535038268e184799b745cae6abb6626e693 +size 497 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/handles.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/handles.hpp new file mode 100644 index 0000000..f0f5f39 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/handles.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fba63abac1f9cadc62bdc013d0d765ebf19414e51196e3fbfef3ae5a37887a18 +size 495 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/heap_memory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/heap_memory.hpp new file mode 100644 index 0000000..5493b5c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/heap_memory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab0059ad4d9c121fc520a5b0bd07d3ca9b96d5d790f862e506c05c4b6dcb4d8d +size 518 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/init_once.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/init_once.hpp new file mode 100644 index 0000000..5e205dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/init_once.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:102d3aa7c752d66654353f5ad7185a5ef60e6b88f4a4f3c03a70f01991df94eb +size 591 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/jobs.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/jobs.hpp new file mode 100644 index 0000000..49a357f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/jobs.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af3b9837acfe70f21d40c8ea01382f96478aa53c7c195dcd5f6e4b588696c4da +size 483 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/limits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/limits.hpp new file mode 100644 index 0000000..ae21832 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/limits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:255ec01d72f6003225b3d9cd4ceb5422a97ad9a7a4e820d3b2b3bafb3c297917 +size 493 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/local_memory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/local_memory.hpp new file mode 100644 index 0000000..ff37363 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/local_memory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1de63cb324e539f1e6ba27b04f2c1a27317f7084e5d081df472f865a8e6cb3b3 +size 520 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/memory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/memory.hpp new file mode 100644 index 0000000..a820596 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/memory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14064e4b9161f43d34afe30a7c8073fba572d36bdd5a97d98fbcd88afb16e48e +size 490 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/mutex.hpp new file mode 100644 index 0000000..bc63076 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81e7d5f5da2ddef51df2413b1804695b02277896d158305442d61ca6c376e35f +size 488 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/overlapped.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/overlapped.hpp new file mode 100644 index 0000000..77978c4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/overlapped.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b6800c170ae14063520c964c0d0c00ac89ce58f783c9ee739d19612ba7ac096 +size 513 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/page_protection_flags.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/page_protection_flags.hpp new file mode 100644 index 0000000..4e7cf15 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/page_protection_flags.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb371b4baf59697e5af8d9ab509dbe8a0f683bdb227e4f0e8974b3b2528931d7 +size 565 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/pipes.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/pipes.hpp new file mode 100644 index 0000000..43e5ae0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/pipes.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e0fd8bc7e675e40d844d250d16e759c432ca48009a0e1d49218467dee80e79e +size 488 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/priority_class.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/priority_class.hpp new file mode 100644 index 0000000..98fb193 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/priority_class.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f8d44fb8e536e41278fbda3fd5fc45dee1e61a26a0d6d50e851e0d03afbbcc1e +size 533 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/process.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/process.hpp new file mode 100644 index 0000000..c7e9058 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/process.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a4750ef10d3f1f268e1732e87e460b35e795f274c2b90f4aeb9babdd518c885 +size 498 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/security.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/security.hpp new file mode 100644 index 0000000..6d6b9ca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/security.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7fe97cd2e55285cd618035c82c99c774c3de7d22b845734642c0d674a724a84 +size 500 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/semaphore.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/semaphore.hpp new file mode 100644 index 0000000..b1d24ec --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/semaphore.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db7aa39b4343a0f66b935a59ad977278962379e74c0cac8f92906a9a10000862 +size 508 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/shell.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/shell.hpp new file mode 100644 index 0000000..03e355f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/shell.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7437f13c9f434b4cf3f3487d6cb7777379ae6ce28727786d7ef23c56bf07155a +size 488 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/show_window.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/show_window.hpp new file mode 100644 index 0000000..bb59682 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/show_window.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbdafeaa0ab9c1108db542a9eeac68233344e79ef2d985cc21907ae5728e302b +size 518 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/srw_lock.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/srw_lock.hpp new file mode 100644 index 0000000..30ef3cf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/srw_lock.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5ba6ef9b75093a556ecdb6bb8b7972e5d19f1d77e634c7d4a5cc048447af297 +size 582 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/stack_backtrace.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/stack_backtrace.hpp new file mode 100644 index 0000000..99f6083 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/stack_backtrace.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:660275d50150aae8684024235a2fa0d9d55cd36cab467afb8964418e36eef29f +size 565 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/synchronization.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/synchronization.hpp new file mode 100644 index 0000000..9426f23 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/synchronization.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b6644a696afac9741400c6f29feec97d777a2b1d4a9946d38cd7351772bb066 +size 535 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/system.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/system.hpp new file mode 100644 index 0000000..927f3db --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/system.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15733ccd41fa17c9a487195c1102f8d5bdf897ae174663dacbe8d5606e219981 +size 490 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/thread.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/thread.hpp new file mode 100644 index 0000000..6e799d4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/thread.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ef7f2dc8ece4aa9c4c61d261eaaecd0eb8b6f0c4c588736f9de14622a18e890 +size 490 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/thread_pool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/thread_pool.hpp new file mode 100644 index 0000000..712540e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/thread_pool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f950c6742892cb382f3b90498cfb319dee4b6c42c6735b7d42d3108371d7c58 +size 515 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/time.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/time.hpp new file mode 100644 index 0000000..a8ace51 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/time.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac3a8900e861ab0a429164dff6eba97e6942d2adff24a66f77b36fc495ca628b +size 483 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/timers.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/timers.hpp new file mode 100644 index 0000000..6155b6a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/timers.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5af99266715c4290a294141862d092a5dfa9b3a31f32883d3404c924d9cabbc5 +size 490 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/tls.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/tls.hpp new file mode 100644 index 0000000..bffac3b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/tls.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4069c9c7135bdc45fb538ca8ff07b28e671beac1318ffefdde4cb1d1259e3ab7 +size 475 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/wait.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/wait.hpp new file mode 100644 index 0000000..e560d58 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/wait.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a56716b284b0913ef90a815d15e2bc5a381d13b5286ff3802aca66b8b8bcb936 +size 480 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/waitable_timer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/waitable_timer.hpp new file mode 100644 index 0000000..4747808 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/winapi/waitable_timer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c54cde3e76277ec342ae754d04db876cf416308da5ef4a6e763e948b82d4b7ac +size 530 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/workaround.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/workaround.hpp new file mode 100644 index 0000000..cfb8216 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/detail/workaround.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05218eed322b097f20bd71ffb52aa57721acafa13cb89b641634ab75d251b73c +size 335 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/all.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/all.hpp new file mode 100644 index 0000000..2aee82c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/all.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d10e54d586b0769c93f29b2516259424d6754d3acc7d4c476e5573d22ff1dd1b +size 1088 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/current_exception_cast.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/current_exception_cast.hpp new file mode 100644 index 0000000..6526e1e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/current_exception_cast.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ce6f0adf3c6f89b0f1b9acdb86082b844332c16dc0a46be0309f8e482ee640d +size 969 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/clone_current_exception.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/clone_current_exception.hpp new file mode 100644 index 0000000..38957de --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/clone_current_exception.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fef7179fdde82942d5e2808a6c94fbc6dab9e619b66e92ee36faec3a23f79a8f +size 1523 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/error_info_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/error_info_impl.hpp new file mode 100644 index 0000000..6ca4828 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/error_info_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afd2bf0004079ae850aae6456f7ab6d1fc5b7ba540ffdba534b262b047571edb +size 2603 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/exception_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/exception_ptr.hpp new file mode 100644 index 0000000..b22a29e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/exception_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:72044a74be3a6fac55fa564fa370530af48d3b017586d9164292957e2aa277ee +size 15044 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/is_output_streamable.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/is_output_streamable.hpp new file mode 100644 index 0000000..0807999 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/is_output_streamable.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03e17bb5289229a2f0095292158042eea201bb1e5d722c06f276748346105dd7 +size 1683 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/object_hex_dump.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/object_hex_dump.hpp new file mode 100644 index 0000000..d74f040 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/object_hex_dump.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d20278771122db81717d036dd9dc397ba368cad4604161edb4b83e9a6b97bb62 +size 1544 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/shared_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/shared_ptr.hpp new file mode 100644 index 0000000..b4fd6f4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/shared_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f95697b38d3e5e3d9735c4e89fefb1797d4fdb98c6a98ea8101762229181cb31 +size 570 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/type_info.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/type_info.hpp new file mode 100644 index 0000000..063eb82 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/detail/type_info.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61c40731ffc078fa63b37197c7879707b8077d4e37635d81dc6c4edfcb2d24ba +size 1963 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/diagnostic_information.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/diagnostic_information.hpp new file mode 100644 index 0000000..09f04ab --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/diagnostic_information.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1765dd76c9b767c678eafe07a54cac621d4f22658e02c4d79fb67ecb0bc2437c +size 6225 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/enable_current_exception.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/enable_current_exception.hpp new file mode 100644 index 0000000..d032fc8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/enable_current_exception.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c86cd2285b011fcffefbad55a10ea61cf042b8c09d6278ac227b7ba7048be8ab +size 363 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/enable_error_info.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/enable_error_info.hpp new file mode 100644 index 0000000..e732ff9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/enable_error_info.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15dc4b579c758c6ac086b0ddfea71219f0a4582719ba1bf6628dbf43c225162b +size 363 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_api_function.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_api_function.hpp new file mode 100644 index 0000000..ba79bc6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_api_function.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5bd6f4226a07aedb8da2f6304d1b91693edfec6fbe83d14324aeee4300f6b195 +size 647 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_at_line.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_at_line.hpp new file mode 100644 index 0000000..00b2575 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_at_line.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c80d47d6cd9d7881812e64fa4e8ef678635a456e192a1a377447a9d0aed66416 +size 547 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_errno.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_errno.hpp new file mode 100644 index 0000000..e588a43 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_errno.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b42cd61ed5ef1d23ad7c3c09e2dc2a24d881437b8402ad2a97908152d157e7cc +size 1296 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_file_handle.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_file_handle.hpp new file mode 100644 index 0000000..6b14b59 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_file_handle.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e05ddb3496f484221d00ff32b5582891decb1931c1c3513dd523a0dc3c825fcf +size 548 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_file_name.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_file_name.hpp new file mode 100644 index 0000000..8156c53 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_file_name.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e8f8c04371a21e6be85cff42d4344cbf34c3c761ea37d1c7fc31f3075a018872 +size 723 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_file_open_mode.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_file_open_mode.hpp new file mode 100644 index 0000000..068208c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_file_open_mode.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c10c18c311e1eb32882b593d7f0e903fd9c23a614821f800a4757b7775739c3 +size 733 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_nested_exception.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_nested_exception.hpp new file mode 100644 index 0000000..d9e91e2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_nested_exception.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d84e25ef4c14d8c5386138fa2785c4e66dc48b3e49fabdbe9806175ec1eebe91 +size 576 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_type_info_name.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_type_info_name.hpp new file mode 100644 index 0000000..c6f4c18 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/errinfo_type_info_name.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5bb4ba4865b59ba22fea9670cf73a6ec50000ad8490d1f049cdebb6ac12ca16 +size 637 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/error_info.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/error_info.hpp new file mode 100644 index 0000000..a4d7006 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/error_info.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a40e1a1818b60fe4f978933cfc99f8865174ec6d579205e314458c8464502e6 +size 387 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/exception.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/exception.hpp new file mode 100644 index 0000000..0f38a25 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/exception.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3dc079bac46d9f89de9d8423e6c8f38b9ecf30f6552fa7e6bdfda2ea86113f89 +size 13395 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/get_error_info.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/get_error_info.hpp new file mode 100644 index 0000000..f4184df --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/get_error_info.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79c5c95affcf79050fa5fa8e4d175d1c960627c1c7d5b9f856c79b4a38cd3230 +size 3701 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/info.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/info.hpp new file mode 100644 index 0000000..8c1338a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/info.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b41e3a43d69a06cfae4f8d587543bdb06f059b14d475bd8614699fb26d6a499 +size 8663 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/info_tuple.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/info_tuple.hpp new file mode 100644 index 0000000..586fc0c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/info_tuple.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1818414aa51d87f02a494ea82ae6f05ce9d5d4e28abe65905dc679617cbb1acb +size 2390 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/to_string.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/to_string.hpp new file mode 100644 index 0000000..87c0388 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/to_string.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:69584c5a901d6330a1376ead93f2c0f9785fe7bec22ebb64085a812965a3af01 +size 2268 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/to_string_stub.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/to_string_stub.hpp new file mode 100644 index 0000000..9c21d41 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/exception/to_string_stub.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34e1d3a10535a1db9eae2ab0eb57d449331a44a171ef16d068fee23e8f877fdd +size 3032 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional.hpp new file mode 100644 index 0000000..01c48c0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ea4dd42b936261a749117e245aed5e6ec7612e294dc1dc9fea61f991ecc3251 +size 20124 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/factory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/factory.hpp new file mode 100644 index 0000000..2e36ede --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/factory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bccebf2544b48566f0cc0c54fa4f5d854c7d74a43787ad17d82e8d1ead9a54ac +size 7206 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/forward_adapter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/forward_adapter.hpp new file mode 100644 index 0000000..cc0129b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/forward_adapter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e164429f2797c4ef7d3d7187bc3c52f6a7be17e9da9e60141705d08d9baaa2f6 +size 16401 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/hash.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/hash.hpp new file mode 100644 index 0000000..4dee620 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/hash.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c1e756b0c98774fb26f75e8880ff4bbcfc53e18d8a39e686b32c7af45baa2d1 +size 233 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/hash/extensions.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/hash/extensions.hpp new file mode 100644 index 0000000..4a5c587 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/hash/extensions.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:efc474537dd76c2c774623fffe518e17f599c44ab6b20fb68dbc39ed0cd1f359 +size 234 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/hash/hash.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/hash/hash.hpp new file mode 100644 index 0000000..4dee620 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/hash/hash.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c1e756b0c98774fb26f75e8880ff4bbcfc53e18d8a39e686b32c7af45baa2d1 +size 233 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/hash/hash_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/hash/hash_fwd.hpp new file mode 100644 index 0000000..d25693b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/hash/hash_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0177e56687b53ed7aaee092cd10244379e8078dbcb6d2ed1d85487da783f36a +size 237 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/hash_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/hash_fwd.hpp new file mode 100644 index 0000000..d25693b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/hash_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0177e56687b53ed7aaee092cd10244379e8078dbcb6d2ed1d85487da783f36a +size 237 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/lightweight_forward_adapter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/lightweight_forward_adapter.hpp new file mode 100644 index 0000000..8f93d2c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/lightweight_forward_adapter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb63c82a1215b02c4a3169de71f5e3d6026a22fb001bdac00745c210ea915384 +size 11464 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/overloaded_function.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/overloaded_function.hpp new file mode 100644 index 0000000..eeb8e96 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/overloaded_function.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5819bb758e91d8b2b6ea4a504b32b6f9382909cd322d7766301db7f845c07509 +size 11550 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/overloaded_function/config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/overloaded_function/config.hpp new file mode 100644 index 0000000..1fad36e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/overloaded_function/config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd7d900490adafab512bd9adf520574ef07667d10336fe08e833095b02d76827 +size 1767 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/overloaded_function/detail/base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/overloaded_function/detail/base.hpp new file mode 100644 index 0000000..359e051 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/overloaded_function/detail/base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11aa009f112f773ba237e2649e14dffe16b86e4ab63532ea1be56d4b6ee1c207 +size 3020 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/overloaded_function/detail/function_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/overloaded_function/detail/function_type.hpp new file mode 100644 index 0000000..f2ae9f9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/overloaded_function/detail/function_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3c903bd0a3327b9e26a2de29a85cde6e2b81fec992d226978beb18923866de9 +size 3278 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/value_factory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/value_factory.hpp new file mode 100644 index 0000000..f3623de --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/functional/value_factory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bce63b611ed23a08deb7838440390e09329509aabfec28bd00e408ef96c698a8 +size 2138 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/get_pointer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/get_pointer.hpp new file mode 100644 index 0000000..2a51746 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/get_pointer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56f8d28eef5c78280970bafc3b7b2878fd63e73161e26afb86b3a5e1ec4e1279 +size 2288 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer.hpp new file mode 100644 index 0000000..ee10737 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8dae90c95bdbf6f1fe82fb396767ccffcd8a4e83c614d5e8453ae3b6cb9701f2 +size 11589 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/common_factor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/common_factor.hpp new file mode 100644 index 0000000..5650179 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/common_factor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2521f84197c24d4a460fe6214957df4fd1c11a4a53972607905a73e727cc5cb8 +size 583 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/common_factor_ct.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/common_factor_ct.hpp new file mode 100644 index 0000000..4f2f7c4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/common_factor_ct.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b85a7dda1a533f650df7f1b175291d1851e37f250bc062833eab94fe810bb8a +size 3368 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/common_factor_rt.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/common_factor_rt.hpp new file mode 100644 index 0000000..c5cc668 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/common_factor_rt.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28179a82632d6ccbe5e91c2d6c803b852178b9370e8aa52ca432a73ced0f5bef +size 22779 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/integer_log2.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/integer_log2.hpp new file mode 100644 index 0000000..8a51b98 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/integer_log2.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04fa99f596f9bbdd90273dffd8a7ba5202d7c8ccd5a20d14a1756535a64bda5e +size 2245 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/integer_mask.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/integer_mask.hpp new file mode 100644 index 0000000..ec287ed --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/integer_mask.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c96e1b3efbb580afe2dde46d30a29d1871fa223dd1fba8a2371de4ab6463c5c7 +size 4234 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/static_log2.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/static_log2.hpp new file mode 100644 index 0000000..540b967 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/static_log2.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af8357eeba97d9abce9ad9b7b8e5248b8cf933553ca4e181f704da50cbc81fa1 +size 3540 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/static_min_max.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/static_min_max.hpp new file mode 100644 index 0000000..49c6e38 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer/static_min_max.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af6c4c495b600acf67f8f3ae41b95c32353ac103c2f48ecd359577b2024713df +size 1605 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer_fwd.hpp new file mode 100644 index 0000000..aaa59b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/integer_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:23575339d843ad61aa7255dd53313da4ddbc3bc41037e58db5a595c1c6697640 +size 5181 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/adaptive_pool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/adaptive_pool.hpp new file mode 100644 index 0000000..cc679d2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/adaptive_pool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:616220460f1e914da88269829daddf6b37656d8c2949a08f7c42ff6bb2295ca3 +size 17970 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/allocator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/allocator.hpp new file mode 100644 index 0000000..8a71a68 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/allocator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6077069c3e6a268fce7247dc53a634e6a7a1c151bc3afec3ee53524e8ea529c +size 11433 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/cached_adaptive_pool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/cached_adaptive_pool.hpp new file mode 100644 index 0000000..9abacdf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/cached_adaptive_pool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e812f2862c584ed6ff405f0c7cb5e3f428f278c17981d35542fcdd026a0cb612 +size 13283 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/cached_node_allocator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/cached_node_allocator.hpp new file mode 100644 index 0000000..dedd916 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/cached_node_allocator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f46285e55eab91cce4b7f77a6363fd83bf11dd0a63d3aa2b14f728a221fbf10e +size 11528 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/detail/adaptive_node_pool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/detail/adaptive_node_pool.hpp new file mode 100644 index 0000000..b0b8624 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/detail/adaptive_node_pool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ee7a663ade4d613ad9e555f320cc2eab0ed998d505b6511b1818228561a0ce2 +size 4187 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/detail/allocator_common.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/detail/allocator_common.hpp new file mode 100644 index 0000000..3545fb4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/detail/allocator_common.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a7bf4fb493a87adac31a0e74826c7b1a5f1657953b665626529dd1300d7529b +size 31594 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/detail/node_pool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/detail/node_pool.hpp new file mode 100644 index 0000000..cf117c2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/detail/node_pool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d251903f7c2aadeab4606b84b8f37ce101cae7009a1aca636bfb51d7911e540b +size 3880 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/detail/node_tools.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/detail/node_tools.hpp new file mode 100644 index 0000000..87d69ba --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/detail/node_tools.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b37fa25764ce5c3cc49296170cb7f2dcc7468ef98baacce1e90dc52c10da1e8 +size 1535 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/node_allocator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/node_allocator.hpp new file mode 100644 index 0000000..ae5d9a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/node_allocator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8572772ed26c2e7a4c0db3c81f8a37c96d0f5c74b0643440fd714e477eef5fa2 +size 16625 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/private_adaptive_pool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/private_adaptive_pool.hpp new file mode 100644 index 0000000..e34c9c1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/private_adaptive_pool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d4bd4ba7a7100d041ee329e61bd58fe68e580f8cde56fdad60c09e93285cbb5f +size 17706 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/private_node_allocator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/private_node_allocator.hpp new file mode 100644 index 0000000..bc2d7ac --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/allocators/private_node_allocator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:852b72bdc07b726e038a959f1d9a6aaeb432144eb036fe8ae70d72790380d335 +size 16253 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/anonymous_shared_memory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/anonymous_shared_memory.hpp new file mode 100644 index 0000000..91227fa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/anonymous_shared_memory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8ab4659071f765758e630781cd18adc280e7d885480cc723716660cb20fa47b +size 3532 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/allocation_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/allocation_type.hpp new file mode 100644 index 0000000..b111d14 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/allocation_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2cc2422647ed4062bea6a3811c5912a70b434d0a846d29b7182c1f033659eec6 +size 1716 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/containers_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/containers_fwd.hpp new file mode 100644 index 0000000..44a999c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/containers_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f96b7b09b1f1bd394a760a909cd0336112de9d66cd3b64af2286f722934ae90a +size 1387 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/deque.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/deque.hpp new file mode 100644 index 0000000..88897aa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/deque.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f429179d2d081bd7e45339bb3ab75c7ae03d256cd517308eabdd71b8ba69d4e2 +size 1044 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/flat_map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/flat_map.hpp new file mode 100644 index 0000000..9a65b38 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/flat_map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6478507387557195a010a6cf18b11b5a7de1143a3ea32e300086f04e0e71e940 +size 1097 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/flat_set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/flat_set.hpp new file mode 100644 index 0000000..996c0e0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/flat_set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b8c5db5a5a13ea016b18faec7338c982a157ae8824fe0cb959ae42f7411eed23 +size 1097 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/list.hpp new file mode 100644 index 0000000..594e16c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1627ea6a8b7e8d9c0ec66ec8f60cd1f49e05b44811eb8fd5ef31d23963ad9071 +size 1039 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/map.hpp new file mode 100644 index 0000000..8917500 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5426f0c0c9e7fc53bb2e3f7131847f2126ff96edfba597e29b8b37d31000f5ce +size 1067 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/pair.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/pair.hpp new file mode 100644 index 0000000..7b3ae63 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/pair.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2590ba221f3e980150cb607a75b25159a0930af5aadecd72f3051b4b8d3c5c73 +size 1051 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/set.hpp new file mode 100644 index 0000000..dd3d652 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd0b84d6c9df4d06da26bc0f9fd8a22431914666893b662ea59cf3b0387409a6 +size 1067 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/slist.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/slist.hpp new file mode 100644 index 0000000..8657bc9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/slist.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c6ac4acc98e1ba2d651baa103806e01c4f08c54ad48039e0a571c298d3a971e6 +size 1043 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/stable_vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/stable_vector.hpp new file mode 100644 index 0000000..be9dd55 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/stable_vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9f0002e93855662dbc5de38f84f42e3f1e71149789f2c7dfad7d3818e55d6e2f +size 1095 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/string.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/string.hpp new file mode 100644 index 0000000..067d0f5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/string.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81c7da01416662dce170d38e750cb2acf5b9a8b820f2056409a95c818a48aa22 +size 1086 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/vector.hpp new file mode 100644 index 0000000..aa3754e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0632c99d79b206ceac1fe3a793072691f01facc2ada799e81cec61d82d3b1bd5 +size 1049 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/version_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/version_type.hpp new file mode 100644 index 0000000..de585cf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/containers/version_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d12f53fdbf3df957db5809e0119edb892fdcc3effb423a767f7e1b5abcac2141 +size 1069 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/creation_tags.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/creation_tags.hpp new file mode 100644 index 0000000..f82f394 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/creation_tags.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:028e4d9b3b79ddc28d90f708ed8dafe11c4d12e5a5c3aa073f3b2f3e6594ebb7 +size 2399 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/atomic.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/atomic.hpp new file mode 100644 index 0000000..594f489 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/atomic.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dcac8403881d13a796f93b05d4ae24450c48bf4fdb8249650d58da7677e4ecab +size 22036 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/cast_tags.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/cast_tags.hpp new file mode 100644 index 0000000..8b9deea --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/cast_tags.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b2b4221b19b64cb102a6716626b29a98c473834c6137643bf01eebbfbae8c9e9 +size 959 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/config_begin.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/config_begin.hpp new file mode 100644 index 0000000..7b970b3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/config_begin.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5dd41320ffea8d1e018b7c35fc59bd5e86ffd6ac3285296f2d50210382c72cda +size 3210 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/config_end.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/config_end.hpp new file mode 100644 index 0000000..377fe02 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/config_end.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be2c18196ba9b71075cb6e193ab327216191916cc8e4c45c484577d488caff5c +size 564 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/config_external_begin.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/config_external_begin.hpp new file mode 100644 index 0000000..8ed8073 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/config_external_begin.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:548d9e827042cb33ce0e9e6226e67395882f6001cfdaf72948d75e295ff081a6 +size 714 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/config_external_end.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/config_external_end.hpp new file mode 100644 index 0000000..d97b778 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/config_external_end.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d7685806919226c8156bb6f1822baec80e01032dcefd6da8fbfcfdac2c1539a +size 529 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/file_locking_helpers.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/file_locking_helpers.hpp new file mode 100644 index 0000000..c4c6251 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/file_locking_helpers.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:177c53ff2d26e0c2144eb9752a353758a6208189f121dccf3b5e13eec8c85242 +size 7029 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/file_wrapper.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/file_wrapper.hpp new file mode 100644 index 0000000..7d53e1b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/file_wrapper.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1a5d357423fb322d0ea02de7c52a99d1c0a213c8b35b175a2370086ab638920 +size 6407 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/in_place_interface.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/in_place_interface.hpp new file mode 100644 index 0000000..ddcdebd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/in_place_interface.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9aa2674552e3cbd2b0db3a0f2dd0bc5786e22a0700872eaed9f5a0706659eed +size 2284 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/intermodule_singleton.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/intermodule_singleton.hpp new file mode 100644 index 0000000..3cd5a26 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/intermodule_singleton.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:973fbdd6aafdf760f02ce822e7653ad674c78fc419df052d2d30cab35796de59 +size 1634 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/intermodule_singleton_common.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/intermodule_singleton_common.hpp new file mode 100644 index 0000000..99903fe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/intermodule_singleton_common.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19e5513c31a297d6b3a5283ad620392cf27d9cd465ba684c8fe1fde56508423b +size 20068 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/interprocess_tester.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/interprocess_tester.hpp new file mode 100644 index 0000000..0725ba3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/interprocess_tester.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6bf8ca1b3322e202fe051f87fdbb85390142f860ae79ecf1ac66c4b32ac097a0 +size 1028 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/intersegment_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/intersegment_ptr.hpp new file mode 100644 index 0000000..65b1ed9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/intersegment_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cac375e0246a918282dbba592ecc7365a4cfb0471446fca3250f5956e4ec1f0 +size 34301 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/managed_global_memory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/managed_global_memory.hpp new file mode 100644 index 0000000..351265d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/managed_global_memory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bcf7ad400e9acf5c70c5b220b024628e14f5bb6752876f395a194ed4af9d2603 +size 4072 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/managed_memory_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/managed_memory_impl.hpp new file mode 100644 index 0000000..e9e24fc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/managed_memory_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee7a703555aa2400248a31b9c1ac5e7be969f080a273a7145bd69405db12efde +size 29951 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/managed_multi_shared_memory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/managed_multi_shared_memory.hpp new file mode 100644 index 0000000..92fff0d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/managed_multi_shared_memory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41727bedd1c02df230716020e845381cadf72b45e9ef534bf459e908f4363817 +size 14744 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/managed_open_or_create_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/managed_open_or_create_impl.hpp new file mode 100644 index 0000000..8a2b8bd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/managed_open_or_create_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef48c5d892596e70d3f8629ae698a1896a82d46476db5e8ce1c9e033a9ee91f8 +size 15421 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/math_functions.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/math_functions.hpp new file mode 100644 index 0000000..303cd15 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/math_functions.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c2a5f564f8a0da0409278e6dc7de4b58d4dde535e0e77a389b963d213bd5133 +size 2574 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/min_max.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/min_max.hpp new file mode 100644 index 0000000..4cb2e7b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/min_max.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:044dfd4b216ace68ba94084c42b91aeef1f48f83a621f1d36c0625b1ad8e34e8 +size 1147 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/move.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/move.hpp new file mode 100644 index 0000000..392f5f1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/move.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ab0143959d0bc1bfb949b8dfbe4978d7e94bb82ac61afb2a9a247db9ac1f5a9 +size 879 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/mpl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/mpl.hpp new file mode 100644 index 0000000..9d1d8a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/mpl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3876c02e53452c4470720e1c7f427de56e40a5cc6b6050bc45c8d80e8fb6350b +size 2259 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/named_proxy.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/named_proxy.hpp new file mode 100644 index 0000000..80157ee --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/named_proxy.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8241945e92acdeec70fbcf821dfe8237a1e8a51c03201def51ed00788ab8234d +size 9950 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/nothrow.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/nothrow.hpp new file mode 100644 index 0000000..8ac0f69 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/nothrow.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4f413e3e43cea72bb78dffec1ef93f214ae5f17c6dd5eb1f401e5a8a729eaf7 +size 1199 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/os_file_functions.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/os_file_functions.hpp new file mode 100644 index 0000000..10f177c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/os_file_functions.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77660113d4221e396b06a096f57891ab6fdb653b5b74aca3eddc7816e339da4c +size 22440 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/os_thread_functions.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/os_thread_functions.hpp new file mode 100644 index 0000000..69725a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/os_thread_functions.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8fa020630959af80afef177012d09f073cc9e6d8ccb43ddfb44ebb488b75e09e +size 17427 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/pointer_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/pointer_type.hpp new file mode 100644 index 0000000..d72a7ff --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/pointer_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b03ecffc03ba2a319c101a8dd2b2702fc5c837360cb96362e33be5c594476b75 +size 1890 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/portable_intermodule_singleton.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/portable_intermodule_singleton.hpp new file mode 100644 index 0000000..f3be0bb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/portable_intermodule_singleton.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:84a02b69c59cff787781c1f660ac8b797be6b24302ecf92859607d4632db1b71 +size 11670 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/posix_time_types_wrk.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/posix_time_types_wrk.hpp new file mode 100644 index 0000000..929d981 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/posix_time_types_wrk.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66efb200e1a5a9cfb639413cfb01710f915ab267a6143222da886c1ab1aeece7 +size 1459 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/ptime_wrk.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/ptime_wrk.hpp new file mode 100644 index 0000000..5d9b158 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/ptime_wrk.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9df904543634638373609df637766b76d168802b3291268518e3fd1764ed115 +size 1195 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/robust_emulation.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/robust_emulation.hpp new file mode 100644 index 0000000..61b7fec --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/robust_emulation.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e99e90dc7ef114ebcaae1a586296998b68de01475a9cb120302f71cd680674ed +size 13020 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/segment_manager_helper.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/segment_manager_helper.hpp new file mode 100644 index 0000000..09be2d6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/segment_manager_helper.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45156dbb35d9d6d3f2d27e4e27b4b0cbb8d8b21a7e87bd8636a6268aea59d77b +size 15325 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/shared_dir_helpers.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/shared_dir_helpers.hpp new file mode 100644 index 0000000..5514186 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/shared_dir_helpers.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e892e34152e7622031fb1c4c909f4d645da2cefeb1c37ec9ede541dced9b6c25 +size 6908 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/simple_swap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/simple_swap.hpp new file mode 100644 index 0000000..1236896 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/simple_swap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3ce9ba52ffa61cbe906d3918b7d659d5cee2b2d98a324c30fd19fe9bc073400 +size 859 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/std_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/std_fwd.hpp new file mode 100644 index 0000000..fd3380a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/std_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d11b22c47e831393e71498a7c72c274e32e96059b773ef4bd59711273c962e0 +size 1708 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/transform_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/transform_iterator.hpp new file mode 100644 index 0000000..f49e85f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/transform_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8590dac3b9d0cd39a6fb3d7edeb59fbf1382785f7cbbf4fe80946bdaac47de7e +size 1283 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/type_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/type_traits.hpp new file mode 100644 index 0000000..98efdb0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/type_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:23eba3681b9586e887299d3b0db5c536d2498dd40ec5bd001b67897a6b1e51ab +size 2901 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/utilities.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/utilities.hpp new file mode 100644 index 0000000..3cc04f3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/utilities.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02a681af9a10e574bf03f916bceeb288a2ae5f3761a158e318f9531fafeb9dec +size 5917 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/variadic_templates_tools.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/variadic_templates_tools.hpp new file mode 100644 index 0000000..dbbba2e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/variadic_templates_tools.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aeaf51755f544f638c4c7235a1bb3167c397d3bd10163b2c50ceae8733184762 +size 1115 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/win32_api.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/win32_api.hpp new file mode 100644 index 0000000..828def2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/win32_api.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5bc87d17c184386df002b43a7711186b317dbd4d51d2545bfc741cc956985cbd +size 87936 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/windows_intermodule_singleton.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/windows_intermodule_singleton.hpp new file mode 100644 index 0000000..e27f018 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/windows_intermodule_singleton.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:306afd896afda7b39c840248905ccaeae00db51e12c60dbf82146f905384cba2 +size 10745 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/workaround.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/workaround.hpp new file mode 100644 index 0000000..bac625d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/workaround.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:25fcbb2563fac68febe8df96ded136e99b451de2ec994843db17429aebd3256b +size 9271 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/xsi_shared_memory_file_wrapper.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/xsi_shared_memory_file_wrapper.hpp new file mode 100644 index 0000000..56066ba --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/detail/xsi_shared_memory_file_wrapper.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1c9a8a59c210eb3d88401c0b5ba05c61622870ef88349456d2e554e7cf2b576 +size 3144 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/errors.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/errors.hpp new file mode 100644 index 0000000..2e7633d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/errors.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6025182f51d539c36a6eeac5d8f072f20fa5fdaa751297db1154b15b37c4f50b +size 7483 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/exceptions.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/exceptions.hpp new file mode 100644 index 0000000..6104662 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/exceptions.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:404255525890e8eb13e2d740a80a0d769707bfcb38109b587ceb1c9153a6336e +size 3188 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/file_mapping.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/file_mapping.hpp new file mode 100644 index 0000000..532cf3f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/file_mapping.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46e5117fd075d203ca13545705a48222b1fbd43ca21d584650773317e8e29404 +size 5894 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/flat_map_index.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/flat_map_index.hpp new file mode 100644 index 0000000..19f03da --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/flat_map_index.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a07480f429c0c59a464128cbe9fc776f88f7b6fd18140a590011dfb5fde28fc +size 3250 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/iset_index.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/iset_index.hpp new file mode 100644 index 0000000..22e79b1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/iset_index.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ae246829ef789cfb2b26314c7f8b743b4ee5fe20f83b45ceb7185bfc657132d +size 5611 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/iunordered_set_index.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/iunordered_set_index.hpp new file mode 100644 index 0000000..31d1486 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/iunordered_set_index.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a480a92ef4e5ce3946a1be078a2b5bb11184b108c069b4cb90c2b3861b3c11be +size 13306 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/map_index.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/map_index.hpp new file mode 100644 index 0000000..d0b51ed --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/map_index.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:773999c980931f77e0a598e4ad165af94cfc9de38ddace35caf3467c881b43c7 +size 3640 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/null_index.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/null_index.hpp new file mode 100644 index 0000000..628b9b1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/null_index.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5e0c3a09b2b25f1a2962e26ca7ebf7010eff188dd63f013c8990c706ebfc51d +size 2000 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/unordered_map_index.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/unordered_map_index.hpp new file mode 100644 index 0000000..caad24e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/indexes/unordered_map_index.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:607037b389b25bdbe5aff0bb9f134c8cf82cdd66ed35c410464f7c6660f4db47 +size 4239 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/interprocess_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/interprocess_fwd.hpp new file mode 100644 index 0000000..27ff156 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/interprocess_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4207e2e9b41219ca8d5e032988e4993247a9dc1821779a3485281bc66297aec7 +size 17418 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/ipc/message_queue.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/ipc/message_queue.hpp new file mode 100644 index 0000000..3abbcd5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/ipc/message_queue.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e5d3b0632058dcace33891f7fb801d6b5214acac49311a9cb9ce2bb7cb1774d +size 39895 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_external_buffer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_external_buffer.hpp new file mode 100644 index 0000000..c56628f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_external_buffer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d4badc1affe41a8078fe51a3fd8ba1fbdc31e4291c91b54ccb41dc720a0be8c +size 4595 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_heap_memory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_heap_memory.hpp new file mode 100644 index 0000000..089449e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_heap_memory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc1267244286df205eefff17f99aba95fb82e50ceecd184aa55d82e7e143b5aa +size 5459 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_mapped_file.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_mapped_file.hpp new file mode 100644 index 0000000..9c0edfc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_mapped_file.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f203b2eadba79d8dcf529858b134a8eaceab21cb215d0b1ed715227e5b2aa19c +size 8685 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_shared_memory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_shared_memory.hpp new file mode 100644 index 0000000..5f3a5d6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_shared_memory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5c85fdbba76640cb21a354a9fff94868c5314325672dba71207620be78e87bd +size 9067 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_windows_shared_memory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_windows_shared_memory.hpp new file mode 100644 index 0000000..5ab86e7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_windows_shared_memory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5cd4668d1b3bd4905da785d73129a26e5aac60c81477abdc2814dfef1da36a2a +size 8014 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_xsi_shared_memory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_xsi_shared_memory.hpp new file mode 100644 index 0000000..f44ea53 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/managed_xsi_shared_memory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e15337a002e6b3532204baa48620b01f024d9d24af03746fd5e4cbbfba44fe8 +size 8022 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/mapped_region.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/mapped_region.hpp new file mode 100644 index 0000000..d1228d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/mapped_region.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82fd98529b356baa9ae8dbbf843e38c67d3213d6853bb1f515299d26672e3303 +size 31773 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/mem_algo/detail/mem_algo_common.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/mem_algo/detail/mem_algo_common.hpp new file mode 100644 index 0000000..e541572 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/mem_algo/detail/mem_algo_common.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2338b2fff47fb160e01a4d8deae9d385c7e99461e0684a42a4890ef9d38af8c6 +size 25012 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp new file mode 100644 index 0000000..f623f9e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0718abca9fd43ef35e9e74e18dd3b6833f30003186facef55e31410266d0e682 +size 41335 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/mem_algo/rbtree_best_fit.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/mem_algo/rbtree_best_fit.hpp new file mode 100644 index 0000000..70444bb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/mem_algo/rbtree_best_fit.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:532482db8190365b3a233f27bcf00ecc87446c039c950c3e25911ffb7e5f983d +size 58181 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/mem_algo/simple_seq_fit.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/mem_algo/simple_seq_fit.hpp new file mode 100644 index 0000000..fab7d08 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/mem_algo/simple_seq_fit.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6aca3202e6517287354cb2e9064ba2a0fc31b0a18979a94976e153956c7ea7d0 +size 2081 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/offset_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/offset_ptr.hpp new file mode 100644 index 0000000..d8d218b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/offset_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1db603f00b77069dffa030f7ffae7c57ba4f78d934ae2d42dbf22239f6963d2 +size 30933 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/permissions.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/permissions.hpp new file mode 100644 index 0000000..870b7d6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/permissions.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e145835880930f4ecf6a31daed286749e59ffbcab6914e019a6cd0959a424645 +size 3443 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/segment_manager.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/segment_manager.hpp new file mode 100644 index 0000000..59857ed --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/segment_manager.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f5be8e698ffd520cec030d74a265005437794f4b446ed80e744e5ed0dec6588 +size 50713 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/shared_memory_object.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/shared_memory_object.hpp new file mode 100644 index 0000000..2971248 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/shared_memory_object.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:544eea3a4442b343f5a2157765c9f1f27e5632c45db8b1de7107abdff9aa6cef +size 13550 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/deleter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/deleter.hpp new file mode 100644 index 0000000..4e9c329 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/deleter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3e848808a77f845c7f37b12f351c58ef62e0132dd035fa632c237ebd41c590b +size 1883 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp new file mode 100644 index 0000000..1f636ae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66c25e51f855bf759638f91f13ec9176fd43bf28fdd38f93e57020bf0dab7225 +size 1354 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/detail/shared_count.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/detail/shared_count.hpp new file mode 100644 index 0000000..33aca62 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/detail/shared_count.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b2b0c1f92b8370390cd6a68283e38fff852fbea6ac4fb1f75e06d4775bdf2b78 +size 11546 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/detail/sp_counted_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/detail/sp_counted_base.hpp new file mode 100644 index 0000000..3b7e986 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/detail/sp_counted_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e29b710995ff1ce20b3643dab563a7150f95528548a55ce62e9066d000fc39e +size 833 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp new file mode 100644 index 0000000..fca1e61 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bcc27846ab065f0040c0c894a76d81c8ce37d779fd7c6ee1c33b5868f25614f3 +size 2344 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp new file mode 100644 index 0000000..309b45d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ac5e3338a951029c06b19ca2d39b2b84bbe10e983c29069cfda8f72963c91c9 +size 4922 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/enable_shared_from_this.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/enable_shared_from_this.hpp new file mode 100644 index 0000000..324b9a5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/enable_shared_from_this.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c694115f3cc25a3ea531cef638ed07c3bf4fabc8ba9ac4dbe40e202577f5067 +size 2661 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/intrusive_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/intrusive_ptr.hpp new file mode 100644 index 0000000..7432ba7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/intrusive_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d93a9d2ebac83cc90128d44c2ede6e75759b78b7f66566f53c6cb31d2464b886 +size 10454 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/scoped_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/scoped_ptr.hpp new file mode 100644 index 0000000..014a70a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/scoped_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7dfde0d002155cf857ec62be3d46fc3e7037171d59ef8d96f581cb834120ddb3 +size 5771 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/shared_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/shared_ptr.hpp new file mode 100644 index 0000000..abbbde8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/shared_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1fffc5a4e995c3f7e828cdf443e2038e2d3710ceb419605d64d96c61d9f6dab +size 16662 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/unique_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/unique_ptr.hpp new file mode 100644 index 0000000..ed86b1b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/unique_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10071ebb809b7fccc0102b1041487d54a2b72e359f9fc5d3b1be8dd88c0376e4 +size 2009 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/weak_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/weak_ptr.hpp new file mode 100644 index 0000000..43a5ed8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/smart_ptr/weak_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be7850ac116baeebdf1c3fd351cf207cf1b1ec68773e99cf3e7af650e0c8e091 +size 9111 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/streams/bufferstream.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/streams/bufferstream.hpp new file mode 100644 index 0000000..a7682c1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/streams/bufferstream.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15bc75877551cee4f7c39d8b3befadcaa5dc5a854e25af6895327ba7f5a0ad81 +size 18980 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/streams/vectorstream.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/streams/vectorstream.hpp new file mode 100644 index 0000000..02c6a8f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/streams/vectorstream.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37aa5bad55f8ef9aab0d65af51724af0fc3a13ff633fdbeaa2cd5cb8274cfceb +size 25648 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/detail/common_algorithms.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/detail/common_algorithms.hpp new file mode 100644 index 0000000..f2e094e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/detail/common_algorithms.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9e06335e765d9541084b6adde10aa6893a1cd0d063ef75795cc54600cf615f9 +size 3258 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/detail/condition_algorithm_8a.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/detail/condition_algorithm_8a.hpp new file mode 100644 index 0000000..87dc0f7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/detail/condition_algorithm_8a.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:048c4b85611053738669c1f44dd60bf629378715e9e2035aca6ab6ba2d69cfa6 +size 12723 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/detail/condition_any_algorithm.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/detail/condition_any_algorithm.hpp new file mode 100644 index 0000000..283a4fa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/detail/condition_any_algorithm.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:683f38416dcbcf491cce8caed799336e9806900070693fb164e22f55e61f5fb8 +size 6866 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/detail/locks.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/detail/locks.hpp new file mode 100644 index 0000000..fd5b060 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/detail/locks.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:71642ca84797023597036e141d259b09d13273b75fe98266e7c5c612867bd5eb +size 2210 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/file_lock.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/file_lock.hpp new file mode 100644 index 0000000..92aa9f9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/file_lock.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3915d890d6bc99177b1881a893e2579576f956ffac6252c1da47f37d8622dc53 +size 7962 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_condition.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_condition.hpp new file mode 100644 index 0000000..8012540 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_condition.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db43486d87b52214941e37e0b042c2f885faa00cacc311026ce9913976813c82 +size 5656 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_condition_any.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_condition_any.hpp new file mode 100644 index 0000000..c50685f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_condition_any.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5727e387c131af5eb7bdec1c6e393d6b1d77f5242bde981e3a514e85f04c9ddf +size 4762 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_mutex.hpp new file mode 100644 index 0000000..cb7151a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:692e4a789d4f1e10e21ec2c74da8e6731f3d4060abc637fedbac74a9bbe4f50a +size 6359 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_recursive_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_recursive_mutex.hpp new file mode 100644 index 0000000..3671eb0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_recursive_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a43f4cc30cc92f6bc77e01001fc53a7e387f712f21ac7f749287304cc15858a7 +size 6821 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_semaphore.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_semaphore.hpp new file mode 100644 index 0000000..bbbd6f7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_semaphore.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a374e33a861af91285aed20f217bb713264ed4848af792f77710f72c45b391ef +size 5681 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_sharable_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_sharable_mutex.hpp new file mode 100644 index 0000000..85edfc4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_sharable_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30abd0170b31f6ba3d890c0045dd997d35e069210c3e409efda0ec578ce98810 +size 10918 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_upgradable_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_upgradable_mutex.hpp new file mode 100644 index 0000000..87bd9db --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/interprocess_upgradable_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6d645da3a1acc9fba741243b979b3d03698765ebd188f3e73c74f5443b6de696 +size 22851 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/lock_options.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/lock_options.hpp new file mode 100644 index 0000000..26806b9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/lock_options.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b919be9698ac1a9386a57474f15589d5c25125e6988f2209ecd431e0dca76193 +size 1983 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/mutex_family.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/mutex_family.hpp new file mode 100644 index 0000000..9801d9f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/mutex_family.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0247ad384ab02742d384e43930b10f4c673430f63cf2c6b8de4b4a9357f977fc +size 1887 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_condition.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_condition.hpp new file mode 100644 index 0000000..d96fe1a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_condition.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bf1b565463dca2e103a6b2f2c146c72d6032300687de51be37bf5f053ea7b908 +size 7176 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_condition_any.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_condition_any.hpp new file mode 100644 index 0000000..1ef094b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_condition_any.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3595256123804bfa4d12a1d7001e92dbb1ba394b8df7842a1d3314120858e4e +size 6024 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_mutex.hpp new file mode 100644 index 0000000..4d00192 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7285e2a6d8e94381bc82bb20c5d5cd44783756ee72e1f0e55a4249848e5c12f +size 5991 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_recursive_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_recursive_mutex.hpp new file mode 100644 index 0000000..1596444 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_recursive_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4a8473873e66fa2c11a3c7b73013f44ff4b3574df7acebfa7fde86ccd16616c +size 5992 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_semaphore.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_semaphore.hpp new file mode 100644 index 0000000..013f471 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_semaphore.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50323be968432aa6f8861a0036a92c928b688e6816ec53e4baa8f4915de5db51 +size 6586 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_sharable_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_sharable_mutex.hpp new file mode 100644 index 0000000..0d09c19 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_sharable_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e98c1a9ec98747e7e22faaa26f78b46ce2dc6c7aa003743dd75f4e2abd01de2 +size 9235 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_upgradable_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_upgradable_mutex.hpp new file mode 100644 index 0000000..ffa02bd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/named_upgradable_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dfcb49c1f5e6fe073bbe9667ce4d99649eeff4058d8585896c57ae05c75449f3 +size 15994 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/null_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/null_mutex.hpp new file mode 100644 index 0000000..2c87a2d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/null_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b122919ffb5320afbb19de76249c1fdf8710b1d3cbdaa31036efa24f12b7e96e +size 4197 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/condition.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/condition.hpp new file mode 100644 index 0000000..50429fc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/condition.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d69810b6acfac3cc81d85a6841b78ac45a1211469496a5bda4d6a0544fe17c5b +size 5664 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/mutex.hpp new file mode 100644 index 0000000..38bf48f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c9f0777017d504bb29441ade625c1743a5c1a0afe08ae76f5b7d9a722b8727f +size 3965 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/named_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/named_mutex.hpp new file mode 100644 index 0000000..4715165 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/named_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:70525db67bda5cdc6b143e04f4f789cf1f24f070c6bbc36b97c9af0ff016bad2 +size 3423 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/named_semaphore.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/named_semaphore.hpp new file mode 100644 index 0000000..0ba25e1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/named_semaphore.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9cc23ec534dc0762204d47f9ddc4cc0df68b76cbbf95a8fd58801eac090d74e +size 2622 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/pthread_helpers.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/pthread_helpers.hpp new file mode 100644 index 0000000..1da4a8a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/pthread_helpers.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da3a2d969f2360fb5fd9aadde9b0d924ddf9ded4abb4ced47a5b5eeafa959987 +size 5321 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/ptime_to_timespec.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/ptime_to_timespec.hpp new file mode 100644 index 0000000..7c3918d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/ptime_to_timespec.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:57bed057399b5b6d6ed5bf19e8aae11a584cd1cf641e8f4de9392a5b28b8132c +size 1482 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/recursive_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/recursive_mutex.hpp new file mode 100644 index 0000000..c68be93 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/recursive_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95e963cca4615b2a6ff7d6c9b2dc8c4cca0002bb4055e339bfece9fff28d94a1 +size 4044 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/semaphore.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/semaphore.hpp new file mode 100644 index 0000000..0f1264e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/semaphore.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:36ac6ae356474d41c67ebef6bee3e13a666cdb51750f68d47abbfc77b48a5a08 +size 1762 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/semaphore_wrapper.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/semaphore_wrapper.hpp new file mode 100644 index 0000000..bb60256 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/posix/semaphore_wrapper.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:80b4bc71e0eab668e7c7e19c44b8bbc8a74883ae69e4d89009a29a0595761461 +size 6821 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/scoped_lock.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/scoped_lock.hpp new file mode 100644 index 0000000..31ec03c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/scoped_lock.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7bc0f9ef2ad81d0dcbd92af0b2deb1c7c08400d43a781316e620b99c53b0d538 +size 16117 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/sharable_lock.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/sharable_lock.hpp new file mode 100644 index 0000000..14a4936 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/sharable_lock.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e3485a1ccd9f4c70a867d45ff6ace81b35e9b05134b588fbb718cf7ec1b1268 +size 12918 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_condition.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_condition.hpp new file mode 100644 index 0000000..32fb89c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_condition.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:340b90048d69e7df02107bdf90ecafcff87759e2eebf60c5858a7c84562c082f +size 9058 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_condition_any.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_condition_any.hpp new file mode 100644 index 0000000..62fec45 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_condition_any.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f8d514d71ecb764b61b99d6cb2e95d37c67be80ff6fc2b53907c7ff73648c2f0 +size 7685 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_creation_functor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_creation_functor.hpp new file mode 100644 index 0000000..6fe8463 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_creation_functor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b4f92a850ea872bcc71ac96c7279962771054bdddc1522ced63bd459acae827 +size 2306 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_mutex.hpp new file mode 100644 index 0000000..d33d173 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ede349de5ada01b971847a1a2e122ee115c0b42897aa414aa4d3a80fd6ffa708 +size 6561 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_recursive_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_recursive_mutex.hpp new file mode 100644 index 0000000..2106759 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_recursive_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f4fed06a5f58c5404b8fb8d5e125661c6873cbb53d7e638aaba6f07733fd719 +size 6597 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_semaphore.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_semaphore.hpp new file mode 100644 index 0000000..6f5031a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_semaphore.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:894ccfb1f57a015493f7c1fb3b04e3d7dd292f1946503b9d73b3d359bbbe6a64 +size 4624 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_upgradable_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_upgradable_mutex.hpp new file mode 100644 index 0000000..b2d7d71 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/shm/named_upgradable_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:69ac8e0306b2da71d3cc0d8b759c934186d7472fb83b70d1880204590a5de081 +size 15529 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/condition.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/condition.hpp new file mode 100644 index 0000000..06753a3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/condition.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:debad4e2223cdee0986c06267986d6cec3987aa4404d9491aaabe508589fc10c +size 9785 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/interprocess_barrier.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/interprocess_barrier.hpp new file mode 100644 index 0000000..cb32d4f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/interprocess_barrier.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7a40515d23ccace36c01248320ec11e02bc67d0253bf4df4329afb295639346 +size 1341 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/mutex.hpp new file mode 100644 index 0000000..c5c2bfc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d74f841e69bb374c5ca0dbb5db9054087dec6b5a401de1199ccd1bce38931f78 +size 2380 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/recursive_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/recursive_mutex.hpp new file mode 100644 index 0000000..f38161e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/recursive_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f1f7414e263243cda67137811fc7fed12ce511afd51a40669fe04309b2f82255 +size 5992 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/semaphore.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/semaphore.hpp new file mode 100644 index 0000000..0486bf7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/semaphore.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:649243cf578a82cd1bb5f01ce2289b35af2c295f61ea728caf93f7333cf4f6b3 +size 2581 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/wait.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/wait.hpp new file mode 100644 index 0000000..276f841 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/spin/wait.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:23a757f1204afe2bc629ff31e0c24a85cdb85bcd1b2bcae5accfebb60f36d601 +size 5037 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/upgradable_lock.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/upgradable_lock.hpp new file mode 100644 index 0000000..ec31c7d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/upgradable_lock.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aecd3488ba6ec22a7bb7b6d5c55183ad93decd80d4706feb718a0e4be9c75676 +size 13082 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/condition.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/condition.hpp new file mode 100644 index 0000000..c1a989f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/condition.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3d4ab541008f73cd6a0575f523703b468d4142c20c3cbd71402cd12e45c9772d +size 3713 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/mutex.hpp new file mode 100644 index 0000000..42079b9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ce2365a4f5ca3a5fb1959e9dec6053f52ba7dd7bff4d2affa8eaa1b800242ec +size 3357 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_condition.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_condition.hpp new file mode 100644 index 0000000..2194a27 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_condition.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54a41d11f944f106de00ad1b580b838c3554ef554d53f01b9264f7b814315972 +size 1156 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_condition_any.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_condition_any.hpp new file mode 100644 index 0000000..0c832b5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_condition_any.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e4a056394114eddad59a6cae971347caa41e1976df57bdfc8d0e8dd0a6e0b3b +size 7836 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_mutex.hpp new file mode 100644 index 0000000..7cbc47d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de56cb8463bb8741be24ed7b1941e4f2a3eaad677108969cbe74c9035123c4bd +size 4975 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_recursive_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_recursive_mutex.hpp new file mode 100644 index 0000000..cc474ee --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_recursive_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c1e796f2dd88a35694c99125ad636b8be381923884fca89cf4e7ad8bf0ccf8d +size 2025 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_semaphore.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_semaphore.hpp new file mode 100644 index 0000000..db828f8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_semaphore.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07888e1b4a352d116226fc2dc298769ac8b8f007fab5f0b9adf3ebf5bd6a1bf0 +size 5386 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_sync.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_sync.hpp new file mode 100644 index 0000000..77c55e9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/named_sync.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d589e8054fd3b1f5f4d012fbc2582ddebfcc2330f74780e11fe784d57954b82 +size 8317 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/recursive_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/recursive_mutex.hpp new file mode 100644 index 0000000..aff5ce4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/recursive_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7e19c0468e384882586cf3488204662381a87ca95036096bd46650853f296ba7 +size 1394 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/semaphore.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/semaphore.hpp new file mode 100644 index 0000000..160cf30 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/semaphore.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:22fc3918fd7018b041f60ce7ed81553ea6dccd0da075873eb49dac08f9524b2e +size 3571 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/sync_utils.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/sync_utils.hpp new file mode 100644 index 0000000..116271b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/sync_utils.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b415bd45826f1ca10b740f33783d4d2e28f9a21d96f2610da25ac1fe3953e694 +size 7107 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp new file mode 100644 index 0000000..6d69b73 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8087e7ccf759d20cd8571d1c21d2a65d56d410c9595b29fbdd86b564b231d203 +size 3717 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp new file mode 100644 index 0000000..04d3585 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bcde9b9cb1bbd0173cc42717ca3489784e2d95982420c64a16aa7a282b7bf680 +size 4691 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/winapi_wrapper_common.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/winapi_wrapper_common.hpp new file mode 100644 index 0000000..e30add6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/sync/windows/winapi_wrapper_common.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a37d03dc6089a9e76db3e3790007c32189cfbbaec275caace2de408fc3e12ddb +size 3050 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/windows_shared_memory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/windows_shared_memory.hpp new file mode 100644 index 0000000..2ce186c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/windows_shared_memory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d7c490bb83a44bf81d8b237c2c1c3aa523e08064579cf1b0680fffe9cac31d2 +size 8666 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/xsi_key.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/xsi_key.hpp new file mode 100644 index 0000000..519e160 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/xsi_key.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f7b27f303903d59fedf41c2d4ed7b7b421d8be31c647b71d6f2ac26aff1a64b +size 2918 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/xsi_shared_memory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/xsi_shared_memory.hpp new file mode 100644 index 0000000..bf19db4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/interprocess/xsi_shared_memory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15a948da4bca6c0eaf04539ca04e428526d9a0d15d012e434312eb1255bcc1a2 +size 6978 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/any_hook.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/any_hook.hpp new file mode 100644 index 0000000..f85096d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/any_hook.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbc36e41c9097f9af2dbca14c2efda598e8cb72d7eb3081411d7700e8bef92b8 +size 10506 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/avl_set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/avl_set.hpp new file mode 100644 index 0000000..3b60dea --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/avl_set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07eba1b780c6c0716da3652417f13ff20be4b6471a490abcc6a8e1811c388cb7 +size 44766 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/avl_set_hook.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/avl_set_hook.hpp new file mode 100644 index 0000000..1cadac1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/avl_set_hook.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f978d14aa4a023f1fcde73519278ccf204b218657fb5815d46307c04d1bb0125 +size 10965 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/avltree.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/avltree.hpp new file mode 100644 index 0000000..f37528e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/avltree.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a5d97bb2a9dd13d028733e7ce9ea4d651b81238adb30691c89812de930410fb +size 23816 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/avltree_algorithms.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/avltree_algorithms.hpp new file mode 100644 index 0000000..8bc60d5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/avltree_algorithms.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8e8327a828167f12fcbd6c2b72d35c85cf287f80ce66066ac11b7b36924ec77 +size 28978 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/bs_set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/bs_set.hpp new file mode 100644 index 0000000..e5d8623 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/bs_set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b843fabd099028800f32d4b2943ae9083ca6a501efb641406b9ff49063e26d5d +size 44282 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/bs_set_hook.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/bs_set_hook.hpp new file mode 100644 index 0000000..90031e6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/bs_set_hook.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15795ff4cf9610544d8a21e18996889a7203767b8710343b1ed9656f3f239132 +size 10501 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/bstree.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/bstree.hpp new file mode 100644 index 0000000..53ece5a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/bstree.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1aa186ac2e8968c07b631f72705b5fdfd889097de02eb4e4f6a108d05677b1d7 +size 94900 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/bstree_algorithms.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/bstree_algorithms.hpp new file mode 100644 index 0000000..0d9d1d8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/bstree_algorithms.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a07e1cdba29e7a8e1f3601c205a7caf26158568c7e76292ae707c94ca4b6005 +size 80073 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/circular_list_algorithms.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/circular_list_algorithms.hpp new file mode 100644 index 0000000..5f497a4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/circular_list_algorithms.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e64210905d75e912d43a63bc5ec3cdcff8d906a952fd4498bae3d4a01b58704 +size 15376 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/circular_slist_algorithms.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/circular_slist_algorithms.hpp new file mode 100644 index 0000000..2023a2c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/circular_slist_algorithms.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17abe7d42c3e93077cbb0c1ebf6583d274542650a2c65f2ece8f50fd79c5b534 +size 15029 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/derivation_value_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/derivation_value_traits.hpp new file mode 100644 index 0000000..6e31006 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/derivation_value_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7392ce7e7e2e3808b1052243b6fd27b36bcd868f6c0add6feff1dc276e7253d1 +size 2749 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/algo_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/algo_type.hpp new file mode 100644 index 0000000..2e74abf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/algo_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:924e724f70b9f4acfb09e0968ab5aca4c3b81d0582723ddf74feec4788b43a28 +size 1303 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/algorithm.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/algorithm.hpp new file mode 100644 index 0000000..b50e775 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/algorithm.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f03d12fae23e4fb81982cc9482f3eb47f2730056dab4b13039a1fe92d4f837d +size 2880 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/any_node_and_algorithms.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/any_node_and_algorithms.hpp new file mode 100644 index 0000000..e8708cd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/any_node_and_algorithms.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dfb4fc629a7cdffe75b60d0c2aedb8a76378a2d6b0d940e1f8c2f707acef10bc +size 9467 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/array_initializer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/array_initializer.hpp new file mode 100644 index 0000000..00c2c1e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/array_initializer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5c4745c1e01c6b1e70fc5d103651fac50b35bc27ba907f7551ebfac89b6dae6 +size 2235 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/assert.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/assert.hpp new file mode 100644 index 0000000..f5a2aa8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/assert.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:36311de238c3912eb630daa1ee1b18dbf5b5b7f867594258e28b5ae7383c4dff +size 1520 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/avltree_node.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/avltree_node.hpp new file mode 100644 index 0000000..5e1925f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/avltree_node.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99f6d113429fb6d2c86c5530af083349c01467919f70e56c5fc4bd31aaec262b +size 6714 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/bstree_algorithms_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/bstree_algorithms_base.hpp new file mode 100644 index 0000000..48a0588 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/bstree_algorithms_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7586cdaa5aaaa193ed794964d6b4770e0cfc70ea10a51036bfab4a1644d9db0 +size 5523 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/common_slist_algorithms.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/common_slist_algorithms.hpp new file mode 100644 index 0000000..d876553 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/common_slist_algorithms.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42378ea1d7ecc2869115b13e9f1fabea72d81787c4a428ea08ce54e6814e0c4a +size 5974 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/config_begin.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/config_begin.hpp new file mode 100644 index 0000000..817c83d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/config_begin.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b1d9bf54b366a13c41a7af086a3e7db053d9d488eb7d5a1ba8c35f1c015a0ec +size 2456 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/config_end.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/config_end.hpp new file mode 100644 index 0000000..51c77ce --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/config_end.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d2e15bca78377c31db968ed473249f5de96193ef7a165f81ca339f1aa33223c +size 496 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/default_header_holder.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/default_header_holder.hpp new file mode 100644 index 0000000..167f5da --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/default_header_holder.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76b5a2ceec55e63478d1ef9e0758aeb35e32a238c4ea75f5e0e7c0cba1cb0bd9 +size 2243 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/ebo_functor_holder.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/ebo_functor_holder.hpp new file mode 100644 index 0000000..68faf0a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/ebo_functor_holder.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:292fddb3a3cd5aa48bdc452e429a2ba0306bd70d3d07c02af6ddd9b41df463a1 +size 7965 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/empty_node_checker.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/empty_node_checker.hpp new file mode 100644 index 0000000..ec8501f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/empty_node_checker.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6159152c8ec9f1ac8e9f7ce685479dbdf378203933b7ac95a9f52c14cbb7a714 +size 1243 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/equal_to_value.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/equal_to_value.hpp new file mode 100644 index 0000000..f9511f0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/equal_to_value.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:09c664b005622f03497cecb3d4141c0793a264334abf4cbdedb37be1e79001ad +size 1217 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/exception_disposer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/exception_disposer.hpp new file mode 100644 index 0000000..adf2dcf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/exception_disposer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7473a5ad93d18b8b663fafadc06ea32fa356b556572b440a41845c854dee112e +size 2132 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/function_detector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/function_detector.hpp new file mode 100644 index 0000000..45588ff --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/function_detector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3c1f430d9e9612c22dc72346b24c969a3381c00b0e170bfa694c05a33eee261 +size 3456 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/generic_hook.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/generic_hook.hpp new file mode 100644 index 0000000..15a310c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/generic_hook.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:298f9e771414cf3e258fc074c8a49e2f25e09a4b6ac240e048a43c029d71d757 +size 6252 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/get_value_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/get_value_traits.hpp new file mode 100644 index 0000000..3539b9a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/get_value_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc9fc7bdf8edc9933c958cfdd46cbba8c3ddc57ba5991d26dc3f5649388c7545 +size 7098 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/has_member_function_callable_with.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/has_member_function_callable_with.hpp new file mode 100644 index 0000000..17308e5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/has_member_function_callable_with.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2aa3b5fb03cef2a43273f15724ee14ac78fef5cee7d3b7bea3eaac3b14222a8 +size 18438 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/hashtable_node.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/hashtable_node.hpp new file mode 100644 index 0000000..d8bfc4e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/hashtable_node.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:514c0a7f0b0b2fe8828bcdd4eddc66f8bcca3774ac18b42a28b5e0fbb6fb4416 +size 9688 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/hook_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/hook_traits.hpp new file mode 100644 index 0000000..8a34f5f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/hook_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee060782ac3f919ffdf088e0aa6301d66b87252ff8f96a983057c8d087b68c43 +size 8240 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/iiterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/iiterator.hpp new file mode 100644 index 0000000..1e28a33 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/iiterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c9c7904782390eb038b7490a6bcdbc3e7d6a8bb49bee8f9fc3f020cae2f0fef1 +size 4446 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/is_stateful_value_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/is_stateful_value_traits.hpp new file mode 100644 index 0000000..a7e4d4f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/is_stateful_value_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:20b930951a33734c9ab6bc1f270e363813a1900beaa612d6f659c4f0f0f7222b +size 2524 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/iterator.hpp new file mode 100644 index 0000000..9dd53e4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b6670b7ffcb494dca165e097d0a94a5c70c5542c377fec78e1557d5687f76a8 +size 7592 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/key_nodeptr_comp.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/key_nodeptr_comp.hpp new file mode 100644 index 0000000..be7085b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/key_nodeptr_comp.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b5af59071870021c0bdf9673121218877a00839911ac421247d24494cbaa7e0 +size 4854 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/list_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/list_iterator.hpp new file mode 100644 index 0000000..5246a6c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/list_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3238f306f1f45dff2b096a78aeb4a28e04ecb03c180bc84a78562c5a59ac6103 +size 4751 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/list_node.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/list_node.hpp new file mode 100644 index 0000000..e6d362b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/list_node.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f50360c6199419e05b60e8c50ec0c5fd8033d2c33e169ab6fe7143b9c3dd5796 +size 2152 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/math.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/math.hpp new file mode 100644 index 0000000..331b30b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/math.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f668c404cc3465c8e3ef0473e2a7a7846a1d7813928de85fea8d18a89e624b68 +size 8044 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/minimal_less_equal_header.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/minimal_less_equal_header.hpp new file mode 100644 index 0000000..aa11a07 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/minimal_less_equal_header.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:852205cff09e518acdf2fb999db38c8a412109d015381e0cbd08a6eb77e9eb22 +size 932 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/minimal_pair_header.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/minimal_pair_header.hpp new file mode 100644 index 0000000..fd9ba1b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/minimal_pair_header.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd1e38a2ddb283a47187ffbe2e0030d978d02610993ce0e23c7ed564481a6c2e +size 904 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/mpl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/mpl.hpp new file mode 100644 index 0000000..d28a8a2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/mpl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02e3edeca56dc2654b1708b4149c53e457e10e6f40f46b59e429dd28454f0092 +size 8558 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/node_cloner_disposer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/node_cloner_disposer.hpp new file mode 100644 index 0000000..ceff8a9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/node_cloner_disposer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:161d63bfba7b1ed25bce536adfa278f559ad951e440300ffd3cb5852dc8415fe +size 3973 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/node_holder.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/node_holder.hpp new file mode 100644 index 0000000..1bda1c3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/node_holder.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92fdff27b36a354da849f90ca39a903252c3d76e5fad283ca908cd3c7b2b41bd +size 883 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/node_to_value.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/node_to_value.hpp new file mode 100644 index 0000000..70ce251 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/node_to_value.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:697911c4d618b7a42f4804222bbbd2165edfd222f35413b0adc3c4b1e31ae2a9 +size 3994 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/parent_from_member.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/parent_from_member.hpp new file mode 100644 index 0000000..a8b545d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/parent_from_member.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97714b7e3bc5315211a5027d1b021efe33cd04263ec4d6277c930ad3b9724532 +size 4191 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/rbtree_node.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/rbtree_node.hpp new file mode 100644 index 0000000..49ec62d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/rbtree_node.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ab5cf4f565d36ed9d7a405565e9625b1964640e2a7336ec25ea3728c55bfc6d +size 6952 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/reverse_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/reverse_iterator.hpp new file mode 100644 index 0000000..6567691 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/reverse_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae9a56cd8b06a1239bfaceb0ae46e94541df7e6c83f1aa5b91692bab9a88316b +size 4644 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/simple_disposers.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/simple_disposers.hpp new file mode 100644 index 0000000..7e157b1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/simple_disposers.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af034b446259ff7ef4b02f62d15dfd2878560a947311f80610e110736f0705ad +size 1177 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/size_holder.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/size_holder.hpp new file mode 100644 index 0000000..5786223 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/size_holder.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d3965e4b48911f6871bbbe382dd2e7c7a327acd05398e05e7b456bfd0c9743a +size 2261 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/slist_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/slist_iterator.hpp new file mode 100644 index 0000000..5be3b95 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/slist_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fcb9f226444337d5da1ea97ed2e7579db94d9d021ab48c05a96ef327cded8ab9 +size 4484 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/slist_node.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/slist_node.hpp new file mode 100644 index 0000000..095cf42 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/slist_node.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18622a7d9c61c3c698f0e80d532f46e38f791e25c7a594348d1065de8feb312e +size 1907 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/std_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/std_fwd.hpp new file mode 100644 index 0000000..c6e7546 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/std_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e70011af03350c4449d26ca6ad364ae6a845528ed6841cccb592cccc832e3d1 +size 1226 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/transform_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/transform_iterator.hpp new file mode 100644 index 0000000..b4fff82 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/transform_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e173ca4e8e20339430394ab0482b95431fc162993fb5209fa1c3a71dd724d0e0 +size 5789 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/tree_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/tree_iterator.hpp new file mode 100644 index 0000000..e3770cc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/tree_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d22c9780581dd7ecc3545dddd0287cf05c0cbf75a2c1755721921be3aa102880 +size 6252 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/tree_node.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/tree_node.hpp new file mode 100644 index 0000000..aa2b6d7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/tree_node.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:839e8ab76440ce74507a3f5689fa31236bb72460fb287f61856c0a5152e71b2b +size 2307 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/tree_value_compare.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/tree_value_compare.hpp new file mode 100644 index 0000000..be02f46 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/tree_value_compare.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5a486d57e73467c9ea52e729073a1cccee08c35db15fb7cda1bdef7ba2b4430 +size 7711 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/uncast.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/uncast.hpp new file mode 100644 index 0000000..8be09b8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/uncast.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9244c77f070bee587fed9195f532eb76ec1a6f653036f996f983efeb81e3e59c +size 1646 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/workaround.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/workaround.hpp new file mode 100644 index 0000000..29a7ea6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/detail/workaround.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:146ae3897ca90195125d0b0300f70cc2bf3c07b760d88e9cd3a7b7deb1d17603 +size 1853 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/hashtable.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/hashtable.hpp new file mode 100644 index 0000000..69d31bc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/hashtable.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:919cb236a1a8513dc9b2be6bcece7cd9f4c5bcc758c92a5274b48b5aa77913f1 +size 156279 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/intrusive_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/intrusive_fwd.hpp new file mode 100644 index 0000000..8a03e6c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/intrusive_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2d6074b46e83a12abd18ca9d2ab5ddfcfede0d6704fa145ce31b564367d0480 +size 16316 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/linear_slist_algorithms.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/linear_slist_algorithms.hpp new file mode 100644 index 0000000..ea0f96e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/linear_slist_algorithms.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd44a97a535f993f1108e2d99017f760b71b8218243151b6d22c28a2aeab4c97 +size 11968 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/link_mode.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/link_mode.hpp new file mode 100644 index 0000000..ba164c9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/link_mode.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae4c5846fb093abb4fd51778cbaa84b7ad576352483efe86f806ca477a60cb32 +size 2091 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/list.hpp new file mode 100644 index 0000000..cd0d182 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:36855f5c1e68aefa239a3747442d7a1125288efe8136f879f6db6f466b1e4010 +size 57837 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/list_hook.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/list_hook.hpp new file mode 100644 index 0000000..dfcce7c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/list_hook.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a502925cbf414d777baf1d04a84ec6c30e009d78bb99c4462d1b3b72466d2eca +size 10171 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/member_value_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/member_value_traits.hpp new file mode 100644 index 0000000..ccbf82b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/member_value_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32aa658c44bb06757f69a1c80a684d5c588b849f04856b6cb1838145704db008 +size 3481 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/options.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/options.hpp new file mode 100644 index 0000000..5096add --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/options.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ce4aca6b72e56661cf88533bd18511e0da995822d9fd8babb13eafc60d002bc +size 10556 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/pack_options.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/pack_options.hpp new file mode 100644 index 0000000..30dd125 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/pack_options.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a04ca4824839ca7ba0417ac231a2174cf4320733a6f38c75fb74b7143aa0384c +size 10037 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/parent_from_member.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/parent_from_member.hpp new file mode 100644 index 0000000..cb71e14 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/parent_from_member.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e962a489355b7991ffb780b520272480f2be203cf9fe5fdc09d7f0fe2a4137ca +size 2005 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/pointer_plus_bits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/pointer_plus_bits.hpp new file mode 100644 index 0000000..dd80fca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/pointer_plus_bits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03f1b537cc07eecccdd693deb435f7a44c77613aa2e9aa553b0ecc57b1947501 +size 3752 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/pointer_rebind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/pointer_rebind.hpp new file mode 100644 index 0000000..0c3ceca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/pointer_rebind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2475d55e53380d81ba28b534fb556a9735300511139388ee5481109a3f768e2e +size 6306 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/pointer_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/pointer_traits.hpp new file mode 100644 index 0000000..3d69a22 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/pointer_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b3cf3c4db57e3ce32009983923add7195d4c1bb081fcf9f7f611c9716ec55af3 +size 13506 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/priority_compare.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/priority_compare.hpp new file mode 100644 index 0000000..f75a2a7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/priority_compare.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c0c8f35f72d37575344663ee7fd742e924b2abc49ce38a4061b9f39205592ec +size 1802 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/rbtree.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/rbtree.hpp new file mode 100644 index 0000000..230eace --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/rbtree.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:866732b530e823a779c9d981c062f8fd85c8b62308194586fc1740e60f236d06 +size 23937 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/rbtree_algorithms.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/rbtree_algorithms.hpp new file mode 100644 index 0000000..03cacac --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/rbtree_algorithms.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95f4f149a2eb7666d0920f05a85377cfd7a423ee0e2a687a34e2dbeac1afad40 +size 25946 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/set.hpp new file mode 100644 index 0000000..53a7afa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:425a19dc17aaaa18a6f03a214df273a5456f55dac5b19e275daa7f09cdc29ff7 +size 44135 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/set_hook.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/set_hook.hpp new file mode 100644 index 0000000..8170cf6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/set_hook.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a6e89429c5dcc45515ae279e15fbe37a23588f33a4082f48b1a9f465ffd3aec +size 10812 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/sg_set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/sg_set.hpp new file mode 100644 index 0000000..e070c1f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/sg_set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af034d1a356c13b2f6cddf43c30326833e53d6f390a427c705b99b18973694ea +size 45113 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/sgtree.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/sgtree.hpp new file mode 100644 index 0000000..2a6f7e1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/sgtree.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76811e66d7d0b9bdd60351d62ad3f199f0ccab89c9b3e62a7995c10855f0792f +size 41585 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/sgtree_algorithms.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/sgtree_algorithms.hpp new file mode 100644 index 0000000..9d77d44 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/sgtree_algorithms.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac417f95d3d2b62bf1bed41bc9b8c50150d2bd6417f05552e51399fa7c936953 +size 17515 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/slist.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/slist.hpp new file mode 100644 index 0000000..00dc5de --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/slist.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e638536983a62914ee055c501e841a4eacda85911d4d68712d51721f1f609c4 +size 88224 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/slist_hook.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/slist_hook.hpp new file mode 100644 index 0000000..61a02bd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/slist_hook.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:553149869396df951058b837a48290553e169441c526ccf2a16af02ea626f49c +size 10868 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/splay_set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/splay_set.hpp new file mode 100644 index 0000000..7b1f85c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/splay_set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c37fe5ced987b44b12a2cc63c592358fd7eb6d98228dad9bed3ed51c596f69a +size 46919 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/splaytree.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/splaytree.hpp new file mode 100644 index 0000000..9df49ee --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/splaytree.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a1a5a62fa067ec86d574f692fc514a4065dada63a5f0930154feb66bbbbe55c +size 28017 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/splaytree_algorithms.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/splaytree_algorithms.hpp new file mode 100644 index 0000000..be42510 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/splaytree_algorithms.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0766ed3c3f8df28c5bbcab4d19d310ac0bd8bd0ea8e0d422276d69568ead6850 +size 29751 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/treap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/treap.hpp new file mode 100644 index 0000000..54b6d71 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/treap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f45a19a8f12c74643e3e0f6d3946a55ff5962e5008f164f5c2f26c0dc6f6006d +size 57269 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/treap_algorithms.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/treap_algorithms.hpp new file mode 100644 index 0000000..2488c88 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/treap_algorithms.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db8fc49fdf5207ff14b03efdd60cdbe0c55711fee7699e548f41cbce5ddf639a +size 29213 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/treap_set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/treap_set.hpp new file mode 100644 index 0000000..2569a63 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/treap_set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ea2f91a45e0c81759ebc2cef9b674c912e31493f76946c9094653adcadb5a0e +size 45953 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/trivial_value_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/trivial_value_traits.hpp new file mode 100644 index 0000000..96bd5f8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/trivial_value_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef3a843789481810294836555134af26fa7938345c34a3865d4fb99c39ce8c37 +size 2381 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/unordered_set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/unordered_set.hpp new file mode 100644 index 0000000..9652b8a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/unordered_set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bdbe9712239d47adf6272955e1ead3b26a83e53fff95f7321b55d63604edf238 +size 45070 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/unordered_set_hook.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/unordered_set_hook.hpp new file mode 100644 index 0000000..b1af02f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/intrusive/unordered_set_hook.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:80e3540b962fdfcdf633773b02d7f0b02e06fb9f810eda923f28a8d09601f7af +size 16518 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/is_placeholder.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/is_placeholder.hpp new file mode 100644 index 0000000..d99aac2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/is_placeholder.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5732a33a6201c9377956813d6bb5826391a726c7093fe21991ac75c8977991d +size 634 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/limits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/limits.hpp new file mode 100644 index 0000000..118169c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/limits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a87ec55d61dcdc5d8cfd17820debce7928a88d3f62f99fce8aa456ba6f39b601 +size 6146 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mem_fn.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mem_fn.hpp new file mode 100644 index 0000000..bbe58c6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mem_fn.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a534ea3dc1a654f1821cd494470f04f70d5d01e5f1f2e5c36cec8707e4ef15c +size 596 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/adl_move_swap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/adl_move_swap.hpp new file mode 100644 index 0000000..f7ac843 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/adl_move_swap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf18c5da46ad1c7e632f10b96a7330b335623f36594cc067194d9dbd74815c2f +size 8061 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/adaptive_merge.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/adaptive_merge.hpp new file mode 100644 index 0000000..0887aa6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/adaptive_merge.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9cd47f940a724785b4cfa0034e4970c3de7ee040c61316eb7ab73a7a825705d +size 15696 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/adaptive_sort.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/adaptive_sort.hpp new file mode 100644 index 0000000..c5eed0c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/adaptive_sort.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2446a6b5551a3204e2c404c88b589cc3a2721b7e09aaa0d1eef96b125fa79082 +size 28466 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/adaptive_sort_merge.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/adaptive_sort_merge.hpp new file mode 100644 index 0000000..1e5e9c0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/adaptive_sort_merge.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e873dc080f04f4af218843acd1f8c4d7bd9972a674b43b003f4a1660b01e7147 +size 59949 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/basic_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/basic_op.hpp new file mode 100644 index 0000000..bb184d1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/basic_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e57c7987a84c4d37e9600e247af4f12f1819f01e8427c025176e91c6423cd21 +size 4637 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/heap_sort.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/heap_sort.hpp new file mode 100644 index 0000000..80aebd6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/heap_sort.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:84e53dfa9f6df189ce4049cafa593160ef8ab0b65238c8939a172d2af18f8da9 +size 3655 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/insertion_sort.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/insertion_sort.hpp new file mode 100644 index 0000000..5632dc8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/insertion_sort.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd979653033477ad7c8095fb9e9a16074f246bae10aa9a16d54da9672a148196 +size 4387 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/is_sorted.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/is_sorted.hpp new file mode 100644 index 0000000..2bc194a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/is_sorted.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d4ffc671099e654236445f11715a63d365ce86c67d5b45f2793434dd7d7db315 +size 1383 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/merge.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/merge.hpp new file mode 100644 index 0000000..0569724 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/merge.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8444975136efa3142703349de778fc32d6399ba30c6bf4caf9e2379d405c791c +size 17190 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/merge_sort.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/merge_sort.hpp new file mode 100644 index 0000000..0da2035 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/merge_sort.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5782eb631bfbeb214aacb718da7f360f68ddc25cdc7ae1cb7539d63f576630a +size 4601 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/pdqsort.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/pdqsort.hpp new file mode 100644 index 0000000..acfae17 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/pdqsort.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7426e68da19e942d3dd5aedf6e7d1b28a7d10d795daa72383e714a6883e2f18 +size 13910 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/set_difference.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/set_difference.hpp new file mode 100644 index 0000000..61d03df --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/detail/set_difference.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d9828ebe795c9c7120a7602d73d1de42e5bc0f0ebceece86b0e484a0b601e4a +size 7316 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/move.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/move.hpp new file mode 100644 index 0000000..1cd8ac7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/move.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b71d3cd47bf285ee53c19754eaf7a4eff521be3b49b9a0d8a6b0f8176c496f48 +size 4725 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/predicate.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/predicate.hpp new file mode 100644 index 0000000..17598fe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/predicate.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a289368a42a0c2d7ff78b9576184a999252f4d700bd993658a5a13295b6fd6a +size 1722 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/unique.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/unique.hpp new file mode 100644 index 0000000..4e8d363 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algo/unique.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:689a8d5cf485fbf0ea19e329f6c8a343d96dc895ac062a54abe52b18106f3616 +size 1896 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algorithm.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algorithm.hpp new file mode 100644 index 0000000..605dcff --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/algorithm.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:157d4907cd5e3131a0f4a7efaf51c766f4480819ee0c12226b22a7b5a2e8b4bf +size 4934 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/core.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/core.hpp new file mode 100644 index 0000000..5981203 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/core.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f42d48959eb3d4caf80477509da4e4f9a9ff84bc4e2ad250cc6ce4d0479eef3 +size 15369 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/default_delete.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/default_delete.hpp new file mode 100644 index 0000000..fa60df4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/default_delete.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7554c40b6d48ea15b998cc256d278cd2a5fa634125dc2ee067fa4e3e96748ca8 +size 7544 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/config_begin.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/config_begin.hpp new file mode 100644 index 0000000..5cb300a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/config_begin.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5da2f6f1dee2a4d128bbb3d3189c1861b34a979071dfaf2ded679f95715b7a26 +size 1008 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/config_end.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/config_end.hpp new file mode 100644 index 0000000..bec5b9a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/config_end.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:448a5c06871396d7bc0f2d8ac4d846c4139da36d944e90c7a99283e936d45f0f +size 473 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/destruct_n.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/destruct_n.hpp new file mode 100644 index 0000000..7242a19 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/destruct_n.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8cd5d4e99d852780569df23397f0d830db2f91e6ea4f648efc05ec4ca3992fd +size 1233 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/fwd_macros.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/fwd_macros.hpp new file mode 100644 index 0000000..0f2bc4d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/fwd_macros.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ed3578cbb31ba1cdf7cef76f6c3de1e37741abd50455c2c7b06b47054ee5c83 +size 42861 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/iterator_to_raw_pointer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/iterator_to_raw_pointer.hpp new file mode 100644 index 0000000..240fdc8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/iterator_to_raw_pointer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3fa4d572c214ff41dee704e59f5b354a540939a2706e27170229308661b5103 +size 1758 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/iterator_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/iterator_traits.hpp new file mode 100644 index 0000000..c4cea1b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/iterator_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:88e48c8642adda3342b4d470f41932d3269a9101e5625c78900bfa9275d99ba5 +size 2462 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/meta_utils.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/meta_utils.hpp new file mode 100644 index 0000000..62982c4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/meta_utils.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4578950892ec71f18ba81f1b8ff451c91b9e628bf21b8603d8ca290bcf4b21fa +size 15530 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/meta_utils_core.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/meta_utils_core.hpp new file mode 100644 index 0000000..efa9ba2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/meta_utils_core.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e419c336b1b2d747601603064c1885b26bbddbddfb94bc8c284727b16fd7a63 +size 3225 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/move_helpers.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/move_helpers.hpp new file mode 100644 index 0000000..77d2ab4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/move_helpers.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:870846ad2fb68a57168b80ea2d3e4d88689fe99710c069e2c0e68eecc1481771 +size 11990 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/placement_new.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/placement_new.hpp new file mode 100644 index 0000000..9a6c39a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/placement_new.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:711a959b81852bcf19a804bfed34f72ff2979442c05d558501c892c96799588a +size 884 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/pointer_element.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/pointer_element.hpp new file mode 100644 index 0000000..bdcca7b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/pointer_element.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6049330bbae3883fab64d2fbf5286c5374328299be384edc3436afab3d8bfc1f +size 4948 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/reverse_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/reverse_iterator.hpp new file mode 100644 index 0000000..9065577 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/reverse_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b49aa3294554153c3f4379e05095750b11b617f1e7cd8fcade69c689bb46804 +size 4729 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/std_ns_begin.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/std_ns_begin.hpp new file mode 100644 index 0000000..580aeb9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/std_ns_begin.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1669ddc5d448ab22499fafffd471d1c64ad1744fe49f014e85fd841c176207d5 +size 1344 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/std_ns_end.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/std_ns_end.hpp new file mode 100644 index 0000000..b5b1a26 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/std_ns_end.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a663bf31551458a61b65c53631245373e940a0fc59f169a1003c8290428bcded +size 604 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/to_raw_pointer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/to_raw_pointer.hpp new file mode 100644 index 0000000..d1507a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/to_raw_pointer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9ed24fe7bba6ee62b95de96869096573e0356ea229d55d4dfe58dce9d7b1e14 +size 1245 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/type_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/type_traits.hpp new file mode 100644 index 0000000..8c61364 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/type_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:852b1d10805a39f4ca889eec914827d04017482bd93026cff586ab4f824c6a14 +size 39897 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/unique_ptr_meta_utils.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/unique_ptr_meta_utils.hpp new file mode 100644 index 0000000..eeea9c9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/unique_ptr_meta_utils.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6bf495a004563d10f67c7fef2eec2b69ffb3f3cbcb9525441d5a9e88d6990819 +size 13362 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/workaround.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/workaround.hpp new file mode 100644 index 0000000..751b14f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/detail/workaround.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae454f6b7851dc4c3e48811b8818493eab40fb7d68d3374ca3c7e52f0c4d7241 +size 2444 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/iterator.hpp new file mode 100644 index 0000000..95aaadb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6dc1aa088cf334f672e7d8a7af9503d5222c9ac84d46b6a9229a3616ace55e73 +size 10385 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/make_unique.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/make_unique.hpp new file mode 100644 index 0000000..58be03d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/make_unique.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7e332bf53c04692d7652868c8867e28ea3578b53c26314e6ba5b5f9e76355a7e +size 8588 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/move.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/move.hpp new file mode 100644 index 0000000..c7a73d5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/move.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:905bbbded7462abe236685b7579a16f213476fb3a1b9d59456236ca971781a37 +size 1010 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/traits.hpp new file mode 100644 index 0000000..8ecc27d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cdb2cf2d368e6601d11c0a9e1b89406736442deb83b21318bfee84d7f734617c +size 2554 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/unique_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/unique_ptr.hpp new file mode 100644 index 0000000..49f2b36 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/unique_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b9f7243f666025866a566f007fb692a47aae07bb0c1c8352f790819742b6096 +size 39216 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/utility.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/utility.hpp new file mode 100644 index 0000000..d245496 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/utility.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af7d8e4a4fbbbea7a20ae0c65428d0e8850fc89d27cd7f81b21cf1e0eaadee8e +size 5406 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/utility_core.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/utility_core.hpp new file mode 100644 index 0000000..14293b0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/move/utility_core.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e49ed00398b570f264bea9f1b3c8b9b3a57362396c51a6c3ddc209a3b2daf54d +size 11145 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/O1_size.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/O1_size.hpp new file mode 100644 index 0000000..70f15ab --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/O1_size.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40a06d4f749e0c1404a2a59583dddbd24226ef93471c15b767c730ef71fc67d6 +size 1003 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/O1_size_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/O1_size_fwd.hpp new file mode 100644 index 0000000..d1f47bf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/O1_size_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d127e33b43b9f87605b4bc9c940681af8e4bf76a3616dbf27a8579f412fc4bc1 +size 559 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/accumulate.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/accumulate.hpp new file mode 100644 index 0000000..8b3ed41 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/accumulate.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:80915142292fd93b330eed16505642c222b96014e40f590520fc13e8955b4d1e +size 946 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/advance.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/advance.hpp new file mode 100644 index 0000000..8ae24f3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/advance.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c466196f8ca4798a4c6354472e138f003bbe7ea6ae9237258fa1758b5fffc6c2 +size 1955 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/advance_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/advance_fwd.hpp new file mode 100644 index 0000000..2d8ec71 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/advance_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d6acc3e465cbb29e8e45dc7ce490e3b9d0109939d2807d751bba194ca375bf1 +size 660 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/alias.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/alias.hpp new file mode 100644 index 0000000..11f4a6a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/alias.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cdfa2ff02983cb0fb30c3f16a60493599769b853d702e83b17db028225b93966 +size 452 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/always.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/always.hpp new file mode 100644 index 0000000..b2fed1b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/always.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e18e07eedd427a41d8317dadd64d3658c063f494720b343d6a9c2782555737e +size 838 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/and.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/and.hpp new file mode 100644 index 0000000..c82a0b9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/and.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab93bff72198182b820ee2cc113bc44a2d0af39545d5a02c106d782a2cc00aa5 +size 1593 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/apply.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/apply.hpp new file mode 100644 index 0000000..46e422f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/apply.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:587250723d6cea665a01bac6b28c0243b6a284fe02ec251298a4360675926e7b +size 6087 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/apply_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/apply_fwd.hpp new file mode 100644 index 0000000..8a32e09 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/apply_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5025b30bf1299fa05c599312c9d02c7b023c03bbe85edf305fe502bafbd71da +size 2663 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/apply_wrap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/apply_wrap.hpp new file mode 100644 index 0000000..1d445b1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/apply_wrap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30375a817bb6ebf062cd2858a76ec568347b22c9b86f6071ededee1b79562d10 +size 6177 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/arg.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/arg.hpp new file mode 100644 index 0000000..eb435ae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/arg.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02335a98117d161983fb9a30b0f77b1e3178e927fb9ae3abc173c15192159d3c +size 3216 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/arg_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/arg_fwd.hpp new file mode 100644 index 0000000..6a904fc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/arg_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d4c5805d025a2e07b6bc03ebb520accdd31cfe41768cfca9829cbe1f4125d28 +size 711 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/arithmetic.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/arithmetic.hpp new file mode 100644 index 0000000..9d74928 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/arithmetic.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9aba8c2ea7ef201c0a022292ee264ccca2890c2903b91fc3ca7ceb83b8abb6c8 +size 665 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/as_sequence.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/as_sequence.hpp new file mode 100644 index 0000000..02a16d3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/as_sequence.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e3461aa59d26aa12bfc17edea7785740d451203207995d72e03d9d7e78f5a9c +size 879 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/assert.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/assert.hpp new file mode 100644 index 0000000..21b5198 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/assert.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f1162bb402a06e235c56049606ac866362faa591f254bc53f69f4c4df8dc66a +size 14739 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/at.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/at.hpp new file mode 100644 index 0000000..bb98ae8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/at.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8143c6adde38c7c0935ab4d15961877dd8b33174637b142228988d6b4938db4f +size 1201 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/at_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/at_fwd.hpp new file mode 100644 index 0000000..29fa174 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/at_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc32acd79480d78e0980cef4b4e54176035335c0b25cb1f4d5f2f5c1335484e2 +size 546 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/O1_size_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/O1_size_impl.hpp new file mode 100644 index 0000000..8e7bdb2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/O1_size_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4be7ed0a8cc3176af832acb6659728754c56945a4f01ea8ff68282e628b9027e +size 2104 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/adl_barrier.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/adl_barrier.hpp new file mode 100644 index 0000000..5a9b3c6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/adl_barrier.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28814ccd677294dfb0fd2d9a89153206e40dead79a96319fdf9bf951d402bf9c +size 1559 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/advance_backward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/advance_backward.hpp new file mode 100644 index 0000000..c927a8f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/advance_backward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34ce63a6d5d78f88c3e0b5cbbd54a543fed89a92b63b97c784ef50e0e4c1c102 +size 3419 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/advance_forward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/advance_forward.hpp new file mode 100644 index 0000000..e7d5727 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/advance_forward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb3632ca65632df6b7a3c3a319ea3292552141701795acf3260ff54282f38e86 +size 3338 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/apply_1st.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/apply_1st.hpp new file mode 100644 index 0000000..da0d484 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/apply_1st.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a7d50a83dad8aa45f7331618fb198c86f6fe99483dccca9db6e759652b9696a +size 731 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/arg_typedef.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/arg_typedef.hpp new file mode 100644 index 0000000..5b392e7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/arg_typedef.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:271a886b775714e3fe472e36867eb8de511b844ef344677f0075d81d3e48bceb +size 776 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/arithmetic_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/arithmetic_op.hpp new file mode 100644 index 0000000..6c3a6d7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/arithmetic_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df3905c6777bc27bcd55c42a65ab05075ecaa28e4727f9e850adb6931c3d9e5f +size 2441 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/arity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/arity.hpp new file mode 100644 index 0000000..fa4ac0a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/arity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:faa7d7ad0317c59096b66583e4e4f2dc5b03e41b452c6c4d55f887852e98b8ec +size 1095 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/arity_spec.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/arity_spec.hpp new file mode 100644 index 0000000..9c35431 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/arity_spec.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1dcfb0143f18a92af5e7daf2900831f3470a31e40cb0727fb274dc86760aaa4c +size 1832 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/at_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/at_impl.hpp new file mode 100644 index 0000000..233f171 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/at_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1bec2e9c3422ea9e10e23041931ef75b6d5dcf51c13389f661a86251c48c7f00 +size 1091 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/back_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/back_impl.hpp new file mode 100644 index 0000000..9e13abc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/back_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3b1ff1036279d7865309b06cdc5603cc61f34bac896a760356fa1c936262ac9 +size 1121 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/basic_bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/basic_bind.hpp new file mode 100644 index 0000000..4159272 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/basic_bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2773857d56c28dfd791e45b6bcc41761ce8acf4e1aa425b56e6de41b6ffee9dd +size 550 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/begin_end_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/begin_end_impl.hpp new file mode 100644 index 0000000..85cc2cd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/begin_end_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4822b6ae1e478f69fc2f1ce6d7b2eafa4e64b7ea573a998e6cf5c8a4e98996ba +size 2643 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/clear_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/clear_impl.hpp new file mode 100644 index 0000000..7fba918 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/clear_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f43aa6c6786a806b2fb1400d2ad83e32e678f8c1a9bffbff9687d90606c87cf6 +size 827 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/common_name_wknd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/common_name_wknd.hpp new file mode 100644 index 0000000..55abe29 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/common_name_wknd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b065568c976ed60cb043806b8a53d0393bebb5ec68a4eb27834c14457450632 +size 873 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/comparison_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/comparison_op.hpp new file mode 100644 index 0000000..b4d6f3f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/comparison_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b34d2c80f52dded1b913a41a3d3eb9ffe6d9cd85e2084bc9a107e65376e23d9b +size 2153 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/adl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/adl.hpp new file mode 100644 index 0000000..230f71c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/adl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9925bac775bb4f047a9bffe62ad78cb3e758f96a36944154b5908878c807b08c +size 1416 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/arrays.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/arrays.hpp new file mode 100644 index 0000000..8d1be7f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/arrays.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e5606f2db867c019059c174a8fba732ebb380e3e03c35bf48eb1d2cf3f0366cb +size 829 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/bcc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/bcc.hpp new file mode 100644 index 0000000..341e4aa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/bcc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41d9e982226decb468ee6f06ced5095065806fba76c70733740249118e5bb572 +size 801 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/bind.hpp new file mode 100644 index 0000000..4018aec --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3fc50506b59ea546ec7d871b81716710476a1cfe5dddb2565faa541466dc7041 +size 898 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/compiler.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/compiler.hpp new file mode 100644 index 0000000..fe08aae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/compiler.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b8517de8c73498d197b6bcf0d00e5a38772b7bda20f32790451b70d1489832a8 +size 2134 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/ctps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/ctps.hpp new file mode 100644 index 0000000..5850ffb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/ctps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:647db56e21aebe52eff988315453aff1bdc55c441b27f94e183636bf7c7dbe96 +size 823 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/dependent_nttp.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/dependent_nttp.hpp new file mode 100644 index 0000000..73235d1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/dependent_nttp.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74357aa79278eba14434db8003bf9a72b19ca798d193e4ebf20dc0b229fe7228 +size 1130 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/dmc_ambiguous_ctps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/dmc_ambiguous_ctps.hpp new file mode 100644 index 0000000..481f72b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/dmc_ambiguous_ctps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d977c60e0033701b04651a0c865ec27472db4ce9eb8b941d394ccb7c38b138bb +size 736 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/dtp.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/dtp.hpp new file mode 100644 index 0000000..15b40c8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/dtp.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3726a59fd1c71d3ea36a3c87269724ab0eba128f35c7bbb061416f0491733f2e +size 1571 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/eti.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/eti.hpp new file mode 100644 index 0000000..e5e295f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/eti.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7cc8dd5b9009cd8af39c18ef8ae8d2bb210d69197b39f9bbe66cbc7e94e82f87 +size 1235 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/forwarding.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/forwarding.hpp new file mode 100644 index 0000000..937ef7b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/forwarding.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:539163823886431eb657622930b4d0b93c3c5ac316e3823995fd0157e15c830c +size 721 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/gcc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/gcc.hpp new file mode 100644 index 0000000..a9e6778 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/gcc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78f78e3e42144452a092c06969eed8723b081a9faf0c1860013d774c63f83179 +size 591 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/gpu.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/gpu.hpp new file mode 100644 index 0000000..c4ca991 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/gpu.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5502f35db9b0ec14c1ed38caa7efc2b7baa123600b5533d8e5f91ef99de11bb2 +size 666 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/has_apply.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/has_apply.hpp new file mode 100644 index 0000000..899560b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/has_apply.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:57a0a58f43e03b4e7435db61ba0801dbcada1c522b8905da39b70edfa7df3299 +size 905 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/has_xxx.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/has_xxx.hpp new file mode 100644 index 0000000..c04e90b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/has_xxx.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19e2087e31f5302aca7c9930f01963c414504a1fa2f416b7d9aa1a65ca36aac6 +size 973 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/integral.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/integral.hpp new file mode 100644 index 0000000..101d4b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/integral.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5490eafc60e0eca258a0767371fe76e85d4ee075261a55774653edbcc8fa80cc +size 1045 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/intel.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/intel.hpp new file mode 100644 index 0000000..0af7451 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/intel.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ce4ace676be390de349b31f000af18d49c953e12ffc91c882ee632f1bb4cc2a +size 511 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/lambda.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/lambda.hpp new file mode 100644 index 0000000..2c82444 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/lambda.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ec9f4e943fb91987e5156a11ce26184d9fbaa426f79e5ad3b6aac148486a114e +size 910 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/msvc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/msvc.hpp new file mode 100644 index 0000000..3f22288 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/msvc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62eef1e28b4ce6ca35d07ece37b8bb455289f6ac4c774ef193a4e5741b0d06e5 +size 500 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/msvc_typename.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/msvc_typename.hpp new file mode 100644 index 0000000..d0ab2bb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/msvc_typename.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b5029e579609be6e766019d5d306e72bd1db06bcc616c3abc661f6bc8b737a5 +size 684 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/nttp.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/nttp.hpp new file mode 100644 index 0000000..03e68ce --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/nttp.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9073ecf730c3a0993cee681ad5a2cef4669cb13e0afd640de26861d38852715f +size 1009 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/operators.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/operators.hpp new file mode 100644 index 0000000..4473452 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/operators.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02874c1d4c566bf7fce46e554241b17c208528d40832741f2eeff799c41f4280 +size 1069 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/overload_resolution.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/overload_resolution.hpp new file mode 100644 index 0000000..3f58a28 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/overload_resolution.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4494fcb883f35349c2fd58cc04feb2d6fd354ec8368b8a4d84e5449253f231f +size 818 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/pp_counter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/pp_counter.hpp new file mode 100644 index 0000000..4ffe265 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/pp_counter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3bd7e219c68e112ead0278404c1a9dc507e8710cb7fd23195d61165c95638ab1 +size 713 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/preprocessor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/preprocessor.hpp new file mode 100644 index 0000000..21b2243 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/preprocessor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8050169b5c3d262396d537c4462d0cb4a7071a98309f121efc9a63e5c16caa4a +size 1109 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/static_constant.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/static_constant.hpp new file mode 100644 index 0000000..4fb82ef --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/static_constant.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aca83823971e4b9e0db4deb81dd96e79b2851e00ded38e7a306bbf8f5d268ac2 +size 680 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/ttp.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/ttp.hpp new file mode 100644 index 0000000..2ee283f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/ttp.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b023d0b51d1ae092e5b5226f6558211ffc5258b5f55954a88f3ff3263d90240 +size 1168 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/typeof.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/typeof.hpp new file mode 100644 index 0000000..9a036fe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/typeof.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8bb385b553bc6481cc5fc4e5e2796e30db4358013f139d51ad1d3243409913fe +size 961 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/use_preprocessed.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/use_preprocessed.hpp new file mode 100644 index 0000000..9e53189 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/use_preprocessed.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ef95ff5065ffa6144d9c562d71f082ac8091b19ecf3670b7682b18fb9d921d6 +size 525 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/workaround.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/workaround.hpp new file mode 100644 index 0000000..40f3a54 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/config/workaround.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:57b4a97e529b168efdeb908260c55002e2569c58c98ea23eff68448dca92a4fc +size 497 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/contains_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/contains_impl.hpp new file mode 100644 index 0000000..1a57c56 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/contains_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0273c6d51fcaa928bf01e7e157e03cff606a7bc9336402da8adf4e2ac5f72abf +size 1572 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/count_args.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/count_args.hpp new file mode 100644 index 0000000..79bb75b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/count_args.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9960bd368e3e6a4a58e63497a60d2ef3d93a404837521b4aaf1afa5cb90fd617 +size 2937 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/count_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/count_impl.hpp new file mode 100644 index 0000000..6b74545 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/count_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0063a15ea2b5074972ad8b5248488f7b721f3968551002c0c9e8b4e413966c0a +size 1173 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/empty_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/empty_impl.hpp new file mode 100644 index 0000000..a275284 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/empty_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ba30f4f6da6aee65c5e27eca847c13fddd988e1e03edfe11ce0f5bd81780eca +size 1059 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/erase_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/erase_impl.hpp new file mode 100644 index 0000000..e443445 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/erase_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b07906f60cfa1989444253d71253f5c559844bd4d8c1bc35398532a81445471e +size 1767 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/erase_key_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/erase_key_impl.hpp new file mode 100644 index 0000000..05e6683 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/erase_key_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d241a158e9a860ca593d88f470b409a18b90df6c8d613184f7031fced440db1 +size 749 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/filter_iter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/filter_iter.hpp new file mode 100644 index 0000000..c4ea598 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/filter_iter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5464e770eaf8291cfc1ab18afc0fff51c05536f23d1951b97cc665dc14d54c5a +size 3017 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/find_if_pred.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/find_if_pred.hpp new file mode 100644 index 0000000..da9a27a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/find_if_pred.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:605af1ac25a01a935e6d2c9e979b1ba86ca1776da6baaf8f12189905ba862770 +size 756 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/fold_impl.hpp new file mode 100644 index 0000000..09ba669 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3769cbc4b6339d0c6c2c9864c2b7606770dfbc758ba093a58dfe9419735c20a +size 1271 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/fold_impl_body.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/fold_impl_body.hpp new file mode 100644 index 0000000..b62d0fb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/fold_impl_body.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f66741413b2173ca02eaf6b7d03496fd69e1db4bdc9a1e54322e14f921b7ebe1 +size 8938 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/fold_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/fold_op.hpp new file mode 100644 index 0000000..8921084 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/fold_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07440ffece526c64690a52e50fd47d5d101c54cb0dbb0c8e11d60d881c385c1a +size 822 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/fold_pred.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/fold_pred.hpp new file mode 100644 index 0000000..8663da7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/fold_pred.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee570a6d5f1b9777455d16b7cb677088a8ebdce6ab8f3c41d0dae648d7ebc3f3 +size 764 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/front_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/front_impl.hpp new file mode 100644 index 0000000..f07409d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/front_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e979b5c38d8a720a0530dcbfaa14a1fea8f6e34d13f9c6a1dae8d2a9d8326f9 +size 1032 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/full_lambda.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/full_lambda.hpp new file mode 100644 index 0000000..3cf39dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/full_lambda.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc55ed5e16cc10217a6953b1cb90ac3c9fc254d82637122ba50089958f439651 +size 8796 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_apply.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_apply.hpp new file mode 100644 index 0000000..8af4e75 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_apply.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c63998ae37b2a7922f66845fb6fae1fd7aa9658ec0855a3a99aa3d68d67bb8e +size 767 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_begin.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_begin.hpp new file mode 100644 index 0000000..a4cc0cb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_begin.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df7faf3ad4060d3ff0685cbe0de686187adf57b24e8960f35900bf3969221fef +size 580 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_key_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_key_impl.hpp new file mode 100644 index 0000000..53f14fb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_key_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a2fb65038033de53a0f3fdef0f2090c3b643052fcc3518056a95d142de036e2 +size 856 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_rebind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_rebind.hpp new file mode 100644 index 0000000..cbbf8a5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_rebind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f35d586a5864947c5cf01241578969cc7005f899e4c3059c035ab0f3e527e9b5 +size 2563 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_size.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_size.hpp new file mode 100644 index 0000000..fb61c53 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_size.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c2e82715f4adb91dd433a659dda944410f520036929252680e1274c706a5a93 +size 553 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_tag.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_tag.hpp new file mode 100644 index 0000000..8a03e73 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_tag.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4bc2cf30e239b7cd12311273d61747e44f7c730058a40c955f36fd8685bdc5ba +size 571 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_type.hpp new file mode 100644 index 0000000..548c7dc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/has_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:851cccbd90893edcbf92f1834c8a2bcfe1896c8a4639b4c4ffc54261656eb002 +size 575 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/include_preprocessed.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/include_preprocessed.hpp new file mode 100644 index 0000000..b55dcf2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/include_preprocessed.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:794b0971976e1b15dc6f55c236347d61e3eacf8f56334934797b184514767a86 +size 1333 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/insert_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/insert_impl.hpp new file mode 100644 index 0000000..ab3be22 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/insert_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11f35bf597934768b2fd33bc0f28107e48479c8ffa7aa4571326c9f5c85750e8 +size 1714 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/insert_range_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/insert_range_impl.hpp new file mode 100644 index 0000000..b101971 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/insert_range_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f1a434bbfc8a310cedd1666c891e53024041282df5e987ac0c0e34dba8adeecd +size 2225 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/inserter_algorithm.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/inserter_algorithm.hpp new file mode 100644 index 0000000..db4149f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/inserter_algorithm.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f557102c3628d7c1afff2b39541855ce6034a617cb050bbc678527951c57039 +size 4816 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/integral_wrapper.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/integral_wrapper.hpp new file mode 100644 index 0000000..df070f9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/integral_wrapper.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11a7707ca0672ba04948e3c16439cf0dad5cf68466790053a299f3e0f14dfdae +size 3519 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/is_msvc_eti_arg.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/is_msvc_eti_arg.hpp new file mode 100644 index 0000000..f1b1082 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/is_msvc_eti_arg.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa6d5ff41d835623d1d6accdc5b43a0d367e4547a9a766eabf414d4319bcf49d +size 1318 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/iter_apply.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/iter_apply.hpp new file mode 100644 index 0000000..bbb48f8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/iter_apply.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac3ab1f8ccfcd608a47e81b03d83dfa59ce7edd74ee9e014e0365e2de3c3f8bb +size 902 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/iter_fold_if_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/iter_fold_if_impl.hpp new file mode 100644 index 0000000..fc967e3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/iter_fold_if_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:504cc50396ab3fb279125964afae98e737f77788b2019557833c8e5d7e46753c +size 5848 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/iter_fold_impl.hpp new file mode 100644 index 0000000..6b593d6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb1e3d1f19fc2970d7f9cd1eb3d7c487e8d19ad5bbdfb95223ffb89eae7c7109 +size 1240 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/iter_push_front.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/iter_push_front.hpp new file mode 100644 index 0000000..9c1e426 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/iter_push_front.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fde88965168ff488013f9e09870a6c2d45830528fd265372e3066bd018db054a +size 771 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/joint_iter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/joint_iter.hpp new file mode 100644 index 0000000..6dd0e94 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/joint_iter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:72af6017555d0bee6491ec4072cfe8a373dfb65539af85ff75ed2029829a0be3 +size 2877 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/lambda_arity_param.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/lambda_arity_param.hpp new file mode 100644 index 0000000..c2f8008 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/lambda_arity_param.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82201ea0f099ce7e82f5d4c7927bfbde4622183ac2d0e464824ccbd10ffe83c5 +size 696 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/lambda_no_ctps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/lambda_no_ctps.hpp new file mode 100644 index 0000000..1206f9f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/lambda_no_ctps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1e9d5db37494af834b2563056fffcdacd3adca41a8bb525a3d98b686b066df2 +size 4941 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/lambda_spec.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/lambda_spec.hpp new file mode 100644 index 0000000..3e2722d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/lambda_spec.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:942995a26c98a6bcde38c44e2c2963b4337e5cb2f4df63f0e83c17e63e7f1b3f +size 1214 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/lambda_support.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/lambda_support.hpp new file mode 100644 index 0000000..6964c2c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/lambda_support.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c3344a92747cc59a328ea5540dda6b3c438463450699973156ebd0e01b209d78 +size 5360 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/largest_int.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/largest_int.hpp new file mode 100644 index 0000000..f7f29a4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/largest_int.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58937436c77e3ac4c8fd2e74adea3e5f63c964e8ae40f848e477dd897f745504 +size 1979 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/logical_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/logical_op.hpp new file mode 100644 index 0000000..c26fe7b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/logical_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56e299e3830a2c7b3a51c1c05136fc7ba631f4717d82656a97296d8d4463eaef +size 4535 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/msvc_dtw.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/msvc_dtw.hpp new file mode 100644 index 0000000..34c3f09 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/msvc_dtw.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0608de0ab8b1c1427d5ac35c8f355f13f88c19011855b9bb1082477d0f127389 +size 1742 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/msvc_eti_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/msvc_eti_base.hpp new file mode 100644 index 0000000..7bb7c5b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/msvc_eti_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2cae124f0900ed31baa4c4b101adfaaed0865826aefbcf15399e8a2aa75e74ca +size 1668 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/msvc_is_class.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/msvc_is_class.hpp new file mode 100644 index 0000000..1e3bf36 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/msvc_is_class.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62906f70658a2695fcfa56026eb43288ff6cffc8cbfb3be336e269478649cecd +size 1485 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/msvc_never_true.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/msvc_never_true.hpp new file mode 100644 index 0000000..69a43dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/msvc_never_true.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14d46cdb7de3df47a25462d2ae9174c2b029c74c4d3863099a834373672f54b3 +size 743 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/msvc_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/msvc_type.hpp new file mode 100644 index 0000000..1dd0656 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/msvc_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb544779c6e481f1c184ffdb77ea798177e87ab344fd8635713efe5122f8b1a3 +size 1207 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/na.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/na.hpp new file mode 100644 index 0000000..938d383 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/na.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1a47d9e372cb112a19823d8ddf5c94ee8b10138d28aa868239ed869ac34c0bf9 +size 1645 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/na_assert.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/na_assert.hpp new file mode 100644 index 0000000..4e4ed04 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/na_assert.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:459002c840d1c3a98bb7bf5d217d6da1295a2001742e9d515b63ffe054459bbc +size 958 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/na_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/na_fwd.hpp new file mode 100644 index 0000000..32929fc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/na_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a632e53451b552d1abc6c9118f407a083f8f9ffdd093503de79024fd4b163a04 +size 673 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/na_spec.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/na_spec.hpp new file mode 100644 index 0000000..9a615ed --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/na_spec.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0d448d10de6efb7bad24e344ad386037eb667137c1eebf6c3f0b406cacde540 +size 4449 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/nested_type_wknd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/nested_type_wknd.hpp new file mode 100644 index 0000000..3fe3255 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/nested_type_wknd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b91a2a88e5bbbe78da3a9f5447b31a9af46a07e9852d1ba8a722360d285f9422 +size 1264 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/nttp_decl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/nttp_decl.hpp new file mode 100644 index 0000000..fb0e4b4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/nttp_decl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:809fb409f57a2a5f679758b8ceb5f31ab1c15789217c36c427a7e944cbf133e5 +size 844 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/numeric_cast_utils.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/numeric_cast_utils.hpp new file mode 100644 index 0000000..ad285fc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/numeric_cast_utils.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1098c0dde9eb148c63f2e5aef52fa4f643601ccf8f19908bf95dd56ef7732a4e +size 1763 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/numeric_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/numeric_op.hpp new file mode 100644 index 0000000..e24c4b3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/numeric_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41bb548b53aa7ca69201812481e19611081544cbacb56ffa9e660f8190fbbfe1 +size 8489 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/order_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/order_impl.hpp new file mode 100644 index 0000000..1a202e0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/order_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b882f1f38e2db57d8a3a80d96584315285ad30cd119daefcafc06546ff6d6b79 +size 2044 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/overload_names.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/overload_names.hpp new file mode 100644 index 0000000..e59d200 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/overload_names.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e64052d9c9e2410d0492e557b30e48e51744cbb1a07d6daa3e6d767e325799c +size 2029 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/partition_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/partition_op.hpp new file mode 100644 index 0000000..6e34d7b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/partition_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:293a725b401c050d50fe4b7395e0f01cc7dd189eae781fbbe572f2ab9d835e27 +size 1390 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/pop_back_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/pop_back_impl.hpp new file mode 100644 index 0000000..b79dc08 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/pop_back_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:23640eae7f45aa13fee846d583171a0a3c885226801b1ac5e913ff4ce5ab0681 +size 804 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/pop_front_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/pop_front_impl.hpp new file mode 100644 index 0000000..d2c768b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/pop_front_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b302de66272875f92b1eea419dcce5ef52b94a8c6ac54c99f6599966bd5db00 +size 1078 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/advance_backward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/advance_backward.hpp new file mode 100644 index 0000000..2d0dcab --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/advance_backward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1166597a0c2defd1765edb8eddb73642216deb0f6720825ca5670df037bd3d37 +size 2202 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/advance_forward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/advance_forward.hpp new file mode 100644 index 0000000..85680a3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/advance_forward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:071bca20bda9543f3b7b1016466fcea88d2eb4a29d6fba55aef6ee2509c6d3cf +size 2182 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/and.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/and.hpp new file mode 100644 index 0000000..aadb819 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/and.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5556119a1511a8e280193107ca726435cfd290bd858201ed33ef883d2bd04b30 +size 1258 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/apply.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/apply.hpp new file mode 100644 index 0000000..e536c24 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/apply.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a371bdc8561c9236d6b303c7dba2613de6b28e8f9cb6093314dd70d5b43feabd +size 2745 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/apply_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/apply_fwd.hpp new file mode 100644 index 0000000..fac5149 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/apply_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e1a30be64abdd6ee27b3262e0221d33f2cb6ee2f70064eda2fe60aeebdf9cebd +size 973 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/apply_wrap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/apply_wrap.hpp new file mode 100644 index 0000000..60ff644 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/apply_wrap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c251cb230ac4f4beb69c531dba039ff4ada9366874bec42b028966ad7570702c +size 7078 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/arg.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/arg.hpp new file mode 100644 index 0000000..5fbf989 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/arg.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61a0bdff0b1c7dea9c06b1f39fe7d49356757fb05577565d988cbac828bbf6b6 +size 2690 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/basic_bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/basic_bind.hpp new file mode 100644 index 0000000..2755224 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/basic_bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e66e83b8a67d3a59c8a4a88bce2e7b5d5dac5e76a01ad7363853d3a75ad3ace5 +size 7118 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/bind.hpp new file mode 100644 index 0000000..0547b99 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0cf1f1740bd1ed7343d4d86099219c3732e272023db4e99927224dca2889c852 +size 10420 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/bind_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/bind_fwd.hpp new file mode 100644 index 0000000..11a0884 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/bind_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:629bae6e8eb9b55aee5f759d1a03ba9642e361da50a097e616097b25c8d9f1c0 +size 823 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/bitand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/bitand.hpp new file mode 100644 index 0000000..aa1cd2c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/bitand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:feadd14f26318a5371db4da3e16f1a851e020175a8c5667cd2ff95d79fa29f5b +size 3209 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/bitor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/bitor.hpp new file mode 100644 index 0000000..ad8db90 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/bitor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7ea8d47577361c3721a7e434e59c6b56a780ee50212043a4da3b9d1052338f5 +size 3179 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/bitxor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/bitxor.hpp new file mode 100644 index 0000000..a4a1362 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/bitxor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77c1e2c70776f51badbd56bb10ad5605e97d0f39fec748de90289757259a8639 +size 3209 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/deque.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/deque.hpp new file mode 100644 index 0000000..cb74ef1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/deque.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bcafec5930ca417afa6463e127f5ea5107f9be2e4a661929d5388936e78126dd +size 9724 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/divides.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/divides.hpp new file mode 100644 index 0000000..56b317e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/divides.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d54b58f0efdec9bf15adef8da236d73d5c86cbbd34de1f1d10f533a1b67b90cd +size 3192 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/equal_to.hpp new file mode 100644 index 0000000..bde352f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:438b625e58dac03bd60e4d6bf95c2d7f9cc14bc142638a46612af1bcceb22d34 +size 2098 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/fold_impl.hpp new file mode 100644 index 0000000..41742ac --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c548fdaf9b108337c82c0755f118c38a034a56cdf1237735bf921c664710081 +size 4350 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/full_lambda.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/full_lambda.hpp new file mode 100644 index 0000000..74be77a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/full_lambda.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07757c28215320f0330ed487d5a81fe8fac922107e5678b8eba13528cea1030e +size 11506 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/greater.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/greater.hpp new file mode 100644 index 0000000..fab079e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/greater.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e9d6192340167d3f4deee06f1b9e726bc7f3c13cfa825412ad0a26a0c9b174fc +size 2081 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/greater_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/greater_equal.hpp new file mode 100644 index 0000000..db34154 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/greater_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5cbde03a953532a1a85cf85230d6fbec70a01d6b17640ef394ce391383efcf03 +size 2172 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/inherit.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/inherit.hpp new file mode 100644 index 0000000..6609811 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/inherit.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c5ae60cc2e05bf0a1c4d2394bf5630113a70cf90fd407f061f10c5e9950e558 +size 2750 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/iter_fold_if_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/iter_fold_if_impl.hpp new file mode 100644 index 0000000..368bbbc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/iter_fold_if_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11cd0305f5ffe0f40d03e75725673b1633158717b403b893655283a6e5a31773 +size 4270 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/iter_fold_impl.hpp new file mode 100644 index 0000000..2c1f304 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a104eeae82e6362a7179ff7e93e6310a3502da16d333f800d7411abd3ecb13b7 +size 4154 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/lambda_no_ctps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/lambda_no_ctps.hpp new file mode 100644 index 0000000..6334fca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/lambda_no_ctps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:483ec169cd5b1fa0ad58904197f94a6314556fb7a81e02f6c2778427c52684f9 +size 6473 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/less.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/less.hpp new file mode 100644 index 0000000..a90b27b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/less.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8c659e3c8ff5fda4bad8d241266e6bbbd7e0508b9703926bedebdc13fbc46bf +size 2036 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/less_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/less_equal.hpp new file mode 100644 index 0000000..5c4e4e3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/less_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb5d9c6093f5dd829a52fc4708edd33e6fbd4169355e8bc5a7e1818a1740a617 +size 2127 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/list.hpp new file mode 100644 index 0000000..6d1fd74 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0019a35a151e4ca972999b4677b3c8b516e2b3eba4d877dbfdd1af857cabad8d +size 9617 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/list_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/list_c.hpp new file mode 100644 index 0000000..5cfbdae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/list_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8eb00b77a1c9e1703ffa7615acb145b0a1ece1a8d83186a073d384e4537c6761 +size 10718 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/map.hpp new file mode 100644 index 0000000..bddbcfb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4fe413b5a0125dd27ace1a1ff21db30d66967b6f6b9ca94ded4bec0737c0a2f8 +size 9552 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/minus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/minus.hpp new file mode 100644 index 0000000..a05335a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/minus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ee365b2ca4ec003c3f052da32d6aa54835c459dbfd1ecba3609b1bd29f45a9d +size 3132 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/modulus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/modulus.hpp new file mode 100644 index 0000000..d79f28b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/modulus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:079a3aa5d1d496998faeb0eab8ffda31719d899c8d80ce329d0ad90069d977e1 +size 2294 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/not_equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/not_equal_to.hpp new file mode 100644 index 0000000..b38cf77 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/not_equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4cbf3ee21aedbabf64b2891ee00c07c4cfbd28d928375a0810d1acd4602ffe5d +size 2157 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/or.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/or.hpp new file mode 100644 index 0000000..2a52cc0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/or.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cdfe83ee0b8ac57ece2fe81825462696df4c0e77c067940b3dca2d2146bcd675 +size 1259 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/placeholders.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/placeholders.hpp new file mode 100644 index 0000000..f236edc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/placeholders.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:961f77c7b2b7170fed2aa1d947a579f25b4b24d1676da0bf2f926543610ebda1 +size 2212 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/plus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/plus.hpp new file mode 100644 index 0000000..96edbf6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/plus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:797978593b7742edbc86b23e875c05eb2df3eecbd66dfc6f1a040cd1032a5f29 +size 3102 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/quote.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/quote.hpp new file mode 100644 index 0000000..617e39c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/quote.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:43d4cb8e98d11f4c8f6bdfb7111c2deec9e112cff813877e660b17cb8641a93e +size 2346 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/reverse_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/reverse_fold_impl.hpp new file mode 100644 index 0000000..f2985f1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/reverse_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:400b591c140160c1dc04e3dddc7b858c05176b7b2e35e270ca08843025cf0cf9 +size 8866 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/reverse_iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/reverse_iter_fold_impl.hpp new file mode 100644 index 0000000..1aa0975 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/reverse_iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d0d8aa3172efec1a20cdb6d0ba1c707c1819da79df7cb1d6ce4aac96e1bd558 +size 8246 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/set.hpp new file mode 100644 index 0000000..6dcaef5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64343393f717fa150253fb96f04246bd424d2d158b3c44ee89ef65ad6a098189 +size 9552 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/set_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/set_c.hpp new file mode 100644 index 0000000..144e8cc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/set_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96ed53cbd48bd217b40bac7e48d2a664a5b8335538638836159292d037c54251 +size 10653 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/shift_left.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/shift_left.hpp new file mode 100644 index 0000000..7304e70 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/shift_left.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21ebb2f86fe31d3a09907e197fe777a683d3ea48111846862041d74a64202147 +size 2253 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/shift_right.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/shift_right.hpp new file mode 100644 index 0000000..1617353 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/shift_right.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6d45cb6a9703d6fa3a3e9d15759cdb2428e431f52a76fc27430bbe795b0753dd +size 2268 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/template_arity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/template_arity.hpp new file mode 100644 index 0000000..e9fef38 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/template_arity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f3bbe15c869d28bcd291c8965adf9e0d1dd4f616c54b631f264e8fc1cbfe4c0 +size 763 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/times.hpp new file mode 100644 index 0000000..cae42e9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b95f3b35b2cd3f09b91d073297172cf5579d19eb5bdbee52ba2e4ed0c7c85a4 +size 3132 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/unpack_args.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/unpack_args.hpp new file mode 100644 index 0000000..795b92e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/unpack_args.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb386ff1d89fff88f38aafe045a0091e78518459eecf365af6df32c4f5ea5ce7 +size 1986 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/vector.hpp new file mode 100644 index 0000000..6398407 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:192cb1570ea17a5f871b550a9311010d4e615d5e1876718c4ebde2ce42917640 +size 9747 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/vector_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/vector_c.hpp new file mode 100644 index 0000000..f143b3b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc/vector_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8071ea880d61813a0b4baf926ee675fcf31a3042f4e88c551664c746dda11e8a +size 12238 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/advance_backward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/advance_backward.hpp new file mode 100644 index 0000000..7c8960e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/advance_backward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4c03c83e9e3950e42ee825cb10d94c3e54af988a8bf5517a44265e8e56b4be3 +size 2206 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/advance_forward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/advance_forward.hpp new file mode 100644 index 0000000..913b5b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/advance_forward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50d41920b3f3d73804897c16f790f269609c2684db7bb21f6bb94fd461a5aa78 +size 2186 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/and.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/and.hpp new file mode 100644 index 0000000..ea10ec7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/and.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48f7e389aa4c3af94cf7a3fa8bb021335cf7c4c45f33251c5dce7b6d100fe1c4 +size 1257 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/apply.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/apply.hpp new file mode 100644 index 0000000..f779704 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/apply.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42dacbfb2158468c189ee73d0cb03664f0109008e6933976bf09a94852cae4f6 +size 2744 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/apply_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/apply_fwd.hpp new file mode 100644 index 0000000..a9455bf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/apply_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e5bd2d53e79be26d178acc39a2629864f6fb00a6641b60d811df49d0abe9e79 +size 972 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/apply_wrap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/apply_wrap.hpp new file mode 100644 index 0000000..12c6608 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/apply_wrap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ab2c4e5056a15108f72c4c0fc86495baa9b35fd8d51e6d572eb314667ccd4de +size 6956 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/arg.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/arg.hpp new file mode 100644 index 0000000..2cc570d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/arg.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8dd55033624e38bf06e1c3c2a808b2c052b47403968a151ed349dd66928ad251 +size 2893 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/basic_bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/basic_bind.hpp new file mode 100644 index 0000000..e819ac1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/basic_bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82b529c11b3613997941aa301719081bbb2c337f3eaf5598ebd3a56c72a754ed +size 7326 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/bind.hpp new file mode 100644 index 0000000..03a1157 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5822be58ef4695b5f876df9c7ed5ffb29cf5eeac7f1e095100f2c0e74574a4f9 +size 10623 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/bind_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/bind_fwd.hpp new file mode 100644 index 0000000..c3c2a2b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/bind_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e922cd7f3aa2dd146d2ee7c4a06205b02fefadbf27cbbb51c60b893e453d24ea +size 822 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/bitand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/bitand.hpp new file mode 100644 index 0000000..754ad86 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/bitand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04361fb0c214fe0baea75dee7988b6f3a8390cbf1e0af2adceb4cf7831e6f8f4 +size 3208 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/bitor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/bitor.hpp new file mode 100644 index 0000000..d5b8a74 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/bitor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e331fc1e6f2feadd2799d3104d78e4aac09bf189a3785cff1cb2d858122c0535 +size 3178 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/bitxor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/bitxor.hpp new file mode 100644 index 0000000..d6c2516 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/bitxor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d64fe515d7ab31f32469ca0c6bb3b1d5d801b048c2e9f592f1de596015dff4ac +size 3208 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/deque.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/deque.hpp new file mode 100644 index 0000000..1cd3ad3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/deque.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52440eb38f109bbd3bb99542042d25575ce8c9c6e301c4a404e88d57ae3c8de9 +size 9723 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/divides.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/divides.hpp new file mode 100644 index 0000000..16a2d9f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/divides.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8447006b0a3db43b6790fd4afccf07a0f1130db248807563096f1c86cd301444 +size 3191 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/equal_to.hpp new file mode 100644 index 0000000..7445868 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02ce64be459ad25c1c36bd0839a3fef6fc405f7a7744f12ac0dc6ebd74e13b19 +size 2097 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/fold_impl.hpp new file mode 100644 index 0000000..88fb149 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f74d7a7520ecc7324a6fe40fae8bf9de3fc881bc6ced30ac1ec3389d2bc9581d +size 4354 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/full_lambda.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/full_lambda.hpp new file mode 100644 index 0000000..756e946 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/full_lambda.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5eb8574dfb61185ce0bea8993ac31dccf12923593665c434584f7b72e5b5d0a8 +size 11510 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/greater.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/greater.hpp new file mode 100644 index 0000000..38840c3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/greater.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:045aa5d6bd8a3d800d4e88b3f059a31830583c77f1842638a4ac16e9be020502 +size 2080 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/greater_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/greater_equal.hpp new file mode 100644 index 0000000..5bab029 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/greater_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10790da3ecc6537acf7907af6a0271e3109e350b7929c2da1cf3f3cad177c5e1 +size 2171 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/inherit.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/inherit.hpp new file mode 100644 index 0000000..9567f1d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/inherit.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67eec86cd760d5d50464a5b916c6f0fcb70389b6afdf4b1dc1a01c3f29c67ccd +size 2832 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/iter_fold_if_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/iter_fold_if_impl.hpp new file mode 100644 index 0000000..c1acc01 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/iter_fold_if_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acc097fe7a8a705d537a17859f2f6ff2f7ce7e687261e1f4235f794fdb4688f8 +size 4274 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/iter_fold_impl.hpp new file mode 100644 index 0000000..cca419a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56eee865128b7608c098510ad708a849907a80c9f9f8314e5c6cf416992079e5 +size 4158 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/lambda_no_ctps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/lambda_no_ctps.hpp new file mode 100644 index 0000000..e1b521b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/lambda_no_ctps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3387b7806a1e6c0a6109cc323509d8dd10e15b7f8c2cff882013c07168231433 +size 6477 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/less.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/less.hpp new file mode 100644 index 0000000..15bcc1f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/less.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ec24946d87d5a75ab09d7933c37918bf8a5486ad1954102e3e240def7e18585 +size 2035 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/less_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/less_equal.hpp new file mode 100644 index 0000000..3304449 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/less_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5d569aca0ec9bf6fd37393a9143f3c7e7dffea5d02ddaee311d69df027aee32 +size 2126 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/list.hpp new file mode 100644 index 0000000..763186d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e73c15b7e2fb9c62158af870a854a335fec2490a0f74100a706baad058a4d158 +size 9616 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/list_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/list_c.hpp new file mode 100644 index 0000000..2032686 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/list_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ee008389f1cca2faf27ed1da73c939ce2ff78296416feb06958c2466bb93345 +size 10717 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/map.hpp new file mode 100644 index 0000000..4625f58 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a002cc4fbd7bf1a8fc5e286ae3b19d9708c0036dc2832babbca4d1a872adb183 +size 9551 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/minus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/minus.hpp new file mode 100644 index 0000000..adf3979 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/minus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e298cb9e3132ce14a2ec5ffda044ace342053395ffdb0fdc210671f25946992 +size 3131 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/modulus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/modulus.hpp new file mode 100644 index 0000000..14ea63c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/modulus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:942f0e6c8b73652c912f11456bc9eacd7f8c0f778e4e2bab8ec10763c9e1cb69 +size 2293 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/not_equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/not_equal_to.hpp new file mode 100644 index 0000000..eb85dfc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/not_equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4fb0d2825097e4f8e452514b29d77ac13c9da3ef1860d5dbec1c915b61aaae9 +size 2156 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/or.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/or.hpp new file mode 100644 index 0000000..61413b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/or.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:112ec4d3cb8cc4a9ee79b88a8e585065e67e8c4d86935262516eb7a7943f3820 +size 1258 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/placeholders.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/placeholders.hpp new file mode 100644 index 0000000..b8ef78d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/placeholders.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3d080d1d6bdd3d373c1fa5f19cad988430dfc29a626f7ed5f1e7abaa4381fa8 +size 2211 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/plus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/plus.hpp new file mode 100644 index 0000000..e9704d5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/plus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0b612a0a8f0eeb3414644e5c028a242911ffa119a6460d9acc71497c8701372 +size 3101 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/quote.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/quote.hpp new file mode 100644 index 0000000..ef000cb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/quote.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7881345c5b69527ec6fc972071155341def05719cae294c4ea8b56892032eb3 +size 292 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/reverse_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/reverse_fold_impl.hpp new file mode 100644 index 0000000..1ee6d3c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/reverse_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d35ab02a3f9c90712bb99fceecc74f34b675bbea2751aa00d735935bc790af20 +size 8870 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/reverse_iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/reverse_iter_fold_impl.hpp new file mode 100644 index 0000000..a4d0254 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/reverse_iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:159bc9d2c3b48d007b76dfe2f08274377c7a8a8b7e0b003f174eaaeecfa59c97 +size 8250 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/set.hpp new file mode 100644 index 0000000..3eb75d2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4e7071dad95512f5828c2ac50f842f169d093297cdb2ba903085d0691af03cd +size 9551 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/set_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/set_c.hpp new file mode 100644 index 0000000..5f8a1dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/set_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:608eb89b22961ab2a5b1ba5cdfc115bc58be754a108d1038bf498de563e1eefc +size 10652 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/shift_left.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/shift_left.hpp new file mode 100644 index 0000000..d546fb9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/shift_left.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b91279f3a368dccec4a42dd1ee4b76925dc09a6e5a20ab04a5116fd048e2cf11 +size 2252 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/shift_right.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/shift_right.hpp new file mode 100644 index 0000000..cd9d0bb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/shift_right.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3552891d80d206bcad21c2c1b191ee3e0c63096448939e878ad74955c529c384 +size 2267 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/template_arity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/template_arity.hpp new file mode 100644 index 0000000..09be163 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/template_arity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c008c25aa90b8dc31d8d524dc31eac50e775f0c2955358d90a035beba74ca366 +size 767 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/times.hpp new file mode 100644 index 0000000..2143388 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f79649346ec889d18117680a67ac8f28082fe51abe91ac62eaa3c505fbb5065 +size 3131 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/unpack_args.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/unpack_args.hpp new file mode 100644 index 0000000..c5047c0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/unpack_args.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e151fc458a1fed3cf5bb6dfe4740d55638af7b381c88675f58362d28bf722cf3 +size 1985 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/vector.hpp new file mode 100644 index 0000000..96bdf70 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e22c161ecfd115c7f9154b25cf8e6835e2e30a6d49dbeddf4d98b012fd018c7 +size 9746 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/vector_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/vector_c.hpp new file mode 100644 index 0000000..01100ce --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc551/vector_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:630a3139e05016e8afd31fbedd1190ec07f6d31c8ddb5a2ce4399e551f07ac64 +size 12237 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/advance_backward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/advance_backward.hpp new file mode 100644 index 0000000..2d0dcab --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/advance_backward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1166597a0c2defd1765edb8eddb73642216deb0f6720825ca5670df037bd3d37 +size 2202 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/advance_forward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/advance_forward.hpp new file mode 100644 index 0000000..85680a3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/advance_forward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:071bca20bda9543f3b7b1016466fcea88d2eb4a29d6fba55aef6ee2509c6d3cf +size 2182 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/and.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/and.hpp new file mode 100644 index 0000000..aadb819 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/and.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5556119a1511a8e280193107ca726435cfd290bd858201ed33ef883d2bd04b30 +size 1258 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/apply.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/apply.hpp new file mode 100644 index 0000000..e536c24 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/apply.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a371bdc8561c9236d6b303c7dba2613de6b28e8f9cb6093314dd70d5b43feabd +size 2745 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/apply_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/apply_fwd.hpp new file mode 100644 index 0000000..fac5149 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/apply_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e1a30be64abdd6ee27b3262e0221d33f2cb6ee2f70064eda2fe60aeebdf9cebd +size 973 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/apply_wrap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/apply_wrap.hpp new file mode 100644 index 0000000..3e7cf91 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/apply_wrap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64f625fca0a23b587d22acb3cf02c7bfacd5296eb61e124c5eb6525e51d60808 +size 6957 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/arg.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/arg.hpp new file mode 100644 index 0000000..5fbf989 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/arg.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61a0bdff0b1c7dea9c06b1f39fe7d49356757fb05577565d988cbac828bbf6b6 +size 2690 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/basic_bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/basic_bind.hpp new file mode 100644 index 0000000..2755224 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/basic_bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e66e83b8a67d3a59c8a4a88bce2e7b5d5dac5e76a01ad7363853d3a75ad3ace5 +size 7118 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/bind.hpp new file mode 100644 index 0000000..0547b99 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0cf1f1740bd1ed7343d4d86099219c3732e272023db4e99927224dca2889c852 +size 10420 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/bind_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/bind_fwd.hpp new file mode 100644 index 0000000..11a0884 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/bind_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:629bae6e8eb9b55aee5f759d1a03ba9642e361da50a097e616097b25c8d9f1c0 +size 823 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/bitand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/bitand.hpp new file mode 100644 index 0000000..aa1cd2c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/bitand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:feadd14f26318a5371db4da3e16f1a851e020175a8c5667cd2ff95d79fa29f5b +size 3209 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/bitor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/bitor.hpp new file mode 100644 index 0000000..ad8db90 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/bitor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7ea8d47577361c3721a7e434e59c6b56a780ee50212043a4da3b9d1052338f5 +size 3179 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/bitxor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/bitxor.hpp new file mode 100644 index 0000000..a4a1362 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/bitxor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77c1e2c70776f51badbd56bb10ad5605e97d0f39fec748de90289757259a8639 +size 3209 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/deque.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/deque.hpp new file mode 100644 index 0000000..cb74ef1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/deque.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bcafec5930ca417afa6463e127f5ea5107f9be2e4a661929d5388936e78126dd +size 9724 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/divides.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/divides.hpp new file mode 100644 index 0000000..56b317e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/divides.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d54b58f0efdec9bf15adef8da236d73d5c86cbbd34de1f1d10f533a1b67b90cd +size 3192 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/equal_to.hpp new file mode 100644 index 0000000..bde352f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:438b625e58dac03bd60e4d6bf95c2d7f9cc14bc142638a46612af1bcceb22d34 +size 2098 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/fold_impl.hpp new file mode 100644 index 0000000..41742ac --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c548fdaf9b108337c82c0755f118c38a034a56cdf1237735bf921c664710081 +size 4350 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/full_lambda.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/full_lambda.hpp new file mode 100644 index 0000000..74be77a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/full_lambda.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07757c28215320f0330ed487d5a81fe8fac922107e5678b8eba13528cea1030e +size 11506 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/greater.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/greater.hpp new file mode 100644 index 0000000..fab079e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/greater.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e9d6192340167d3f4deee06f1b9e726bc7f3c13cfa825412ad0a26a0c9b174fc +size 2081 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/greater_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/greater_equal.hpp new file mode 100644 index 0000000..db34154 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/greater_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5cbde03a953532a1a85cf85230d6fbec70a01d6b17640ef394ce391383efcf03 +size 2172 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/inherit.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/inherit.hpp new file mode 100644 index 0000000..6609811 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/inherit.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c5ae60cc2e05bf0a1c4d2394bf5630113a70cf90fd407f061f10c5e9950e558 +size 2750 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/iter_fold_if_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/iter_fold_if_impl.hpp new file mode 100644 index 0000000..368bbbc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/iter_fold_if_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11cd0305f5ffe0f40d03e75725673b1633158717b403b893655283a6e5a31773 +size 4270 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/iter_fold_impl.hpp new file mode 100644 index 0000000..2c1f304 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a104eeae82e6362a7179ff7e93e6310a3502da16d333f800d7411abd3ecb13b7 +size 4154 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/lambda_no_ctps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/lambda_no_ctps.hpp new file mode 100644 index 0000000..6334fca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/lambda_no_ctps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:483ec169cd5b1fa0ad58904197f94a6314556fb7a81e02f6c2778427c52684f9 +size 6473 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/less.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/less.hpp new file mode 100644 index 0000000..a90b27b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/less.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8c659e3c8ff5fda4bad8d241266e6bbbd7e0508b9703926bedebdc13fbc46bf +size 2036 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/less_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/less_equal.hpp new file mode 100644 index 0000000..5c4e4e3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/less_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb5d9c6093f5dd829a52fc4708edd33e6fbd4169355e8bc5a7e1818a1740a617 +size 2127 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/list.hpp new file mode 100644 index 0000000..6d1fd74 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0019a35a151e4ca972999b4677b3c8b516e2b3eba4d877dbfdd1af857cabad8d +size 9617 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/list_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/list_c.hpp new file mode 100644 index 0000000..5cfbdae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/list_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8eb00b77a1c9e1703ffa7615acb145b0a1ece1a8d83186a073d384e4537c6761 +size 10718 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/map.hpp new file mode 100644 index 0000000..bddbcfb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4fe413b5a0125dd27ace1a1ff21db30d66967b6f6b9ca94ded4bec0737c0a2f8 +size 9552 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/minus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/minus.hpp new file mode 100644 index 0000000..a05335a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/minus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ee365b2ca4ec003c3f052da32d6aa54835c459dbfd1ecba3609b1bd29f45a9d +size 3132 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/modulus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/modulus.hpp new file mode 100644 index 0000000..d79f28b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/modulus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:079a3aa5d1d496998faeb0eab8ffda31719d899c8d80ce329d0ad90069d977e1 +size 2294 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/not_equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/not_equal_to.hpp new file mode 100644 index 0000000..b38cf77 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/not_equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4cbf3ee21aedbabf64b2891ee00c07c4cfbd28d928375a0810d1acd4602ffe5d +size 2157 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/or.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/or.hpp new file mode 100644 index 0000000..2a52cc0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/or.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cdfe83ee0b8ac57ece2fe81825462696df4c0e77c067940b3dca2d2146bcd675 +size 1259 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/placeholders.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/placeholders.hpp new file mode 100644 index 0000000..f236edc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/placeholders.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:961f77c7b2b7170fed2aa1d947a579f25b4b24d1676da0bf2f926543610ebda1 +size 2212 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/plus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/plus.hpp new file mode 100644 index 0000000..96edbf6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/plus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:797978593b7742edbc86b23e875c05eb2df3eecbd66dfc6f1a040cd1032a5f29 +size 3102 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/quote.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/quote.hpp new file mode 100644 index 0000000..5db9102 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/quote.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce4724d8b80c5b10086c4f07e370191d6cae56bea2906e668913e3c2a7eb8bdb +size 293 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/reverse_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/reverse_fold_impl.hpp new file mode 100644 index 0000000..f2985f1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/reverse_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:400b591c140160c1dc04e3dddc7b858c05176b7b2e35e270ca08843025cf0cf9 +size 8866 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/reverse_iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/reverse_iter_fold_impl.hpp new file mode 100644 index 0000000..1aa0975 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/reverse_iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d0d8aa3172efec1a20cdb6d0ba1c707c1819da79df7cb1d6ce4aac96e1bd558 +size 8246 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/set.hpp new file mode 100644 index 0000000..6dcaef5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64343393f717fa150253fb96f04246bd424d2d158b3c44ee89ef65ad6a098189 +size 9552 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/set_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/set_c.hpp new file mode 100644 index 0000000..144e8cc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/set_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96ed53cbd48bd217b40bac7e48d2a664a5b8335538638836159292d037c54251 +size 10653 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/shift_left.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/shift_left.hpp new file mode 100644 index 0000000..7304e70 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/shift_left.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21ebb2f86fe31d3a09907e197fe777a683d3ea48111846862041d74a64202147 +size 2253 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/shift_right.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/shift_right.hpp new file mode 100644 index 0000000..1617353 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/shift_right.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6d45cb6a9703d6fa3a3e9d15759cdb2428e431f52a76fc27430bbe795b0753dd +size 2268 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/template_arity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/template_arity.hpp new file mode 100644 index 0000000..e9fef38 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/template_arity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f3bbe15c869d28bcd291c8965adf9e0d1dd4f616c54b631f264e8fc1cbfe4c0 +size 763 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/times.hpp new file mode 100644 index 0000000..cae42e9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b95f3b35b2cd3f09b91d073297172cf5579d19eb5bdbee52ba2e4ed0c7c85a4 +size 3132 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/unpack_args.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/unpack_args.hpp new file mode 100644 index 0000000..795b92e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/unpack_args.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb386ff1d89fff88f38aafe045a0091e78518459eecf365af6df32c4f5ea5ce7 +size 1986 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/vector.hpp new file mode 100644 index 0000000..6398407 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:192cb1570ea17a5f871b550a9311010d4e615d5e1876718c4ebde2ce42917640 +size 9747 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/vector_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/vector_c.hpp new file mode 100644 index 0000000..f143b3b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/bcc_pre590/vector_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8071ea880d61813a0b4baf926ee675fcf31a3042f4e88c551664c746dda11e8a +size 12238 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/advance_backward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/advance_backward.hpp new file mode 100644 index 0000000..7c8960e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/advance_backward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4c03c83e9e3950e42ee825cb10d94c3e54af988a8bf5517a44265e8e56b4be3 +size 2206 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/advance_forward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/advance_forward.hpp new file mode 100644 index 0000000..913b5b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/advance_forward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50d41920b3f3d73804897c16f790f269609c2684db7bb21f6bb94fd461a5aa78 +size 2186 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/and.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/and.hpp new file mode 100644 index 0000000..ea10ec7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/and.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48f7e389aa4c3af94cf7a3fa8bb021335cf7c4c45f33251c5dce7b6d100fe1c4 +size 1257 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/apply.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/apply.hpp new file mode 100644 index 0000000..f779704 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/apply.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42dacbfb2158468c189ee73d0cb03664f0109008e6933976bf09a94852cae4f6 +size 2744 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/apply_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/apply_fwd.hpp new file mode 100644 index 0000000..a9455bf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/apply_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e5bd2d53e79be26d178acc39a2629864f6fb00a6641b60d811df49d0abe9e79 +size 972 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/apply_wrap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/apply_wrap.hpp new file mode 100644 index 0000000..9ab4d99 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/apply_wrap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5af7a500dc1f73b2175dd31d748c42ee2044fe95fe2e3a7e875c2f494aa68219 +size 1238 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/arg.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/arg.hpp new file mode 100644 index 0000000..2cc570d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/arg.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8dd55033624e38bf06e1c3c2a808b2c052b47403968a151ed349dd66928ad251 +size 2893 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/basic_bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/basic_bind.hpp new file mode 100644 index 0000000..dd4d46f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/basic_bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3460f34d3f4ac8da72b7df2f0e889c7258c77ec790536ee8eec9fd10042fa53b +size 9530 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/bind.hpp new file mode 100644 index 0000000..67e85c1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb0e7549ad3bb27733c8c2f0b08435ab6f2c0108064676bd28394d445d1856fd +size 13253 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/bind_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/bind_fwd.hpp new file mode 100644 index 0000000..0509d79 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/bind_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b59863423d85fa3b93b81788bd19dfc46944287fcd3321819a78710c578dc1f5 +size 1081 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/bitand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/bitand.hpp new file mode 100644 index 0000000..754ad86 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/bitand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04361fb0c214fe0baea75dee7988b6f3a8390cbf1e0af2adceb4cf7831e6f8f4 +size 3208 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/bitor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/bitor.hpp new file mode 100644 index 0000000..d5b8a74 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/bitor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e331fc1e6f2feadd2799d3104d78e4aac09bf189a3785cff1cb2d858122c0535 +size 3178 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/bitxor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/bitxor.hpp new file mode 100644 index 0000000..d6c2516 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/bitxor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d64fe515d7ab31f32469ca0c6bb3b1d5d801b048c2e9f592f1de596015dff4ac +size 3208 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/deque.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/deque.hpp new file mode 100644 index 0000000..1cd3ad3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/deque.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52440eb38f109bbd3bb99542042d25575ce8c9c6e301c4a404e88d57ae3c8de9 +size 9723 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/divides.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/divides.hpp new file mode 100644 index 0000000..16a2d9f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/divides.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8447006b0a3db43b6790fd4afccf07a0f1130db248807563096f1c86cd301444 +size 3191 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/equal_to.hpp new file mode 100644 index 0000000..7445868 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02ce64be459ad25c1c36bd0839a3fef6fc405f7a7744f12ac0dc6ebd74e13b19 +size 2097 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/fold_impl.hpp new file mode 100644 index 0000000..88fb149 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f74d7a7520ecc7324a6fe40fae8bf9de3fc881bc6ced30ac1ec3389d2bc9581d +size 4354 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/full_lambda.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/full_lambda.hpp new file mode 100644 index 0000000..90a5768 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/full_lambda.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4edbd14474c1d7eccbf047a58e012c6efc89af3094cac518f074090cce1dfb47 +size 10728 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/greater.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/greater.hpp new file mode 100644 index 0000000..38840c3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/greater.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:045aa5d6bd8a3d800d4e88b3f059a31830583c77f1842638a4ac16e9be020502 +size 2080 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/greater_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/greater_equal.hpp new file mode 100644 index 0000000..5bab029 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/greater_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10790da3ecc6537acf7907af6a0271e3109e350b7929c2da1cf3f3cad177c5e1 +size 2171 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/inherit.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/inherit.hpp new file mode 100644 index 0000000..9567f1d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/inherit.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67eec86cd760d5d50464a5b916c6f0fcb70389b6afdf4b1dc1a01c3f29c67ccd +size 2832 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/iter_fold_if_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/iter_fold_if_impl.hpp new file mode 100644 index 0000000..c1acc01 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/iter_fold_if_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acc097fe7a8a705d537a17859f2f6ff2f7ce7e687261e1f4235f794fdb4688f8 +size 4274 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/iter_fold_impl.hpp new file mode 100644 index 0000000..cca419a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56eee865128b7608c098510ad708a849907a80c9f9f8314e5c6cf416992079e5 +size 4158 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/lambda_no_ctps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/lambda_no_ctps.hpp new file mode 100644 index 0000000..e1b521b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/lambda_no_ctps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3387b7806a1e6c0a6109cc323509d8dd10e15b7f8c2cff882013c07168231433 +size 6477 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/less.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/less.hpp new file mode 100644 index 0000000..15bcc1f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/less.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ec24946d87d5a75ab09d7933c37918bf8a5486ad1954102e3e240def7e18585 +size 2035 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/less_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/less_equal.hpp new file mode 100644 index 0000000..3304449 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/less_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5d569aca0ec9bf6fd37393a9143f3c7e7dffea5d02ddaee311d69df027aee32 +size 2126 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/list.hpp new file mode 100644 index 0000000..763186d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e73c15b7e2fb9c62158af870a854a335fec2490a0f74100a706baad058a4d158 +size 9616 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/list_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/list_c.hpp new file mode 100644 index 0000000..2032686 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/list_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ee008389f1cca2faf27ed1da73c939ce2ff78296416feb06958c2466bb93345 +size 10717 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/map.hpp new file mode 100644 index 0000000..4625f58 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a002cc4fbd7bf1a8fc5e286ae3b19d9708c0036dc2832babbca4d1a872adb183 +size 9551 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/minus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/minus.hpp new file mode 100644 index 0000000..adf3979 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/minus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e298cb9e3132ce14a2ec5ffda044ace342053395ffdb0fdc210671f25946992 +size 3131 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/modulus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/modulus.hpp new file mode 100644 index 0000000..14ea63c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/modulus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:942f0e6c8b73652c912f11456bc9eacd7f8c0f778e4e2bab8ec10763c9e1cb69 +size 2293 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/not_equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/not_equal_to.hpp new file mode 100644 index 0000000..eb85dfc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/not_equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4fb0d2825097e4f8e452514b29d77ac13c9da3ef1860d5dbec1c915b61aaae9 +size 2156 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/or.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/or.hpp new file mode 100644 index 0000000..61413b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/or.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:112ec4d3cb8cc4a9ee79b88a8e585065e67e8c4d86935262516eb7a7943f3820 +size 1258 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/placeholders.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/placeholders.hpp new file mode 100644 index 0000000..b8ef78d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/placeholders.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3d080d1d6bdd3d373c1fa5f19cad988430dfc29a626f7ed5f1e7abaa4381fa8 +size 2211 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/plus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/plus.hpp new file mode 100644 index 0000000..e9704d5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/plus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0b612a0a8f0eeb3414644e5c028a242911ffa119a6460d9acc71497c8701372 +size 3101 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/quote.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/quote.hpp new file mode 100644 index 0000000..af5c665 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/quote.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9cf2f4f8b21bb706886b2adb76fa1c1eca3ea06c9fd43e1889b0e5dcf4825bc3 +size 2187 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/reverse_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/reverse_fold_impl.hpp new file mode 100644 index 0000000..8bd7744 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/reverse_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:16293df37c25ff8a277b36af2a1184d3883d5aa73faae01768c027ba8c88802f +size 7372 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/reverse_iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/reverse_iter_fold_impl.hpp new file mode 100644 index 0000000..223d946 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/reverse_iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba3bcf3f96dbae8d9cc54d8df52417c2df1346aeb6c3a3d3f4ddf0d5aa874847 +size 6717 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/set.hpp new file mode 100644 index 0000000..3eb75d2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4e7071dad95512f5828c2ac50f842f169d093297cdb2ba903085d0691af03cd +size 9551 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/set_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/set_c.hpp new file mode 100644 index 0000000..5f8a1dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/set_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:608eb89b22961ab2a5b1ba5cdfc115bc58be754a108d1038bf498de563e1eefc +size 10652 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/shift_left.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/shift_left.hpp new file mode 100644 index 0000000..d546fb9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/shift_left.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b91279f3a368dccec4a42dd1ee4b76925dc09a6e5a20ab04a5116fd048e2cf11 +size 2252 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/shift_right.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/shift_right.hpp new file mode 100644 index 0000000..cd9d0bb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/shift_right.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3552891d80d206bcad21c2c1b191ee3e0c63096448939e878ad74955c529c384 +size 2267 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/template_arity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/template_arity.hpp new file mode 100644 index 0000000..e29c8bf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/template_arity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7f7f402db7af2a929cd4eea606d870506e73ab076f073cd5b0d08322cb718d9 +size 306 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/times.hpp new file mode 100644 index 0000000..2143388 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f79649346ec889d18117680a67ac8f28082fe51abe91ac62eaa3c505fbb5065 +size 3131 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/unpack_args.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/unpack_args.hpp new file mode 100644 index 0000000..3d93ce2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/unpack_args.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91d1e3057b2731938c0e74eede0338fbe7f2c7d578d1d888bcbc8d3a50bde152 +size 1906 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/vector.hpp new file mode 100644 index 0000000..96bdf70 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e22c161ecfd115c7f9154b25cf8e6835e2e30a6d49dbeddf4d98b012fd018c7 +size 9746 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/vector_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/vector_c.hpp new file mode 100644 index 0000000..01100ce --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/dmc/vector_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:630a3139e05016e8afd31fbedd1190ec07f6d31c8ddb5a2ce4399e551f07ac64 +size 12237 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp new file mode 100644 index 0000000..7c8960e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4c03c83e9e3950e42ee825cb10d94c3e54af988a8bf5517a44265e8e56b4be3 +size 2206 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp new file mode 100644 index 0000000..913b5b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50d41920b3f3d73804897c16f790f269609c2684db7bb21f6bb94fd461a5aa78 +size 2186 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/and.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/and.hpp new file mode 100644 index 0000000..ea10ec7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/and.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48f7e389aa4c3af94cf7a3fa8bb021335cf7c4c45f33251c5dce7b6d100fe1c4 +size 1257 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/apply.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/apply.hpp new file mode 100644 index 0000000..f779704 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/apply.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42dacbfb2158468c189ee73d0cb03664f0109008e6933976bf09a94852cae4f6 +size 2744 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/apply_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/apply_fwd.hpp new file mode 100644 index 0000000..a9455bf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/apply_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e5bd2d53e79be26d178acc39a2629864f6fb00a6641b60d811df49d0abe9e79 +size 972 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp new file mode 100644 index 0000000..9ab4d99 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5af7a500dc1f73b2175dd31d748c42ee2044fe95fe2e3a7e875c2f494aa68219 +size 1238 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/arg.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/arg.hpp new file mode 100644 index 0000000..2cc570d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/arg.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8dd55033624e38bf06e1c3c2a808b2c052b47403968a151ed349dd66928ad251 +size 2893 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/basic_bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/basic_bind.hpp new file mode 100644 index 0000000..9bc5fc2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/basic_bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f0c1779e43d8f709ce7e9d08888c621c23fe724cc63b7ee9edf5f4e4ed7324f +size 10260 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/bind.hpp new file mode 100644 index 0000000..66d4be9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10c17e1a8b7279f7db31cdf284a82788ba473eb36e02b607beecc2ba369b28d3 +size 14409 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/bind_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/bind_fwd.hpp new file mode 100644 index 0000000..1a9018e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/bind_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87f020aaafed9bcbdc23b541798663f5609176b9b1b0a6611b8ed48a8cecffe0 +size 964 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/bitand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/bitand.hpp new file mode 100644 index 0000000..754ad86 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/bitand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04361fb0c214fe0baea75dee7988b6f3a8390cbf1e0af2adceb4cf7831e6f8f4 +size 3208 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/bitor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/bitor.hpp new file mode 100644 index 0000000..d5b8a74 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/bitor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e331fc1e6f2feadd2799d3104d78e4aac09bf189a3785cff1cb2d858122c0535 +size 3178 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/bitxor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/bitxor.hpp new file mode 100644 index 0000000..d6c2516 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/bitxor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d64fe515d7ab31f32469ca0c6bb3b1d5d801b048c2e9f592f1de596015dff4ac +size 3208 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/deque.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/deque.hpp new file mode 100644 index 0000000..1cd3ad3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/deque.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52440eb38f109bbd3bb99542042d25575ce8c9c6e301c4a404e88d57ae3c8de9 +size 9723 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/divides.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/divides.hpp new file mode 100644 index 0000000..16a2d9f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/divides.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8447006b0a3db43b6790fd4afccf07a0f1130db248807563096f1c86cd301444 +size 3191 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/equal_to.hpp new file mode 100644 index 0000000..7445868 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02ce64be459ad25c1c36bd0839a3fef6fc405f7a7744f12ac0dc6ebd74e13b19 +size 2097 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp new file mode 100644 index 0000000..88fb149 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f74d7a7520ecc7324a6fe40fae8bf9de3fc881bc6ced30ac1ec3389d2bc9581d +size 4354 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/full_lambda.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/full_lambda.hpp new file mode 100644 index 0000000..756e946 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/full_lambda.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5eb8574dfb61185ce0bea8993ac31dccf12923593665c434584f7b72e5b5d0a8 +size 11510 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/greater.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/greater.hpp new file mode 100644 index 0000000..38840c3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/greater.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:045aa5d6bd8a3d800d4e88b3f059a31830583c77f1842638a4ac16e9be020502 +size 2080 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/greater_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/greater_equal.hpp new file mode 100644 index 0000000..5bab029 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/greater_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10790da3ecc6537acf7907af6a0271e3109e350b7929c2da1cf3f3cad177c5e1 +size 2171 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/inherit.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/inherit.hpp new file mode 100644 index 0000000..9567f1d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/inherit.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67eec86cd760d5d50464a5b916c6f0fcb70389b6afdf4b1dc1a01c3f29c67ccd +size 2832 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp new file mode 100644 index 0000000..c1acc01 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acc097fe7a8a705d537a17859f2f6ff2f7ce7e687261e1f4235f794fdb4688f8 +size 4274 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp new file mode 100644 index 0000000..cca419a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56eee865128b7608c098510ad708a849907a80c9f9f8314e5c6cf416992079e5 +size 4158 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/lambda_no_ctps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/lambda_no_ctps.hpp new file mode 100644 index 0000000..e1b521b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/lambda_no_ctps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3387b7806a1e6c0a6109cc323509d8dd10e15b7f8c2cff882013c07168231433 +size 6477 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/less.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/less.hpp new file mode 100644 index 0000000..15bcc1f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/less.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ec24946d87d5a75ab09d7933c37918bf8a5486ad1954102e3e240def7e18585 +size 2035 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/less_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/less_equal.hpp new file mode 100644 index 0000000..3304449 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/less_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5d569aca0ec9bf6fd37393a9143f3c7e7dffea5d02ddaee311d69df027aee32 +size 2126 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/list.hpp new file mode 100644 index 0000000..763186d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e73c15b7e2fb9c62158af870a854a335fec2490a0f74100a706baad058a4d158 +size 9616 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/list_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/list_c.hpp new file mode 100644 index 0000000..2032686 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/list_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ee008389f1cca2faf27ed1da73c939ce2ff78296416feb06958c2466bb93345 +size 10717 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/map.hpp new file mode 100644 index 0000000..4625f58 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a002cc4fbd7bf1a8fc5e286ae3b19d9708c0036dc2832babbca4d1a872adb183 +size 9551 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/minus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/minus.hpp new file mode 100644 index 0000000..adf3979 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/minus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e298cb9e3132ce14a2ec5ffda044ace342053395ffdb0fdc210671f25946992 +size 3131 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/modulus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/modulus.hpp new file mode 100644 index 0000000..14ea63c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/modulus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:942f0e6c8b73652c912f11456bc9eacd7f8c0f778e4e2bab8ec10763c9e1cb69 +size 2293 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/not_equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/not_equal_to.hpp new file mode 100644 index 0000000..eb85dfc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/not_equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4fb0d2825097e4f8e452514b29d77ac13c9da3ef1860d5dbec1c915b61aaae9 +size 2156 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/or.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/or.hpp new file mode 100644 index 0000000..61413b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/or.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:112ec4d3cb8cc4a9ee79b88a8e585065e67e8c4d86935262516eb7a7943f3820 +size 1258 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/placeholders.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/placeholders.hpp new file mode 100644 index 0000000..b8ef78d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/placeholders.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3d080d1d6bdd3d373c1fa5f19cad988430dfc29a626f7ed5f1e7abaa4381fa8 +size 2211 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/plus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/plus.hpp new file mode 100644 index 0000000..e9704d5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/plus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0b612a0a8f0eeb3414644e5c028a242911ffa119a6460d9acc71497c8701372 +size 3101 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/quote.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/quote.hpp new file mode 100644 index 0000000..2961fee --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/quote.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ebb0610e131486e432f922aff55d17b0ceceb410becbc4a1f7de7c688a3299ca +size 2214 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp new file mode 100644 index 0000000..8bd7744 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:16293df37c25ff8a277b36af2a1184d3883d5aa73faae01768c027ba8c88802f +size 7372 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/reverse_iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/reverse_iter_fold_impl.hpp new file mode 100644 index 0000000..223d946 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/reverse_iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba3bcf3f96dbae8d9cc54d8df52417c2df1346aeb6c3a3d3f4ddf0d5aa874847 +size 6717 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/set.hpp new file mode 100644 index 0000000..3eb75d2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4e7071dad95512f5828c2ac50f842f169d093297cdb2ba903085d0691af03cd +size 9551 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/set_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/set_c.hpp new file mode 100644 index 0000000..5f8a1dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/set_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:608eb89b22961ab2a5b1ba5cdfc115bc58be754a108d1038bf498de563e1eefc +size 10652 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/shift_left.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/shift_left.hpp new file mode 100644 index 0000000..d546fb9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/shift_left.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b91279f3a368dccec4a42dd1ee4b76925dc09a6e5a20ab04a5116fd048e2cf11 +size 2252 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/shift_right.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/shift_right.hpp new file mode 100644 index 0000000..cd9d0bb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/shift_right.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3552891d80d206bcad21c2c1b191ee3e0c63096448939e878ad74955c529c384 +size 2267 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp new file mode 100644 index 0000000..52e786c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe95d6339096ac5d92c216124164dfe12c925108140a36f3d1aad96d3997c754 +size 2740 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/times.hpp new file mode 100644 index 0000000..2143388 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f79649346ec889d18117680a67ac8f28082fe51abe91ac62eaa3c505fbb5065 +size 3131 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/unpack_args.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/unpack_args.hpp new file mode 100644 index 0000000..3d93ce2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/unpack_args.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91d1e3057b2731938c0e74eede0338fbe7f2c7d578d1d888bcbc8d3a50bde152 +size 1906 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/vector.hpp new file mode 100644 index 0000000..96bdf70 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e22c161ecfd115c7f9154b25cf8e6835e2e30a6d49dbeddf4d98b012fd018c7 +size 9746 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/vector_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/vector_c.hpp new file mode 100644 index 0000000..01100ce --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/gcc/vector_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:630a3139e05016e8afd31fbedd1190ec07f6d31c8ddb5a2ce4399e551f07ac64 +size 12237 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/advance_backward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/advance_backward.hpp new file mode 100644 index 0000000..0ee553e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/advance_backward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74006bfb438fe0f91ba1be44e28b62896d25af4aefbf7409c3dfd0215646221e +size 2691 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/advance_forward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/advance_forward.hpp new file mode 100644 index 0000000..65528ae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/advance_forward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07ff033d768dac7a47c16f1365768f7766266479486aca3f8a92f3f2387356cd +size 2671 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/and.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/and.hpp new file mode 100644 index 0000000..e0038e2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/and.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:626bc53a4ac1b8b27a6c3dba518a7572a36329dc6aa708c8314f854e1d97bde6 +size 1383 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/apply.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/apply.hpp new file mode 100644 index 0000000..3a3f507 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/apply.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74392fc7d8c4b99e54b13f5a2ba9a43934a3b27ffcd5d9d1d2ec01bdab0b62b3 +size 2683 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/apply_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/apply_fwd.hpp new file mode 100644 index 0000000..2708f56 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/apply_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c560cb1faf80770bab1a5716c61566a3863d242ecf71e585d2b017d9c8cbf86 +size 829 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/apply_wrap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/apply_wrap.hpp new file mode 100644 index 0000000..12fa4c2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/apply_wrap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:69e9637ca2c1b9882ff818e310f1e6e38e16ad1febf209918165c7d5dbfaa029 +size 4692 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/arg.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/arg.hpp new file mode 100644 index 0000000..2cc570d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/arg.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8dd55033624e38bf06e1c3c2a808b2c052b47403968a151ed349dd66928ad251 +size 2893 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/basic_bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/basic_bind.hpp new file mode 100644 index 0000000..7b163da --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/basic_bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e4028082921f5bed438e7feafcb743a9376aa3f54d789538fb844aa784f9e00 +size 7357 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/bind.hpp new file mode 100644 index 0000000..e4c2e61 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:add03e5ab486db0b3c75dfc725f0d033964aeab87678154d5580309152143045 +size 10869 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/bind_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/bind_fwd.hpp new file mode 100644 index 0000000..c3c2a2b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/bind_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e922cd7f3aa2dd146d2ee7c4a06205b02fefadbf27cbbb51c60b893e453d24ea +size 822 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/bitand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/bitand.hpp new file mode 100644 index 0000000..c100e6a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/bitand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21d44542dd87974cad9317cd0705bd545d7bbaee46e6e0c8ae29bd1ea652dad0 +size 3119 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/bitor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/bitor.hpp new file mode 100644 index 0000000..a1d72f7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/bitor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6b0019a4010d987e409ad9ec88a245e192e8cbb2d7447fedf1dfd971594a44f +size 3096 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/bitxor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/bitxor.hpp new file mode 100644 index 0000000..6686cc5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/bitxor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df878de2984f1b365cbe5eccb4bcea9da443a93f561d4180924b2d812df84862 +size 3119 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/deque.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/deque.hpp new file mode 100644 index 0000000..bf2cb6e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/deque.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afe19d5ffbbd006c2451b60340782751d7c3dd9cc750234d3bbced631c32e696 +size 14714 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/divides.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/divides.hpp new file mode 100644 index 0000000..257e1f8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/divides.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98a0f4ff55f237aab4deaefe9c89cdc22c61113e600102e7250edd41bc79636d +size 3104 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/equal_to.hpp new file mode 100644 index 0000000..9caf793 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02a6fb4811e0d71f2df531c791c6d4d67d7e86081da3e27c97ba69c930ab39c9 +size 2350 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/fold_impl.hpp new file mode 100644 index 0000000..3d74b35 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:982fd5495e28a7f8e73fdaec1288a03745179ac2c065f1e626eb1844c39c6fad +size 6622 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/full_lambda.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/full_lambda.hpp new file mode 100644 index 0000000..8eddd50 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/full_lambda.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed8ad8fb76d22414f34292b139533c89db4c70270f84e40db13884239e6c3d60 +size 11215 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/greater.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/greater.hpp new file mode 100644 index 0000000..20931d5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/greater.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e192e3ba7ec2b132208a5686e49ce509e6fefa57e774839b969d18d52079cbf1 +size 2334 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/greater_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/greater_equal.hpp new file mode 100644 index 0000000..7454b21 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/greater_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3188b71fab56a945412696409ed0d25f15bc13fc3b8ffc424ab4b92b951509e4 +size 2425 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/inherit.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/inherit.hpp new file mode 100644 index 0000000..7666a0a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/inherit.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:80903ee2104e741d24b3c693698a5f8a33bd7a35714dd5468c9d12ed2bbe7f2a +size 3265 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/iter_fold_if_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/iter_fold_if_impl.hpp new file mode 100644 index 0000000..c1acc01 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/iter_fold_if_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acc097fe7a8a705d537a17859f2f6ff2f7ce7e687261e1f4235f794fdb4688f8 +size 4274 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/iter_fold_impl.hpp new file mode 100644 index 0000000..f8074e8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:330d54d9d42ca7c62c5ca6f961a2d81765907456485482d4928725a7c3461284 +size 6461 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/lambda_no_ctps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/lambda_no_ctps.hpp new file mode 100644 index 0000000..e1b521b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/lambda_no_ctps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3387b7806a1e6c0a6109cc323509d8dd10e15b7f8c2cff882013c07168231433 +size 6477 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/less.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/less.hpp new file mode 100644 index 0000000..5b83176 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/less.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:358f543967dbe4af676cf3bed19b80ffe5e90bdbeed3a7079ea20d9b1b2e95c8 +size 2289 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/less_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/less_equal.hpp new file mode 100644 index 0000000..bda02be --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/less_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05280a36353a5cfaa5b8e83915e4993e382ca496da997cba9a8ccdb517178cf4 +size 2380 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/list.hpp new file mode 100644 index 0000000..1384cff --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:00a452e40b988a1a25e004e4e49248704f2750fd7010810f8bff49ad56afe7b2 +size 14620 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/list_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/list_c.hpp new file mode 100644 index 0000000..1d30800 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/list_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2beb061c6a2630d4bcfd38d186608537ff7e1e32932ff0e4c91e3777657e15aa +size 13129 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/map.hpp new file mode 100644 index 0000000..317d8ad --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:193080ade16f2bfa0b096b6d67191bf7bfed3da2db0651ef3c043d3f0444610d +size 14547 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/minus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/minus.hpp new file mode 100644 index 0000000..0d0595d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/minus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7bb1c0d7b87dc733cd219689a7aa814b6d9e08ede884a331210e6ffb92f2a457 +size 3058 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/modulus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/modulus.hpp new file mode 100644 index 0000000..3f522a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/modulus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4666eeae7e9ac1def8b320bfebe971cf96bfccf337c959d5c111b2173a18fd8 +size 2552 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/not_equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/not_equal_to.hpp new file mode 100644 index 0000000..469ec8c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/not_equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5fb115dcd98f925238be387148b0506073e6d9d7f076ec2313a47523823e4cc +size 2410 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/or.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/or.hpp new file mode 100644 index 0000000..74e9869 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/or.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f4bdb93ca20a0836db578101deef4eff29f57337ba38a1c449f695d3ef638a0 +size 1384 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/placeholders.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/placeholders.hpp new file mode 100644 index 0000000..b8ef78d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/placeholders.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3d080d1d6bdd3d373c1fa5f19cad988430dfc29a626f7ed5f1e7abaa4381fa8 +size 2211 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/plus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/plus.hpp new file mode 100644 index 0000000..fe63bbb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/plus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:503788f5d2d053f93c04e135d6a568fac773383d9413375f7e61585f2e818725 +size 3035 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/quote.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/quote.hpp new file mode 100644 index 0000000..ef000cb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/quote.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7881345c5b69527ec6fc972071155341def05719cae294c4ea8b56892032eb3 +size 292 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/reverse_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/reverse_fold_impl.hpp new file mode 100644 index 0000000..44a8100 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/reverse_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79505de6fd04df160b8177c82b8f8caed195387bf48f8adb307b7ffb68d6024a +size 9758 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/reverse_iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/reverse_iter_fold_impl.hpp new file mode 100644 index 0000000..3d85503 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/reverse_iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b2a6266fdb4b7c12812dd9dca576eb2506d1177b8eccc66f1d89c6a048149c1c +size 9138 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/set.hpp new file mode 100644 index 0000000..a6abcdc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d18a2f67529ace4533087c2966eabf00444d75fcd0ecda9ebdd8672307d02c0 +size 14547 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/set_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/set_c.hpp new file mode 100644 index 0000000..4ca2ccd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/set_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:311d65179abf1db1872e4cfe5cbf9df0cd11259cb11a36888cd81104f4663257 +size 13056 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/shift_left.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/shift_left.hpp new file mode 100644 index 0000000..2a69b0f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/shift_left.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d25d214690d87cc5ac5ee15173fa933ab570293dff245be8df33a606a43b5f2e +size 2570 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/shift_right.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/shift_right.hpp new file mode 100644 index 0000000..f3ac67b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/shift_right.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0539c283227179578848857ed9416cd6cd7a4d57e9accb89e42e35c1c75b37ae +size 2587 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/template_arity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/template_arity.hpp new file mode 100644 index 0000000..1d25e19 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/template_arity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4cbcb3b2451ac6a6c643e2ffa2538d8e2262ea4de7fc29a5503184989f4bc1c9 +size 833 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/times.hpp new file mode 100644 index 0000000..9ad3274 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d02a737bc43005cc7dbc5c2d0e9311791534780a67d2a61a1bc22af368c1d7d6 +size 3058 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/unpack_args.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/unpack_args.hpp new file mode 100644 index 0000000..aa9deb2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/unpack_args.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:280ab64981ecb9acf9bb4f17ea8c803a7e79ded65e30ead506a0104a76e7ad4b +size 2296 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/vector.hpp new file mode 100644 index 0000000..3a5b8a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e85b42966bd78b28f0c863cb0bb0acf7adeca1c70ed0e576a0da18d89acd48cf +size 14766 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/vector_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/vector_c.hpp new file mode 100644 index 0000000..1f8fcfb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc60/vector_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4eb75141c5083226384a062d286ed589226545f1f9bb140f81c1f7ae6ef716d7 +size 13905 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/advance_backward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/advance_backward.hpp new file mode 100644 index 0000000..7c8960e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/advance_backward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4c03c83e9e3950e42ee825cb10d94c3e54af988a8bf5517a44265e8e56b4be3 +size 2206 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/advance_forward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/advance_forward.hpp new file mode 100644 index 0000000..913b5b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/advance_forward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50d41920b3f3d73804897c16f790f269609c2684db7bb21f6bb94fd461a5aa78 +size 2186 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/and.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/and.hpp new file mode 100644 index 0000000..914b945 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/and.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e022a01294d586476190960b4155f0e0bf45f3832d1539190e3c01c77f6973c +size 1374 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/apply.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/apply.hpp new file mode 100644 index 0000000..ae24bb9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/apply.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5937ad19ebba092c24ef64e7d004972de9d08435b47a497511138eebb9358bde +size 2515 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/apply_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/apply_fwd.hpp new file mode 100644 index 0000000..2708f56 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/apply_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c560cb1faf80770bab1a5716c61566a3863d242ecf71e585d2b017d9c8cbf86 +size 829 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/apply_wrap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/apply_wrap.hpp new file mode 100644 index 0000000..6861367 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/apply_wrap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9fbcc4a587492c3474c60d2e9564e24a16a78776afdcecb6960d24df0e17b851 +size 2055 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/arg.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/arg.hpp new file mode 100644 index 0000000..2cc570d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/arg.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8dd55033624e38bf06e1c3c2a808b2c052b47403968a151ed349dd66928ad251 +size 2893 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/basic_bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/basic_bind.hpp new file mode 100644 index 0000000..7b163da --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/basic_bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e4028082921f5bed438e7feafcb743a9376aa3f54d789538fb844aa784f9e00 +size 7357 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/bind.hpp new file mode 100644 index 0000000..e4c2e61 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:add03e5ab486db0b3c75dfc725f0d033964aeab87678154d5580309152143045 +size 10869 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/bind_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/bind_fwd.hpp new file mode 100644 index 0000000..c3c2a2b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/bind_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e922cd7f3aa2dd146d2ee7c4a06205b02fefadbf27cbbb51c60b893e453d24ea +size 822 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/bitand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/bitand.hpp new file mode 100644 index 0000000..939ac73 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/bitand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a9110766ed9ba7e3781f18b883536e8783f459b669f704d42610fef0e4760a5 +size 3139 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/bitor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/bitor.hpp new file mode 100644 index 0000000..270f8d1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/bitor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d1e31648147c74a1839eb63e808fcd77b0692680cf4cc029457159dabb99433 +size 3116 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/bitxor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/bitxor.hpp new file mode 100644 index 0000000..910f828 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/bitxor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a75da53ae095275e503dff1b5258eb91453711c8ce6279ba06240ab9ba68e6e7 +size 3139 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/deque.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/deque.hpp new file mode 100644 index 0000000..bf2cb6e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/deque.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afe19d5ffbbd006c2451b60340782751d7c3dd9cc750234d3bbced631c32e696 +size 14714 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/divides.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/divides.hpp new file mode 100644 index 0000000..0b7c04d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/divides.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17bbe20780afd4e6b08e688d1433a93d410c42558fee8b4b7921b084a8dbf26f +size 3124 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/equal_to.hpp new file mode 100644 index 0000000..ee244fc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d8feabfebf9bb500296ae6fd98acc3437f69576c62c6bfb62e7b79d461fe9fe +size 2334 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/fold_impl.hpp new file mode 100644 index 0000000..c6bc795 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:06860ea1510a11a9c9a9e95208dbde1ec2dedccd5cb2d82a8de93a3c307cb35f +size 5758 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/full_lambda.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/full_lambda.hpp new file mode 100644 index 0000000..8eddd50 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/full_lambda.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed8ad8fb76d22414f34292b139533c89db4c70270f84e40db13884239e6c3d60 +size 11215 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/greater.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/greater.hpp new file mode 100644 index 0000000..eb1c36f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/greater.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a552a40a32e158d9774dae4ce9cec3545c1b9794034f2e395783171d7147064 +size 2318 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/greater_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/greater_equal.hpp new file mode 100644 index 0000000..c4dbb6a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/greater_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18c750d86dd4ea13d6b97e0fc07186fd6fc664edb2d8243fbe85cd41b095fc40 +size 2409 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/inherit.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/inherit.hpp new file mode 100644 index 0000000..7666a0a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/inherit.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:80903ee2104e741d24b3c693698a5f8a33bd7a35714dd5468c9d12ed2bbe7f2a +size 3265 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/iter_fold_if_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/iter_fold_if_impl.hpp new file mode 100644 index 0000000..c1acc01 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/iter_fold_if_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acc097fe7a8a705d537a17859f2f6ff2f7ce7e687261e1f4235f794fdb4688f8 +size 4274 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/iter_fold_impl.hpp new file mode 100644 index 0000000..5e0e8ab --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6899060d4c524736d22aef1f81fb222007058a5001e6549c8bcce1432973b9ea +size 5597 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/lambda_no_ctps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/lambda_no_ctps.hpp new file mode 100644 index 0000000..e1b521b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/lambda_no_ctps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3387b7806a1e6c0a6109cc323509d8dd10e15b7f8c2cff882013c07168231433 +size 6477 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/less.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/less.hpp new file mode 100644 index 0000000..df821f6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/less.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cdd023290a901c5b2e4eaad0650c6666a85af8a0b153d32fd3c561aef2c935be +size 2273 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/less_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/less_equal.hpp new file mode 100644 index 0000000..49a97b8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/less_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85155e73522f906f0ea2c8d228c5915c00dd81fc8ba3c961aca7fe671252af06 +size 2364 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/list.hpp new file mode 100644 index 0000000..1384cff --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:00a452e40b988a1a25e004e4e49248704f2750fd7010810f8bff49ad56afe7b2 +size 14620 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/list_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/list_c.hpp new file mode 100644 index 0000000..1d30800 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/list_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2beb061c6a2630d4bcfd38d186608537ff7e1e32932ff0e4c91e3777657e15aa +size 13129 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/map.hpp new file mode 100644 index 0000000..317d8ad --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:193080ade16f2bfa0b096b6d67191bf7bfed3da2db0651ef3c043d3f0444610d +size 14547 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/minus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/minus.hpp new file mode 100644 index 0000000..9471cbe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/minus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb24a03e18e5684a86cb5c6f0bfd40d1f7da8067047d78cf2b9d140e441fe962 +size 3078 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/modulus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/modulus.hpp new file mode 100644 index 0000000..533cb77 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/modulus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fef96edfc8fb060733a024d56108e0e56c4ccc86bf00dce3232c36b80c0620d7 +size 2536 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/not_equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/not_equal_to.hpp new file mode 100644 index 0000000..7f7fb0b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/not_equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51b66db91e7a6b901f2a4c92cd41a0537f9e1a49b8a56af7faf63b141fca4fa0 +size 2394 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/or.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/or.hpp new file mode 100644 index 0000000..84a33cf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/or.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:89486f95fda0b7d0fcd29f6d0b441adf602e3fc3156e18d5992a5debf8682e3e +size 1375 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/placeholders.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/placeholders.hpp new file mode 100644 index 0000000..b8ef78d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/placeholders.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3d080d1d6bdd3d373c1fa5f19cad988430dfc29a626f7ed5f1e7abaa4381fa8 +size 2211 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/plus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/plus.hpp new file mode 100644 index 0000000..6c1e2a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/plus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b1a74da0f1608f664c97b6d718463c7898f70d0510af40a1abef47767ed6186 +size 3055 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/quote.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/quote.hpp new file mode 100644 index 0000000..fe5e7a7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/quote.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c9bb597547c1fc8fd076c12dd5f34e4047b90e984544029396990b1bdb9e6fdb +size 2236 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/reverse_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/reverse_fold_impl.hpp new file mode 100644 index 0000000..1ee6d3c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/reverse_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d35ab02a3f9c90712bb99fceecc74f34b675bbea2751aa00d735935bc790af20 +size 8870 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/reverse_iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/reverse_iter_fold_impl.hpp new file mode 100644 index 0000000..a4d0254 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/reverse_iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:159bc9d2c3b48d007b76dfe2f08274377c7a8a8b7e0b003f174eaaeecfa59c97 +size 8250 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/set.hpp new file mode 100644 index 0000000..a6abcdc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d18a2f67529ace4533087c2966eabf00444d75fcd0ecda9ebdd8672307d02c0 +size 14547 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/set_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/set_c.hpp new file mode 100644 index 0000000..4ca2ccd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/set_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:311d65179abf1db1872e4cfe5cbf9df0cd11259cb11a36888cd81104f4663257 +size 13056 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/shift_left.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/shift_left.hpp new file mode 100644 index 0000000..7abd556 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/shift_left.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6fafe9168d432e15459680ed280091c3156fcd5b03fe49c51952db075b3ea5a8 +size 2554 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/shift_right.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/shift_right.hpp new file mode 100644 index 0000000..5994fa8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/shift_right.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2334be3ff1f8ad40d04cf8fd5ddd664bad1b9ddecd86da2736c2b9034a9b674d +size 2571 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/template_arity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/template_arity.hpp new file mode 100644 index 0000000..1d25e19 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/template_arity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4cbcb3b2451ac6a6c643e2ffa2538d8e2262ea4de7fc29a5503184989f4bc1c9 +size 833 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/times.hpp new file mode 100644 index 0000000..ae0e3cd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fda2098cd33f86052ef1880498169b1def4e672399e5cf422a8135459a18b303 +size 3078 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/unpack_args.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/unpack_args.hpp new file mode 100644 index 0000000..aa9deb2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/unpack_args.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:280ab64981ecb9acf9bb4f17ea8c803a7e79ded65e30ead506a0104a76e7ad4b +size 2296 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/vector.hpp new file mode 100644 index 0000000..3a5b8a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e85b42966bd78b28f0c863cb0bb0acf7adeca1c70ed0e576a0da18d89acd48cf +size 14766 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/vector_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/vector_c.hpp new file mode 100644 index 0000000..1f8fcfb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/msvc70/vector_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4eb75141c5083226384a062d286ed589226545f1f9bb140f81c1f7ae6ef716d7 +size 13905 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/advance_backward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/advance_backward.hpp new file mode 100644 index 0000000..7c8960e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/advance_backward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4c03c83e9e3950e42ee825cb10d94c3e54af988a8bf5517a44265e8e56b4be3 +size 2206 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/advance_forward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/advance_forward.hpp new file mode 100644 index 0000000..913b5b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/advance_forward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50d41920b3f3d73804897c16f790f269609c2684db7bb21f6bb94fd461a5aa78 +size 2186 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/and.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/and.hpp new file mode 100644 index 0000000..ea10ec7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/and.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48f7e389aa4c3af94cf7a3fa8bb021335cf7c4c45f33251c5dce7b6d100fe1c4 +size 1257 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/apply.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/apply.hpp new file mode 100644 index 0000000..f779704 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/apply.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42dacbfb2158468c189ee73d0cb03664f0109008e6933976bf09a94852cae4f6 +size 2744 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/apply_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/apply_fwd.hpp new file mode 100644 index 0000000..a9455bf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/apply_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e5bd2d53e79be26d178acc39a2629864f6fb00a6641b60d811df49d0abe9e79 +size 972 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/apply_wrap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/apply_wrap.hpp new file mode 100644 index 0000000..12c6608 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/apply_wrap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ab2c4e5056a15108f72c4c0fc86495baa9b35fd8d51e6d572eb314667ccd4de +size 6956 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/arg.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/arg.hpp new file mode 100644 index 0000000..2cc570d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/arg.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8dd55033624e38bf06e1c3c2a808b2c052b47403968a151ed349dd66928ad251 +size 2893 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/basic_bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/basic_bind.hpp new file mode 100644 index 0000000..9bc5fc2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/basic_bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f0c1779e43d8f709ce7e9d08888c621c23fe724cc63b7ee9edf5f4e4ed7324f +size 10260 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/bind.hpp new file mode 100644 index 0000000..66d4be9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10c17e1a8b7279f7db31cdf284a82788ba473eb36e02b607beecc2ba369b28d3 +size 14409 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/bind_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/bind_fwd.hpp new file mode 100644 index 0000000..1a9018e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/bind_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87f020aaafed9bcbdc23b541798663f5609176b9b1b0a6611b8ed48a8cecffe0 +size 964 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/bitand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/bitand.hpp new file mode 100644 index 0000000..754ad86 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/bitand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04361fb0c214fe0baea75dee7988b6f3a8390cbf1e0af2adceb4cf7831e6f8f4 +size 3208 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/bitor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/bitor.hpp new file mode 100644 index 0000000..d5b8a74 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/bitor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e331fc1e6f2feadd2799d3104d78e4aac09bf189a3785cff1cb2d858122c0535 +size 3178 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/bitxor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/bitxor.hpp new file mode 100644 index 0000000..d6c2516 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/bitxor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d64fe515d7ab31f32469ca0c6bb3b1d5d801b048c2e9f592f1de596015dff4ac +size 3208 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/deque.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/deque.hpp new file mode 100644 index 0000000..1cd3ad3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/deque.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52440eb38f109bbd3bb99542042d25575ce8c9c6e301c4a404e88d57ae3c8de9 +size 9723 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/divides.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/divides.hpp new file mode 100644 index 0000000..16a2d9f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/divides.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8447006b0a3db43b6790fd4afccf07a0f1130db248807563096f1c86cd301444 +size 3191 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/equal_to.hpp new file mode 100644 index 0000000..7445868 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02ce64be459ad25c1c36bd0839a3fef6fc405f7a7744f12ac0dc6ebd74e13b19 +size 2097 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/fold_impl.hpp new file mode 100644 index 0000000..88fb149 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f74d7a7520ecc7324a6fe40fae8bf9de3fc881bc6ced30ac1ec3389d2bc9581d +size 4354 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/full_lambda.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/full_lambda.hpp new file mode 100644 index 0000000..8eddd50 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/full_lambda.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed8ad8fb76d22414f34292b139533c89db4c70270f84e40db13884239e6c3d60 +size 11215 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/greater.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/greater.hpp new file mode 100644 index 0000000..38840c3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/greater.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:045aa5d6bd8a3d800d4e88b3f059a31830583c77f1842638a4ac16e9be020502 +size 2080 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/greater_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/greater_equal.hpp new file mode 100644 index 0000000..5bab029 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/greater_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10790da3ecc6537acf7907af6a0271e3109e350b7929c2da1cf3f3cad177c5e1 +size 2171 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/inherit.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/inherit.hpp new file mode 100644 index 0000000..9567f1d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/inherit.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67eec86cd760d5d50464a5b916c6f0fcb70389b6afdf4b1dc1a01c3f29c67ccd +size 2832 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/iter_fold_if_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/iter_fold_if_impl.hpp new file mode 100644 index 0000000..c1acc01 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/iter_fold_if_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acc097fe7a8a705d537a17859f2f6ff2f7ce7e687261e1f4235f794fdb4688f8 +size 4274 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/iter_fold_impl.hpp new file mode 100644 index 0000000..cca419a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56eee865128b7608c098510ad708a849907a80c9f9f8314e5c6cf416992079e5 +size 4158 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/lambda_no_ctps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/lambda_no_ctps.hpp new file mode 100644 index 0000000..e1b521b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/lambda_no_ctps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3387b7806a1e6c0a6109cc323509d8dd10e15b7f8c2cff882013c07168231433 +size 6477 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/less.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/less.hpp new file mode 100644 index 0000000..15bcc1f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/less.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ec24946d87d5a75ab09d7933c37918bf8a5486ad1954102e3e240def7e18585 +size 2035 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/less_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/less_equal.hpp new file mode 100644 index 0000000..3304449 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/less_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5d569aca0ec9bf6fd37393a9143f3c7e7dffea5d02ddaee311d69df027aee32 +size 2126 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/list.hpp new file mode 100644 index 0000000..763186d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e73c15b7e2fb9c62158af870a854a335fec2490a0f74100a706baad058a4d158 +size 9616 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/list_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/list_c.hpp new file mode 100644 index 0000000..2032686 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/list_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ee008389f1cca2faf27ed1da73c939ce2ff78296416feb06958c2466bb93345 +size 10717 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/map.hpp new file mode 100644 index 0000000..4625f58 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a002cc4fbd7bf1a8fc5e286ae3b19d9708c0036dc2832babbca4d1a872adb183 +size 9551 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/minus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/minus.hpp new file mode 100644 index 0000000..adf3979 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/minus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e298cb9e3132ce14a2ec5ffda044ace342053395ffdb0fdc210671f25946992 +size 3131 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/modulus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/modulus.hpp new file mode 100644 index 0000000..14ea63c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/modulus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:942f0e6c8b73652c912f11456bc9eacd7f8c0f778e4e2bab8ec10763c9e1cb69 +size 2293 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/not_equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/not_equal_to.hpp new file mode 100644 index 0000000..eb85dfc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/not_equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4fb0d2825097e4f8e452514b29d77ac13c9da3ef1860d5dbec1c915b61aaae9 +size 2156 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/or.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/or.hpp new file mode 100644 index 0000000..61413b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/or.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:112ec4d3cb8cc4a9ee79b88a8e585065e67e8c4d86935262516eb7a7943f3820 +size 1258 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/placeholders.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/placeholders.hpp new file mode 100644 index 0000000..b8ef78d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/placeholders.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3d080d1d6bdd3d373c1fa5f19cad988430dfc29a626f7ed5f1e7abaa4381fa8 +size 2211 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/plus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/plus.hpp new file mode 100644 index 0000000..e9704d5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/plus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0b612a0a8f0eeb3414644e5c028a242911ffa119a6460d9acc71497c8701372 +size 3101 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/quote.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/quote.hpp new file mode 100644 index 0000000..af5c665 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/quote.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9cf2f4f8b21bb706886b2adb76fa1c1eca3ea06c9fd43e1889b0e5dcf4825bc3 +size 2187 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/reverse_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/reverse_fold_impl.hpp new file mode 100644 index 0000000..8bd7744 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/reverse_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:16293df37c25ff8a277b36af2a1184d3883d5aa73faae01768c027ba8c88802f +size 7372 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/reverse_iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/reverse_iter_fold_impl.hpp new file mode 100644 index 0000000..223d946 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/reverse_iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba3bcf3f96dbae8d9cc54d8df52417c2df1346aeb6c3a3d3f4ddf0d5aa874847 +size 6717 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/set.hpp new file mode 100644 index 0000000..3eb75d2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4e7071dad95512f5828c2ac50f842f169d093297cdb2ba903085d0691af03cd +size 9551 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/set_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/set_c.hpp new file mode 100644 index 0000000..5f8a1dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/set_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:608eb89b22961ab2a5b1ba5cdfc115bc58be754a108d1038bf498de563e1eefc +size 10652 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/shift_left.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/shift_left.hpp new file mode 100644 index 0000000..d546fb9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/shift_left.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b91279f3a368dccec4a42dd1ee4b76925dc09a6e5a20ab04a5116fd048e2cf11 +size 2252 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/shift_right.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/shift_right.hpp new file mode 100644 index 0000000..cd9d0bb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/shift_right.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3552891d80d206bcad21c2c1b191ee3e0c63096448939e878ad74955c529c384 +size 2267 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/template_arity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/template_arity.hpp new file mode 100644 index 0000000..e29c8bf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/template_arity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7f7f402db7af2a929cd4eea606d870506e73ab076f073cd5b0d08322cb718d9 +size 306 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/times.hpp new file mode 100644 index 0000000..2143388 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f79649346ec889d18117680a67ac8f28082fe51abe91ac62eaa3c505fbb5065 +size 3131 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/unpack_args.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/unpack_args.hpp new file mode 100644 index 0000000..3d93ce2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/unpack_args.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91d1e3057b2731938c0e74eede0338fbe7f2c7d578d1d888bcbc8d3a50bde152 +size 1906 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/vector.hpp new file mode 100644 index 0000000..96bdf70 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e22c161ecfd115c7f9154b25cf8e6835e2e30a6d49dbeddf4d98b012fd018c7 +size 9746 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/vector_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/vector_c.hpp new file mode 100644 index 0000000..01100ce --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/mwcw/vector_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:630a3139e05016e8afd31fbedd1190ec07f6d31c8ddb5a2ce4399e551f07ac64 +size 12237 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/advance_backward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/advance_backward.hpp new file mode 100644 index 0000000..7c8960e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/advance_backward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4c03c83e9e3950e42ee825cb10d94c3e54af988a8bf5517a44265e8e56b4be3 +size 2206 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/advance_forward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/advance_forward.hpp new file mode 100644 index 0000000..913b5b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/advance_forward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50d41920b3f3d73804897c16f790f269609c2684db7bb21f6bb94fd461a5aa78 +size 2186 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/and.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/and.hpp new file mode 100644 index 0000000..e0038e2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/and.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:626bc53a4ac1b8b27a6c3dba518a7572a36329dc6aa708c8314f854e1d97bde6 +size 1383 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/apply.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/apply.hpp new file mode 100644 index 0000000..414d444 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/apply.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17875a0c7163cdf64a3c138338c4e4dba5c1bc5b56360a814b15dc052722b15c +size 4474 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/apply_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/apply_fwd.hpp new file mode 100644 index 0000000..10b67e9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/apply_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9370ae2f082ee75482ad769ab861250d5e7e565fe2d4f823111ec61d99281629 +size 915 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/apply_wrap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/apply_wrap.hpp new file mode 100644 index 0000000..605b3ec --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/apply_wrap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b27736f5cc1b340b64d7317faca4ee84c424e708b64c01290bf87a8897caf83 +size 1164 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/arg.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/arg.hpp new file mode 100644 index 0000000..2cc570d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/arg.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8dd55033624e38bf06e1c3c2a808b2c052b47403968a151ed349dd66928ad251 +size 2893 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/basic_bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/basic_bind.hpp new file mode 100644 index 0000000..24fe240 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/basic_bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d58e38670650cb718b4ca909f1d78b9b50bc2633e0ed6b75079c8fbb2a1064f5 +size 10017 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/bind.hpp new file mode 100644 index 0000000..ab26598 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92ca444c7bcb6893399a7908c7b9b660ef25d4dff786457f4bf000dc3eb68ef7 +size 13529 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/bind_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/bind_fwd.hpp new file mode 100644 index 0000000..1a9018e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/bind_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87f020aaafed9bcbdc23b541798663f5609176b9b1b0a6611b8ed48a8cecffe0 +size 964 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/bitand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/bitand.hpp new file mode 100644 index 0000000..0911931 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/bitand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e552044a1929bbe5574bed8d13c4596da7a068a4e3a25a6735d26b64a958e67a +size 2855 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/bitor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/bitor.hpp new file mode 100644 index 0000000..b00e528 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/bitor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ba6d20374c28253126c365336c059fffbeaf842ffe09c4f100b13db9199047a +size 2834 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/bitxor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/bitxor.hpp new file mode 100644 index 0000000..8b073b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/bitxor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e635fc547ee9adb1aa176ce25e94bc941332f25478809ff62ce5eab6a4881876 +size 2855 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/deque.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/deque.hpp new file mode 100644 index 0000000..bf2cb6e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/deque.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afe19d5ffbbd006c2451b60340782751d7c3dd9cc750234d3bbced631c32e696 +size 14714 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/divides.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/divides.hpp new file mode 100644 index 0000000..e9eff7b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/divides.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:934e537bd3615db7b8dd02df5757997b82f31d4232446e02d2edf54d2cab4ebe +size 2838 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/equal_to.hpp new file mode 100644 index 0000000..7beddf8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:285931eb5709f16bb9e6622d1de8a24de0ad4a2330ca053a1cfe0e1982c26f67 +size 2091 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/fold_impl.hpp new file mode 100644 index 0000000..c6bc795 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:06860ea1510a11a9c9a9e95208dbde1ec2dedccd5cb2d82a8de93a3c307cb35f +size 5758 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/full_lambda.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/full_lambda.hpp new file mode 100644 index 0000000..8eddd50 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/full_lambda.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed8ad8fb76d22414f34292b139533c89db4c70270f84e40db13884239e6c3d60 +size 11215 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/greater.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/greater.hpp new file mode 100644 index 0000000..e137a2f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/greater.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a131e96e06838378abb55eda8f3a197903bce070b4ce3f82cb028e835760bdc4 +size 2074 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/greater_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/greater_equal.hpp new file mode 100644 index 0000000..9b46ae0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/greater_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e2b73fa5e056f4268b830d99be86c5a1961c9bc30293ed08d0e5e931117f2b09 +size 2165 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/inherit.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/inherit.hpp new file mode 100644 index 0000000..7666a0a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/inherit.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:80903ee2104e741d24b3c693698a5f8a33bd7a35714dd5468c9d12ed2bbe7f2a +size 3265 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/iter_fold_if_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/iter_fold_if_impl.hpp new file mode 100644 index 0000000..c1acc01 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/iter_fold_if_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acc097fe7a8a705d537a17859f2f6ff2f7ce7e687261e1f4235f794fdb4688f8 +size 4274 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/iter_fold_impl.hpp new file mode 100644 index 0000000..5e0e8ab --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6899060d4c524736d22aef1f81fb222007058a5001e6549c8bcce1432973b9ea +size 5597 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/lambda_no_ctps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/lambda_no_ctps.hpp new file mode 100644 index 0000000..e1b521b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/lambda_no_ctps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3387b7806a1e6c0a6109cc323509d8dd10e15b7f8c2cff882013c07168231433 +size 6477 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/less.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/less.hpp new file mode 100644 index 0000000..eebb92a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/less.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1961ca877009444fa02a629ffe81b4de3090ec5520e0341e3706fa5dc9f90baf +size 2029 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/less_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/less_equal.hpp new file mode 100644 index 0000000..20a3388 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/less_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e2d57256bc06b20648028cfd8205c4b1bb4a830d272b0bb2d4719c53478a4448 +size 2120 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/list.hpp new file mode 100644 index 0000000..1384cff --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:00a452e40b988a1a25e004e4e49248704f2750fd7010810f8bff49ad56afe7b2 +size 14620 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/list_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/list_c.hpp new file mode 100644 index 0000000..1d30800 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/list_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2beb061c6a2630d4bcfd38d186608537ff7e1e32932ff0e4c91e3777657e15aa +size 13129 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/map.hpp new file mode 100644 index 0000000..317d8ad --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:193080ade16f2bfa0b096b6d67191bf7bfed3da2db0651ef3c043d3f0444610d +size 14547 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/minus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/minus.hpp new file mode 100644 index 0000000..5d4132e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/minus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47bcb8ddf66f16b01026ac8f7ffddf6938110af91868492147990a09e49fc05d +size 2796 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/modulus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/modulus.hpp new file mode 100644 index 0000000..c72923f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/modulus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a13855e3190a8eb4d79ee67dd791f8d36fd13102af425af6b65f0bf88fe81e9c +size 2287 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/not_equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/not_equal_to.hpp new file mode 100644 index 0000000..35ad47e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/not_equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29af8019eeae5b3513f4bc8824714dec3c0106d6851fce6e0edef0b83c3b1614 +size 2150 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/or.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/or.hpp new file mode 100644 index 0000000..74e9869 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/or.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f4bdb93ca20a0836db578101deef4eff29f57337ba38a1c449f695d3ef638a0 +size 1384 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/placeholders.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/placeholders.hpp new file mode 100644 index 0000000..b8ef78d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/placeholders.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3d080d1d6bdd3d373c1fa5f19cad988430dfc29a626f7ed5f1e7abaa4381fa8 +size 2211 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/plus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/plus.hpp new file mode 100644 index 0000000..c0b9de4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/plus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92736597f3a65aedc540e859099c6d8682de595278b11c47cd919e9d635cba40 +size 2775 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/quote.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/quote.hpp new file mode 100644 index 0000000..fe5e7a7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/quote.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c9bb597547c1fc8fd076c12dd5f34e4047b90e984544029396990b1bdb9e6fdb +size 2236 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/reverse_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/reverse_fold_impl.hpp new file mode 100644 index 0000000..1ee6d3c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/reverse_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d35ab02a3f9c90712bb99fceecc74f34b675bbea2751aa00d735935bc790af20 +size 8870 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/reverse_iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/reverse_iter_fold_impl.hpp new file mode 100644 index 0000000..a4d0254 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/reverse_iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:159bc9d2c3b48d007b76dfe2f08274377c7a8a8b7e0b003f174eaaeecfa59c97 +size 8250 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/set.hpp new file mode 100644 index 0000000..a6abcdc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d18a2f67529ace4533087c2966eabf00444d75fcd0ecda9ebdd8672307d02c0 +size 14547 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/set_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/set_c.hpp new file mode 100644 index 0000000..4ca2ccd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/set_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:311d65179abf1db1872e4cfe5cbf9df0cd11259cb11a36888cd81104f4663257 +size 13056 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/shift_left.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/shift_left.hpp new file mode 100644 index 0000000..9f3b485 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/shift_left.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f66c9222adb66c3082c95168b27670ae2b4fd3e73e50d0bf1a3c14d00d0e0ea +size 2246 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/shift_right.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/shift_right.hpp new file mode 100644 index 0000000..5473b0d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/shift_right.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ec42899eafaf37a26eb0472c13f6e43e2b187fdb347bb342f9789ba100499fb4 +size 2261 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/template_arity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/template_arity.hpp new file mode 100644 index 0000000..09be163 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/template_arity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c008c25aa90b8dc31d8d524dc31eac50e775f0c2955358d90a035beba74ca366 +size 767 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/times.hpp new file mode 100644 index 0000000..17060fd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f1f42cae699ee9220fad203abbd028e0faa263da736be643ce56421ceb7d453b +size 2796 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/unpack_args.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/unpack_args.hpp new file mode 100644 index 0000000..aa9deb2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/unpack_args.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:280ab64981ecb9acf9bb4f17ea8c803a7e79ded65e30ead506a0104a76e7ad4b +size 2296 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/vector.hpp new file mode 100644 index 0000000..3a5b8a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e85b42966bd78b28f0c863cb0bb0acf7adeca1c70ed0e576a0da18d89acd48cf +size 14766 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/vector_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/vector_c.hpp new file mode 100644 index 0000000..1f8fcfb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ctps/vector_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4eb75141c5083226384a062d286ed589226545f1f9bb140f81c1f7ae6ef716d7 +size 13905 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/advance_backward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/advance_backward.hpp new file mode 100644 index 0000000..7c8960e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/advance_backward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4c03c83e9e3950e42ee825cb10d94c3e54af988a8bf5517a44265e8e56b4be3 +size 2206 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/advance_forward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/advance_forward.hpp new file mode 100644 index 0000000..913b5b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/advance_forward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50d41920b3f3d73804897c16f790f269609c2684db7bb21f6bb94fd461a5aa78 +size 2186 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/and.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/and.hpp new file mode 100644 index 0000000..ea10ec7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/and.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48f7e389aa4c3af94cf7a3fa8bb021335cf7c4c45f33251c5dce7b6d100fe1c4 +size 1257 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/apply.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/apply.hpp new file mode 100644 index 0000000..f779704 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/apply.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42dacbfb2158468c189ee73d0cb03664f0109008e6933976bf09a94852cae4f6 +size 2744 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/apply_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/apply_fwd.hpp new file mode 100644 index 0000000..a9455bf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/apply_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e5bd2d53e79be26d178acc39a2629864f6fb00a6641b60d811df49d0abe9e79 +size 972 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/apply_wrap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/apply_wrap.hpp new file mode 100644 index 0000000..9ab4d99 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/apply_wrap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5af7a500dc1f73b2175dd31d748c42ee2044fe95fe2e3a7e875c2f494aa68219 +size 1238 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/arg.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/arg.hpp new file mode 100644 index 0000000..2cc570d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/arg.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8dd55033624e38bf06e1c3c2a808b2c052b47403968a151ed349dd66928ad251 +size 2893 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/basic_bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/basic_bind.hpp new file mode 100644 index 0000000..8a0f66f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/basic_bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:250c73542ddbef5a838fb96b1aa9f9a89a87ddab4e89e7c3b94dcba523c46014 +size 8482 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/bind.hpp new file mode 100644 index 0000000..bd2e371 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d3884aa5d62ca2f07a8c136a50ba24b6593143dd79dc52d4641fe8f21de84c1 +size 11779 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/bind_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/bind_fwd.hpp new file mode 100644 index 0000000..1a9018e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/bind_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87f020aaafed9bcbdc23b541798663f5609176b9b1b0a6611b8ed48a8cecffe0 +size 964 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/bitand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/bitand.hpp new file mode 100644 index 0000000..6547ec0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/bitand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55f47c165028941ba60213f71d9c1c8260cd852f5aa9037be09c18b219e82d8a +size 3312 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/bitor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/bitor.hpp new file mode 100644 index 0000000..ace6169 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/bitor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:365d440a60565f083fb57ac488f7f9d12a4592b2bf2f1eb43a9caa4ba9c20bea +size 3280 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/bitxor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/bitxor.hpp new file mode 100644 index 0000000..a6467e5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/bitxor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7bd18e679129947faf674791612902486e51455e8af81dd96c24a824de3660b +size 3312 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/deque.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/deque.hpp new file mode 100644 index 0000000..1cd3ad3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/deque.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52440eb38f109bbd3bb99542042d25575ce8c9c6e301c4a404e88d57ae3c8de9 +size 9723 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/divides.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/divides.hpp new file mode 100644 index 0000000..a1bf2a2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/divides.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:841806855f1ecb1d5364ee7a5832c1895266dbcf389960c3209a3fa164779cb1 +size 3297 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/equal_to.hpp new file mode 100644 index 0000000..56a4b98 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03f7aab4fae511295fbed6aa13fc82efd7cd3c909a23d59e1f98187f644b9ff1 +size 2197 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/fold_impl.hpp new file mode 100644 index 0000000..88fb149 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f74d7a7520ecc7324a6fe40fae8bf9de3fc881bc6ced30ac1ec3389d2bc9581d +size 4354 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/full_lambda.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/full_lambda.hpp new file mode 100644 index 0000000..8eddd50 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/full_lambda.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed8ad8fb76d22414f34292b139533c89db4c70270f84e40db13884239e6c3d60 +size 11215 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/greater.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/greater.hpp new file mode 100644 index 0000000..e96a398 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/greater.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4e6594b8a654f07df3b8a2248f49dcecc75456c85077dd4966c79c4889d86b1 +size 2181 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/greater_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/greater_equal.hpp new file mode 100644 index 0000000..1dceb70 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/greater_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b26d3b382ff6b7b5fb2a3b69ccb2e70c4847ee7550cbd22a644e9d16015d492 +size 2272 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/inherit.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/inherit.hpp new file mode 100644 index 0000000..9567f1d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/inherit.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67eec86cd760d5d50464a5b916c6f0fcb70389b6afdf4b1dc1a01c3f29c67ccd +size 2832 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/iter_fold_if_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/iter_fold_if_impl.hpp new file mode 100644 index 0000000..c1acc01 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/iter_fold_if_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acc097fe7a8a705d537a17859f2f6ff2f7ce7e687261e1f4235f794fdb4688f8 +size 4274 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/iter_fold_impl.hpp new file mode 100644 index 0000000..cca419a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56eee865128b7608c098510ad708a849907a80c9f9f8314e5c6cf416992079e5 +size 4158 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/lambda_no_ctps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/lambda_no_ctps.hpp new file mode 100644 index 0000000..e1b521b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/lambda_no_ctps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3387b7806a1e6c0a6109cc323509d8dd10e15b7f8c2cff882013c07168231433 +size 6477 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/less.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/less.hpp new file mode 100644 index 0000000..f15cec2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/less.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca34a61e735f290760d041d9dd7f5d37b6a22a9a95d809c7191ce5c0b3c9a8b8 +size 2136 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/less_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/less_equal.hpp new file mode 100644 index 0000000..94ad4b8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/less_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:752d75a57b6adb2c93121f6f92ec78035488cddc7919cb21ca2bfe61de893b95 +size 2227 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/list.hpp new file mode 100644 index 0000000..763186d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e73c15b7e2fb9c62158af870a854a335fec2490a0f74100a706baad058a4d158 +size 9616 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/list_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/list_c.hpp new file mode 100644 index 0000000..2032686 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/list_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ee008389f1cca2faf27ed1da73c939ce2ff78296416feb06958c2466bb93345 +size 10717 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/map.hpp new file mode 100644 index 0000000..4625f58 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a002cc4fbd7bf1a8fc5e286ae3b19d9708c0036dc2832babbca4d1a872adb183 +size 9551 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/minus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/minus.hpp new file mode 100644 index 0000000..abb48fc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/minus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e23455510e76a32fcbd57c788e49350eb28a23dd6491eb4b006a0de540ebf44 +size 3233 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/modulus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/modulus.hpp new file mode 100644 index 0000000..f50c1d6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/modulus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6618b3af1a69d94e8fb0db3779cc59afe79643742b08be80d83acdeff71aa083 +size 2399 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/not_equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/not_equal_to.hpp new file mode 100644 index 0000000..dae38af --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/not_equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c6c600bedf8ca42ac86fab32f32dddd1b103e79519742f15a8d28db1a12e48f +size 2257 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/or.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/or.hpp new file mode 100644 index 0000000..61413b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/or.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:112ec4d3cb8cc4a9ee79b88a8e585065e67e8c4d86935262516eb7a7943f3820 +size 1258 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/placeholders.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/placeholders.hpp new file mode 100644 index 0000000..b8ef78d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/placeholders.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3d080d1d6bdd3d373c1fa5f19cad988430dfc29a626f7ed5f1e7abaa4381fa8 +size 2211 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/plus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/plus.hpp new file mode 100644 index 0000000..e6dcc13 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/plus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4fb69be800763cc55b387b54f763621a8f9b1f817838f2515f50251552fbc0ae +size 3201 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/quote.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/quote.hpp new file mode 100644 index 0000000..ef000cb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/quote.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7881345c5b69527ec6fc972071155341def05719cae294c4ea8b56892032eb3 +size 292 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/reverse_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/reverse_fold_impl.hpp new file mode 100644 index 0000000..8bd7744 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/reverse_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:16293df37c25ff8a277b36af2a1184d3883d5aa73faae01768c027ba8c88802f +size 7372 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/reverse_iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/reverse_iter_fold_impl.hpp new file mode 100644 index 0000000..223d946 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/reverse_iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba3bcf3f96dbae8d9cc54d8df52417c2df1346aeb6c3a3d3f4ddf0d5aa874847 +size 6717 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/set.hpp new file mode 100644 index 0000000..3eb75d2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4e7071dad95512f5828c2ac50f842f169d093297cdb2ba903085d0691af03cd +size 9551 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/set_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/set_c.hpp new file mode 100644 index 0000000..5f8a1dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/set_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:608eb89b22961ab2a5b1ba5cdfc115bc58be754a108d1038bf498de563e1eefc +size 10652 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/shift_left.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/shift_left.hpp new file mode 100644 index 0000000..af79738 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/shift_left.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7f16a43266d7ae88913f5a4b560216f63d83ba000ab8eb8301f5b1aeabf1afe +size 2417 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/shift_right.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/shift_right.hpp new file mode 100644 index 0000000..9cdf6aa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/shift_right.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46a2992c613a563f0a0380775411a5249e468c9745780232c615ca0365728792 +size 2434 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/template_arity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/template_arity.hpp new file mode 100644 index 0000000..09be163 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/template_arity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c008c25aa90b8dc31d8d524dc31eac50e775f0c2955358d90a035beba74ca366 +size 767 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/times.hpp new file mode 100644 index 0000000..8f10dbd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7706a9885b40de50fdade2fa440f90b99b770f665d74834f25d149fdd4035e7d +size 3233 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/unpack_args.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/unpack_args.hpp new file mode 100644 index 0000000..3d93ce2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/unpack_args.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91d1e3057b2731938c0e74eede0338fbe7f2c7d578d1d888bcbc8d3a50bde152 +size 1906 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/vector.hpp new file mode 100644 index 0000000..96bdf70 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e22c161ecfd115c7f9154b25cf8e6835e2e30a6d49dbeddf4d98b012fd018c7 +size 9746 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/vector_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/vector_c.hpp new file mode 100644 index 0000000..01100ce --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/no_ttp/vector_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:630a3139e05016e8afd31fbedd1190ec07f6d31c8ddb5a2ce4399e551f07ac64 +size 12237 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/advance_backward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/advance_backward.hpp new file mode 100644 index 0000000..7c8960e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/advance_backward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4c03c83e9e3950e42ee825cb10d94c3e54af988a8bf5517a44265e8e56b4be3 +size 2206 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/advance_forward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/advance_forward.hpp new file mode 100644 index 0000000..913b5b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/advance_forward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50d41920b3f3d73804897c16f790f269609c2684db7bb21f6bb94fd461a5aa78 +size 2186 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/and.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/and.hpp new file mode 100644 index 0000000..5eaac44 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/and.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad7d1282dcc8e799fac2d1b01c52bfb0d5dcdcfc4086496326f251138e28ff7a +size 1154 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/apply.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/apply.hpp new file mode 100644 index 0000000..d934f86 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/apply.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10c539730f88cb1c341d31397ea10a36df45e8af3026535adacfea259ca0f36b +size 2161 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/apply_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/apply_fwd.hpp new file mode 100644 index 0000000..a9455bf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/apply_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e5bd2d53e79be26d178acc39a2629864f6fb00a6641b60d811df49d0abe9e79 +size 972 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/apply_wrap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/apply_wrap.hpp new file mode 100644 index 0000000..9ab4d99 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/apply_wrap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5af7a500dc1f73b2175dd31d748c42ee2044fe95fe2e3a7e875c2f494aa68219 +size 1238 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/arg.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/arg.hpp new file mode 100644 index 0000000..2cc570d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/arg.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8dd55033624e38bf06e1c3c2a808b2c052b47403968a151ed349dd66928ad251 +size 2893 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/basic_bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/basic_bind.hpp new file mode 100644 index 0000000..9bc5fc2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/basic_bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f0c1779e43d8f709ce7e9d08888c621c23fe724cc63b7ee9edf5f4e4ed7324f +size 10260 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/bind.hpp new file mode 100644 index 0000000..66d4be9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10c17e1a8b7279f7db31cdf284a82788ba473eb36e02b607beecc2ba369b28d3 +size 14409 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/bind_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/bind_fwd.hpp new file mode 100644 index 0000000..1a9018e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/bind_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87f020aaafed9bcbdc23b541798663f5609176b9b1b0a6611b8ed48a8cecffe0 +size 964 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/bitand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/bitand.hpp new file mode 100644 index 0000000..bd00b2f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/bitand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4bd9d5d090a6671970c39b3d4e4fc9ad1faadb0d01b9e7fa6b959a435bfa508 +size 3101 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/bitor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/bitor.hpp new file mode 100644 index 0000000..88e6b43 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/bitor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9fa235711dc5c34be22b688b9c776989b5dd8bca09bd1957ef2c8b45eb040b2 +size 3072 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/bitxor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/bitxor.hpp new file mode 100644 index 0000000..f1dfdb5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/bitxor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87f8d30e7c197645d7187ff700b607c8de7418dda70b98eec57ad7fa936b4256 +size 3101 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/deque.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/deque.hpp new file mode 100644 index 0000000..1cd3ad3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/deque.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52440eb38f109bbd3bb99542042d25575ce8c9c6e301c4a404e88d57ae3c8de9 +size 9723 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/divides.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/divides.hpp new file mode 100644 index 0000000..081d69c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/divides.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:80020a6f74086bcb21f9f078404d7ae229183e8d2eb5124e0c1bb4a710b37ed2 +size 3084 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/equal_to.hpp new file mode 100644 index 0000000..a928a32 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:622f2aff9d41cf1d36d29cef2a6ab7b6d807afa135cbd3181c83353176fa756f +size 2040 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/fold_impl.hpp new file mode 100644 index 0000000..88fb149 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f74d7a7520ecc7324a6fe40fae8bf9de3fc881bc6ced30ac1ec3389d2bc9581d +size 4354 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/full_lambda.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/full_lambda.hpp new file mode 100644 index 0000000..8eddd50 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/full_lambda.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed8ad8fb76d22414f34292b139533c89db4c70270f84e40db13884239e6c3d60 +size 11215 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/greater.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/greater.hpp new file mode 100644 index 0000000..c1fd22f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/greater.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:594ea57b6dda4888da5a4a113a59f950ca11d024d2039025ae9704613a288301 +size 2024 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/greater_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/greater_equal.hpp new file mode 100644 index 0000000..c7e7359 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/greater_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8923f7199187d645b83e671197915317071b5f46a19a8e7dadfb8b2eb55f5afe +size 2109 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/inherit.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/inherit.hpp new file mode 100644 index 0000000..70be044 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/inherit.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e4f16f5181481038c98e1d14bdae1a8dab3acd1f0952499a969fe3093d61813d +size 2467 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/iter_fold_if_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/iter_fold_if_impl.hpp new file mode 100644 index 0000000..c1acc01 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/iter_fold_if_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acc097fe7a8a705d537a17859f2f6ff2f7ce7e687261e1f4235f794fdb4688f8 +size 4274 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/iter_fold_impl.hpp new file mode 100644 index 0000000..cca419a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56eee865128b7608c098510ad708a849907a80c9f9f8314e5c6cf416992079e5 +size 4158 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/lambda_no_ctps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/lambda_no_ctps.hpp new file mode 100644 index 0000000..d6e1fb8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/lambda_no_ctps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7687e5715126913c0f29f61ba86eef94d7fdaa705c47d08587285adc1b9e790f +size 6414 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/less.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/less.hpp new file mode 100644 index 0000000..4df5dae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/less.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67641601043e466b350f94941c1d3e02a18d8b0ff68281458f9956ee951f1b08 +size 1982 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/less_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/less_equal.hpp new file mode 100644 index 0000000..d689930 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/less_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07ae54b1fb81d7afa70f08367d9c0cef03b26b9af8fcf21b83ec15b63874962b +size 2067 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/list.hpp new file mode 100644 index 0000000..763186d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e73c15b7e2fb9c62158af870a854a335fec2490a0f74100a706baad058a4d158 +size 9616 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/list_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/list_c.hpp new file mode 100644 index 0000000..2032686 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/list_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ee008389f1cca2faf27ed1da73c939ce2ff78296416feb06958c2466bb93345 +size 10717 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/map.hpp new file mode 100644 index 0000000..4625f58 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a002cc4fbd7bf1a8fc5e286ae3b19d9708c0036dc2832babbca4d1a872adb183 +size 9551 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/minus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/minus.hpp new file mode 100644 index 0000000..aa59930 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/minus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c7e258a04b367a488facbb089266c416dd221826513b39988d10d004231d6b2 +size 3026 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/modulus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/modulus.hpp new file mode 100644 index 0000000..d09343a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/modulus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c6d4e1fd64c52dbdbd40c976218d98aeb3e9974f03937d8c7b9de6223f199e51 +size 2237 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/not_equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/not_equal_to.hpp new file mode 100644 index 0000000..dbbfba7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/not_equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e891eb2effc6feb6890ba54bc66b8417a402b8bad6b4fc18860e8ce7a70b876 +size 2095 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/or.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/or.hpp new file mode 100644 index 0000000..3273c78 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/or.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7645364581e874da099ebbfbb4fe0ad416f23276474c698814e26ec9644bec14 +size 1156 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/placeholders.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/placeholders.hpp new file mode 100644 index 0000000..b8ef78d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/placeholders.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3d080d1d6bdd3d373c1fa5f19cad988430dfc29a626f7ed5f1e7abaa4381fa8 +size 2211 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/plus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/plus.hpp new file mode 100644 index 0000000..e8423b4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/plus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:43498ca5ededf2531ce0b4cae79c82d57082b779ab90371842f93d5b5415f70a +size 2997 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/quote.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/quote.hpp new file mode 100644 index 0000000..af5c665 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/quote.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9cf2f4f8b21bb706886b2adb76fa1c1eca3ea06c9fd43e1889b0e5dcf4825bc3 +size 2187 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/reverse_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/reverse_fold_impl.hpp new file mode 100644 index 0000000..8bd7744 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/reverse_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:16293df37c25ff8a277b36af2a1184d3883d5aa73faae01768c027ba8c88802f +size 7372 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/reverse_iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/reverse_iter_fold_impl.hpp new file mode 100644 index 0000000..223d946 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/reverse_iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba3bcf3f96dbae8d9cc54d8df52417c2df1346aeb6c3a3d3f4ddf0d5aa874847 +size 6717 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/set.hpp new file mode 100644 index 0000000..3eb75d2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4e7071dad95512f5828c2ac50f842f169d093297cdb2ba903085d0691af03cd +size 9551 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/set_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/set_c.hpp new file mode 100644 index 0000000..5f8a1dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/set_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:608eb89b22961ab2a5b1ba5cdfc115bc58be754a108d1038bf498de563e1eefc +size 10652 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/shift_left.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/shift_left.hpp new file mode 100644 index 0000000..f63bc1b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/shift_left.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb4861e3e4721b71e4dc519af02e9fad59b8175c28fe490a8031111fca17b28a +size 2193 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/shift_right.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/shift_right.hpp new file mode 100644 index 0000000..c6b3ff8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/shift_right.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f59b49a8785292bbaa9f9d078974e674eb43862436be2f74b21bb488f26a9f9 +size 2207 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/template_arity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/template_arity.hpp new file mode 100644 index 0000000..e29c8bf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/template_arity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7f7f402db7af2a929cd4eea606d870506e73ab076f073cd5b0d08322cb718d9 +size 306 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/times.hpp new file mode 100644 index 0000000..34d1232 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9cce2da1dc586e84d510cec378a45b3232bf74f3580751c05e91d1d07a432b89 +size 3026 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/unpack_args.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/unpack_args.hpp new file mode 100644 index 0000000..3d93ce2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/unpack_args.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91d1e3057b2731938c0e74eede0338fbe7f2c7d578d1d888bcbc8d3a50bde152 +size 1906 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/vector.hpp new file mode 100644 index 0000000..96bdf70 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e22c161ecfd115c7f9154b25cf8e6835e2e30a6d49dbeddf4d98b012fd018c7 +size 9746 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/vector_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/vector_c.hpp new file mode 100644 index 0000000..01100ce --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessed/plain/vector_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:630a3139e05016e8afd31fbedd1190ec07f6d31c8ddb5a2ce4399e551f07ac64 +size 12237 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/add.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/add.hpp new file mode 100644 index 0000000..c2e26e5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/add.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:142dcf0b8b8d30b72d92c932b4353b15ad7b8c487837464721644f0e28c27da0 +size 1854 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/def_params_tail.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/def_params_tail.hpp new file mode 100644 index 0000000..16ba733 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/def_params_tail.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54274b3bb920f4a7199ce344151990668a74f0a8e73483f8034910e1280d728e +size 4473 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/default_params.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/default_params.hpp new file mode 100644 index 0000000..427628b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/default_params.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6af730994a52590c6cf07779d2b6e2bd7ceff1856823b7e094fbd5aa0fd047b +size 2395 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/enum.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/enum.hpp new file mode 100644 index 0000000..1288483 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/enum.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc3581adf5d053d47ad28b8cb6257853a89dffc56269b498fd614fdd70be41f5 +size 1656 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/ext_params.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/ext_params.hpp new file mode 100644 index 0000000..22f236b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/ext_params.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:834dd20dc86e338f0a382ef24cf13abcfa1f6aab52e53e45066c1610843d64ff +size 2917 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/filter_params.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/filter_params.hpp new file mode 100644 index 0000000..51ae764 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/filter_params.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b217235df47e7251345b416b4977fa31f2c91bde1083aae1b966d1dedff389fe +size 1271 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/is_seq.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/is_seq.hpp new file mode 100644 index 0000000..db29b9f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/is_seq.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd4796e1d3b0e24a369a58ff74c43f76b5fb32414a82c36e903414773201d014 +size 2074 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/params.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/params.hpp new file mode 100644 index 0000000..a0dbdaf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/params.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49ad39c4d3b81363d8c01cdf9a90e299a830a76c6a9c0f915e867591d770efd7 +size 1926 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/partial_spec_params.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/partial_spec_params.hpp new file mode 100644 index 0000000..e22d9ec --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/partial_spec_params.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98f480c010f1b3f5573c3bc8dc292669fa9ddc2fe10e566e5d561b2295287976 +size 1005 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/range.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/range.hpp new file mode 100644 index 0000000..a6081d5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/range.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2e467746e05ba33e260af651f80840ed4f74ad3560425f84a428fce525e595b +size 843 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/repeat.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/repeat.hpp new file mode 100644 index 0000000..2991f92 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/repeat.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a1e44e66f09002829ae8656c1d898473f0c2d7b0f806d889218ff7a1ebd2f4d +size 1846 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/sub.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/sub.hpp new file mode 100644 index 0000000..b37d774 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/sub.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a7ba4fbf672be58570346fc9e41516470f8aab3aa850ad28c75223329e310f4e +size 1843 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/token_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/token_equal.hpp new file mode 100644 index 0000000..f9bbffb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/token_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc7de69970a4409546857a2cb661a95f62228b75cdb0d71c40a4a8e69adff718 +size 1897 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/tuple.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/tuple.hpp new file mode 100644 index 0000000..17a19a8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/preprocessor/tuple.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9a81a1c9c68ad22f9deb17f40deab930deaf1f18814a68c77d4980f738cf227 +size 1288 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/ptr_to_ref.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/ptr_to_ref.hpp new file mode 100644 index 0000000..6dbc46e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/ptr_to_ref.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4edf9744de591f5319c47307abc8777688b12c52ada8648ad279d897d0b36d5 +size 1095 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/push_back_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/push_back_impl.hpp new file mode 100644 index 0000000..b6ab936 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/push_back_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d2270ad96a22228249079313c63074adf226b798c124d99cc2fcbc3abb1de17 +size 2071 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/push_front_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/push_front_impl.hpp new file mode 100644 index 0000000..26c69fd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/push_front_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6122b367c417b0cd2af9a8d5bfe264557233e5f6160e964a3fc0d915a65d1ce5 +size 2092 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/O1_size.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/O1_size.hpp new file mode 100644 index 0000000..9f5759a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/O1_size.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76940057dcee7a4e9b9c7bf444fb6bbf15d2cc38417d7d21937391ad84a61553 +size 722 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/back.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/back.hpp new file mode 100644 index 0000000..cfa9f39 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/back.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7bd0cebc1aed4310a5f87a44d1a296a5c6d9ff94d1a9d8e727835820b8910b0d +size 777 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/empty.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/empty.hpp new file mode 100644 index 0000000..674bd85 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/empty.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a25cbded637e4beada32c8d22ed614670e8afee8021ddde3f599854301d3782 +size 823 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/front.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/front.hpp new file mode 100644 index 0000000..112dc67 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/front.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91421373f13aa522643121f631a5fe18806aa9e11e93f4ab80b6d63f12e196e3 +size 726 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/iterator.hpp new file mode 100644 index 0000000..7c32738 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5cf861e7c684fc52c0e69fbd07f56c249632668fc9eda0fdb896e4944f0ab07d +size 2654 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/size.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/size.hpp new file mode 100644 index 0000000..d66aeaf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/size.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:080d7314afec38fd92f7728f51875cd282c4a8c2976cb9a9cf67eb036924006b +size 812 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/tag.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/tag.hpp new file mode 100644 index 0000000..e9ed7a5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/range_c/tag.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3e6d3e3d9608cce1fadac4d5766823a266150d5c72fc2c53981acceef371b08 +size 543 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/reverse_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/reverse_fold_impl.hpp new file mode 100644 index 0000000..8a1fa1b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/reverse_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76d4c331e35e62e72f0f5663c269da3e1c20746b79eafb8e8c75ed7736195edb +size 1384 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/reverse_fold_impl_body.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/reverse_fold_impl_body.hpp new file mode 100644 index 0000000..e94d8c5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/reverse_fold_impl_body.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad84e878c93d0342abcdb5f116c293faee45c4d3949b044db373b49de9c5317a +size 10599 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/reverse_iter_fold_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/reverse_iter_fold_impl.hpp new file mode 100644 index 0000000..d697cad --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/reverse_iter_fold_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2bcaf337993e4b037a064fad1ac43124793b19ef1505d3e338055e6ab5946ce8 +size 1356 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/sequence_wrapper.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/sequence_wrapper.hpp new file mode 100644 index 0000000..7d36fdb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/sequence_wrapper.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:72b191fa3ac6c8828ab8c7f849e10eac56df238fe24691df214ad9568ccdfddd +size 8170 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/shift_op.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/shift_op.hpp new file mode 100644 index 0000000..b9d8bd1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/shift_op.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9fe3aa6464e97d023bfa82efcf00656e061db51290baaac6545d1164b3e05d4 +size 2246 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/single_element_iter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/single_element_iter.hpp new file mode 100644 index 0000000..015e88c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/single_element_iter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8dccbdedf3f411ddfd9f59e3b217f2bd00d188e6747f5134a5b1aab0e2eff21 +size 2789 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/size_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/size_impl.hpp new file mode 100644 index 0000000..5c60cd2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/size_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b79342c64ba805e79214b4ed053a546aef4698950579ff97967bf49b0667b37 +size 1322 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/sort_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/sort_impl.hpp new file mode 100644 index 0000000..922f204 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/sort_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30305b44d22c3ff7c78779f667416e00d590fb5a01bd3e0dff8edbc243a8a086 +size 2877 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/static_cast.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/static_cast.hpp new file mode 100644 index 0000000..21bbaca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/static_cast.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c47fb69b45b1ab486e2921caeb899019f874764df12c1937119741c2c590072 +size 768 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/template_arity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/template_arity.hpp new file mode 100644 index 0000000..c70793c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/template_arity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e5f7fa518eff15dccd658f4d73bae3faa96765513e25dde4d1d38eaec73763fc +size 4735 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/template_arity_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/template_arity_fwd.hpp new file mode 100644 index 0000000..9bad335 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/template_arity_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf95228a7010cfaf32d7c214b20000e09c26afdf4739d698d29238098147c80f +size 563 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/test.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/test.hpp new file mode 100644 index 0000000..e55fbc4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/test.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ed164d512a109de82fcaab4ff243a47377c345f11ea006e98f58861bb1e6e09 +size 729 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/test/assert.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/test/assert.hpp new file mode 100644 index 0000000..cadbf8d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/test/assert.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e40bdc56cae244c1ed927d54e62ce551d9d67136feb53a01b9e58c19386e7475 +size 910 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/test/data.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/test/data.hpp new file mode 100644 index 0000000..8749c1b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/test/data.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:25112c8e566a345f4154da6bc8eb3040f70ec4ae3f0fbd021435d0571e92eb92 +size 596 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/test/test_case.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/test/test_case.hpp new file mode 100644 index 0000000..d06a26c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/test/test_case.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0669b85dd2a392dae20d0118adadd10f6761415e224fddd297b3e68db4ee699e +size 547 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/traits_lambda_spec.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/traits_lambda_spec.hpp new file mode 100644 index 0000000..7fe4910 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/traits_lambda_spec.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cccf5d2089695f55d733209245b6614ec5740d061b306174bc808cda424ce0c8 +size 1569 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/transform_iter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/transform_iter.hpp new file mode 100644 index 0000000..d975e2e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/transform_iter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:352348f0dc9262fa7f0da40665cf82769b5d36ede84bf4184d0d54108fbb0af5 +size 2636 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/type_wrapper.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/type_wrapper.hpp new file mode 100644 index 0000000..2629471 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/type_wrapper.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5699ac051ca130e263ed8889deea522e9e7ca167a8c1f99f4c01cc4da210c15d +size 1181 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/unwrap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/unwrap.hpp new file mode 100644 index 0000000..36a98b0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/unwrap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9494178ee595a0ff3e16197fb15d13c6d50fc1979ff954120d193c43b0c613c5 +size 929 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/value_wknd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/value_wknd.hpp new file mode 100644 index 0000000..1341a90 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/value_wknd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c84c8e72c3bef461dae2b4f1f905f546bbe05fbec3109193eaa259fbee6efa6 +size 2029 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/yes_no.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/yes_no.hpp new file mode 100644 index 0000000..d0eeed6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/aux_/yes_no.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:980dbf5b1bd243891caeeaec32a63b7819c18cdac6db0b0413a813bad36ac873 +size 1180 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/back.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/back.hpp new file mode 100644 index 0000000..2851148 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/back.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5532e15090e00f74d8d2f568c107db66cb7afc126eca6f54e98f1b6318f5e648 +size 901 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/back_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/back_fwd.hpp new file mode 100644 index 0000000..61512fe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/back_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41fad83b18de9aee4ecb2737d8217bb6edb98658a94e98167fe199515ffc8fd6 +size 544 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/back_inserter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/back_inserter.hpp new file mode 100644 index 0000000..7bd3f6b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/back_inserter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b6a008191c12e8d94a39e57648785e704093aa11ac4b7545910b1bb287152d28 +size 686 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/base.hpp new file mode 100644 index 0000000..ad5f8fd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:65d8c570aee85912038ad328879377fa606128103919d69944fbd1b9b48707ae +size 716 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/begin.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/begin.hpp new file mode 100644 index 0000000..b3f41dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/begin.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a375f18358f453b319fab748d1e12ec7e1cb85a0c9434b2253a69cfea13713e5 +size 440 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/begin_end.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/begin_end.hpp new file mode 100644 index 0000000..02b5b33 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/begin_end.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bb43a74752087b6298c9b54cf719c045f256c635e65d98248dfa122b011d167 +size 1444 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/begin_end_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/begin_end_fwd.hpp new file mode 100644 index 0000000..d2f7998 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/begin_end_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c386498474bd3bdbb291f1fe95e9ec99324f4cc75f3894664e58b4cf34b7196d +size 646 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bind.hpp new file mode 100644 index 0000000..2e4fe5f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e171638f418e5d0e8b53186b6068830d74c44c5a901ad5c13887edad27c7d018 +size 14951 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bind_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bind_fwd.hpp new file mode 100644 index 0000000..7d849ec --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bind_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d88766b0b16801785b270bdf1b80c5c4b4aad0c0836e74b649e71bdbd7ad2eb8 +size 2493 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bitand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bitand.hpp new file mode 100644 index 0000000..a03b58c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bitand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0cc372da1c89e7f7155eda2e50d5ce3f15b2e73319aaef7f1bb4183628e5f9c +size 1146 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bitor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bitor.hpp new file mode 100644 index 0000000..28aaede --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bitor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f280c8661254f6e99cf5112466049459a3e5b3131d060e9d81623accc1a7462 +size 1133 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bitwise.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bitwise.hpp new file mode 100644 index 0000000..0384029 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bitwise.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:185e6479c9c0262c992fc687bd375e050e2f14a184c7f019d12aef76542c63af +size 613 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bitxor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bitxor.hpp new file mode 100644 index 0000000..59733c0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bitxor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bf3903eae8b1155f617d7b56b5759c49f13fec9c44e1ea68d03dcae7100a589c +size 587 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bool.hpp new file mode 100644 index 0000000..a1a7cb7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc2dbc31841313aab6fe3468199c6b15ce12eea0a8bb4b073f8caf10b2a6389b +size 964 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bool_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bool_fwd.hpp new file mode 100644 index 0000000..b76e23b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/bool_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e2bda031dcee52f1bea6015e5ad2af309e0a0ecce882de63b4d39c9f2c04ed4f +size 766 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/char.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/char.hpp new file mode 100644 index 0000000..c46ffb8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/char.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0045205642a23207558ec3809456d066fab7ea7b82f0b1db20509da2978c0b61 +size 575 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/char_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/char_fwd.hpp new file mode 100644 index 0000000..06900ee --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/char_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2e04164606e82597ec3662dc59f3bb1c1c536b5e58a656498ba64e75739a2c5 +size 734 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/clear.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/clear.hpp new file mode 100644 index 0000000..d71e33f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/clear.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a67b46819809b86bdb7fa26c2488561ee6bcc9c8ab70d85ad8e3d9a4bd9a75b5 +size 910 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/clear_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/clear_fwd.hpp new file mode 100644 index 0000000..3a359ab --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/clear_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a298da13e96589319d5a75065f623d93afaf4d345a4a0e5879bc8299153c235 +size 549 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/comparison.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/comparison.hpp new file mode 100644 index 0000000..98f97c7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/comparison.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e061241bb23f20d48e3cd91021f9299d2516d6a439aa8e46e499848f00322f0e +size 635 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/contains.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/contains.hpp new file mode 100644 index 0000000..cd36ada --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/contains.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e87122453394ce0538bf97f75ed496fced290276ae284c3c6cd26d47454ade2 +size 1009 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/contains_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/contains_fwd.hpp new file mode 100644 index 0000000..9e08285 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/contains_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f86e6a8c6fbde1e29dcf1d66c5c6495f1ec59709677452d80ce5afe59ef31dea +size 603 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/copy.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/copy.hpp new file mode 100644 index 0000000..ed1c658 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/copy.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1553ebcf2e8163096c0a9c5bed99031fdb9aa9e5689094c0ebe6cc0958fd97b +size 1106 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/copy_if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/copy_if.hpp new file mode 100644 index 0000000..1a9121a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/copy_if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e88a8602a03dd109826835a55e2c96634c7631ae82c7a66216e29ed75486f723 +size 2085 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/count.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/count.hpp new file mode 100644 index 0000000..593f690 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/count.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4350b4ce8f1aa0a7ce8bd21a4ba62f9c8c723069e1f01deff20add937b518936 +size 953 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/count_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/count_fwd.hpp new file mode 100644 index 0000000..4292f98 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/count_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:57f3454d3c28e3bef957b87bdc7d942c985b0c1d0317f25263e5a91be2c4b548 +size 561 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/count_if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/count_if.hpp new file mode 100644 index 0000000..bb8aaad --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/count_if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aace25ca89c47b36dc424ea97aa03771e9e185c4cfa06ebbb54c84b90b66f3cf +size 1766 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/deque.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/deque.hpp new file mode 100644 index 0000000..3e750cd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/deque.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c1176b5c2d49c7d837d4539d86b288589b41a468f3ff7f6417b04e41b0ac937 +size 1682 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/deref.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/deref.hpp new file mode 100644 index 0000000..900e705 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/deref.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f1d8706088282dad91168203a105c4670ef03275f8716f91735fe957954ece7a +size 939 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/distance.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/distance.hpp new file mode 100644 index 0000000..21ad6d1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/distance.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de2db4eb792b7645c8bf8ff8edbbfd69988db7cd29852e017802f2e50b442e5f +size 2028 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/distance_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/distance_fwd.hpp new file mode 100644 index 0000000..0ff85d8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/distance_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9aacedd79495484e7ae28a5a108d6618ce6ba7e3850ad55524fc9cd68ab0c9cb +size 666 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/divides.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/divides.hpp new file mode 100644 index 0000000..5d8438b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/divides.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53ca3251d266947d51f8d365e15dacfbb5ffe7f5ab866526d7c34c9201bde248 +size 523 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/empty.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/empty.hpp new file mode 100644 index 0000000..5106f9b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/empty.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f5df664afc9c845a624cffc9ec4ef01e6f8624079cc458f192e879a2b47e54e +size 910 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/empty_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/empty_base.hpp new file mode 100644 index 0000000..44326af --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/empty_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb8b82192f91af9b13d00197d5568c52fe64df3478ffd4b750222ca89a934097 +size 1399 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/empty_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/empty_fwd.hpp new file mode 100644 index 0000000..974265c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/empty_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aec2468473451a7833a6502ddbd0d53a7b2e34d8b283ca7da6b954e7504a28a6 +size 549 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/empty_sequence.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/empty_sequence.hpp new file mode 100644 index 0000000..50410a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/empty_sequence.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5862e01fcde3cd58ce1c7af33052f7d7b8a7813347774134d20877089020a62d +size 921 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/end.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/end.hpp new file mode 100644 index 0000000..6654c38 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/end.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91fed9a32d03ad8235e8152c88c2ec0743f2ebc747d69a875c9b89cf6eb798cd +size 434 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/equal.hpp new file mode 100644 index 0000000..f235b90 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d3e08d0f19d70e875137251952514bf39cab9482c7ec9627df95409b56ea179 +size 2668 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/equal_to.hpp new file mode 100644 index 0000000..d6a0afd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:989a43e4ffd1b27c34be6a81c1a0dbae02f5748816d8090ed8f0e226f17c6a2e +size 528 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/erase.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/erase.hpp new file mode 100644 index 0000000..e09f153 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/erase.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05e261c5691e133f47ee480d82bbc2ad508a48dadfbf9c54103848b5c05da1e7 +size 1071 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/erase_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/erase_fwd.hpp new file mode 100644 index 0000000..ce97662 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/erase_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae81e26230bffbe114595f4ff5601fe5034f949ec2da488d7bbe0be14d764609 +size 580 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/erase_key.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/erase_key.hpp new file mode 100644 index 0000000..d2f497b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/erase_key.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:27005e79cdd2edf4b41b152f17e3f838b541f2095f4482b75da7a25924044af1 +size 1047 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/erase_key_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/erase_key_fwd.hpp new file mode 100644 index 0000000..3f691b0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/erase_key_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2cb83ad674bd0a0710656b3cfe62b41cade9ec4571b4f2ecfdfbc34bd9b46520 +size 583 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/eval_if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/eval_if.hpp new file mode 100644 index 0000000..ea2d6e4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/eval_if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fdfad47fe1e2b98d4ffc3cf9c61da48e7aa274713e33233ea01379f8ec13717b +size 1754 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/filter_view.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/filter_view.hpp new file mode 100644 index 0000000..46bb339 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/filter_view.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c07330e83bb964552c9566e515a7560dae6538c57e2b5a7cdf21511caa45a5e +size 1145 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/find.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/find.hpp new file mode 100644 index 0000000..8d20b33 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/find.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26078484a57dce1c6cac3c7cc86c520a1db295763f2049fcf95125eb1beec0dd +size 841 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/find_if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/find_if.hpp new file mode 100644 index 0000000..6d6e690 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/find_if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc185d56a4044c14e230782c3f44bd9d8decac52e90016964f8cc1b0bcfaf981 +size 1196 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/fold.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/fold.hpp new file mode 100644 index 0000000..f2f9867 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/fold.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b9962b1844b7cf7f9277a1db9241ee5525364d9ae80bb1ff06a4712b5600de5 +size 1177 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/for_each.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/for_each.hpp new file mode 100644 index 0000000..d63358d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/for_each.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:146ccd64155dc2f715fbdc10f7b932fce2ef1abbdd7d57bc8e27b933dd6cb708 +size 3077 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/front.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/front.hpp new file mode 100644 index 0000000..3414564 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/front.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:00aa047e2529ed40ccc16a1e4e870a42eec70bc9c2869d40c5a8d0f5e5b622f4 +size 910 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/front_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/front_fwd.hpp new file mode 100644 index 0000000..e5a0a7d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/front_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c716fa5a6a6c845b4f0f2660f5cb725f484d7a2565aa2dc01e3b0d574beb8ba5 +size 549 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/front_inserter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/front_inserter.hpp new file mode 100644 index 0000000..b4ee1d3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/front_inserter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:135ac08604b23b3f3db0a80b778ec662e24d9d400e3063a81d4d84bdfceac9a0 +size 692 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/get_tag.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/get_tag.hpp new file mode 100644 index 0000000..b98866b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/get_tag.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:68f397ef0a3fcce76b4d80df7b8c6f85311bca57da9c0fc7bc25690e1e2869db +size 576 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/greater.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/greater.hpp new file mode 100644 index 0000000..c9ba31c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/greater.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52a3c9828fc06efd64eb1bb9ecdb360bfcf7e6ef81b3efbf210a61e537748bd1 +size 523 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/greater_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/greater_equal.hpp new file mode 100644 index 0000000..a3537be --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/greater_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c2135302525c67960bd64f9eb8694998a0650c5639e39732c8bb9dd6a635236 +size 548 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/has_key.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/has_key.hpp new file mode 100644 index 0000000..04875e9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/has_key.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8772ea6c3ca40b56ec319ee52dad216c644700ecb174a19665b363ed0088ada8 +size 1059 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/has_key_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/has_key_fwd.hpp new file mode 100644 index 0000000..22ae8f0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/has_key_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34ecf39c063d1f9d813fbe7062e72699ac67252653cb99342aab54f28394bc98 +size 622 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/has_xxx.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/has_xxx.hpp new file mode 100644 index 0000000..530f7ef --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/has_xxx.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6f2cbd32bf95c1fdaf10943f1c0c13cd03f06de75002b9d02a029ece6392d3f +size 22052 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/identity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/identity.hpp new file mode 100644 index 0000000..5cb6d13 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/identity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7758b3b5b174259e1044abe427fba646c06a151807a0c77c0581eab7cf83ec8b +size 951 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/if.hpp new file mode 100644 index 0000000..09d72f4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:06dd08c2df80b8b7c99f6a544b1e9fd82d6848e90e64574d0ac49577dae2a49d +size 2912 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/index_if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/index_if.hpp new file mode 100644 index 0000000..d20c5f5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/index_if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e9079eebf0f9540be8fe4aa27d37b670dd22a0e92b3193e75bf9a9ec3c965812 +size 1508 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/index_of.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/index_of.hpp new file mode 100644 index 0000000..c051eec --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/index_of.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:57fb062e1ef612afa759545196e68f12a5d30252fe576a45ed2da57cfb109924 +size 899 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/inherit.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/inherit.hpp new file mode 100644 index 0000000..5e410b2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/inherit.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:328aaef7ed46f7b0253e4963c7b0665e382c0589af6583d7f7d8b1c317aaaa3c +size 5670 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/inherit_linearly.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/inherit_linearly.hpp new file mode 100644 index 0000000..85425a9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/inherit_linearly.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b51a792cb111856a8d9f6fa91e84bc6da8fe087e4fa9b06376bbc29d8a304ad +size 966 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/insert.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/insert.hpp new file mode 100644 index 0000000..5cf06b4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/insert.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d808a47d516f5aa72963791f1cd12534085a3d03987e9caf0907a59d6b567bc +size 1030 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/insert_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/insert_fwd.hpp new file mode 100644 index 0000000..48184dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/insert_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:169199ad6dd38b7fd75b4dc3325955c7997492ae40a9b20a3106dcdf46ea85c5 +size 585 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/insert_range.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/insert_range.hpp new file mode 100644 index 0000000..7ff72ac --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/insert_range.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef2dfd67e47765809ceb6550522013a4ec104a807e39bcce1439640381abced5 +size 1081 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/insert_range_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/insert_range_fwd.hpp new file mode 100644 index 0000000..2e23d4f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/insert_range_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b88a84dac9280fa968bae345a29dc0b3dabd0e29079f4c04263d0805984107cc +size 614 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/inserter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/inserter.hpp new file mode 100644 index 0000000..76fef27 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/inserter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0e13043d9c474bdba2595ceb54b0fe7a3c0e6a9ee6b2c8ae176edb1fd723681 +size 648 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/int.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/int.hpp new file mode 100644 index 0000000..53edd37 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/int.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:688205b1725a34a4df16cceef3509db8a786731f3b45d6fa1f908ff550654292 +size 520 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/int_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/int_fwd.hpp new file mode 100644 index 0000000..28108c8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/int_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a609ceed046808f5d3b26893d45d2f55eb5ce6d15243ea770837e4ebfa4c31e +size 678 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/integral_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/integral_c.hpp new file mode 100644 index 0000000..9adb6ed --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/integral_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d60b28ac065c4ac0ed4cf4c0ee5366de6c273a22602830980068de7e4f1ca1cb +size 1507 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/integral_c_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/integral_c_fwd.hpp new file mode 100644 index 0000000..490b523 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/integral_c_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5e1a0e49eeb4e6b3f0d6f026981cf89408093dd52000a39340213da85cb5177 +size 887 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/integral_c_tag.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/integral_c_tag.hpp new file mode 100644 index 0000000..576d117 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/integral_c_tag.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6fb4fbb74c0630652c670677c672c577a0a6e1b6902cc45181c9e00b51b3145 +size 725 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/is_placeholder.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/is_placeholder.hpp new file mode 100644 index 0000000..aba0a7c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/is_placeholder.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77117902ce08acd1a594f5d5376cd4abd958f5a9bb7c53dc39904fb906e17352 +size 1483 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/is_sequence.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/is_sequence.hpp new file mode 100644 index 0000000..5041f85 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/is_sequence.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbf467b9a203145eb042c784be7ba5b79c77e74d8255cc73d508660cf8125f3f +size 2644 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/iter_fold.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/iter_fold.hpp new file mode 100644 index 0000000..354d07f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/iter_fold.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:651891801347e54c6e826eab4fc3a7fd09a209eccf60d3906e0bec4dbaf54031 +size 1272 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/iter_fold_if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/iter_fold_if.hpp new file mode 100644 index 0000000..cff1f93 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/iter_fold_if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:24d7596ac1506624a9449a6a701970d434ea7345b000681da69e5a7a5394fac8 +size 3072 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/iterator_category.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/iterator_category.hpp new file mode 100644 index 0000000..506d997 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/iterator_category.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad3ffccb3737453fac4dc2c71202658064550c4d6737e0af52d50ace57debcbf +size 820 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/iterator_range.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/iterator_range.hpp new file mode 100644 index 0000000..47a04f2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/iterator_range.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cec11dbb36cdb016674d63570d071b066d9c5b6a3ba310eee900dd97f96032a +size 943 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/iterator_tags.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/iterator_tags.hpp new file mode 100644 index 0000000..a2c538a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/iterator_tags.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a3ef7e27c16c38ea5600a18cfa65cd8ede360a9e78ba879ec2be85cc23ccda0 +size 764 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/joint_view.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/joint_view.hpp new file mode 100644 index 0000000..5d3cf37 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/joint_view.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfc4207894fc486c0117297e733849825dc46d33cc5e77cdbe8ef457635be4e3 +size 1656 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/key_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/key_type.hpp new file mode 100644 index 0000000..65b7f75 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/key_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe092b18be26253571cf8f7cc676349badb08dc65cac9fd4e429fefb77ff759a +size 1064 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/key_type_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/key_type_fwd.hpp new file mode 100644 index 0000000..431a51a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/key_type_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04793c0a03a5747fd3eef842fe9560689f7999a018be63c86a77604ab1feebbe +size 625 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/lambda.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/lambda.hpp new file mode 100644 index 0000000..8d36abb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/lambda.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d18e65e60be7085e5c1c680e9b6e507142807cda534db6bdb3fa9fd1034c395b +size 780 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/lambda_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/lambda_fwd.hpp new file mode 100644 index 0000000..1607b57 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/lambda_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47fbe349690d24ee254e27c87829efbd01234708fae5bca2d016445d2f1a340e +size 1201 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/less.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/less.hpp new file mode 100644 index 0000000..d7114c6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/less.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:766fd3ef7a1f934d525025577ea9649af1b53cc2401add2062982b1176c12a12 +size 511 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/less_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/less_equal.hpp new file mode 100644 index 0000000..df6f097 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/less_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:829c9d8a1a3d8e0295f0a06272b1c1e0c8fcfdc5afc49e3e2d775accbe7757bf +size 536 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/arity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/arity.hpp new file mode 100644 index 0000000..c042b9c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/arity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5c11b556382551c904c7e6d1542bb30afc976097bc5350959bffc1cc5bcebf3 +size 535 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/list.hpp new file mode 100644 index 0000000..0fcbb2d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c4f6563e9a64f7f76c6f1dd9269cd53898634887b5906b96988ee101712b0ed +size 515 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/map.hpp new file mode 100644 index 0000000..8da612a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b2ff8304f328cd2b42dd5c0e9e59029ed011c69d776989d49e9eac2bf710328 +size 510 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/set.hpp new file mode 100644 index 0000000..bf3c8a8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3772c2e36e5c9ee6ecd6990d936b470f372a30bd46dc46037134a9a5e16f8de +size 510 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/string.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/string.hpp new file mode 100644 index 0000000..9b235bd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/string.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef312ddd22dc9e90d9cbf974e572ec96533d36801d42cf5d27276345821dae48 +size 623 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/unrolling.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/unrolling.hpp new file mode 100644 index 0000000..b5d9869 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/unrolling.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e3e89cc65efd3675b344b9e6b225e0feb8268d0a2309bdaa0735c14d81e4236 +size 529 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/vector.hpp new file mode 100644 index 0000000..ab872eb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/limits/vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86064edf12142ce5aa7e21c3a978ffdea88c5dfecb00f34e12d5d9fb99688873 +size 525 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list.hpp new file mode 100644 index 0000000..83c36bc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4bb66f497c04a95a3ae1460dbd62bcdcac4ab6a4ad42256d47bad148f75a4a4b +size 1608 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/O1_size.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/O1_size.hpp new file mode 100644 index 0000000..ddffefc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/O1_size.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56a4438c61d5ff928f22120fb6c0e705f3226fabac309b1639ebe6f4bbb7cc8b +size 689 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/begin_end.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/begin_end.hpp new file mode 100644 index 0000000..bf710a4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/begin_end.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3978fbebb460737c00bd567e9d4f9d2a5f45136354d8f7b0f6e736152aa5f59c +size 945 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/clear.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/clear.hpp new file mode 100644 index 0000000..8bbda1a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/clear.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6c61c02b5ce42af3072b82e3099b901fa25679ceb61c30cd9866e58ca05079c +size 726 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/empty.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/empty.hpp new file mode 100644 index 0000000..6dc1d9d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/empty.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce6e6b3a9be51a4acb82c6f4a73298f3d5cde9234fbe562e9c893283787ede03 +size 723 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/front.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/front.hpp new file mode 100644 index 0000000..4696f1f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/front.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dfab90462a9ff855e4811b21afe20b40c3baa4508adc117c41d4c21d98466a06 +size 700 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/include_preprocessed.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/include_preprocessed.hpp new file mode 100644 index 0000000..cac41e9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/include_preprocessed.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e101776e1c68bef67983764e1a0c319a972fa7038ceba8c4ee2bd7f505dc8be +size 951 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/item.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/item.hpp new file mode 100644 index 0000000..e4c4a34 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/item.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4414c22c494e22563f6fa4cb1db10fbb9ffe74865e34314d8718d5ad86e02af6 +size 1172 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/iterator.hpp new file mode 100644 index 0000000..2a9d393 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c357d127ac45d8856444a163954f817bea08ab97859f998be188129eb798360c +size 1684 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/numbered.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/numbered.hpp new file mode 100644 index 0000000..54de4f3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/numbered.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5ea09c8b3d70113610f2aabb2630e222ebbc5dcd49621364df2aef78f8ed0e2 +size 1307 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/numbered_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/numbered_c.hpp new file mode 100644 index 0000000..89ff686 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/numbered_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:926e5cef3901ba3f707a9d856cfcf9352a359b3a76cbbd9d8cadf870321b29e4 +size 1435 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/pop_front.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/pop_front.hpp new file mode 100644 index 0000000..020c667 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/pop_front.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c2c6f6b18228f8bfb9fcb4cbacb570256962efa4d42d571ba2141c92d7a6e7d +size 767 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list10.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list10.hpp new file mode 100644 index 0000000..1573738 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list10.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14a28891a3ef987bafdc7c13ceae19c683fd7802d5782ec9632ca6aa6f9bbb6d +size 2599 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list10_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list10_c.hpp new file mode 100644 index 0000000..b283620 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list10_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4baf44e972808978597359f8f17853f3fc1a1ca2e435ec633b3ae7da0110006 +size 2859 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list20.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list20.hpp new file mode 100644 index 0000000..06f3caf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list20.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4426b2e12cf4bb37529706f3889d3ab5766df6fa65c3382309e39be024f90a77 +size 4451 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list20_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list20_c.hpp new file mode 100644 index 0000000..650415a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list20_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7e5d3b8ba5011e02d06eabacf98541e84f24208f1dae34903c232c0ff4ab22c +size 3958 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list30.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list30.hpp new file mode 100644 index 0000000..2eac718 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list30.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:963201f09919c81f15d9036b796f57749f3131be25168515735d351472f24b85 +size 6351 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list30_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list30_c.hpp new file mode 100644 index 0000000..a29dc3a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list30_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99b5dd7d89834f00a60e71dd36219ce6237d906fb814779557483b4a027c2f15 +size 5108 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list40.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list40.hpp new file mode 100644 index 0000000..8aff911 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list40.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3335cbbff592a32ac0f6f9ced50dbff88811674505b472201c764f8c9d45b27e +size 8251 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list40_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list40_c.hpp new file mode 100644 index 0000000..a5a3d17 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list40_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b527e643550486766029f51cd33a2745a5d1d73efd2b178009b10bd64774c3a3 +size 6258 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list50.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list50.hpp new file mode 100644 index 0000000..0698e20 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list50.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:feccaf83d9c636e6a0b53a3c71db6c34c234aa08297f8e4e074cc7a770817ebe +size 10151 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list50_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list50_c.hpp new file mode 100644 index 0000000..64e55b4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/preprocessed/plain/list50_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17789610fd2365d94c39018181c0b5c2d10ea0e8711ee1b9f6dab1f16eca0065 +size 7408 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/push_back.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/push_back.hpp new file mode 100644 index 0000000..6ae06f4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/push_back.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:971b31e07b5a1a739c0dae95ef94a6649e7b17cbd8a691c4827149eececc132a +size 781 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/push_front.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/push_front.hpp new file mode 100644 index 0000000..b2e9c7d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/push_front.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1eef3c5de7cff42f5ba477e627bcfad8e3d73e7f0a3a4cab690d094f03a1069d +size 914 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/size.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/size.hpp new file mode 100644 index 0000000..97f2325 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/size.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e565a60bcaf9f145a5c08889b85b8e10cd4fa4dd972251e55d36c05cec086ab +size 674 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/tag.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/tag.hpp new file mode 100644 index 0000000..f1e05f6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/aux_/tag.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bcfca2428cdd25043e655dc923e4c13bb7dc686f17c45679c5ee0cb888efc1f4 +size 523 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list0.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list0.hpp new file mode 100644 index 0000000..5018948 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list0.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff3a2f2d19273a1f35d57a12a48734eb5cba4b9c260bcc42e0999cfb1efbcf5f +size 1071 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list0_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list0_c.hpp new file mode 100644 index 0000000..951d9c0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list0_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:584bf909871f217891b78b881b6c6d5410c88e2a810c1b715eaf975f49f2998f +size 648 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list10.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list10.hpp new file mode 100644 index 0000000..44dc3af --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list10.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:27486c18a436f5f7bf2f48ce5f783d3e8f0ba6b8d7b435ce42e38ed560bf2908 +size 1051 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list10_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list10_c.hpp new file mode 100644 index 0000000..d5f201c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list10_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aeca00503b02932f417e8bac940d673b3de1c7caad0a63b6008b6f95d53a80d7 +size 1060 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list20.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list20.hpp new file mode 100644 index 0000000..630cce4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list20.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a7c55ad977b59782f3c2a9cc7ef77af8c048b41c623f63f622bc80fe45b6037 +size 1050 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list20_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list20_c.hpp new file mode 100644 index 0000000..2427610 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list20_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d625e9b9f14365a217b1fccd30d598abc3e2573207ed237473414816d258c14 +size 1062 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list30.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list30.hpp new file mode 100644 index 0000000..5af4959 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list30.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2dc0b3d2e74c9ecfef658925c56e21e2c86f9746168d41ed893cf2c4bda1ebaa +size 1050 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list30_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list30_c.hpp new file mode 100644 index 0000000..b3bf99a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list30_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67b7fc0109e7bee291524e6c3b83f95f5b8405fb30470b3c48d2bef9457f8322 +size 1062 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list40.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list40.hpp new file mode 100644 index 0000000..47098c0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list40.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d707698615d0b044b60cfb54da15796abcf8292b7dd54bdf51899958bde41612 +size 1050 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list40_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list40_c.hpp new file mode 100644 index 0000000..a308755 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list40_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e4778dd036a6e035cd901499c48a1c06fe6be8669f94d4fa610c7b981bf2a75a +size 1062 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list50.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list50.hpp new file mode 100644 index 0000000..a7fa709 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list50.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:532fb1535b8435f8029358491d1dbbc1befd0cd80c74ca0cdc0e5fdd5f325bf0 +size 1050 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list50_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list50_c.hpp new file mode 100644 index 0000000..0ec7d71 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list/list50_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff4a688df4122beb40a157a8e648e5838469bfa7efdb888291f3789db5052913 +size 1062 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list_c.hpp new file mode 100644 index 0000000..64ed5f1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/list_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:68648b7dbe516176d4f310a21061021f1781fe82f6e4dcd09b6006c7d8d40f66 +size 1814 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/logical.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/logical.hpp new file mode 100644 index 0000000..7b2ba03 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/logical.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07b1c3926dc70fe644ff150099eaa167f4dafbb383dd763682fa7118632c860a +size 502 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/long.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/long.hpp new file mode 100644 index 0000000..3776f5e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/long.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:84c92ce736ec42f067dd102b92fd6ef71676906f534c4f37cadd1511280e17a1 +size 525 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/long_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/long_fwd.hpp new file mode 100644 index 0000000..55a2d76 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/long_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7e3e6dfbaffd41bdbd5183c91d6e878dda858b936175fa639eb7f02802ce6717 +size 684 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/lower_bound.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/lower_bound.hpp new file mode 100644 index 0000000..3196066 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/lower_bound.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b50410a890c297aad96008a5f448a68717fefb1bdaa7a1ad7b65ce29fe9b5044 +size 3603 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map.hpp new file mode 100644 index 0000000..1d13133 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6670fdac98a15d3845f2336140126726f15278ea9f9401d6e49ab0b54965ea03 +size 1593 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/at_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/at_impl.hpp new file mode 100644 index 0000000..b5dc1a4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/at_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1ab571911e2be8c55fa2341669a76d58342b26d3c9761b43161a032c673f2f1 +size 3391 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/begin_end_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/begin_end_impl.hpp new file mode 100644 index 0000000..4ca8392 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/begin_end_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42338399cf4cf21156304437fadfbe038cd227507b36ed13bd45cbc481e225da +size 1231 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/clear_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/clear_impl.hpp new file mode 100644 index 0000000..abd8f86 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/clear_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c50a685f00d73cf55f65401c0bc782c9d95a0e68272594d0e92a3c65407f32d8 +size 773 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/contains_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/contains_impl.hpp new file mode 100644 index 0000000..14c988b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/contains_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:843a7b6274588cf91a597518d6289b85f9e5f1287312c85b5e12844efeb87d7f +size 1017 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/empty_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/empty_impl.hpp new file mode 100644 index 0000000..0f9be00 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/empty_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f1f954c743cb83a3f041b54582e15d333b6195983ff51dfda3851c7e28d7ed61 +size 733 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/erase_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/erase_impl.hpp new file mode 100644 index 0000000..3c19bae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/erase_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a21c43126086bdec46dd7bf5b3038b9749c564f3ec470d750f3f29fdd1c9f31 +size 918 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/erase_key_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/erase_key_impl.hpp new file mode 100644 index 0000000..2ca65e3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/erase_key_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1c5244c83ab34e6b64f2752c5b3365e0bc97db5aec3712665078ab2580d2de6 +size 1285 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/has_key_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/has_key_impl.hpp new file mode 100644 index 0000000..3f97c82 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/has_key_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ecd0045fd2e278695ef37f86ff900a416e2a0af5d6dddd6b5a1b030931ff92d6 +size 1087 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/include_preprocessed.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/include_preprocessed.hpp new file mode 100644 index 0000000..5b8b306 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/include_preprocessed.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e77bf82ce516230b1cd029402c6719b1be3ca0710487ffe0764bb00333c4222f +size 1586 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/insert_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/insert_impl.hpp new file mode 100644 index 0000000..c834404 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/insert_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:684bfc7aa5c45de46b89442fb8a3f5f5db9f2bbaf578c5aed2572c3403829503 +size 1622 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/insert_range_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/insert_range_impl.hpp new file mode 100644 index 0000000..ffbdf50 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/insert_range_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18d58f2fca25995d426179792c9227f6bce6bbc0d8fad6be5431d75a7cae4d4f +size 920 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/item.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/item.hpp new file mode 100644 index 0000000..045e2d2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/item.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db0fdf7d2d0f2773f2d5048b9558a385b4cf077879181a399c32861db22e7577 +size 3932 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/iterator.hpp new file mode 100644 index 0000000..1b31693 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f00c8445202f46c413a146cce4b6dc0b43c865dd97e3a0cb332b6bbb5bfd357 +size 3604 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/key_type_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/key_type_impl.hpp new file mode 100644 index 0000000..d8dd16a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/key_type_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7fb210fdda75b871770d4096764134281f96d6cd6c85fccf49bec8852f9b9248 +size 781 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/map0.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/map0.hpp new file mode 100644 index 0000000..1e1513e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/map0.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ae44da83a268b682c2acfeb75e6ab6ac8fe5893f29b2ddb6e55c6bfdfc1bcf4 +size 2155 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/numbered.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/numbered.hpp new file mode 100644 index 0000000..2a28a05 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/numbered.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:269ebc4da6d8b3ec917b84cc2e091e222368e285761244201d7eddd34104f767 +size 2458 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/no_ctps/map10.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/no_ctps/map10.hpp new file mode 100644 index 0000000..0d06bce --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/no_ctps/map10.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5c09518875afc70ad46614ae506d7217b9d3f8dd75e9ec90cea4e1bdf70a2e5 +size 6280 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/no_ctps/map20.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/no_ctps/map20.hpp new file mode 100644 index 0000000..3ad213f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/no_ctps/map20.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da1955d698aa8f8ddbd2aa7d0ee06eb638749fce7ee1329fd6b9a5d3fcabe189 +size 8177 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/no_ctps/map30.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/no_ctps/map30.hpp new file mode 100644 index 0000000..00513e7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/no_ctps/map30.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fede46aa3f7a7958e565de653844c3125357116e14bc042718e731cf41f68f45 +size 10077 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/no_ctps/map40.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/no_ctps/map40.hpp new file mode 100644 index 0000000..bce4976 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/no_ctps/map40.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa82ee830ea25996227d8cf6d3ee241be7658650f1c3afd76d3e5d220e19b431 +size 11977 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/no_ctps/map50.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/no_ctps/map50.hpp new file mode 100644 index 0000000..39e566a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/no_ctps/map50.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a496040019cde20adc9229101441005272fca173e65bade661a9258dded8ac26 +size 13877 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/plain/map10.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/plain/map10.hpp new file mode 100644 index 0000000..b838113 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/plain/map10.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eda4a71d4a25493a296c98267186077b8894c09f23eee5062b8c9fc1f43074a4 +size 5380 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/plain/map20.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/plain/map20.hpp new file mode 100644 index 0000000..42be91a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/plain/map20.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ae85510f49e84398e11e5a21238049103d4f355e42d4339694a682cbf9de3b2 +size 7277 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/plain/map30.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/plain/map30.hpp new file mode 100644 index 0000000..d48d68f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/plain/map30.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ec1946f659702d2660d50e8dd03643bed759dec9b0a347b08d5c177459c410f +size 9177 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/plain/map40.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/plain/map40.hpp new file mode 100644 index 0000000..a9ae4e1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/plain/map40.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5df8cd987dae577ebdf2c658464c11311a25a725e4f15f911cf0243a838ea22 +size 11077 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/plain/map50.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/plain/map50.hpp new file mode 100644 index 0000000..3977237 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/plain/map50.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a7e26d6b2614e1a968be215168793b8b3b8334962181c656588f48c5099e6521 +size 12977 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/typeof_based/map10.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/typeof_based/map10.hpp new file mode 100644 index 0000000..ed9a492 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/typeof_based/map10.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab83819e5fa1c4de954fa27b3b37d694ed07ffd5dafb9b152d8d061d7fd7640d +size 2878 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/typeof_based/map20.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/typeof_based/map20.hpp new file mode 100644 index 0000000..68467d1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/typeof_based/map20.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:22f920ea1cbad2bee0f4efe66faf582198b3daa652bf13d13d5204a9d287ad08 +size 4727 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/typeof_based/map30.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/typeof_based/map30.hpp new file mode 100644 index 0000000..0fd2928 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/typeof_based/map30.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d449a5f740c5bf906a0f4db2fb3edad96945b36c68e0a8f70eaf2d51528fcd69 +size 6627 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/typeof_based/map40.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/typeof_based/map40.hpp new file mode 100644 index 0000000..181c39d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/typeof_based/map40.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5389fe52c7d3c8256f8d6bf18834ffb09f7174f9a95c757bc4b690ee3cd785c3 +size 8527 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/typeof_based/map50.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/typeof_based/map50.hpp new file mode 100644 index 0000000..fdeeb33 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/preprocessed/typeof_based/map50.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a43f696f4fb23f8a1a4138ffbff050cf78e21d4f0c2cc92a81b1007a5a1396c6 +size 10427 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/size_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/size_impl.hpp new file mode 100644 index 0000000..a86b5cb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/size_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:72bf75ca440247125980c318b388f775a80c1d601a6f1d44bd199aa9626b6cd3 +size 682 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/tag.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/tag.hpp new file mode 100644 index 0000000..e670190 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/tag.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b206c88079890e437f3413b2c196b8b38a00f2c1b71b53c2a5f7000307dae5b +size 538 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/value_type_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/value_type_impl.hpp new file mode 100644 index 0000000..8e1296c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/aux_/value_type_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e351ac43e30e6c5491948b6131f992ae7a7b34938e5c9b931832e12f1691e29a +size 792 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map0.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map0.hpp new file mode 100644 index 0000000..94038ef --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map0.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f1b97891dd14845ea5217a61f6081ee5ea2d6e4f73b6bf0ea22c0d51d2d5cd22 +size 1270 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map10.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map10.hpp new file mode 100644 index 0000000..c24a5b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map10.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f913af4b7e5b46c19742b1fc9bb8fd9c4360ccdc50a8c131b852c317aa5df235 +size 1078 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map20.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map20.hpp new file mode 100644 index 0000000..9984b2d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map20.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb5150b89abf7fc56dba45fad750eaac9f4b723f28bd69ad4502924492697bfb +size 1080 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map30.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map30.hpp new file mode 100644 index 0000000..2f1bc9a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map30.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f71b98da90ed14dc20bc5708c268d1096d002e6233ea36f81314e830eaaeff6 +size 1080 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map40.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map40.hpp new file mode 100644 index 0000000..88ec718 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map40.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:991cf0561b9c895113e332ae435b69dd76d1678d7fdd0a27e56cb7de7dadfe4f +size 1080 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map50.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map50.hpp new file mode 100644 index 0000000..b1afb13 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/map/map50.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:396f2c6c95c07a8891e3a75045e4820f0bbccf5ba8d25fb50996ceacb07a4de2 +size 1080 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/math/fixed_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/math/fixed_c.hpp new file mode 100644 index 0000000..89d3e52 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/math/fixed_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99782fd719c1f532426de346f125dc69cfb0d99e6088c060dd1850a5df80a6ae +size 809 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/math/is_even.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/math/is_even.hpp new file mode 100644 index 0000000..baa48c0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/math/is_even.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50a4faafb414525104192fc32a4628e7804a091fcbd8ab35c503826cabbd12e7 +size 1152 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/math/rational_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/math/rational_c.hpp new file mode 100644 index 0000000..e1ca72b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/math/rational_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:024b47ff9bc5cd5fd9684e5ffecf2dbd7a837d61f0b4bd07fb49e5e734fed1c5 +size 811 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/max.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/max.hpp new file mode 100644 index 0000000..bcbe289 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/max.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:24620432eeb8b13db89295020a346e139da9c9897967bf9b9444084b2f3076b4 +size 432 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/max_element.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/max_element.hpp new file mode 100644 index 0000000..83c06ea --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/max_element.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:942acb7cb0e248f8c98ecffcd685e62c5bb234a8483d7e283460998f042cc36a +size 1580 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/min.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/min.hpp new file mode 100644 index 0000000..440645a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/min.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb43bac84231624f42a4e70796526b67d3af45523451dc17e54be899e6dd1dbd +size 432 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/min_element.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/min_element.hpp new file mode 100644 index 0000000..949f738 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/min_element.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cde3926059d73b7f3cc0b67411fbc2f4f4918b64c6e6fe8c796a580822271fbd +size 815 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/min_max.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/min_max.hpp new file mode 100644 index 0000000..220bd60 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/min_max.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ae1dadaf6ceed37b7a1c1baa6f6d6a15c0667bb3f7e271ba6dc538e01efacbf +size 908 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/minus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/minus.hpp new file mode 100644 index 0000000..38bfd7b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/minus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:366b618998c4b90750a22717311c8dcb93d0b95130498c7c1f9941cf5a122a1c +size 515 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/modulus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/modulus.hpp new file mode 100644 index 0000000..dc14ae3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/modulus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb8b5daa599dfc39fe08800d330e1c504bcbe000d7534eaaa2818aa93abaaf59 +size 552 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiplies.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiplies.hpp new file mode 100644 index 0000000..c8c7973 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiplies.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e285d96bd07939cff098d2299c54efef2e16754b21fb12c6b96496f7007f17da +size 1341 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/aux_/count_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/aux_/count_impl.hpp new file mode 100644 index 0000000..c770533 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/aux_/count_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fcc282e5e0300985e156d80be50a8243fc21317e2ae7e71762170d52b56fd133 +size 2121 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/aux_/insert_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/aux_/insert_impl.hpp new file mode 100644 index 0000000..2678a98 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/aux_/insert_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f13fdec966e119bd274da60dc479e3d4bd968a0a919b78d33444beba4e25b7a +size 812 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/aux_/item.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/aux_/item.hpp new file mode 100644 index 0000000..a3a829d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/aux_/item.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e8f13dacb96f2782e04bc4b565e7ef28ee4c40fab257a1e1ea2250ad5b1925e7 +size 3553 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/aux_/multiset0.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/aux_/multiset0.hpp new file mode 100644 index 0000000..6578532 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/aux_/multiset0.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8cd41684f0a34e1501e2614accd1af8b028c14d8e535d3eb8590cb13f266f7d2 +size 794 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/aux_/tag.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/aux_/tag.hpp new file mode 100644 index 0000000..c901d24 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/aux_/tag.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f75aa46e3f8b3e860f3cf22ad4e21b2c95782d11351c81d0a2436f6029fd168 +size 520 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/multiset0.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/multiset0.hpp new file mode 100644 index 0000000..3ed8bb0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/multiset/multiset0.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b974e85cf527f6bf6acc8914bc0a824ee35ae08422827e092f54c83db8b09b84 +size 1322 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/negate.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/negate.hpp new file mode 100644 index 0000000..ec30eda --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/negate.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb1f155c4639c1dfc2603c7552a5397949c826a9b5d2382e7af94c79ced4f2ba +size 1879 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/next.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/next.hpp new file mode 100644 index 0000000..d4dbcbc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/next.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db8c72758017419b5012abc162cf632cbb4bc608e7c9444e8e7b955bb2a21096 +size 438 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/next_prior.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/next_prior.hpp new file mode 100644 index 0000000..85fbfbb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/next_prior.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9215bab0c43bd36129b706c7750c5a38bba4dd29ab8e75bfb126e2068ec3e982 +size 1047 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/not.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/not.hpp new file mode 100644 index 0000000..8990b49 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/not.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:554499a67dc788704abef318787f0ba26045186cc1f9b8620fa8fa84a570a3a5 +size 1029 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/not_equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/not_equal_to.hpp new file mode 100644 index 0000000..f7a300d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/not_equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3feb028d5ef946121cb9176d927ea5e52e24238f123de13b755a4af481fa1ad +size 544 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/numeric_cast.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/numeric_cast.hpp new file mode 100644 index 0000000..052e0ef --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/numeric_cast.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:efae0441fe1ccd0a1e27160d2155706a4c02b3be92ad83b7221e18a8ecf927a7 +size 1219 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/or.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/or.hpp new file mode 100644 index 0000000..4615fb0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/or.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8be6b8cfb713cd176685caf65f3cbf39856bb50a6295670fbf276d4574c3fb8c +size 1623 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/order.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/order.hpp new file mode 100644 index 0000000..afeaec3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/order.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:655aadb57445b5d2d04ccd23313405da0bf1d87918525b562e627ea0288f6535 +size 1041 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/order_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/order_fwd.hpp new file mode 100644 index 0000000..422e003 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/order_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:16f3dd96014c91b6eb8c83a9eea365fe79a71aeae3fe5b3166bf37c5a0ff461a +size 612 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pair.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pair.hpp new file mode 100644 index 0000000..090e540 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pair.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90a4e3bae007707a422084b2bdc3dad34bb6ccf62ac950a45ac890636864e98e +size 1501 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pair_view.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pair_view.hpp new file mode 100644 index 0000000..876d440 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pair_view.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10fb1f4cb19825c5996f9a520a7cdc18a5c7e23371e1fbcdfa43ea9233ecf86f +size 4355 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/partition.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/partition.hpp new file mode 100644 index 0000000..3b18281 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/partition.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41cd5ff4b21ed558e17e3e45977652fb2b3ca4c72e6365359f21476824238f85 +size 1046 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/placeholders.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/placeholders.hpp new file mode 100644 index 0000000..f6c39f4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/placeholders.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a72651ec976974622a93731a1c6d6675af0d5365a24d8573752e40a288c6679 +size 2450 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/plus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/plus.hpp new file mode 100644 index 0000000..2c3cbf7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/plus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:420d03c24bafc45f41d42ce2cb029fa5b58fcde9fb196a8fa0d8fb9778ba3b34 +size 511 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pop_back.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pop_back.hpp new file mode 100644 index 0000000..b011c51 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pop_back.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62b1f6b1db2dd952394dd94bfc59aec685e471e8ea258151dfcbb6552204efa0 +size 937 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pop_back_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pop_back_fwd.hpp new file mode 100644 index 0000000..56d896f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pop_back_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42767b6ddbf4d78b11eb57067ba3a1d20453927ffe65ccc95a6bdc52bba2a80b +size 564 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pop_front.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pop_front.hpp new file mode 100644 index 0000000..9173239 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pop_front.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48acc68382549fd28cd6eab8654f0b1fd6138e1f77a8eee5b97dd8f89ec8521c +size 946 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pop_front_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pop_front_fwd.hpp new file mode 100644 index 0000000..39357b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/pop_front_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b0d41d826b3bbad6978b52018c5f682c5d12ebadf1538ecfcc81a4b13cf44aa +size 569 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/print.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/print.hpp new file mode 100644 index 0000000..a1db3e2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/print.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1937474674cd3071a410575d8387b694cd19b58cd6d494e50cfe97575ccf5e9c +size 1669 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/prior.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/prior.hpp new file mode 100644 index 0000000..9ed689e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/prior.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d8bb4bc5d56f15f1829338925dc233d36af3da7ae958e7074b095353f87665c +size 441 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/protect.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/protect.hpp new file mode 100644 index 0000000..39d62b8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/protect.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0f08cc513a245a7498017755dfe74dadc591be2820fd9ac3449c8faa5a73886 +size 1237 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/push_back.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/push_back.hpp new file mode 100644 index 0000000..babadf0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/push_back.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:709c800058488d9b32f9798aae12ccaf8e10bf6ae1d1b74da6b6da297c068620 +size 1289 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/push_back_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/push_back_fwd.hpp new file mode 100644 index 0000000..55c9c68 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/push_back_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18a3af3de643c04c01efc2db3ee6c11931578638bb151cf3d006cf120cfacadb +size 581 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/push_front.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/push_front.hpp new file mode 100644 index 0000000..84cfd1d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/push_front.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:31c3ef744324bfa29201e82e78ff402be0529b8543e5ca82edbf698dc248fd2c +size 1301 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/push_front_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/push_front_fwd.hpp new file mode 100644 index 0000000..157aa97 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/push_front_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f05de27ad94821fee096f90f9977b25248c5aaf2f02974cb339418818b8b68bf +size 586 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/quote.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/quote.hpp new file mode 100644 index 0000000..f3fe454 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/quote.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fcb0df9da8d23be7d25db56d5479060a77f585f3a885cdc39a71fa128e4abe28 +size 3634 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/range_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/range_c.hpp new file mode 100644 index 0000000..413dffa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/range_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:560ada46c52188c45ceee98c5092d5f55a5ba1151c5e149f7edbd5d631e1584f +size 1124 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/remove.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/remove.hpp new file mode 100644 index 0000000..04f7294 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/remove.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ae59e3d4656c20d0669ba396f13112e81be2b4121d3649c7f1227958136d24a +size 1033 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/remove_if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/remove_if.hpp new file mode 100644 index 0000000..d6223cf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/remove_if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3824f44dd6c175186d35ad5b50b4e7ff200edb9b5898af9c0b6df30a29d64daf +size 1892 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/replace.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/replace.hpp new file mode 100644 index 0000000..aca227b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/replace.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:33dde266a07c35f01e166671e4a06e1ced9f0401413a24f79d5f644d4df25a8e +size 1169 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/replace_if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/replace_if.hpp new file mode 100644 index 0000000..cfec3e5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/replace_if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81132146d317e3ee26dcebee4c6e9319d1a13e3dc122e5a15af1296ef73e515b +size 1795 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/reverse.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/reverse.hpp new file mode 100644 index 0000000..71fbc7c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/reverse.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ade13f15a7584236d4201e39dcc4d1ba9d009e0b8562fd8ed8b331f0c39e2519 +size 759 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/reverse_fold.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/reverse_fold.hpp new file mode 100644 index 0000000..0cd913b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/reverse_fold.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46ba1d4bed094f24051acb4a51709b33c3610b5cb37464a39b1e90ad49c87b7c +size 1282 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/reverse_iter_fold.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/reverse_iter_fold.hpp new file mode 100644 index 0000000..6901881 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/reverse_iter_fold.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40b9efab4a923f5729f7c21e70c699df7e55f9799f493a75a69d8e1a6ca06dab +size 1497 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/same_as.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/same_as.hpp new file mode 100644 index 0000000..cc55e05 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/same_as.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0be317738941c6ddee3822051c0f78ab9abf4a8c17b032b4563981f462c6641d +size 1124 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/sequence_tag.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/sequence_tag.hpp new file mode 100644 index 0000000..345e570 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/sequence_tag.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eba6c10ea3345b75379f2209e8c1b8aa0e52c1bc2e3714866a95cb57113631b7 +size 2989 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/sequence_tag_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/sequence_tag_fwd.hpp new file mode 100644 index 0000000..cd34aed --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/sequence_tag_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:026ad6db1cbefeaead66b087de30406949be26887b27d2822b79d5cc03d74a63 +size 588 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set.hpp new file mode 100644 index 0000000..61ed25a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6cd87ee79bf484523e15710cf646dc102698f8031a67042cb6b44d18a4cd0f7 +size 1593 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/at_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/at_impl.hpp new file mode 100644 index 0000000..3740510 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/at_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3edba3c1566dd5390589b0927a6a79c3cc388c185e0a2f7a6cb20bd1aff196a7 +size 929 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/begin_end_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/begin_end_impl.hpp new file mode 100644 index 0000000..04e5356 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/begin_end_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c6901e76dd9685b7d4a7f6c7a4b8e6723a52d49989c58120151c0d316e20046 +size 919 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/clear_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/clear_impl.hpp new file mode 100644 index 0000000..235839a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/clear_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfc736d7f598de06f4e7d1e84ffa27641de046cb7d9b77c17d6944b92abdd5f3 +size 773 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/empty_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/empty_impl.hpp new file mode 100644 index 0000000..7d8ca8c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/empty_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4323938a994fb1f8cae9bf05d6b272e4449f6bd8e0ca5af1d20e584a3bcef820 +size 733 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/erase_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/erase_impl.hpp new file mode 100644 index 0000000..2b9e27a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/erase_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c519269342048c0b58534b5567f975b241ae47a45b110da29a8f134a5fa99432 +size 911 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/erase_key_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/erase_key_impl.hpp new file mode 100644 index 0000000..b83d8bf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/erase_key_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e1ea17a4e372834edbebfae720e9d66a4184217fd8600c369a047e8e28fa6244 +size 1299 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/has_key_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/has_key_impl.hpp new file mode 100644 index 0000000..c61153e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/has_key_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7034e62fcf5a7409a4d9303ae3ed83690c38ddb77d65fbd4fb854c4cd04b2ced +size 1705 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/include_preprocessed.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/include_preprocessed.hpp new file mode 100644 index 0000000..e7e4558 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/include_preprocessed.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d014fe3aeb77d984dbcdb21c769c2d8c9c4f8ffc3265b98dac482537fda280f9 +size 1189 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/insert_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/insert_impl.hpp new file mode 100644 index 0000000..60ee513 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/insert_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c44f47d7cbdca0a677497b6acf9d1dd75ac09091019dd5b2be50dfc4addec678 +size 1519 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/insert_range_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/insert_range_impl.hpp new file mode 100644 index 0000000..a7e4439 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/insert_range_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44801d3f066f3973982fb9cb582c48945fd21b7cb4105d69199a7329eedd307a +size 920 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/item.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/item.hpp new file mode 100644 index 0000000..683b370 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/item.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f574bc12a4d504c71d389496cc95265d7e645d5ed5c44dfdc5ae08c6760e37a7 +size 2307 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/iterator.hpp new file mode 100644 index 0000000..faa4840 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7749400368cf8b13e50190de52a76b4816dbbb19c2ab31abbab855e4cebba0c +size 2283 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/key_type_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/key_type_impl.hpp new file mode 100644 index 0000000..ec00312 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/key_type_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5df9fc023b598c42597d37214a7746bd63441f43526eb8c594f1c66039fc3099 +size 756 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/numbered.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/numbered.hpp new file mode 100644 index 0000000..be3a5c2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/numbered.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ef3805fcafcf81c65bc70547d2d95816929c07fe6d138679f35ae126963307f +size 1082 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/numbered_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/numbered_c.hpp new file mode 100644 index 0000000..47d7230 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/numbered_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:807dbcaab3532215d85c52ee2658143a84205a85fa7b00ef340cc0029c670994 +size 1198 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set10.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set10.hpp new file mode 100644 index 0000000..7a6afdf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set10.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:485ad0f84e4c7c349e544627c25529c6e23f1f0e44f0eeff40d4e8464b4df50e +size 2578 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set10_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set10_c.hpp new file mode 100644 index 0000000..b5cfd23 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set10_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:69e2399e6f08805aedf911dc61170e2cb5fb44a527be0930ba580ec69298fe5d +size 2419 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set20.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set20.hpp new file mode 100644 index 0000000..7b84cbe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set20.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19100a5f4c2e8aa6e350b8261b067fdf3f82cda3d2ca17a9c1c2b8d1e0b5920a +size 4605 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set20_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set20_c.hpp new file mode 100644 index 0000000..8dc1107 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set20_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73e90577c0adfe33aa195ababb5f99e4f9b363e41aaa2d49b234b2d13ce4814f +size 3504 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set30.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set30.hpp new file mode 100644 index 0000000..26f5d36 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set30.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f413b74a85ff42447e85c3c0e243c393ce712d23356b3841d085748d6d693873 +size 6687 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set30_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set30_c.hpp new file mode 100644 index 0000000..a388590 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set30_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:23ff55b7f8b5023fbd7044b9b51efa427878fe8be288a4162310da67a8a6ce0f +size 4654 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set40.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set40.hpp new file mode 100644 index 0000000..5fad164 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set40.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2bd0db04bdfd155b2eb50429ae5053a92b8614f97094f9f7014ed8d9a7803cc9 +size 8741 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set40_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set40_c.hpp new file mode 100644 index 0000000..401c4f2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set40_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d811058c6b819956c7f28ff4194fb02190ef7fbd70b9dbf22522622354f7bccf +size 5804 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set50.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set50.hpp new file mode 100644 index 0000000..4700a00 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set50.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07546a94004ea03927ff6ba62e017a510387edc3290cd0980b11ff4dfd73b91e +size 10822 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set50_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set50_c.hpp new file mode 100644 index 0000000..856b230 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/preprocessed/plain/set50_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62695a5c50f01863ba3e09f0d9e2945c049c1d4e30c1da6ad96612193cc4ffe1 +size 6954 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/set0.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/set0.hpp new file mode 100644 index 0000000..6870733 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/set0.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34ce31738d43f0bef61b755d7450b7279ebce7ff6dc99e70aeb01b9c397f26af +size 1883 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/size_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/size_impl.hpp new file mode 100644 index 0000000..9776cef --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/size_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a64e0306018c7ed3b57feccd46961cca23658642756318579c696f6338f64205 +size 682 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/tag.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/tag.hpp new file mode 100644 index 0000000..188f800 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/tag.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e3c989975075c81d4ade29300a03a4cc8f00386f2b0b925349413f0157a0dcd +size 538 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/value_type_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/value_type_impl.hpp new file mode 100644 index 0000000..9aab32b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/aux_/value_type_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1914fec4073c1445c1e2d17df2dc7eb2b4701b4a5bc2deee5b49c0f78b047a3 +size 766 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set0.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set0.hpp new file mode 100644 index 0000000..364e68f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set0.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0a536a9d828c06f5c3e4eb9b479a53129bf8bfdd119e0895e904b6507875b83 +size 1222 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set0_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set0_c.hpp new file mode 100644 index 0000000..10051e0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set0_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59af2c05abc85d41c921e03b87159db8bc298a55731e2955f9b7eb83f4d24858 +size 679 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set10.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set10.hpp new file mode 100644 index 0000000..a318b14 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set10.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e461c72f42c6be55c7ae9bfa0118bb7aa734ef2e1a78599805c958cdcd4a5d24 +size 1078 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set10_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set10_c.hpp new file mode 100644 index 0000000..724f18c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set10_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:63bb3e7e383eed38ccc994681744e0f8534c7f7ee5ab80c5deb600c195721446 +size 1128 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set20.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set20.hpp new file mode 100644 index 0000000..fc9e0b3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set20.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90444b276895f087dbae9135afcbc12a41621364777c237be0f5caa781b90ce7 +size 1080 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set20_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set20_c.hpp new file mode 100644 index 0000000..723d412 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set20_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b995ddcb4a05ede5a215792f28e503d063f40a7f9af8554f2f91e799fa82400 +size 1130 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set30.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set30.hpp new file mode 100644 index 0000000..0f804a5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set30.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ecfe873957dbb12c188af1c5f58d43f98926a1887fb908a38d5bd3d583f4773 +size 1080 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set30_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set30_c.hpp new file mode 100644 index 0000000..fb84b44 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set30_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0a352cf15dec2700a557569b662620b57c5466497f5d7fdb4b6d0b936db30bd +size 1130 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set40.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set40.hpp new file mode 100644 index 0000000..5a2d5d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set40.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c6b3402c332aed1ff55694706b98bc16644f6eac758ade12504c69973ce362ed +size 1080 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set40_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set40_c.hpp new file mode 100644 index 0000000..838f55b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set40_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:71ebf8831df9e442aa799633dc839835a4b9ca07ebeba11efead76c68185b53f +size 1130 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set50.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set50.hpp new file mode 100644 index 0000000..35bbe2a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set50.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4149cf253269e2faef224d7e90242bb49d8c4af0e47a4bb163b676dd84dc8420 +size 1080 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set50_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set50_c.hpp new file mode 100644 index 0000000..f7822af --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set/set50_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d9b6dc1cc9202e309ec6c26b1885ff0e8e78fa7e95f86eb701bac1392c72315 +size 1130 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set_c.hpp new file mode 100644 index 0000000..b8ea27e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/set_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1f7a13391b30c7d03c96d35193bc0ce852015d2dce0f960800a7f3ffb149725 +size 1796 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/shift_left.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/shift_left.hpp new file mode 100644 index 0000000..19ea92d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/shift_left.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a761d93bcf06405010c07b34ac992dc0b511f850d2140b72c604db13dfe63074 +size 560 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/shift_right.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/shift_right.hpp new file mode 100644 index 0000000..c6903cc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/shift_right.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a9549bb564bce2e560764737d42b004f7dca8cf3fca9f21d30986207418cb595 +size 564 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/single_view.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/single_view.hpp new file mode 100644 index 0000000..dd90f72 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/single_view.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cc224ae9c616fa3d32bed6f3006115dec694f7255a8b10bbb6925e15c96d74a +size 813 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/size.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/size.hpp new file mode 100644 index 0000000..5e7d1f7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/size.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f27eb12ecc2987f26cd3504062066845e7ecc650bb35d51f75f9bc29d3e6ea6f +size 1008 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/size_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/size_fwd.hpp new file mode 100644 index 0000000..605b8ad --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/size_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aaecb60cbac1ae0b847278d697cecc439b5b87487ddb955513e5145fcbe6ccab +size 544 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/size_t.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/size_t.hpp new file mode 100644 index 0000000..80689fe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/size_t.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:503e0adb9abb737bc4eba77b4640c9f30a5798806ed74e07eb24e3df2be04f85 +size 617 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/size_t_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/size_t_fwd.hpp new file mode 100644 index 0000000..9b823e5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/size_t_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1efc71182d8d2f981a3b5be7f4b1640e7b49fe9d352924d110a329065822e934 +size 723 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/sizeof.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/sizeof.hpp new file mode 100644 index 0000000..7c71074 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/sizeof.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59469f31b1e1d18a50dc14a4f0745002544ddd947c9dfc6e2c4aa1dced59cf0e +size 766 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/sort.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/sort.hpp new file mode 100644 index 0000000..ea7ee94 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/sort.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3bd1fc8d57f403a901fc6ae2f528e8fe7dd9bf5211e4a192e6046918e934f420 +size 614 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/stable_partition.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/stable_partition.hpp new file mode 100644 index 0000000..bf0a842 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/stable_partition.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2d913e790b1fb6b61c3429ddc89efe1bcf23d7db564634804d3d127b9d7d8dc +size 1709 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/string.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/string.hpp new file mode 100644 index 0000000..ca4db45 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/string.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:618d06f7a43df8a769b9c3537d4610164fa4470a12d895d412b5f27134b07a2e +size 24547 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/switch.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/switch.hpp new file mode 100644 index 0000000..5cfb8e1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/switch.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:851491536fa7f63c9231df1d780d43a56bf59149a778b330b39ed0b4d05bca60 +size 1187 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/tag.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/tag.hpp new file mode 100644 index 0000000..5a9905b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/tag.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2bccc8d2911980cc041905c37134bb0250084f923c79be57f86b760fdbb4c3a1 +size 1023 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/times.hpp new file mode 100644 index 0000000..e2af64a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c65e9af530d8e6ecd1bd8ae35ee254f9c3fba4aeae92d67f51458c61286178f +size 515 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/transform.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/transform.hpp new file mode 100644 index 0000000..778073b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/transform.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e377b86fcb965a371ed3c4307b4569b08d446ffbfeb92ac8a26cdd518daddf1 +size 4202 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/transform_view.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/transform_view.hpp new file mode 100644 index 0000000..293a9b9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/transform_view.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8260dfe9e02299e5821c1fab055acb34e31b3b0a2cffa2e1388f3412ca046cf7 +size 1124 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/unique.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/unique.hpp new file mode 100644 index 0000000..b9cedb3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/unique.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5257adc16cde0aeb438f6b47513a144442e516841950ce596cb9d2efa73446fd +size 2053 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/unpack_args.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/unpack_args.hpp new file mode 100644 index 0000000..9d5fe3f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/unpack_args.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:71db6700d6423d29c0d9b2bbf01b21f144d7b1ff7be40b8f7aa6e209be099631 +size 3563 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/upper_bound.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/upper_bound.hpp new file mode 100644 index 0000000..aec8a81 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/upper_bound.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ceb115a5f8bc42f1279f7b8502ee9c9f9180bdc703e6c004370216d5060902d +size 3555 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/value_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/value_type.hpp new file mode 100644 index 0000000..0cd6199 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/value_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f3322e6c6b9dd4d4cd7b9412cdc52fbf8a7bf106db23d37cf37a0a3af167896 +size 1084 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/value_type_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/value_type_fwd.hpp new file mode 100644 index 0000000..1524e04 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/value_type_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e2e3570e56dec00343b3344b583342cf3cfa3039879889d8f6659d534c35f329 +size 635 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector.hpp new file mode 100644 index 0000000..a58f2cc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:492a438cb7dbf6ccf0e99bc3d2d21073215dd0a479920c2b19acbe95b4af616b +size 1644 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/O1_size.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/O1_size.hpp new file mode 100644 index 0000000..6ef7623 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/O1_size.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2818d1c241921e40fec8c34efe4f5e272ba5ff32a5fa45133aede6935e4c182a +size 1213 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/at.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/at.hpp new file mode 100644 index 0000000..407d9a4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/at.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5fd29b495501993893963019b0961aa3e694ba5bb29a937f38eda6f4216822a9 +size 2562 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/back.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/back.hpp new file mode 100644 index 0000000..fea6f5c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/back.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7f33db9354d152d9098d8f42bccc52ead40259904dbf1fd4f84e6a38a2b97fb +size 1316 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/begin_end.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/begin_end.hpp new file mode 100644 index 0000000..b1b9897 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/begin_end.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef88e130f13748e6f8b911bb508eec455ac12a5027c4bb1cf6adc7c4524c0388 +size 1091 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/clear.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/clear.hpp new file mode 100644 index 0000000..21e03cd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/clear.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb98480c71a8d886a11321b1b2fb3c366ed1cac41b5cf8c2323f6a91fc40f27f +size 1202 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/empty.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/empty.hpp new file mode 100644 index 0000000..2bcc8ee --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/empty.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:baca7576cf24909017514c4378c16a0be6b01c15dc15369f1bf4669301581002 +size 1433 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/front.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/front.hpp new file mode 100644 index 0000000..46b22b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/front.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4ebd866106aa63f0d7e22688b8afaf2c878206aea9c899cc7953b3f70ceeaa6 +size 1271 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/include_preprocessed.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/include_preprocessed.hpp new file mode 100644 index 0000000..ccdf343 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/include_preprocessed.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:415bf6fcfb50be230221941452a31a7f6600d03151f99869bc68c055f1a72158 +size 1656 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/item.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/item.hpp new file mode 100644 index 0000000..40bd554 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/item.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa83fd1c5fc4753e6f6a7274d3d097fed05dd87534166a9843faa29cd09f468e +size 2461 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/iterator.hpp new file mode 100644 index 0000000..3da7396 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d991a753c7b5c08eb9fcd800fde47cc7571a74776e35f1b5d5f8861ecae831db +size 2971 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/numbered.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/numbered.hpp new file mode 100644 index 0000000..f86bd84 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/numbered.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2115913baa885d11d43f62b957b39149624ba6938ef475fc52bb48767a386ef7 +size 4783 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/numbered_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/numbered_c.hpp new file mode 100644 index 0000000..2b155da --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/numbered_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5b066fc11ca054a76a138cc6359c8501579fd7556936db8b577c87e3e6daf48 +size 1941 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/pop_back.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/pop_back.hpp new file mode 100644 index 0000000..e6f34cc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/pop_back.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dda2404b2aabf0e3134becc85e55204eba19e157922c91e658661adaf359e4a9 +size 916 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/pop_front.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/pop_front.hpp new file mode 100644 index 0000000..7050829 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/pop_front.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c6f83df45e3fc70afcc834e8962b3d0c997d287b5653aa5f0152774feefd7038 +size 921 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector10.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector10.hpp new file mode 100644 index 0000000..5c3308d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector10.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:301524038d1803b0e323d2dc89954c30a58ee4ace4c13f1fb8d770be4ed03037 +size 30637 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector10_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector10_c.hpp new file mode 100644 index 0000000..7c0748f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector10_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e1118ac1b08b12fec4ad418363009729d486857d21867e5562b5fed5c1556021 +size 3266 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector20.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector20.hpp new file mode 100644 index 0000000..afdc5a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector20.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d625aa8f69dad229c3da35b908ae3a98b9b7c89497eb3fff967e556d65c239cc +size 46245 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector20_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector20_c.hpp new file mode 100644 index 0000000..9efec5e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector20_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:20fd755d3948a42ed503eccc7e37a0d3b903a79c3b41b4f2ee1ff26845f12c77 +size 6361 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector30.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector30.hpp new file mode 100644 index 0000000..e3948f2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector30.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ddaa4db42616f482be030ed96ac9a09937f1fce7cef28b59cee66d53bd82a30 +size 62745 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector30_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector30_c.hpp new file mode 100644 index 0000000..a37e2ad --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector30_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75f0c7ed66f2483c874a30641d8fd58f3941d729f1afa6d5b739e1106e08c7dc +size 9509 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector40.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector40.hpp new file mode 100644 index 0000000..c2c2be4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector40.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1a127c0a3857d57d0358ae69685edd7cc59c963d5a959cdfdadf38eb501a43ef +size 79245 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector40_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector40_c.hpp new file mode 100644 index 0000000..c669152 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector40_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:530e0881d8a755eee8366addc1ce7578fb704423fdd1e1b8bbd76c1291aa0552 +size 12656 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector50.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector50.hpp new file mode 100644 index 0000000..46318b9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector50.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a786a9e3e572ce73a12fe96bccbe1f1aa6f7d4d6cc66f20abc3a6148edfcb06 +size 95745 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector50_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector50_c.hpp new file mode 100644 index 0000000..a00ea79 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/no_ctps/vector50_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f376f4aa912511bfa07255ff65565f2080556a8a724e0910441f8c4c5fbd43c7 +size 15811 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector10.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector10.hpp new file mode 100644 index 0000000..09d564a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector10.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc256186db7f55cc4ecd457ae4e922656bdd410987b805a490c62072c63ef484 +size 18549 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector10_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector10_c.hpp new file mode 100644 index 0000000..7c0748f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector10_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e1118ac1b08b12fec4ad418363009729d486857d21867e5562b5fed5c1556021 +size 3266 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector20.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector20.hpp new file mode 100644 index 0000000..2364839 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector20.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a7da8c86354867cbeffe891564f29c8965b0822812ed5ec3c403f27168602517 +size 34765 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector20_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector20_c.hpp new file mode 100644 index 0000000..9efec5e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector20_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:20fd755d3948a42ed503eccc7e37a0d3b903a79c3b41b4f2ee1ff26845f12c77 +size 6361 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector30.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector30.hpp new file mode 100644 index 0000000..6393c46 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector30.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb9695c5cd2cae7351fe61579790fcb16d4e97f08e43010d3667ecaf9832afec +size 51265 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector30_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector30_c.hpp new file mode 100644 index 0000000..a37e2ad --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector30_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75f0c7ed66f2483c874a30641d8fd58f3941d729f1afa6d5b739e1106e08c7dc +size 9509 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector40.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector40.hpp new file mode 100644 index 0000000..62a74ce --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector40.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92682f3df98a666338be4e46d79f2c606b948902ed87aaca100c9a69088a1c90 +size 67765 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector40_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector40_c.hpp new file mode 100644 index 0000000..c669152 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector40_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:530e0881d8a755eee8366addc1ce7578fb704423fdd1e1b8bbd76c1291aa0552 +size 12656 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector50.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector50.hpp new file mode 100644 index 0000000..a79a772 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector50.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05d5a35ca5ca2bc36b39dedfb5c001f06b115c2b482aa871c21b8bbd0015bde8 +size 84265 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector50_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector50_c.hpp new file mode 100644 index 0000000..a00ea79 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/plain/vector50_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f376f4aa912511bfa07255ff65565f2080556a8a724e0910441f8c4c5fbd43c7 +size 15811 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector10.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector10.hpp new file mode 100644 index 0000000..e566b17 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector10.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac63f7a70a9f120b97012712f857b5c09b4f41b59257f80cdd367f8b4f839acf +size 2476 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector10_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector10_c.hpp new file mode 100644 index 0000000..6c2d455 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector10_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df2e89fc565e98b7b82fd343f56bee93b27ecbcb6ea01c1da7f3193ff0f01e46 +size 2737 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector20.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector20.hpp new file mode 100644 index 0000000..6f87a8c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector20.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29510ab2e86dbeecb75b5c7a0f8f109155ff529323f8036b265fd40f89e93cf2 +size 4315 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector20_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector20_c.hpp new file mode 100644 index 0000000..344a51c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector20_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4281fde9a38fc8e366fc0893979c33333e9abbcca91ea79e96412ce198c88ebd +size 3822 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector30.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector30.hpp new file mode 100644 index 0000000..90fd9e2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector30.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a3916d7f9aa26ddd7666f364bcdda239cda37a3f13a283ebe79aab87297b86b +size 6215 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector30_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector30_c.hpp new file mode 100644 index 0000000..513f0bd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector30_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7a1fadf98e30c6f64a7bbb607fbc1f913be2d1113475f5a30f3e4d547a0506a +size 4972 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector40.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector40.hpp new file mode 100644 index 0000000..cbf465c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector40.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fdb931c2ffeed3ceec0dfada4672500d9f8fc9c7da8dcfb46a53b4f1ebe0097e +size 8115 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector40_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector40_c.hpp new file mode 100644 index 0000000..a2d89f2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector40_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:597d5922bf50915225590ac7132104ac6930e88307b78e04d6d2f105a07c7f12 +size 6122 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector50.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector50.hpp new file mode 100644 index 0000000..942df95 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector50.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2bdccac69a954f464db7e1bf99e6a879353f84291e05b67c35375f71e6db083 +size 10015 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector50_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector50_c.hpp new file mode 100644 index 0000000..44d2632 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/preprocessed/typeof_based/vector50_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d50a6bdc1e2bc1648f5f59a7f3b212a6055a235f4183230bb6a2e089e1b933b +size 7272 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/push_back.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/push_back.hpp new file mode 100644 index 0000000..2f52cf8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/push_back.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77f8d65ac9177ccff2aad11b02158ac6259372a869058e808fd45c9f331ed1ef +size 896 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/push_front.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/push_front.hpp new file mode 100644 index 0000000..3700d5d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/push_front.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ba9ac3cdf8f36705b81311ed35d16a9d10adee4674518eff6a7f558c805b29b +size 940 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/size.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/size.hpp new file mode 100644 index 0000000..6e7bcd1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/size.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8af0d511f58dc5d3826ab90ba5e58bcefc838f8a15c8d70ba7628b2ad4683a80 +size 1095 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/tag.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/tag.hpp new file mode 100644 index 0000000..b564dc4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/tag.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49ebd03cdbdfc9463387b2e6d38fcc0471cfd60de1669253919f1251aaaceb69 +size 744 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/vector0.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/vector0.hpp new file mode 100644 index 0000000..ff73143 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/aux_/vector0.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c3466c054ed61f3c3f64c38390e91d69dc345fbfa939c69afe3302c9baa61cc +size 1306 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector0.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector0.hpp new file mode 100644 index 0000000..84ad52e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector0.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eff694d029130071b6808b1abe67cf388c77232e30264a92f612986b36ef1a87 +size 1144 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector0_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector0_c.hpp new file mode 100644 index 0000000..6d7a5c6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector0_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5a5e058e35bca75e27ec97eca8df945af4288e9ff548b895f57f7611030d477 +size 674 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector10.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector10.hpp new file mode 100644 index 0000000..97d62f5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector10.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c0cab768e99f212e758c2f96c1093deb4f18423e3ab79bd2421f18142402f21 +size 1165 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector10_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector10_c.hpp new file mode 100644 index 0000000..c3945b5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector10_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:beb53988c6d9c60c73eae7383f19d54eb4a5a9fa7cfef63a964f8c1598715b7b +size 1221 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector20.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector20.hpp new file mode 100644 index 0000000..050067b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector20.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17e18fccec56759e169770830b7c27b43589eab76c9010de665b3d78e2de4e5d +size 1167 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector20_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector20_c.hpp new file mode 100644 index 0000000..0b87612 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector20_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83031e55aa622cb678cbbf904aee0c7f2a446cf206e39b9424ace0f9713a71d4 +size 1223 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector30.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector30.hpp new file mode 100644 index 0000000..ee54024 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector30.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a87290167e3a658ff1d1a77b75892890b32d33f3c522c4f5f64c337e9f759525 +size 1167 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector30_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector30_c.hpp new file mode 100644 index 0000000..7f0aaca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector30_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe753c5f860c6f1216e398d5abbd8fc2a94b27ebb8f0ee3e38b4777e26cded78 +size 1252 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector40.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector40.hpp new file mode 100644 index 0000000..0e646b0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector40.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e569c3a2d66bc893c9a4bf1e70f3ee410a37232ded9faf339fa55f0321c7867 +size 1167 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector40_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector40_c.hpp new file mode 100644 index 0000000..ff0daad --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector40_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:036abeaa5eea7c4d9e475d4bce2db2805d16c39f77eb30bc9a9c9b02ce9ff0c4 +size 1223 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector50.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector50.hpp new file mode 100644 index 0000000..36805b1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector50.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bffb050a36ba6b432914678935e9101541f1b177fbe399a01de7711f002fb27f +size 1167 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector50_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector50_c.hpp new file mode 100644 index 0000000..7c5b225 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector/vector50_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:961a7d037fbe92b85d43c8f54eb3eddc2e268fd9735ea78fc787fc05450a5070 +size 1220 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector_c.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector_c.hpp new file mode 100644 index 0000000..3688220 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/vector_c.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a3d51e25c5d76f757aa5aee132efc57cb8f7a006e9ea252d2c57ab6814a2ea6 +size 1932 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/void.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/void.hpp new file mode 100644 index 0000000..c3f72b9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/void.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6968500000ec19d3ebdd17670e434fa70cb2ff36ae93e55dd0d5f94e9dc1d52 +size 1608 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/void_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/void_fwd.hpp new file mode 100644 index 0000000..dc36549 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/void_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed43f10ad35cda66de81db316ea0f9ffe12efc791d206dae028c8e2f8a3b1166 +size 599 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/zip_view.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/zip_view.hpp new file mode 100644 index 0000000..f42f75f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/mpl/zip_view.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1bf762684810986247792ee1ed12818aadcffb14a2734d176ecfde68c32e9c0 +size 1542 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/bounds.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/bounds.hpp new file mode 100644 index 0000000..80166a1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/bounds.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a7684a73c46bca05f75db21b7456aa07bf174c439e05494ab64d145bc8644b3 +size 706 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/cast.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/cast.hpp new file mode 100644 index 0000000..28a3b0d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/cast.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:71664136d5a92bb5669da8d20dcec1eb4ab4f4bcdc067ad32652524602565a65 +size 2123 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/conversion_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/conversion_traits.hpp new file mode 100644 index 0000000..a3f999a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/conversion_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d76a813b2688b11d8e6668b021811343df8aae28b0d35adf64949e64ea7cc3d +size 954 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/converter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/converter.hpp new file mode 100644 index 0000000..c5e071c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/converter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d33001875f224c1d5d78f6dafc9a648b7156543050711332a81491c6c4ca66cf +size 2239 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/converter_policies.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/converter_policies.hpp new file mode 100644 index 0000000..03b49a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/converter_policies.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:878c62e52beaea335ce720f5c1b02c82ffbb0caeeadefbdb218459016edf3f64 +size 4470 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/bounds.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/bounds.hpp new file mode 100644 index 0000000..3d92c09 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/bounds.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0ef0270bfc67f6b687bcd02a9c2e85a46f619203a0c4194b812a9f427bb9603 +size 1820 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/conversion_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/conversion_traits.hpp new file mode 100644 index 0000000..d78bea9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/conversion_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8efba8a46cc4e6cc4ebfb8ebfa7c9df43dd47a8b5ea44182a21ff253e9d47b9a +size 3587 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/converter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/converter.hpp new file mode 100644 index 0000000..ba6f208 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/converter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef702fee32ba76c59ce6e336e046380fe2fecc476ac276b2f0172037119800e0 +size 19234 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/int_float_mixture.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/int_float_mixture.hpp new file mode 100644 index 0000000..5024b1a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/int_float_mixture.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:27c3475c909925114434dd06a9dce8228a433899314ba7b80b2c717e9305c838 +size 2600 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/is_subranged.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/is_subranged.hpp new file mode 100644 index 0000000..37bb113 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/is_subranged.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0876b25143bc1fdfec3581a4179a369fc250c34db3c8420d95149d721d8bd072 +size 7686 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/meta.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/meta.hpp new file mode 100644 index 0000000..41ab543 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/meta.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:69f7785a568178241abfa69a720a31f1fbe620f6f5ff1911872653edbfc78d69 +size 3662 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/numeric_cast_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/numeric_cast_traits.hpp new file mode 100644 index 0000000..0487a94 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/numeric_cast_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c42ad3f4cf741e7f1505bba5b88578028e0c92d06b7f266415ac046e7d2461f3 +size 5523 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/old_numeric_cast.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/old_numeric_cast.hpp new file mode 100644 index 0000000..83f87f1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/old_numeric_cast.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e1292474b1fcb18d3dd85908c15b83bc260a183cc49d3bd65a024f1c9ea06dac +size 10969 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_common.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_common.hpp new file mode 100644 index 0000000..0dfaa56 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_common.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6d3e512e768360a5a267ea6f57a234cc664c2a3f439aeb8d42396ec23af9b8ae +size 42776 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_long_long.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_long_long.hpp new file mode 100644 index 0000000..c9cfb64 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_long_long.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18fe29720b858d4ec3db9e44828f340020d797dbc16bef8906fd7677a95ef5b0 +size 9311 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/sign_mixture.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/sign_mixture.hpp new file mode 100644 index 0000000..9804f8b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/sign_mixture.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51f43c2007a1ab463260103b25e9bd830419371cb137598d94964d5a59deb6d3 +size 2547 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/udt_builtin_mixture.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/udt_builtin_mixture.hpp new file mode 100644 index 0000000..78e1d5f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/detail/udt_builtin_mixture.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8dffa1ad10dd7bc7a78afddab0325e8cecf951e94fb2820c7ecc2fc7dd2d9d62 +size 2480 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/int_float_mixture.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/int_float_mixture.hpp new file mode 100644 index 0000000..28fa1d7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/int_float_mixture.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bddb30968cb676f38087970c18384b9a9f528080446ac470f18d9d411c49a30b +size 1042 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/int_float_mixture_enum.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/int_float_mixture_enum.hpp new file mode 100644 index 0000000..5431e68 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/int_float_mixture_enum.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e184b040c8bb3390deb8ec866d87c2492a244b7262b2fd0990bdecfacd2093b3 +size 851 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/is_subranged.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/is_subranged.hpp new file mode 100644 index 0000000..1e2b639 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/is_subranged.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc2c362607ef6c8c0faabaec3f9f9c124377e43a606fb4d91bb7ec7cf2dc42c6 +size 908 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/numeric_cast_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/numeric_cast_traits.hpp new file mode 100644 index 0000000..6b4fd0f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/numeric_cast_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dbb4008d98809f04efc7cc8c9bfe6d8d6223bd10cda0cd649fbf1e635e515290 +size 983 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/sign_mixture.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/sign_mixture.hpp new file mode 100644 index 0000000..8921f98 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/sign_mixture.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df9aec74af40872ac97ff2d25c5bec3c0b2e692e1b28f1b23f93fc8595acc3da +size 1007 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/sign_mixture_enum.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/sign_mixture_enum.hpp new file mode 100644 index 0000000..3dc97ec --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/sign_mixture_enum.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfffad1a0069323e40377ddd58a6adc4b3ab213af8c32ad25f7ab898199044ec +size 840 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/udt_builtin_mixture.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/udt_builtin_mixture.hpp new file mode 100644 index 0000000..cb3e460 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/udt_builtin_mixture.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:deb5f526e976c97b678009bf5a4e115c0acd83457958382e25f55cd61bae18e9 +size 957 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/udt_builtin_mixture_enum.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/udt_builtin_mixture_enum.hpp new file mode 100644 index 0000000..ab3c60c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/conversion/udt_builtin_mixture_enum.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61025c6776952f21f945cacf15b075736d9aa2dbab100b68918e27b43e6eb392 +size 745 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval.hpp new file mode 100644 index 0000000..5857691 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21cdd49e4134be186a487ac54971b8130045e3e9dda2e760bf93297cf4c7c55b +size 1058 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/arith.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/arith.hpp new file mode 100644 index 0000000..15ee155 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/arith.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea57deeffdf91d1f76204ae60d26471a07c0fd66c5e7e1b03809e7790458fc9e +size 10353 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/arith2.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/arith2.hpp new file mode 100644 index 0000000..970c6ab --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/arith2.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab582ec819f98b783314537c902a6091f6bc4ca74b0669be29b1675705a5aa65 +size 10092 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/arith3.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/arith3.hpp new file mode 100644 index 0000000..dd46fb1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/arith3.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34d0efe491af741200c236fc57966c0fb1d8d45b35aa2e3bc01297acb2bb5766 +size 2150 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/checking.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/checking.hpp new file mode 100644 index 0000000..d86909a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/checking.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53edae05995aad20924085dd924149bb70953cfb2b3fc17eb5119175e502a995 +size 2824 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare.hpp new file mode 100644 index 0000000..8838c34 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2558a9b8c31fd4a81e1e08968b47b852c6b8d0135c99004bc52678f9052cca7 +size 705 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/certain.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/certain.hpp new file mode 100644 index 0000000..e98c42d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/certain.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92129d4e23a890b1ce344b51dbe3d8f97267565250c5dba8310caf7ccf01834d +size 3405 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/explicit.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/explicit.hpp new file mode 100644 index 0000000..e0a13ea --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/explicit.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:282bf9c15a1aa8f998d12b325d05298b9f23b107a299ebade897c92e2a83e2c7 +size 6110 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/lexicographic.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/lexicographic.hpp new file mode 100644 index 0000000..9caa6ed --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/lexicographic.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bcdaa133a8e5ac3170f6e33fe4e5a03c22b3d068a08746f31aa67bfb40bac1d0 +size 3865 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/possible.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/possible.hpp new file mode 100644 index 0000000..be3af83 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/possible.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b64967f7a2c1f346a07df3c6ab6efcac2965714ba1b02a714cd5d7da674add3f +size 3415 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/set.hpp new file mode 100644 index 0000000..4a7bb19 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a832364c5b82871495f3d898278aff417eb905107f80a582cd327b5c2363e6c +size 2614 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/tribool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/tribool.hpp new file mode 100644 index 0000000..0e31f88 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/compare/tribool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:485db04e62b467fb15789cfb714de12c233ae0cd9494b961859a120fc29d5d46 +size 4617 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/constants.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/constants.hpp new file mode 100644 index 0000000..df11429 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/constants.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3351252d53e82130a0793fc2874cca3df1ddb8a3f0152290eb47ba39ebf6544 +size 3177 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/alpha_rounding_control.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/alpha_rounding_control.hpp new file mode 100644 index 0000000..6682a97 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/alpha_rounding_control.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60d2d8801276039382aab5ad5d27782d0526f5f41d53cc7ded002f955c3fea67 +size 3607 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/bcc_rounding_control.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/bcc_rounding_control.hpp new file mode 100644 index 0000000..99b2be1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/bcc_rounding_control.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e1590cf9fada31a27bde23b31b18f7311dd87dececb13ee3adbd4838f08071b +size 1580 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/bugs.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/bugs.hpp new file mode 100644 index 0000000..271ddb6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/bugs.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:807df20dabe8565ab4f9db768cd3d86ec0cab128c4bcc6c8341ada536e917e15 +size 1513 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/c99_rounding_control.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/c99_rounding_control.hpp new file mode 100644 index 0000000..e629140 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/c99_rounding_control.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:94fa1324ea8f8b68fe8079aca30627475ca667442196cbbb1749cd204a210770 +size 1292 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/c99sub_rounding_control.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/c99sub_rounding_control.hpp new file mode 100644 index 0000000..93a536d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/c99sub_rounding_control.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32f9adf4e35ee338cf527459b3871ed6fb9dd4a96c418e463e5343135876c8ab +size 1368 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/division.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/division.hpp new file mode 100644 index 0000000..8809a90 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/division.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59ecfca9ac4532a71de23f5edc8eb1711b39a65327ebf1873ed23655af9c3d8a +size 7499 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/ia64_rounding_control.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/ia64_rounding_control.hpp new file mode 100644 index 0000000..6894440 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/ia64_rounding_control.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:94666d2917dc1f2fcdd7363d621171d757a2f7c071b30e118ed43414a01029ce +size 2149 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/interval_prototype.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/interval_prototype.hpp new file mode 100644 index 0000000..6d7805c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/interval_prototype.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc0fef93ad3ed8e5c4fe9e5986266fd8cc57747fd991a0ccc31442867a0ea245 +size 1035 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/msvc_rounding_control.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/msvc_rounding_control.hpp new file mode 100644 index 0000000..d167474 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/msvc_rounding_control.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52cf1515eef844c904003a8a8b93aae6855660d2b5c216bae1e2d1c37f55d08b +size 3415 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/ppc_rounding_control.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/ppc_rounding_control.hpp new file mode 100644 index 0000000..d204aeb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/ppc_rounding_control.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f334590f7d334d2cc9dad5c864e8a7684c04637a58701483f3523b34734ddc1 +size 2955 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/sparc_rounding_control.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/sparc_rounding_control.hpp new file mode 100644 index 0000000..9f603a8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/sparc_rounding_control.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5af98d88590189e7035a28b69b011a87f4894140ca271e9bfe4a0c081ffbf97b +size 3062 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/test_input.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/test_input.hpp new file mode 100644 index 0000000..4b1201a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/test_input.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1cded3d6edc15e78e463e4b006c4f93b507fa985778a1f227c5003a23db57e9a +size 2326 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/x86_rounding_control.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/x86_rounding_control.hpp new file mode 100644 index 0000000..6cbccca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/x86_rounding_control.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4dad88a5482a3f8937ff686d5a7d5b21189a15f1194f29fc595e580c39ee2d6 +size 3143 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/x86gcc_rounding_control.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/x86gcc_rounding_control.hpp new file mode 100644 index 0000000..d415257 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/detail/x86gcc_rounding_control.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9cb53039e2e63299c7a9a73492877fe247941e6e7444ae026ecc4726216b766 +size 1262 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/ext/integer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/ext/integer.hpp new file mode 100644 index 0000000..6725749 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/ext/integer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:989a1aefec1537c55d065f79ea3e53db0ab8502db971dfec66214d5d88f6196e +size 1817 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/ext/x86_fast_rounding_control.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/ext/x86_fast_rounding_control.hpp new file mode 100644 index 0000000..1fbdc92 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/ext/x86_fast_rounding_control.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a1da8081d2c34524b6c1e6e8b8c6de2dfac95ee2f5d911fc61bbb201aa4c7fa +size 2774 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/hw_rounding.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/hw_rounding.hpp new file mode 100644 index 0000000..396e3de --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/hw_rounding.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:09f0dd3d3a045442f87d9be78b8acc16888e91b2739fd6a73c8c80ce13296caf +size 2418 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/interval.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/interval.hpp new file mode 100644 index 0000000..73eb0fb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/interval.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0957b4a01a699abc36ba75be6b8875dd9d4a5968cff65d86844f4b8cc75694c +size 12198 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/io.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/io.hpp new file mode 100644 index 0000000..d2ae37b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/io.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49a9372d6a49b7cf4b1c6e198399afcd84f34b8b221dac5a8ca85ce0e457cd20 +size 1174 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/limits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/limits.hpp new file mode 100644 index 0000000..75a0cb6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/limits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95bb47275f57b2cdf043622bd39c9aa7e4f844bd3e2c5639191ecb5f4c7bd9ae +size 1621 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/policies.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/policies.hpp new file mode 100644 index 0000000..3bdc1e0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/policies.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5fcb15e2f95aae7d7887b39786a149b17ee378cda26d2ae58f72197bd177c7b6 +size 1771 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/rounded_arith.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/rounded_arith.hpp new file mode 100644 index 0000000..f96baf2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/rounded_arith.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b9caaa0b161bd08bec2aae02ff61e23a90f7cadb38af5f97f67b7c7883e0f9a +size 4783 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/rounded_transc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/rounded_transc.hpp new file mode 100644 index 0000000..6b3aee8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/rounded_transc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:24ba451e23ce34f44cba0137e8f7bd0c3e91c4487a7201dbc33f89620cfa64f7 +size 5269 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/rounding.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/rounding.hpp new file mode 100644 index 0000000..fb5eaaf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/rounding.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73ab1de326d62de18d63fe003cf228e95d04b3b67b7bd07a07215a40b6cad9fb +size 2595 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/transc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/transc.hpp new file mode 100644 index 0000000..6ba20aa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/transc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98eb54fa0e66e71c804f9302ff454e946ffc2b408f02fa37b991f23b304f6726 +size 7917 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/utility.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/utility.hpp new file mode 100644 index 0000000..b1c2933 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/interval/utility.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01edd94c492513df8a42c66d57c48bfa79136d619c2771fe88045390466401c6 +size 10783 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint.hpp new file mode 100644 index 0000000..0408985 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6586bd36b98d23bd201446ad08e6994280e69b610e05c8b42344580a470987a8 +size 3241 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/algebra_dispatcher.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/algebra_dispatcher.hpp new file mode 100644 index 0000000..52f95d9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/algebra_dispatcher.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:322f0a5d5c0bd09aacf8de601a2cd01a7eeacfe4bed9121b0418a221bbbd27e6 +size 2549 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/array_algebra.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/array_algebra.hpp new file mode 100644 index 0000000..c378d3e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/array_algebra.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cca3bfd8c7cb1316615f8c2e9027f6c54387598e325e7b8d5f837d2c9b3beceb +size 10846 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/default_operations.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/default_operations.hpp new file mode 100644 index 0000000..6f09c33 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/default_operations.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f63927d03e13bbaff606c5d7777512b8323187b6b914d29445bece39045ac511 +size 23794 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/detail/extract_value_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/detail/extract_value_type.hpp new file mode 100644 index 0000000..1ac97f9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/detail/extract_value_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4db3054286aff5e69a0551f550bd4048d44640760cd0c015052a7195663edf56 +size 1358 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/detail/for_each.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/detail/for_each.hpp new file mode 100644 index 0000000..d0bc36d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/detail/for_each.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b52d1d145f7f1ed89aea838d5f93ce6643940424a893b377909fe81e6b7ccefb +size 9551 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/detail/macros.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/detail/macros.hpp new file mode 100644 index 0000000..58778f5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/detail/macros.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5756cec9bdec5d6311e95e6653f0fd88cdd90576c6a289206d1ddd9acb7843a9 +size 1134 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/detail/norm_inf.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/detail/norm_inf.hpp new file mode 100644 index 0000000..18e617b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/detail/norm_inf.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:31d7a78a114e14d55b26fef28aa8a69318a4441f3e81f704cb841530374dd5ac +size 969 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/fusion_algebra.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/fusion_algebra.hpp new file mode 100644 index 0000000..eeed512 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/fusion_algebra.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13297d5b0ddaff3b83b3eeb846c7925b472d65c5ef797f9319ca998f94127fd7 +size 11422 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/fusion_algebra_dispatcher.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/fusion_algebra_dispatcher.hpp new file mode 100644 index 0000000..7cf5f41 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/fusion_algebra_dispatcher.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29716b5d3bd5b85ec09696fa554a8d0437e6d59b518ff403a9b88f5253a8f546 +size 1258 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/multi_array_algebra.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/multi_array_algebra.hpp new file mode 100644 index 0000000..06d10de --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/multi_array_algebra.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f66b4814b1c83d9b6485d8446b8c39b6ff61b3a0d9553ff815a2963545a036f4 +size 7380 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/norm_result_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/norm_result_type.hpp new file mode 100644 index 0000000..591f241 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/norm_result_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b816676676eda7d7ce8e034ec78dd76b444a9bd21a2578cbe79e4126e9a2c1ef +size 821 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/operations_dispatcher.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/operations_dispatcher.hpp new file mode 100644 index 0000000..c166970 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/operations_dispatcher.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19b6130cf366cd721e51ac340fe2a1270835673640046bb0a73f44374d6b0c2c +size 976 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/range_algebra.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/range_algebra.hpp new file mode 100644 index 0000000..0d12deb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/range_algebra.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:23d1e0d895fe1856bcc4230fc092e66ca603e6f156751d7c871c8ca27552f393 +size 8358 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/vector_space_algebra.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/vector_space_algebra.hpp new file mode 100644 index 0000000..d0c42a3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/algebra/vector_space_algebra.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e4fc367d97d4203888093c9e45e5e8d90e1e2b8a402106275d0f6a373869212c +size 6363 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/config.hpp new file mode 100644 index 0000000..669ee46 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e5ce900769fd5177fc8d90410a796afc2127ce6657ae7cbc52cbee2240b20879 +size 1201 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/blaze/blaze_algebra_dispatcher.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/blaze/blaze_algebra_dispatcher.hpp new file mode 100644 index 0000000..b997bd6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/blaze/blaze_algebra_dispatcher.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b00ebd810c19d3b1e42b286f2cc35ba43f09560ebaa1874289551c0b1ca9b5a +size 1155 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/blaze/blaze_resize.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/blaze/blaze_resize.hpp new file mode 100644 index 0000000..7fb605e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/blaze/blaze_resize.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07640c21ae2484a2ae648a7d1b74e9d3056db5c2c91d5e17219a03bee7e824be +size 1708 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute.hpp new file mode 100644 index 0000000..81cb9a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1bb95dab58d3788f7dd8e7d0ff6be3565fc38782e5355a3a34937ee3a891fdfd +size 993 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute_algebra.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute_algebra.hpp new file mode 100644 index 0000000..44ee3f8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute_algebra.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ebaa344db28265e7bcc3c0e4a78b627113e94e6ffc81444bbf69282efd5676ae +size 2026 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute_algebra_dispatcher.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute_algebra_dispatcher.hpp new file mode 100644 index 0000000..591894a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute_algebra_dispatcher.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ea05959177d31887dc9a1bd7af488b952734d10d2aec37827419bc30b23fbb8 +size 1169 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute_operations.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute_operations.hpp new file mode 100644 index 0000000..1351be1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute_operations.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1721db3511a941f42d177f6f686414b25502e6e85be1e8b1998718b23b4c1791 +size 8749 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute_operations_dispatcher.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute_operations_dispatcher.hpp new file mode 100644 index 0000000..4a6421e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute_operations_dispatcher.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e2d294d552050c5b2be51e722e1608b6c407bc6899e4561bf79b4b2312674863 +size 1202 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute_resize.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute_resize.hpp new file mode 100644 index 0000000..5ce1fd9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/compute/compute_resize.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff67c00a0e78504990229066fb0b20539cdb5996c95228bcdfc4859146ce4b06 +size 2487 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/eigen/eigen.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/eigen/eigen.hpp new file mode 100644 index 0000000..c030bc9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/eigen/eigen.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bcdc2789840e4cd0df1d650289b9bd89a32281e18120ce30bb0a0123f31dd663 +size 754 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp new file mode 100644 index 0000000..4a2bee1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e1adde9dae18d7a61f150afd4f4ca593ae9395ee98f4e1af6ebff86a7079bb43 +size 3081 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/eigen/eigen_algebra_dispatcher.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/eigen/eigen_algebra_dispatcher.hpp new file mode 100644 index 0000000..fa83335 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/eigen/eigen_algebra_dispatcher.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:65ec9437669e345ae3210fad068755709904decb2a0a8a14bf370075c8c4efc1 +size 1270 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/eigen/eigen_resize.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/eigen/eigen_resize.hpp new file mode 100644 index 0000000..ced204c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/eigen/eigen_resize.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e60c70cb81574ab1e0f5b5947d71be34bb0900fd575f6119c6c9d6ba165372ec +size 3119 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/gsl/gsl_wrapper.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/gsl/gsl_wrapper.hpp new file mode 100644 index 0000000..56dc097 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/gsl/gsl_wrapper.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8aeeb88dc576be5e43f51c3f9ee6b37244566795996ab04f3ffd13814e7ff74d +size 5248 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mkl/mkl_operations.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mkl/mkl_operations.hpp new file mode 100644 index 0000000..ec369d9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mkl/mkl_operations.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15aeb6a454e28f1bec900f5308b55419935c72aa41b7f6116499cb06e141444f +size 6731 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mpi/mpi.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mpi/mpi.hpp new file mode 100644 index 0000000..9469455 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mpi/mpi.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19a2ba3b5e4b52ccdfd56691f6f4795e522e9e7008ee64d40565fc23ec5140a5 +size 637 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mpi/mpi_nested_algebra.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mpi/mpi_nested_algebra.hpp new file mode 100644 index 0000000..5f8c52f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mpi/mpi_nested_algebra.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:926c2859a1751b11b41abcaa0ddaddb7d58266aa7808785b5557f0b7e8938cab +size 1628 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mpi/mpi_state.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mpi/mpi_state.hpp new file mode 100644 index 0000000..9dc7aba --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mpi/mpi_state.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a471c657f99c4d0d7a6a3df71d1fb5d8eb623d13034a1256bd94b09e128e4eb5 +size 2962 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mpi/mpi_vector_state.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mpi/mpi_vector_state.hpp new file mode 100644 index 0000000..5deacf1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mpi/mpi_vector_state.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c809b1667a8fa74241a7e09971d4b108d13192faf27b23d50849213434a4743c +size 2990 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mtl4/implicit_euler_mtl4.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mtl4/implicit_euler_mtl4.hpp new file mode 100644 index 0000000..0cc80ea --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mtl4/implicit_euler_mtl4.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ebeec2a7f60381d3c1be3db892cc5fa4d1ae2c2ea20bbf09234e01dede80f53 +size 4642 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mtl4/mtl4.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mtl4/mtl4.hpp new file mode 100644 index 0000000..9018e4a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mtl4/mtl4.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a85f77fb44e394bfd70ff9a2c947b3c2064aefff05170a002fd7dc68b3321e6 +size 704 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mtl4/mtl4_algebra_dispatcher.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mtl4/mtl4_algebra_dispatcher.hpp new file mode 100644 index 0000000..9851700 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mtl4/mtl4_algebra_dispatcher.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ec70844b116d5343c429a80c5f6bd4215e5d4fe062d70e098c10db57bf1c0b5 +size 2746 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mtl4/mtl4_resize.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mtl4/mtl4_resize.hpp new file mode 100644 index 0000000..d5411f7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/mtl4/mtl4_resize.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f31567de1793f579e363b9e08676f0b5e9df165dd32034d45933f83abaf24d5 +size 4112 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/nt2/nt2_algebra_dispatcher.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/nt2/nt2_algebra_dispatcher.hpp new file mode 100644 index 0000000..2e82890 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/nt2/nt2_algebra_dispatcher.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4b2e175816439e7e87632dc9e29df8565f9023f60869fa4a32d68c3a140d075 +size 1024 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/nt2/nt2_copy.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/nt2/nt2_copy.hpp new file mode 100644 index 0000000..2f3acb8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/nt2/nt2_copy.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b307f9cb468498359c23f0e1bc25b100dea9bb825219091bc37431ce0eaa916e +size 1150 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/nt2/nt2_norm_inf.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/nt2/nt2_norm_inf.hpp new file mode 100644 index 0000000..95a90c1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/nt2/nt2_norm_inf.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0326aec6dff5dbad01b4a1bb9fe567122cad494e076e158059a90567eab3a4dc +size 1148 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/nt2/nt2_resize.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/nt2/nt2_resize.hpp new file mode 100644 index 0000000..9d1be18 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/nt2/nt2_resize.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8516c627ae5cd1c325a5a6255f3905c1aae8c8a592ea86aaa76383b6fb8af09e +size 1638 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/openmp/openmp.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/openmp/openmp.hpp new file mode 100644 index 0000000..4863759 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/openmp/openmp.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ca71cf42e1b3bd10a3a2e31516f66781a4052723af26df0491d7b668fbc881d +size 900 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/openmp/openmp_nested_algebra.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/openmp/openmp_nested_algebra.hpp new file mode 100644 index 0000000..e5d448d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/openmp/openmp_nested_algebra.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:279827a5f2e8359cc5d6e044924770a0436f966f8925578ad534dafd1b8d51e8 +size 18879 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/openmp/openmp_range_algebra.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/openmp/openmp_range_algebra.hpp new file mode 100644 index 0000000..6be85a3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/openmp/openmp_range_algebra.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87bd3f729c0ff1f8326bbf5b54fb54695043c1e347a3200a76db343c060ce3f1 +size 18082 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/openmp/openmp_state.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/openmp/openmp_state.hpp new file mode 100644 index 0000000..68ada5f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/openmp/openmp_state.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd2f19077d3f9195f0a3b2dfe4f6abcfeb13c6297d8b9fd43e8339c69d0a8164 +size 5204 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust.hpp new file mode 100644 index 0000000..3e40f14 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30f340555a79c91d64f27c0f5a684712bf6c6aed0850a8fd5d06687ca50f82ed +size 937 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust_algebra.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust_algebra.hpp new file mode 100644 index 0000000..2bec98c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust_algebra.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:715a6aeda5e34e33aa5808ff0fa002d85cfd5eda8b2f96b7a0a3fc8319646e8c +size 8129 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust_algebra_dispatcher.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust_algebra_dispatcher.hpp new file mode 100644 index 0000000..5b173cd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust_algebra_dispatcher.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39af530b2e705c6083b993daaafdd4451f9cf801fff766bf63d7e95d618fd1f0 +size 2857 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust_operations.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust_operations.hpp new file mode 100644 index 0000000..38faf4d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust_operations.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8101d99b174476160455f7f6dab4fedb0672fa8bab628aabec29cc8a63c44e72 +size 7441 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust_operations_dispatcher.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust_operations_dispatcher.hpp new file mode 100644 index 0000000..055ac92 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust_operations_dispatcher.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e4686123710ebf9342e3b8265becd8cffc2bc73f5ef7801694dfe37b8341d35c +size 2934 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust_resize.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust_resize.hpp new file mode 100644 index 0000000..64d62cb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/thrust/thrust_resize.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a862846c1539a6d8cdc337d111d213e1007bfde15edd35fcded296de2b5ee8e +size 8486 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl.hpp new file mode 100644 index 0000000..fc529c7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d4ada58e89f35ae05fe9ac329fbebd2a0cc21e2756ebae6172345079414ba56a +size 985 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_abs.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_abs.hpp new file mode 100644 index 0000000..9f9841e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_abs.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfadd4df9e5769503f3425a5899cc47f39b9edf90cf9dd85eed213f03ebd4fe7 +size 1575 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_algebra_dispatcher.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_algebra_dispatcher.hpp new file mode 100644 index 0000000..0a11cfc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_algebra_dispatcher.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28e2496837a790b3dd179e51ac6fb3dbffcd51c582c99a7cc81a0e4c1376a976 +size 1305 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_copy.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_copy.hpp new file mode 100644 index 0000000..3bf5523 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_copy.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ece95ffc9eda31bf679a7f2ab1f2817146820d1b063d4b5f7a72ec640c8fe8d0 +size 1269 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_norm_inf.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_norm_inf.hpp new file mode 100644 index 0000000..21047d6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_norm_inf.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54d0fb5da18581c96e12dea143dc49553cc520e4f6b0710641bae60c1ac6d347 +size 1749 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_resize.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_resize.hpp new file mode 100644 index 0000000..3f6f389 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_resize.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3b7292e98ecea62aa3165df8ea0b2609d768239fa9fb7158e08d594f9a5a0596 +size 2274 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_same_instance.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_same_instance.hpp new file mode 100644 index 0000000..efb00c7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/vexcl/vexcl_same_instance.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:57de932e29462a55c540d505ac4f091b5441313d8eb5ae7f4b434707a2424986 +size 1562 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/viennacl/viennacl_operations.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/viennacl/viennacl_operations.hpp new file mode 100644 index 0000000..c818209 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/viennacl/viennacl_operations.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da35cb1f01a1adf9d7fac8a2020b700d04ac11b1dcb9848b2a5630963ae471bd +size 7774 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/viennacl/viennacl_resize.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/viennacl/viennacl_resize.hpp new file mode 100644 index 0000000..17d81c1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/external/viennacl/viennacl_resize.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c6e88b6234fef0beaa9ab9bc7da05769a006161719ba96825585ce80952975a +size 1586 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/check_adapter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/check_adapter.hpp new file mode 100644 index 0000000..cad7553 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/check_adapter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:771fba6f1e79cd5bddcce801e528f7f99210190b9edb54274264c0878ed14eab +size 5875 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/detail/functors.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/detail/functors.hpp new file mode 100644 index 0000000..ae22848 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/detail/functors.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3aac0e729941fbc47bc897858236eabbed0429545698626b86ab79451ee43614 +size 1712 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/detail/integrate_adaptive.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/detail/integrate_adaptive.hpp new file mode 100644 index 0000000..c345ae2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/detail/integrate_adaptive.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6304c96e87dbbcf9046a5200f7516fb776b46689841a72299ded690a4c9cd316 +size 5355 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/detail/integrate_const.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/detail/integrate_const.hpp new file mode 100644 index 0000000..235eeae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/detail/integrate_const.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:38aa0fbc0aa952e9860fc0c7466662f9ea07642df19ee3a475c0590fcf607849 +size 5880 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/detail/integrate_n_steps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/detail/integrate_n_steps.hpp new file mode 100644 index 0000000..a3c8c4c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/detail/integrate_n_steps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f8069d0965b5720f58b487d6c682571392730b244feab71bdd666f94c28101fb +size 5817 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/detail/integrate_times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/detail/integrate_times.hpp new file mode 100644 index 0000000..9b7fb0a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/detail/integrate_times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05cc5285b1a0d5dc8d0ce45d0580d7e484cc692b703f709d6fb3995be803eff2 +size 5923 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/integrate.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/integrate.hpp new file mode 100644 index 0000000..d8c35f2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/integrate.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15c3811c5fac8fa64d7b9fbde02c648351ebe5098def1c72c73906cf383e4bd3 +size 4991 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/integrate_adaptive.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/integrate_adaptive.hpp new file mode 100644 index 0000000..3989808 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/integrate_adaptive.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74107928f15882fee2cc9a73ff6fa600f8f8d0ed682ce5c4fccefd9cd0dd709d +size 4574 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/integrate_const.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/integrate_const.hpp new file mode 100644 index 0000000..26d5f28 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/integrate_const.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db76262aa4a99358f681af7fd76aa82669f89b139b7c5b373268e73ceba2983e +size 7908 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/integrate_n_steps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/integrate_n_steps.hpp new file mode 100644 index 0000000..031ddea --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/integrate_n_steps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3031c1ba9ceddbf1b90717c49c2103cdbe515db707af7346fe691c8efb89744d +size 7235 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/integrate_times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/integrate_times.hpp new file mode 100644 index 0000000..e8bb2c5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/integrate_times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:502234c8fc52e5786c767255a0bf7b77b69e8065878c21f7654fbd459b22d862 +size 9077 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/max_step_checker.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/max_step_checker.hpp new file mode 100644 index 0000000..fa703cf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/max_step_checker.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:027caeb3c65b416d19c98f6ce4709dfc74fc9766b257f121a688278f247926c9 +size 2853 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/null_observer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/null_observer.hpp new file mode 100644 index 0000000..33f372e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/null_observer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e532ae740b97809d77ac7eda46d62d0554fa7cbd0ff458205a1162b05df442a8 +size 829 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/observer_collection.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/observer_collection.hpp new file mode 100644 index 0000000..97d9bb2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/integrate/observer_collection.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce00dcf23b03417f7cdc7a8bcab17e383cba6158df3aa13ae9c2d65753b4b924 +size 1375 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/adaptive_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/adaptive_iterator.hpp new file mode 100644 index 0000000..0bc4f08 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/adaptive_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0a69fd969cad0b229536f9fbd4b97d9d1fb7f4117e83c96402d6748fb02f0a3c +size 6873 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/adaptive_time_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/adaptive_time_iterator.hpp new file mode 100644 index 0000000..ead1c22 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/adaptive_time_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2eaa871c0400a8e5b3809a7890969db7a9f2f4cd53575a70efeb5f82caf0ccd +size 7177 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/const_step_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/const_step_iterator.hpp new file mode 100644 index 0000000..6505f69 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/const_step_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:abfb88a3d9f1a0cb31a7ce8f2e78decd10edbfe16090971dcc1aea748827fed2 +size 7202 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/const_step_time_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/const_step_time_iterator.hpp new file mode 100644 index 0000000..2f3792d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/const_step_time_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44e7ae7b7645523baef039b25c2dc3b76cca06a9b6db40c99c7cb4012d2edaa4 +size 7268 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/detail/ode_iterator_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/detail/ode_iterator_base.hpp new file mode 100644 index 0000000..d8b379e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/detail/ode_iterator_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0ae7c84d13781bde1353aa87d6e69fd7b32921b90d618c60dad862e65234f45 +size 5976 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/impl/adaptive_iterator_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/impl/adaptive_iterator_impl.hpp new file mode 100644 index 0000000..da3c2fa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/impl/adaptive_iterator_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41e306b4c28aba5066a1907a2c33398343413349a76b58d75208caf1d996db2c +size 10029 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/impl/const_step_iterator_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/impl/const_step_iterator_impl.hpp new file mode 100644 index 0000000..a98a866 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/impl/const_step_iterator_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58e444f436d966618b8de76a453fb9614e62de1baac4c4b11d9e754f9dd29e16 +size 8877 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/impl/n_step_iterator_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/impl/n_step_iterator_impl.hpp new file mode 100644 index 0000000..5169edd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/impl/n_step_iterator_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67fa3c9dfb890058e6da151d4f0e222e23d7ba1a140491975c502afe405fde82 +size 9059 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/impl/times_iterator_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/impl/times_iterator_impl.hpp new file mode 100644 index 0000000..2d289a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/impl/times_iterator_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b01b199d15ed6211c7e66d27c01a79f9944bfceda2e4d13655ef589b62b17be +size 14488 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/detail/functors.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/detail/functors.hpp new file mode 100644 index 0000000..ae22848 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/detail/functors.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3aac0e729941fbc47bc897858236eabbed0429545698626b86ab79451ee43614 +size 1712 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/detail/integrate_adaptive.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/detail/integrate_adaptive.hpp new file mode 100644 index 0000000..5b0d1e6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/detail/integrate_adaptive.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:595cc519b5699aac21560d88f2a0f612037432fed1a85652222ff33aab4fe1f4 +size 3950 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/detail/integrate_const.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/detail/integrate_const.hpp new file mode 100644 index 0000000..5f14fa4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/detail/integrate_const.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc849ef642a40a8feb0cbc4ee1bdb06ffec82ef6d77f6c02f3a99ab930e6f894 +size 3815 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/detail/integrate_n_steps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/detail/integrate_n_steps.hpp new file mode 100644 index 0000000..2896426 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/detail/integrate_n_steps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb2ce6626773d9ec85d04249a4be602ec9b1a54924d7ed9bc22a7a89b1fd733b +size 3892 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/detail/integrate_times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/detail/integrate_times.hpp new file mode 100644 index 0000000..8d6c39a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/detail/integrate_times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e600964c3f24515602d612f94095daf53ecb843fbefd31b03b3387351a1b9730 +size 2018 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/integrate.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/integrate.hpp new file mode 100644 index 0000000..4169a1f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/integrate.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc118e53be6e3c4a7d29eea5b6cd4ed149ec5269491b547d0533bcfeb7e05403 +size 3934 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/integrate_adaptive.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/integrate_adaptive.hpp new file mode 100644 index 0000000..b4a1b53 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/integrate_adaptive.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2496b38fe422c3580c0e3b0ab79f76e1cef2008e961766472607ace695334fba +size 4592 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/integrate_const.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/integrate_const.hpp new file mode 100644 index 0000000..6869925 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/integrate_const.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:218a461697110af8c53f848d72ca8feda06da97d8d8f13528e720e78bdd3b064 +size 5438 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/integrate_n_steps.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/integrate_n_steps.hpp new file mode 100644 index 0000000..55cbd9e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/integrate_n_steps.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bcc1d75efa8574012834fea6bbc1e64d97dd31cb1b9ad856f12efdb4327e7c7a +size 4688 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/integrate_times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/integrate_times.hpp new file mode 100644 index 0000000..91bd04f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/integrate_times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c6f7533cf4ec39d37f64b41e633f092cc0e917087fa4c746bba9b026b1daaf81 +size 4926 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/null_observer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/null_observer.hpp new file mode 100644 index 0000000..4686127 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/null_observer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85dcf174a498291542a5cba57d7b3cf177882bb6d7d69d7618928168cd9521d6 +size 829 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/observer_collection.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/observer_collection.hpp new file mode 100644 index 0000000..5b0c80c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/integrate/observer_collection.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6579fee0fbfcc9c705c080deb3712ecf0e362985ef302be3342708189af66473 +size 1375 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/n_step_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/n_step_iterator.hpp new file mode 100644 index 0000000..9a06a4f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/n_step_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5a506af6e1bf32baffaa768fd0524eac1e96ca32d0763c97423a5f6dd81ee0b +size 6747 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/n_step_time_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/n_step_time_iterator.hpp new file mode 100644 index 0000000..6b22756 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/n_step_time_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:57bacd367bccecf1ecce17c4b47bc5daf693ac8e11250249eb91b72b81477015 +size 6901 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/times_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/times_iterator.hpp new file mode 100644 index 0000000..17a621d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/times_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:400a93597920a00e6d681895d0a385f030cc5351fffe968fa7182d3a31f1030a +size 7762 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/times_time_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/times_time_iterator.hpp new file mode 100644 index 0000000..2cb2b89 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/iterator/times_time_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f487f4a99bbcc479da2ace9f186d1fb0185aa197dfbb2c30b97c2a8e21a0960 +size 7963 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/adams_bashforth.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/adams_bashforth.hpp new file mode 100644 index 0000000..a36741c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/adams_bashforth.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef8993fa2ac1b1f1cf63b54affa37e6172ff1c11a3d36a5799bff35606cb6b79 +size 15264 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp new file mode 100644 index 0000000..0f6e2a3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:362d3e456d849256a0593cb1bb63d75a63af4074b87a5df49bf21e7e0607efd4 +size 12015 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/adams_moulton.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/adams_moulton.hpp new file mode 100644 index 0000000..ecaf08b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/adams_moulton.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26a5b5e65056c134daf1e54016a81160725cb74351d2c2ab2ea471cbeea7759c +size 6112 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp new file mode 100644 index 0000000..d553b8f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78b34ed52220e87e00d76259de73ab82bad2f4ad9ad54af41f75198e190da354 +size 2518 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/base/explicit_error_stepper_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/base/explicit_error_stepper_base.hpp new file mode 100644 index 0000000..35ed1a5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/base/explicit_error_stepper_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9bc7b056749e32cdd7fea59676ba3cf865739f7d224bcd29d9ca475730075c72 +size 25420 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/base/explicit_error_stepper_fsal_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/base/explicit_error_stepper_fsal_base.hpp new file mode 100644 index 0000000..bdb9133 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/base/explicit_error_stepper_fsal_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50ae3bb3ba3bb6dca84a29268dbb65cabee321b0ff877c2d651207d7f733c740 +size 29224 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/base/explicit_stepper_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/base/explicit_stepper_base.hpp new file mode 100644 index 0000000..e3c6a7a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/base/explicit_stepper_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca599775fe213ceeb87c09fde6b1e37fe8608eca76ccd3139848adf9a60d29e0 +size 16425 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/base/symplectic_rkn_stepper_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/base/symplectic_rkn_stepper_base.hpp new file mode 100644 index 0000000..e2e0f92 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/base/symplectic_rkn_stepper_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:496fd86ffb265e5d73cd9ef06e4aea03cdcc8d80870935ee348f8af62ddd7475 +size 19778 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp new file mode 100644 index 0000000..8b1f55e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3a13093404515b2a56e6ad23491ec12ac3e3c183548625ba779d4d8701c9bebd +size 26189 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp new file mode 100644 index 0000000..1787c01 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd0d478dad6f54ea97bfb4e6bd046b87194fedf828c33af7dcf01a97b058b97d +size 33846 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp new file mode 100644 index 0000000..5e2bae9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c418dbee15b16d6ffc365031beccde6c0300a041c943711bdbb8ec24aabe4e1 +size 38000 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/controlled_step_result.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/controlled_step_result.hpp new file mode 100644 index 0000000..118f12c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/controlled_step_result.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7fe94953d9fb2aeb1876209597c5ab20af64cda5951e7fe0a59fcd632fa0dfb6 +size 1092 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp new file mode 100644 index 0000000..cbb73ae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbc0352f0c8ee158daee4f035bad8824a4539955736376a68f924554411d5001 +size 14591 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/adams_bashforth_call_algebra.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/adams_bashforth_call_algebra.hpp new file mode 100644 index 0000000..a0589d8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/adams_bashforth_call_algebra.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:27e9993d88a3b0f660cef0274b15c4d2bb954733469e79ae5ca467e69e19e18f +size 6920 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/adams_bashforth_coefficients.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/adams_bashforth_coefficients.hpp new file mode 100644 index 0000000..94fb604 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/adams_bashforth_coefficients.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6fa13aa6cc20b37394bc6c9ffd4e6614b7d8ba553087ed437dfb7a5959d2eb1c +size 5537 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/adams_moulton_call_algebra.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/adams_moulton_call_algebra.hpp new file mode 100644 index 0000000..f8dbca3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/adams_moulton_call_algebra.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9681316a0c2a592ce774eedb3211277ca7e009d5ab2b9abe39534749ef76c437 +size 6984 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/adams_moulton_coefficients.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/adams_moulton_coefficients.hpp new file mode 100644 index 0000000..9355931 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/adams_moulton_coefficients.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:733343a75ca10f65eb8e2f3ac96c427810083e5a23371a86091bca6e2be60b48 +size 5441 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/generic_rk_algorithm.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/generic_rk_algorithm.hpp new file mode 100644 index 0000000..5278f62 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/generic_rk_algorithm.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9391a270930dc2c2394bb8a325d603dede93260919ecc007ab849e0488d379fa +size 8266 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/generic_rk_call_algebra.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/generic_rk_call_algebra.hpp new file mode 100644 index 0000000..c42d3cb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/generic_rk_call_algebra.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d9f6065bc2959d21cb09f393ee9c5dfd2cc33679957e52a27b043c806ae26e8 +size 10521 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/generic_rk_operations.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/generic_rk_operations.hpp new file mode 100644 index 0000000..774ee20 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/generic_rk_operations.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa84ddfc909e06a60e8d1a44a1c289022e0781f10000b9dc2c6c24b92b4f14e0 +size 9799 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/rotating_buffer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/rotating_buffer.hpp new file mode 100644 index 0000000..41088ac --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/detail/rotating_buffer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:70313a6cdceccddde2317e3cd109e83a06d70748cb11157c9c201b09eaf74196 +size 1534 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/euler.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/euler.hpp new file mode 100644 index 0000000..046b163 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/euler.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76c4bce7e28ac05d3f4874edc41c3f277ba360108442a0075635a7d2a8eb7e37 +size 6587 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/explicit_error_generic_rk.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/explicit_error_generic_rk.hpp new file mode 100644 index 0000000..d8ed1ab --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/explicit_error_generic_rk.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a84a0f68073022f76a5e83e827b06448c2a4800f9c39d4b15bf8f06fee34fa9 +size 10708 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/explicit_generic_rk.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/explicit_generic_rk.hpp new file mode 100644 index 0000000..3df34d1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/explicit_generic_rk.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe1ea8f3f96d104c860a4334ee60883f406d466c1562764fbac2675cab86e23a +size 8491 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/extrapolation_stepper.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/extrapolation_stepper.hpp new file mode 100644 index 0000000..3fe7c51 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/extrapolation_stepper.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4105036f103879dbfeefc2abba436485c69eaa9695b3272fbcf8a09d093dd11b +size 11155 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation.hpp new file mode 100644 index 0000000..21d6ff7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e9a24f7f38057ec04f0927fbf949b5de709a0b1069116304b760b41155bbc931 +size 1376 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_controlled_runge_kutta.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_controlled_runge_kutta.hpp new file mode 100644 index 0000000..184858d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_controlled_runge_kutta.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c45704bbe69713d451f8fd8aec96f648a371b3d77c0d32a56788783821fe0756 +size 2088 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_dense_output_runge_kutta.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_dense_output_runge_kutta.hpp new file mode 100644 index 0000000..3c8da9c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_dense_output_runge_kutta.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:06c5e3dfdcca82a21bbe9dd56ada2f17b690ae0b5ab2a917c7a2728c6928cb69 +size 2360 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_rosenbrock4.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_rosenbrock4.hpp new file mode 100644 index 0000000..a11a688 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_rosenbrock4.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b1de04cdf8bccf42f8979b3dd8f8734e866f6793c62c29a590ddcd346f15ed0 +size 2570 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54.hpp new file mode 100644 index 0000000..da3f48d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58bdaae7ce317c9a8e9b500c7cadfbbf7ef4a452cdc567ecec24cff4ed9d49f0 +size 1523 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54_classic.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54_classic.hpp new file mode 100644 index 0000000..cafba8d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54_classic.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f21478d6759463a12d4920ffb87c4f0e549cbfb56e9acba7ebe5ca946b1ad2b +size 1614 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_dopri5.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_dopri5.hpp new file mode 100644 index 0000000..42e93d7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_dopri5.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee65612b21fbc3bfd322d2d3d5ab11ee34db9be1432635bb66ac986721fd4bff +size 2056 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_fehlberg78.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_fehlberg78.hpp new file mode 100644 index 0000000..ae19104 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_fehlberg78.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e70ba81d35c459e797f924be4ffab0f006055935d95669aee250c82a67d5063 +size 1468 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/make_controlled.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/make_controlled.hpp new file mode 100644 index 0000000..f0c8f4f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/make_controlled.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c93a85a046ce93d21a93ab330ee53925bc136823d16a1abe78fbec1efacc3beb +size 2791 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/make_dense_output.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/make_dense_output.hpp new file mode 100644 index 0000000..28da227 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/generation/make_dense_output.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c95666d453cd810baf5ac99a242399179e217935d13e259f21b3869d2befceeb +size 2838 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/implicit_euler.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/implicit_euler.hpp new file mode 100644 index 0000000..a178262 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/implicit_euler.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b705728420ab54b339708c6fe0e3aaea0e92c04bbd0d63525bb3582423053878 +size 5236 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/modified_midpoint.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/modified_midpoint.hpp new file mode 100644 index 0000000..bc5e5ab --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/modified_midpoint.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b07268dbe099da1d91420b29df6fb2b00844ccca002b5da11ed0218a800e71db +size 10566 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/rosenbrock4.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/rosenbrock4.hpp new file mode 100644 index 0000000..03c014d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/rosenbrock4.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db74ad85477f90c69791b3aa31488dde537c4c3e4318bbe30eae47f98d51fa91 +size 14602 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/rosenbrock4_controller.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/rosenbrock4_controller.hpp new file mode 100644 index 0000000..129436e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/rosenbrock4_controller.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e80f5e56131ab26eede27e63ebbab23396efbceffb97d2528a84e0be5328be72 +size 7288 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp new file mode 100644 index 0000000..5863b7f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3b8bf70b8f363796e515dd1a4ae56e864b8c49035f5555e1e3ea4faf9977b7a +size 5232 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta4.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta4.hpp new file mode 100644 index 0000000..d9ca84a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta4.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f253ca3b2a5df5e6cd295a562d3836ee4a2e6ad0a15df894d6187ec3f2306bc2 +size 5860 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta4_classic.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta4_classic.hpp new file mode 100644 index 0000000..b5ed2e0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta4_classic.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2507761eb14fa20651e6ca5715463d23198b4a14864d0998b4fdac03e10d2dcc +size 9255 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp new file mode 100644 index 0000000..86f9edc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7dc95951a6472269f20a652ef6e25d4e25af4cb4f05e2a058ed8c0ffb41ead06 +size 8676 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp new file mode 100644 index 0000000..c24b73a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4dabc98f804d1d46e9563cf2ccd7bb78cdf5b9d31a8501b72ff7df09f57bd5a +size 14318 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp new file mode 100644 index 0000000..d3d44fa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5934e015c0ee4ff8d8a52418bd04b314e077d0ab2e30a1aa93a4ee0f5c8579d7 +size 21484 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp new file mode 100644 index 0000000..ca4a922 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:27025f7427fb55c7f013bb7cbffa59c1cbfa229351e400b87866a5742c8ae170 +size 15005 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/stepper_categories.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/stepper_categories.hpp new file mode 100644 index 0000000..080ff90 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/stepper_categories.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:232abf2a2325b5c85b6fb33ca84ae510db5e186b85cce99d05425282881a4b08 +size 2162 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/symplectic_euler.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/symplectic_euler.hpp new file mode 100644 index 0000000..32b4927 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/symplectic_euler.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9f19c32b2ab33f082b0ee099e45ad3b27e207ba5a9f6346629921e938f48e8c2 +size 3937 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/symplectic_rkn_sb3a_m4_mclachlan.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/symplectic_rkn_sb3a_m4_mclachlan.hpp new file mode 100644 index 0000000..8d6bbc3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/symplectic_rkn_sb3a_m4_mclachlan.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d4015a3e9b3e5499c0821308fecf04211f91e39b6db152972d0d9c16e13adf1 +size 5120 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/symplectic_rkn_sb3a_mclachlan.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/symplectic_rkn_sb3a_mclachlan.hpp new file mode 100644 index 0000000..e83611a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/symplectic_rkn_sb3a_mclachlan.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:88f816c4626f44937cd67ee9da83fb50adad769e55621b6f3c3436fa14fa8efb +size 5389 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/velocity_verlet.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/velocity_verlet.hpp new file mode 100644 index 0000000..fa9df31 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/stepper/velocity_verlet.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fddeaf351960a0cdaa69f5f2b90e48520ea5dd4924360509e42b64d5e8cf56de +size 13544 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/bind.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/bind.hpp new file mode 100644 index 0000000..9b9e52b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/bind.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61a537e10a0833e6b0dda3eae8ae2d2ff680c389d71e4b889cea2b6f1876780f +size 1710 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/copy.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/copy.hpp new file mode 100644 index 0000000..ca5c15a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/copy.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a68525bb5c10982d4bad446c065bf46fc4558fc5fe61062f3806426bc1513b9 +size 2158 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/detail/is_range.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/detail/is_range.hpp new file mode 100644 index 0000000..2795a24 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/detail/is_range.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95429194536b13e52cf4842b6c4a5dee6c2df12e18d6d0c32545bfcc739fc387 +size 2712 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/detail/less_with_sign.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/detail/less_with_sign.hpp new file mode 100644 index 0000000..1ae7e3d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/detail/less_with_sign.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b49006f4fa414c223d6274d9650d6b7715e1807af181369e07c459023d645a16 +size 1951 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/is_pair.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/is_pair.hpp new file mode 100644 index 0000000..47ce040 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/is_pair.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e6c2ab5661990eb19e0355a3f1e486a6109a04ed8967291a5aeaa0f4bafc650f +size 895 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/is_resizeable.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/is_resizeable.hpp new file mode 100644 index 0000000..254069b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/is_resizeable.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f6290d8142a8539be292bbaf5c04fd4cc102d9c61bc3d182560750a834c18bb +size 2102 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/multi_array_adaption.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/multi_array_adaption.hpp new file mode 100644 index 0000000..9bbb4c5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/multi_array_adaption.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1d643566db5a8a6dc10317498e16b4671014e327fc7b1a1f4bec151352772e8 +size 3493 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/n_ary_helper.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/n_ary_helper.hpp new file mode 100644 index 0000000..fbf07f8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/n_ary_helper.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb012a399bb91dabf748afe9c7a629e533bb7e3131339f300a28a1cc1736fc0e +size 4077 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/odeint_error.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/odeint_error.hpp new file mode 100644 index 0000000..2f5840e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/odeint_error.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a57608c3d1cea7d18ab8a77d23efa5e94b2bf4f759c2826f7df541ae11576dc +size 1536 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/resize.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/resize.hpp new file mode 100644 index 0000000..72d3d39 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/resize.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c305504620ee05d770cf783d27c614bec3f9f6392d4c183996a72a24fcb7c52 +size 3079 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/resizer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/resizer.hpp new file mode 100644 index 0000000..cca2f82 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/resizer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e07c6c8576bd8d763fe00c1b5605514aa21678a4c49accdc526f123be53e911e +size 1941 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/same_instance.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/same_instance.hpp new file mode 100644 index 0000000..fef55ec --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/same_instance.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:277c3223704b4c6de8c8c783b4963d2b02c3d3020f401f020a0b4eb2cba12037 +size 1172 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/same_size.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/same_size.hpp new file mode 100644 index 0000000..e22d189 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/same_size.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11ba4af7d6487e0fc02fade96e5922e7dfba56b37e73ac29057e572053b29165 +size 3066 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/split.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/split.hpp new file mode 100644 index 0000000..cd830eb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/split.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46004fec22a7fd08618b3c773a04f5956bf8200c6b0dfe353f152b29237baa1c +size 1473 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/split_adaptor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/split_adaptor.hpp new file mode 100644 index 0000000..5bf02a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/split_adaptor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d74d72bf92701c88b2cc7a994a4cc89cb00d867c4d1cfe77d74463daf8f251d6 +size 3101 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/state_wrapper.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/state_wrapper.hpp new file mode 100644 index 0000000..4ebd75a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/state_wrapper.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df39023a505afdd600a2658abc64cb03c7d6ec392f03c1760eb67374c64964a8 +size 1098 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/stepper_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/stepper_traits.hpp new file mode 100644 index 0000000..1b36b09 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/stepper_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c916ee872df5e09e06e76801cdac38af3b4a49d07a1e80d2865beb092babe3e +size 1546 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/ublas_matrix_expression.patch b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/ublas_matrix_expression.patch new file mode 100644 index 0000000..8feb1a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/ublas_matrix_expression.patch @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:823024f8c468778fd57d7e6bc7a462779988ddf42057f3a50b7c31560f060c67 +size 388 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/ublas_wrapper.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/ublas_wrapper.hpp new file mode 100644 index 0000000..5fe29c3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/ublas_wrapper.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2605950e1cb4f8eb57b594dc7b52afaf8d45550d4aafce5800faff722d60bd14 +size 9889 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/unit_helper.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/unit_helper.hpp new file mode 100644 index 0000000..37dee68 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/unit_helper.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:796ecc239916033c50bc478fbc5cea246cceaf680ef8d4e6bfb371b68613f314 +size 3209 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/unwrap_reference.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/unwrap_reference.hpp new file mode 100644 index 0000000..7891be0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/util/unwrap_reference.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5535569a2df82bb794bed607dd44d0b547b698bd721ee6c80a05cd5f06282089 +size 2442 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/version.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/version.hpp new file mode 100644 index 0000000..518edc0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/odeint/version.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7dc9e5476c6ac92a08230443da2da513550c3562cce4600f152493e3d8a32bd4 +size 1207 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/assignment.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/assignment.hpp new file mode 100644 index 0000000..fd54521 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/assignment.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4dbc7d57cf2baa18ca724b71cf9cba735b4f2bce919ea0d94d22b4c4cbe54847 +size 35347 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/banded.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/banded.hpp new file mode 100644 index 0000000..e9074b8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/banded.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa35be788799f9f4a94159f67c15f2aa1d0169883e66f1ac1d4a01c5f80dd8e1 +size 86847 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/blas.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/blas.hpp new file mode 100644 index 0000000..ba6309e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/blas.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6228c85db99c8a40ccbc7ce0504c4ba315185db2f8f35c3b7f4a587dfd21d698 +size 18132 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/concepts.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/concepts.hpp new file mode 100644 index 0000000..970c503 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/concepts.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b047e204e080cc46e73b4353129b34cb3c4108dd471ff5b64ed1941e2fbbad99 +size 73824 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/config.hpp new file mode 100644 index 0000000..1a7bc09 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6dd31c3427ed9dc1a4558aee939c39bfd75f3875b3778510a505f3845e04cacc +size 8016 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/definitions.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/definitions.hpp new file mode 100644 index 0000000..1ce1e53 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/definitions.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a7ee1ac2751dcdeef0e03ecd7d034409ae073ddc717821d7af18c37c2805f99 +size 6508 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/documentation.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/documentation.hpp new file mode 100644 index 0000000..7a50515 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/documentation.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05673f4a0c57d79d577dc52b01ed1a2a74c13222cd912a95fa1cb253f59b6c66 +size 883 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/duff.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/duff.hpp new file mode 100644 index 0000000..3f8616f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/duff.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97fe2ec666aef1c1c8bbd12f8db338a9ba881a42ba16ba2c88d68ed1707c0c0b +size 1378 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/iterator.hpp new file mode 100644 index 0000000..a1fa075 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f52e176fd0cb4d0aa9f028cb2466bfaf27e3a73887c3fd39833d15ac45a56e6 +size 50340 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/matrix_assign.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/matrix_assign.hpp new file mode 100644 index 0000000..2f8d5e2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/matrix_assign.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:036c0bce7895847f0bf97c17a8cfc252d877e7d89aaa6138e6ef296543d6f0b3 +size 78675 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/raw.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/raw.hpp new file mode 100644 index 0000000..0b04a43 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/raw.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73d411a7bf7c62bef0d64b8d0d90fb49789e0ae23b25ced284aa1d39a917a2e0 +size 30299 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/returntype_deduction.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/returntype_deduction.hpp new file mode 100644 index 0000000..6ceb45b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/returntype_deduction.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c499eb56bd60c8f3b6ac3e75ba6870c0c698793a51d4f8061fc80bd504921f24 +size 4776 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/temporary.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/temporary.hpp new file mode 100644 index 0000000..0e82ddc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/temporary.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f19f730633e4b61d9baca58e5d26557121eec6e9963d1a67312fc648a22cdd1 +size 829 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/vector_assign.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/vector_assign.hpp new file mode 100644 index 0000000..d3818b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/detail/vector_assign.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:386fcbcf23d67375659cb6ea81224f1be6d1872029bfef2e20b6bc4be520aa49 +size 23992 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/doxydoc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/doxydoc.hpp new file mode 100644 index 0000000..7038d06 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/doxydoc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bdddd5957fa9fc1ff82ef826819263d65abe8d1f3eb299a946d6d0e56f271656 +size 4087 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/exception.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/exception.hpp new file mode 100644 index 0000000..3fb3353 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/exception.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4be5c03d7bf8a97ad0282d9911ef43295dc53ec382facd6a384554a7ec8c0b24 +size 8822 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/experimental/sparse_view.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/experimental/sparse_view.hpp new file mode 100644 index 0000000..b97aa33 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/experimental/sparse_view.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3db08c7e81a025ef2d2ec50a7494b80f7897e5c9d06d94411cbe54181adb036 +size 10452 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/expression_types.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/expression_types.hpp new file mode 100644 index 0000000..3e11bb0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/expression_types.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d5c564166a7a29f796f6fac42f07cfa839c5a50094b7fca55b583735ac0985d +size 18467 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/functional.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/functional.hpp new file mode 100644 index 0000000..f0f04d2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/functional.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c08d9d81604ee32a101dac1f19286b92591b10ae101f5c4f8be5bd1a8871145d +size 79106 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/fwd.hpp new file mode 100644 index 0000000..c4de537 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fab1208c8cb104ef66c8016e4114df2ebee0ac94353bce98b5fffb73e28c2ae9 +size 7215 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/hermitian.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/hermitian.hpp new file mode 100644 index 0000000..75765cd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/hermitian.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c1fb30fe38c90ca41754313d5560e943c9ad821cac0fff529e2dca404e9cf7f +size 102000 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/io.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/io.hpp new file mode 100644 index 0000000..23edb01 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/io.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:677892585c3090751b51021554b9bed61c3cfb27a723c67217d4d733873df2f9 +size 13687 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/lu.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/lu.hpp new file mode 100644 index 0000000..c05a1c1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/lu.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc96eb0492cf2655c424fe6679a431c83cd9051a6c5b91c211d47524443db16f +size 14044 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/matrix.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/matrix.hpp new file mode 100644 index 0000000..6b1c72c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/matrix.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4135ddb03ba7dba2b1de6165892c4d8f892531ab160dfdb702dc4942c05edec1 +size 215236 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/matrix_expression.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/matrix_expression.hpp new file mode 100644 index 0000000..3e8bdaf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/matrix_expression.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:668a5d096df65fa1cfdd38b4ddfd3360167598e38ddba8fadd4f399d09f1f0a1 +size 213106 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/matrix_proxy.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/matrix_proxy.hpp new file mode 100644 index 0000000..6c78007 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/matrix_proxy.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:997506036c3a994a994a360b4c5905b32107597193ab00977e479d88af69849d +size 201494 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/matrix_sparse.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/matrix_sparse.hpp new file mode 100644 index 0000000..eb193f1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/matrix_sparse.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81d2a98434edf4588b2d8c650eb31a3838702a5c227364fb2b34ecb7cea775de +size 231404 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/matrix_vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/matrix_vector.hpp new file mode 100644 index 0000000..25fac61 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/matrix_vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f066e16553f03fadedcdabb64dee3eb5cf841cf9d67be1e99e36feecb0d9149e +size 10196 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation.hpp new file mode 100644 index 0000000..2a2e0bf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c78cd2d55db45e88de55f44f8a2353da061e5cf60e858a4854d876f8111eb532 +size 32110 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/begin.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/begin.hpp new file mode 100644 index 0000000..b3ef4e0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/begin.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:255191c2a2758909b6a3d1514afffd47be9307685575d84666832432712fba69 +size 11390 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/c_array.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/c_array.hpp new file mode 100644 index 0000000..e5fef05 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/c_array.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e649c41e9dcd4783f167bb794bee88cf096fe6109a87cd058cab3bc4cc016ff +size 957 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/end.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/end.hpp new file mode 100644 index 0000000..843b065 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/end.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ce5716c976fb0df0e9d7b1ab0fcb38cf8a5670c12c8d4e7591100d1e4516c31 +size 11290 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/num_columns.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/num_columns.hpp new file mode 100644 index 0000000..638acae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/num_columns.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42a69fc73d51943b28f96b93964d2d5aa67c7e1cfbb850a6660e52d317ed3608 +size 1179 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/num_rows.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/num_rows.hpp new file mode 100644 index 0000000..b9ae1b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/num_rows.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56e273a98238dbc38f645cd8ff134d29071b1681f63b15e1a42bc6a2a9424094 +size 1159 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/size.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/size.hpp new file mode 100644 index 0000000..43fcf59 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation/size.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1adda26e694ea765691788fc1943306d7a7b2c97a2cf2ce4fcae4ca1fc0d28b +size 10115 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation_blocked.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation_blocked.hpp new file mode 100644 index 0000000..7db8811 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation_blocked.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e203bf160370f021e4d8a6578b56e0e4508e7b9385ebedbd39034a6b94aac78 +size 13813 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation_sparse.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation_sparse.hpp new file mode 100644 index 0000000..e005b77 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operation_sparse.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c2536879ead82a4191b75de8767455e997af42596c749f0843ca2aa5255db78 +size 8146 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operations.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operations.hpp new file mode 100644 index 0000000..3029bbb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/operations.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53c5cf5a9598ab9fd366c0ec9e396b37ed447bbe75aaca866bc7478f073ecfde +size 739 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/storage.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/storage.hpp new file mode 100644 index 0000000..06c902d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/storage.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29ab5fe9d5555b0de700d0b6491f9d44f528ad4c1034def1afe67f735288cf75 +size 66511 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/storage_sparse.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/storage_sparse.hpp new file mode 100644 index 0000000..5789592 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/storage_sparse.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e47802f4cdb31ece87d3f80667eac003788fcf0b47dcc675746354a4233fca75 +size 19863 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/symmetric.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/symmetric.hpp new file mode 100644 index 0000000..0a571d7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/symmetric.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9f0dcd06a477946306cf64137b23f003cb9ca24abd3aa3c4d2232a30c4eeadc2 +size 88183 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/tags.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/tags.hpp new file mode 100644 index 0000000..4a950af --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/tags.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e55b7be0e07fbab584edb49fb0ab619b249a0ee400836a41f61d0ac8bfb84ee +size 731 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/traits.hpp new file mode 100644 index 0000000..840ac2f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03f115a0c157065230b2aecf92c7f338830f9057d680585d67bee42eb0e086aa +size 25310 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/traits/c_array.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/traits/c_array.hpp new file mode 100644 index 0000000..256101d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/traits/c_array.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4ab3e5a9fed5b86efffa1e0aef709bb223c16bbdd5ab66612effced70681ef5 +size 2838 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/traits/const_iterator_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/traits/const_iterator_type.hpp new file mode 100644 index 0000000..a6ce929 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/traits/const_iterator_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c17375fb4fd5216abc092f10aa5f57252e65a39d4712c3c91823ce65541abce1 +size 4269 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/traits/iterator_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/traits/iterator_type.hpp new file mode 100644 index 0000000..8d7e780 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/traits/iterator_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4df29c4e530b6e26fe3676ce3976a2226d44c4a4bbdd25b147aec744f0bc1302 +size 4046 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/triangular.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/triangular.hpp new file mode 100644 index 0000000..b3584d8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/triangular.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb7e492618ea19f1d3dabe4e3f466115ff68bbf2285d8b4e04bbc62b362aab6b +size 105304 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/vector.hpp new file mode 100644 index 0000000..2a52d50 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dba2891d0355fade2bd6f8a2f97b5ae47f043836fd7758a14e152b8859f5f243 +size 106031 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/vector_expression.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/vector_expression.hpp new file mode 100644 index 0000000..cae4aac --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/vector_expression.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21737a4527f1d1ba5893b28442fb0d72e3459eddbaaa292b7d4d4a2357c5da16 +size 65227 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/vector_of_vector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/vector_of_vector.hpp new file mode 100644 index 0000000..8b2eef4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/vector_of_vector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5be82ca485b8df942a956cefe8e18b4be5c963eceb72e587a6424cd7c1324fd7 +size 53270 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/vector_proxy.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/vector_proxy.hpp new file mode 100644 index 0000000..2c4e216 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/vector_proxy.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1a7e8e1926df94f5f6bd10814080da91a14f2e73f49ce7dfc7e290072c5b0806 +size 64597 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/vector_sparse.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/vector_sparse.hpp new file mode 100644 index 0000000..8f673ea --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/numeric/ublas/vector_sparse.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99fc805923b004f76f37dd51c8deb84d668de4398e230d58bf7f287c4583e972 +size 83145 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/operators.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/operators.hpp new file mode 100644 index 0000000..7302129 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/operators.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5f0a4b70be8e3a3da035586d1bfb938345764e94e02317337a6974841b72195 +size 35718 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef.h new file mode 100644 index 0000000..3387afe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:edd5ae86c93dac1feb35fd0527e4350658be43e55f6ea85e93576c63bbb48aa6 +size 635 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture.h new file mode 100644 index 0000000..2913b4f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d01bb1f7420a818367d5bd051d9d9eb8a92b82f797d8c454e89fc9b14ef2c114 +size 1213 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/alpha.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/alpha.h new file mode 100644 index 0000000..09de930 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/alpha.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7902e87c43695f79fe5a20b197e1ee93d7749a1612470e0deffcdcb28aad3653 +size 1618 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/arm.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/arm.h new file mode 100644 index 0000000..6f2623d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/arm.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19b0d6587afa4cc26ead5e69a30eb2de3dd4c2b5dd107d1ced6b371140bb6854 +size 2467 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/blackfin.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/blackfin.h new file mode 100644 index 0000000..c167a7e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/blackfin.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:612444bc559a89571757271c97a46b4c20a76875be58ae6ac876e6fb656c4502 +size 1138 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/convex.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/convex.h new file mode 100644 index 0000000..a346f26 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/convex.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6833251fcfcfc85b3aecabe5a0a08a76f0a34432b9fd3981d734fe583967623 +size 1861 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/ia64.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/ia64.h new file mode 100644 index 0000000..1196a59 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/ia64.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d1742d09649ea9a362666d7178b234e497cc87837385f63f0b31cac6950bb55 +size 1271 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/m68k.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/m68k.h new file mode 100644 index 0000000..1df6bd7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/m68k.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:026edc8edc6cb55949248933b78c379483d9263bece81737c1944512bd9e2081 +size 2576 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/mips.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/mips.h new file mode 100644 index 0000000..0cc9a45 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/mips.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99870612c7f9a859a9cb5a09c6438d373035fbafcc8bec101b58e57324410ed8 +size 2194 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/parisc.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/parisc.h new file mode 100644 index 0000000..24106bb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/parisc.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:69b333ff8e62e352be75c7a3a954e86ea4c4bac7b3810a5b81825312b7b3c5ef +size 1890 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/ppc.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/ppc.h new file mode 100644 index 0000000..845826e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/ppc.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7cd3056588668f47bb6e7928f5d4886c860f97b2af7978328682f0624fd2637e +size 2145 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/ptx.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/ptx.h new file mode 100644 index 0000000..e3a784b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/ptx.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1bbaf57dde57a7acd662a15d5e344e5ed6c43d6d08896618c3730ceb0a131394 +size 987 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/pyramid.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/pyramid.h new file mode 100644 index 0000000..f2a0e70 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/pyramid.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9469bb33e20e44e808ecad51f255edfa2e401ef1e0f01ac28114a52d4f308929 +size 928 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/rs6k.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/rs6k.h new file mode 100644 index 0000000..53189f9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/rs6k.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b2c368032915a0c13131c834b801c4be77e606a9c728a3779a3a165eb4cd592 +size 1380 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/sparc.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/sparc.h new file mode 100644 index 0000000..177835c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/sparc.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f829856cca13e3043b57ab83ced5cf48df2b14610e2b3dd4d88e06c8ab1f33f2 +size 1360 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/superh.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/superh.h new file mode 100644 index 0000000..660326a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/superh.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb8cbc49168e3f26bd4647bd8046285c35bac9316c4463536fb32ed1e2e8237e +size 1793 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/sys370.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/sys370.h new file mode 100644 index 0000000..1813c02 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/sys370.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ed1cbaef9c42a086e3e174decb10dfd90dfc30b2fc404e5249540072103530c +size 1033 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/sys390.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/sys390.h new file mode 100644 index 0000000..b23bce0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/sys390.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cfb8ec651c239b38bb1c15b9d917b4d0e9e028a5ee0ddebe6e3ddc8f8dd0e166 +size 1031 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/x86.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/x86.h new file mode 100644 index 0000000..789d934 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/x86.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:36ee0b28d38b4655771a0ff113a770281994f79f35f131d29e9fe0db3a001854 +size 960 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/x86/32.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/x86/32.h new file mode 100644 index 0000000..c3e1b9d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/x86/32.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4729b22f5c4a5c41b5c9d65388d71cd74c79273e6dd6a356096d3160476d765b +size 2694 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/x86/64.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/x86/64.h new file mode 100644 index 0000000..1545d96 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/x86/64.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:156bde7bc247d1325135f7883a53c4882555acadddc317fd495cef5b9d5ed8b5 +size 1271 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/z.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/z.h new file mode 100644 index 0000000..be019fd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/architecture/z.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e06f02b6ee36be68a0e1d68e31e1e437bd6398785f5eac26e7f49c5b079fcd3 +size 935 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler.h new file mode 100644 index 0000000..66d1a65 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:920fa053ed5d7937c6e82f7c208791540203ea11856ba38b5a6fdf7636e559a3 +size 1608 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/borland.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/borland.h new file mode 100644 index 0000000..afbbd59 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/borland.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ac2c8185a38a39212e678b58d93c07d2e3e7cf3e98bacbf10daf2f7c619f2f9 +size 1853 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/clang.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/clang.h new file mode 100644 index 0000000..5a90bc9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/clang.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e72e4d975969548a82795fe909c516b88fbfda9f2f12cb0696d9012d5c61f216 +size 1532 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/comeau.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/comeau.h new file mode 100644 index 0000000..10a4e2a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/comeau.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:572b9c80e406f6dd78dac2d1cd1ddcbde201c173290f52a714317edbabe45526 +size 1674 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/compaq.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/compaq.h new file mode 100644 index 0000000..3afe4d4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/compaq.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50dae8a9d6f51cf42a96e1a85a4f6a4c45d75091fe0f595ed4cb64a48aec2611 +size 1911 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/diab.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/diab.h new file mode 100644 index 0000000..0d3090d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/diab.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5472208e050d66596e1bf96f14d8792906ce6f080a1ce74ebe863713bcb405a +size 1489 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/digitalmars.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/digitalmars.h new file mode 100644 index 0000000..6a8962e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/digitalmars.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad003d0ac3eadc9388d0905151233068cd8831137c1585d9e0b00d0bf360cc89 +size 1437 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/dignus.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/dignus.h new file mode 100644 index 0000000..3384d0a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/dignus.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2761ec7cd1ad145c59dfba1a0ebacd6e6db927452aec6880c73095db301706e3 +size 1455 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/edg.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/edg.h new file mode 100644 index 0000000..b67ada9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/edg.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e04c9a1a4f88472110512c86f175873197653f98820aedf71d0239f766a6557 +size 1452 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/ekopath.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/ekopath.h new file mode 100644 index 0000000..e2f8296 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/ekopath.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32977c70faba88d87b4b04b6e655270f3503b6400cdd14794869c422c253d2af +size 1534 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/gcc.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/gcc.h new file mode 100644 index 0000000..b64929f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/gcc.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:736439a8472dccc8d7a79e100b18d814d5215f49317ac7a6304c13d8f9913994 +size 1959 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/gcc_xml.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/gcc_xml.h new file mode 100644 index 0000000..4287938 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/gcc_xml.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f827cd9632a96d3b95d0f2fbccf9311cf495bbb347dd4c0dcc86e86222d417a +size 1371 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/greenhills.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/greenhills.h new file mode 100644 index 0000000..17a20ae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/greenhills.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e34c39f841cb5b6fd5d6a216109ba6f4f487be4207ed480d3a97fba73a5b84ae +size 1920 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/hp_acc.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/hp_acc.h new file mode 100644 index 0000000..efab41c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/hp_acc.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed8a9ff8e0317ab05f29c4094536ad8a8174e8ad6d024cf08a7e99eb04ea2209 +size 1614 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/iar.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/iar.h new file mode 100644 index 0000000..7301d67 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/iar.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1dcb8df1c3d15ce81150c281e286cf83fef9f9a58ec37d9d3d6e10db65085bb4 +size 1395 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/ibm.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/ibm.h new file mode 100644 index 0000000..2394898 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/ibm.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9888d40214fde76a1a46226d4d74b429849fc9d1aa538c021df1ea0bd99f8116 +size 2157 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/intel.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/intel.h new file mode 100644 index 0000000..38ad36e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/intel.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:232daf26fd8e5cf3357d0b13fb783c5e5514df2131ddb42a159dd3cc4f3f3615 +size 2671 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/kai.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/kai.h new file mode 100644 index 0000000..b3f891c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/kai.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6d061bc1ce360d18cf6aea6fcc14a3d030a1b333bd71a45720af7cf5baac75bf +size 1375 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/llvm.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/llvm.h new file mode 100644 index 0000000..9c999b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/llvm.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fecad0d852c77621ed8f0c9f62b6cc7ec3569f6b99042ac11361a576e6dbd168 +size 1448 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/metaware.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/metaware.h new file mode 100644 index 0000000..86ba8ac --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/metaware.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07c6a2041a88b36c576b33a79b294f63198a033907132be61f6390e9b8b8e723 +size 1353 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/metrowerks.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/metrowerks.h new file mode 100644 index 0000000..e20b2e3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/metrowerks.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:520c6f1728bc87906e216ec1b366467e4c6abf695348d55ee092a618f4cdf896 +size 2572 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/microtec.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/microtec.h new file mode 100644 index 0000000..37e88ad --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/microtec.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4d97a5a09f5a24b413a7848357ba8d3ff3bb2437a20890e8256508e7fccb976 +size 1336 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/mpw.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/mpw.h new file mode 100644 index 0000000..65cd364 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/mpw.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7aa16fe06f0757170d7c69f1082c3852d442fb0f05269e44d69c45f9ba896e0 +size 1747 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/nvcc.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/nvcc.h new file mode 100644 index 0000000..5294f79 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/nvcc.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea6f9b9f9ea286a98c0eca3fe13ff1b279230782bc435563e675acbfc4bdd2ad +size 2749 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/palm.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/palm.h new file mode 100644 index 0000000..0cd54a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/palm.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e28e96e7a18d0c22e4a70e472a1903ead9fae5c8e46365ee86de7c1345a215a6 +size 1403 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/pgi.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/pgi.h new file mode 100644 index 0000000..1e74ce8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/pgi.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa0145fdd5e3ddf63ad03b1c6dc5b049d8a59b8dfb6d33f2655bd441b924d59d +size 1721 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/sgi_mipspro.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/sgi_mipspro.h new file mode 100644 index 0000000..19b0a72 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/sgi_mipspro.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4072d4671571b47503786effcd19f39597f3df1ca9f96f3f9fab057dec30fd8 +size 1922 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/sunpro.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/sunpro.h new file mode 100644 index 0000000..11f9917 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/sunpro.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77ede256080d51e841dde55c6796ce0c9d79b10f8d427735eab874c731ef2e8e +size 2349 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/tendra.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/tendra.h new file mode 100644 index 0000000..61c1f43 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/tendra.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:68bc07a4400b1856295ee1b433c0d9f4cce53b71e2cbed36aba72c3facb1f71b +size 1401 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/visualc.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/visualc.h new file mode 100644 index 0000000..a986a84 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/visualc.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb308a565f5cc56e4272ea7583efe1bb724279eb323a2625ffcb968db76bba2a +size 3309 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/watcom.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/watcom.h new file mode 100644 index 0000000..fef36c7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/compiler/watcom.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b96ea94dde9b8791a3b8a5948adb2941a809fee86492e7225d974819b2eef81 +size 1475 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/_cassert.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/_cassert.h new file mode 100644 index 0000000..6bfa980 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/_cassert.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:688d791806004c3f334cb94fcdb604811da4647b18eb50159cd0394274b567c2 +size 350 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/_exception.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/_exception.h new file mode 100644 index 0000000..760f714 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/_exception.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:061a222cb7dc702ddac9b7b7f36a0477ea82847c784b6c6c082fb4a336617532 +size 330 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/comp_detected.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/comp_detected.h new file mode 100644 index 0000000..c9ba689 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/comp_detected.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64b0bd865ce40ecdbbc079fbe70f3f507cdc885d3529e467d10878654bd01a38 +size 274 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/endian_compat.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/endian_compat.h new file mode 100644 index 0000000..abf287e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/endian_compat.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:93abbdf14dd518cad566a7c8cc475a37c703c2ec30fe52521af4218a8a1733fa +size 777 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/os_detected.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/os_detected.h new file mode 100644 index 0000000..ce57ed0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/os_detected.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b575705f932b165c9282867d283df29afc6f9e5d17b79f1250964e9d16f8bff +size 270 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/platform_detected.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/platform_detected.h new file mode 100644 index 0000000..0464607 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/platform_detected.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c173711895acaa0f30bc6952c4b2643b65f34d5f578c9b394b5195ff59d4779c +size 274 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/test.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/test.h new file mode 100644 index 0000000..beda065 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/test.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a4b5be3b09fc4e81da4734ca6a604ba3528d479874bc5f0f2d4c235fa003a97 +size 364 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/test_def.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/test_def.h new file mode 100644 index 0000000..51154c6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/detail/test_def.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae781b0a4d5ab24af97e10c0f7cd78c12d187be7dbcf68a6b398c6f797cf5ebd +size 1970 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware.h new file mode 100644 index 0000000..29ac27c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2be7d681b896bc21c91cccb33819efea05b26552ade89debf201301c2736784f +size 420 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd.h new file mode 100644 index 0000000..7c1fb82 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d60bd522964a003416345d6fa70bedb12cec6a2e87e8ad7c67d1d8d2b29e9065 +size 3538 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/arm.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/arm.h new file mode 100644 index 0000000..86168cc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/arm.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:824e1ae030db998b529773cd9411928288b7b74a27af34b58c96ba19579f93ff +size 1652 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/arm/versions.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/arm/versions.h new file mode 100644 index 0000000..a017a69 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/arm/versions.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6958dc50a272b4dd0fd20247769185d53195a3a572cae31c2d1f7723388df758 +size 804 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/ppc.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/ppc.h new file mode 100644 index 0000000..20c7163 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/ppc.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3cec6723beb314a8b0397e543c59173c4edbd6958162553d6473dfb081ab5d73 +size 1864 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/ppc/versions.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/ppc/versions.h new file mode 100644 index 0000000..6410559 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/ppc/versions.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1477e4ffbf7eb360e2495d052d9d9db13b758398ce76b67f5f5360cf5b70dc1b +size 1217 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/x86.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/x86.h new file mode 100644 index 0000000..2b22491 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/x86.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7214aaaceb3ae99312a447e29f1c729edf0f55ae0368b14ffa6935d07306c96a +size 3805 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/x86/versions.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/x86/versions.h new file mode 100644 index 0000000..e465ca9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/x86/versions.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce1eb47ea5d5f3e51ba400a1b2fc8276f464d07363112b9339562013d0a0d721 +size 3246 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/x86_amd.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/x86_amd.h new file mode 100644 index 0000000..47a09b5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/x86_amd.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:051048c86c31919b6e5f2f8e279e1103408675c3d6b379d9bb289783a4c8be7d +size 2677 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/x86_amd/versions.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/x86_amd/versions.h new file mode 100644 index 0000000..bd01a6a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/hardware/simd/x86_amd/versions.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8210c425892159fbd06e023df9688f0a15ae42020ce3c3d6adae4baff6a802a3 +size 1327 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/language.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/language.h new file mode 100644 index 0000000..e9a7b86 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/language.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92666722eaeba0b7657fffa8f86255d08c9f0582a1204fd794cfca83ffc365ee +size 515 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/language/cuda.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/language/cuda.h new file mode 100644 index 0000000..cb2f41f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/language/cuda.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb8df22e08628565f4199aa6835a2fc14592f2b3704b65a604d4badfa8f61798 +size 1224 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/language/objc.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/language/objc.h new file mode 100644 index 0000000..771ae40 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/language/objc.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8fb4528b7252d88acf177cddc3e13e500bce647705f019b1585afe76883cf1de +size 935 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/language/stdc.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/language/stdc.h new file mode 100644 index 0000000..5fc763c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/language/stdc.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:055f774283f22953c14a13abe0d1d11a04e01efd56cc16bec9982f9c851eca45 +size 1329 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/language/stdcpp.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/language/stdcpp.h new file mode 100644 index 0000000..d4602ae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/language/stdcpp.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a69cfa7148e90a6c5535e51a8ed711bb423baaf738dc678c823cd579c9716ce1 +size 3164 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library.h new file mode 100644 index 0000000..0d224b3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f9b4f8cddb65235a59dc3803509e38a9c6e1f494baadac7dd5b5f782ea1b716 +size 424 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c.h new file mode 100644 index 0000000..1a51f87 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4bd3710a1477118a3694ce4a204d0e0fb4ed160ba2fbd3be275ef0ede5481e9c +size 605 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/_prefix.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/_prefix.h new file mode 100644 index 0000000..e0f628f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/_prefix.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cfe353310a9f9db1ae4f55018358ceeb0c6b013c5cfe7b68c639d43dd910709 +size 319 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/cloudabi.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/cloudabi.h new file mode 100644 index 0000000..ba5c534 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/cloudabi.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3db76b5c3fcc87e5abd26c7f937f2c79cf9e82b683723dc527c3444dc6d85c49 +size 1291 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/gnu.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/gnu.h new file mode 100644 index 0000000..3e0687e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/gnu.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:caad7121b0552c74ff1fdd80837e7d0d2096e45498a75dfd777dcb869883e7c4 +size 1491 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/uc.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/uc.h new file mode 100644 index 0000000..703c323 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/uc.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:06c82b6697ed9bf3814cc2708147474f783be22853bfd074853a59d462b97bfa +size 1102 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/vms.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/vms.h new file mode 100644 index 0000000..73aee1e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/vms.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05c0c8b07c74c4f036fc5a0f5e212a754fc313b9d6d07ce560e0662f1f0d8792 +size 1034 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/zos.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/zos.h new file mode 100644 index 0000000..d972a2e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/c/zos.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1a0ecfd85a93e801c2a6f02cd06b12309c5d6397bed68d4ddf42a073fa922a2 +size 1388 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std.h new file mode 100644 index 0000000..4af447f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1829c6d4169e0d0286ccb83d370b4519685e87d392fcb515352a409bcb29043 +size 858 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/_prefix.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/_prefix.h new file mode 100644 index 0000000..8d8991b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/_prefix.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5b8484ce654f546ace537aee3251da9da87a9c37919e21aeee31369efa8e78c +size 825 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/cxx.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/cxx.h new file mode 100644 index 0000000..6a59b20 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/cxx.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39b086e860bbef79d3fa99182940d6b7f6c2a555d521923cd7bc2103770e2ccc +size 1050 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/dinkumware.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/dinkumware.h new file mode 100644 index 0000000..bf04060 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/dinkumware.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3a542818d32894900c9afaac8ec55f2ccae9e81b82dc9accf880516d65e57cfc +size 1412 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/libcomo.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/libcomo.h new file mode 100644 index 0000000..641290b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/libcomo.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a26d487893ff0c7a0389a39c7c7f51cd68945da59888331df7e6331fb72a6e43 +size 1137 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/modena.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/modena.h new file mode 100644 index 0000000..728d6a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/modena.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90889b71e4bc5562faf7233ef516b1e821b2be28bc2a4b51430afbae5175efee +size 1132 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/msl.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/msl.h new file mode 100644 index 0000000..661a702 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/msl.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8d19ba528b09aa6617ff843df367b2e54805c27a080a12ef509d859810c4add +size 1303 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/roguewave.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/roguewave.h new file mode 100644 index 0000000..6ba51c0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/roguewave.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e618f51e321a267d6079205693fb1933dba55f2a9931e21b00f8bf7e0a64f8ec +size 1438 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/sgi.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/sgi.h new file mode 100644 index 0000000..e7685ca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/sgi.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c2be6719d25b5eca68d2367d22708e722366e2ff866122630049373572084885 +size 1203 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/stdcpp3.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/stdcpp3.h new file mode 100644 index 0000000..312e26a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/stdcpp3.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d23ddfebac9ebbac0c498cd5e1531674852efb6b9f83bd5ba76081027a409fc4 +size 1338 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/stlport.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/stlport.h new file mode 100644 index 0000000..b0b2b67 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/stlport.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8c0ccb3aa3b11815cd748c27656d349ae726705adb85e0b09782dc7e2f6887f +size 1759 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/vacpp.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/vacpp.h new file mode 100644 index 0000000..1cc415b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/library/std/vacpp.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d08fc91d7ca55900469853bf4a15d120081e161c9f7600b5659e526cee7474a +size 1023 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/make.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/make.h new file mode 100644 index 0000000..11ce690 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/make.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b8ea947d7c0d2e3ac23a30e7b21a597cdfc3d67795c7b276a1d2e8de20a3aaf +size 5105 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os.h new file mode 100644 index 0000000..7398629 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e42157ef2328bf9247d6bf3eb8198b7f9224c70246c27fa983cb5d66f8f03e4c +size 990 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/aix.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/aix.h new file mode 100644 index 0000000..ee1ec72 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/aix.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b1bd1eb4f2b40c038f6c7b3b81928576a266be5707338ad7f245250455dd6e0 +size 1729 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/amigaos.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/amigaos.h new file mode 100644 index 0000000..7ae4520 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/amigaos.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc731177fc4c137899ac75e95b7456534cf1116058d9c8a200ad5d2a394a14df +size 1106 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/android.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/android.h new file mode 100644 index 0000000..9ff0b4a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/android.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75313ece35b37cee46ca628fa2a81e435d545b59510beeedc5c18c8edc27f338 +size 1067 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/beos.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/beos.h new file mode 100644 index 0000000..9afa029 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/beos.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:70ddfa8e8900bb4ce7665f5390602198a139a86ef04590eaa9b6b5a9620eff27 +size 1001 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd.h new file mode 100644 index 0000000..216214d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0347e98a9333a2fbcab83d5ae26198e05b496a6e214e5a2ceaa24bae6e681823 +size 3097 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd/bsdi.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd/bsdi.h new file mode 100644 index 0000000..f9061cc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd/bsdi.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c3dcea3dd2f3209fa5e8cf33080a5b1ae23e0894fe66b97864e250c2a3ab721 +size 1163 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd/dragonfly.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd/dragonfly.h new file mode 100644 index 0000000..634f24f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd/dragonfly.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f6b0f03d3773ee2e14b01706a2ea5717af0a0be94601f2197a164b1959d893a +size 1283 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd/free.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd/free.h new file mode 100644 index 0000000..c11a459 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd/free.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f235c571637fb092c62d50b463d628660c527773b8ecf50d34e1d4d43898293b +size 1807 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd/net.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd/net.h new file mode 100644 index 0000000..4baed3a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd/net.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f20e8d25886da1b93a08422558e4e40c01bc2318a25fc4fe6110b75389dfe63 +size 2523 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd/open.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd/open.h new file mode 100644 index 0000000..369f6a9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/bsd/open.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe9fe946ac6941aedf640ceb4aec388a35107f82d78de82357d44bc91b4b1a06 +size 9112 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/cygwin.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/cygwin.h new file mode 100644 index 0000000..efe89ad --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/cygwin.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:449617e5f141f42ca9c006bc70f854d994fd763b68262bdc615d6c889c4ad07d +size 1215 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/haiku.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/haiku.h new file mode 100644 index 0000000..964c853 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/haiku.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:12a110643f309d622b5e8d3f5acbf8d74ef45baed0c63a7c8d3c99b3e4c541fc +size 1068 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/hpux.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/hpux.h new file mode 100644 index 0000000..44ba2ee --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/hpux.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9042d928c1ce8b976c91edce55b8392e88df08fbdeb3cf7404d123248ad8d6ed +size 1112 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/ios.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/ios.h new file mode 100644 index 0000000..9588fee --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/ios.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0fc6d7ac8e7de6dfba128576112944992585decfe642b7ea58f0caa0f22cbf12 +size 1354 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/irix.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/irix.h new file mode 100644 index 0000000..13100f5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/irix.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:810361cf184818e2da9525cc6e22b5523e5efea70d73420c438829f4ea3ac331 +size 1048 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/linux.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/linux.h new file mode 100644 index 0000000..00dd57c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/linux.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0b29d567f566ab8e6e2d4322762a2adb814eb40291a4579b9f55e760f2bdcc7 +size 1070 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/macos.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/macos.h new file mode 100644 index 0000000..6ca1133 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/macos.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:36e623b26fd1dfc902f8f738e281b2652ba6193cc31721f3d5d3f0cc1f6019b9 +size 1813 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/os400.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/os400.h new file mode 100644 index 0000000..4827363 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/os400.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc31820d250a50ea22d70f89653c103e02e5ab80fb0bbefed3a6f711f3893326 +size 1027 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/qnxnto.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/qnxnto.h new file mode 100644 index 0000000..aad648a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/qnxnto.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1419926cf0b3ca0150b08968d69ee513b64cdb5ccb347e6841297c0c1e2f05ff +size 1507 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/solaris.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/solaris.h new file mode 100644 index 0000000..1e78493 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/solaris.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e80389492a4c73cb4e7b423e9fe49ae2402f57f3428981e667ab6b2e74d82ce6 +size 1112 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/unix.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/unix.h new file mode 100644 index 0000000..64cb15c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/unix.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:20d0d60cd547d6427fde9dfb5c32a8a8b465aad1bfb8c0bad05e4242e74dac17 +size 1877 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/vms.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/vms.h new file mode 100644 index 0000000..e5a80a5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/vms.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa671764e348542cff2d3d67b4502d9b1859702b8e9a6adbda5a2d4ac59c5344 +size 1183 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/windows.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/windows.h new file mode 100644 index 0000000..aec3051 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/os/windows.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:38198445bfc5f39adf88bf8f09c0d417b5b63c4cc838d1c15a2318cccb582959 +size 1352 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/other.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/other.h new file mode 100644 index 0000000..9c5096e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/other.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c24d37e3c974d15745070a3ac5854360614087be8ea187711bc58d060abe13e7 +size 420 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/other/endian.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/other/endian.h new file mode 100644 index 0000000..5255ae9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/other/endian.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:498014fb704ae0c8d9bb83e15e014b50d21d6ecf61dbfc0c8eae1a63993330d6 +size 7361 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/other/workaround.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/other/workaround.h new file mode 100644 index 0000000..108f172 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/other/workaround.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:20c9beafc4a7faa01b72544de6c5092027e432cc29cca1046dfc8e819fa656c4 +size 2813 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform.h new file mode 100644 index 0000000..f672b80 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74696b064252382e97e8fe0a6892f24e1d41f71fb31606665967be14259a3577 +size 1005 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/cloudabi.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/cloudabi.h new file mode 100644 index 0000000..886d902 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/cloudabi.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d2ae912d5288c0b03983e4562fb60725eec8022be47387b01bfc04e356779b9 +size 1033 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/ios.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/ios.h new file mode 100644 index 0000000..4893cef --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/ios.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79c4517b71ed8c01400c4f62ffeac824a86e43f248db890bbd76f731e058f6c6 +size 1774 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/mingw.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/mingw.h new file mode 100644 index 0000000..eca0ca4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/mingw.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f56db4d0080d3605a31198edf8f9070314a6f634f51fa50879a3e7f537f0bc4f +size 2241 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/mingw32.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/mingw32.h new file mode 100644 index 0000000..28cb589 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/mingw32.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b37efb942aedfd2c3f771726ddf35aaf45bc10ce0bef9a6b1a6e9a66dec94e8 +size 1846 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/mingw64.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/mingw64.h new file mode 100644 index 0000000..01e188b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/mingw64.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74bf44af9fe7c2264010dfcdea0d2cf24b5dbab6ac2abf495618b84e9fd820bb +size 1855 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_desktop.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_desktop.h new file mode 100644 index 0000000..2164a42 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_desktop.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7fbbbc91c25fcd42dbbd374cf247f4085f483ec5cd65ddcdb68eaa9244b59beb +size 1576 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_phone.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_phone.h new file mode 100644 index 0000000..31afad2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_phone.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:216c8967ba941742909f76881c574070cb2dd6854615ac9946ea2b65dde3ef81 +size 1386 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_runtime.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_runtime.h new file mode 100644 index 0000000..286f787 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_runtime.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c9d97b39786abb7142444cf4cbb045d95d0259d4b5d860277b2c1d10f6f9e01 +size 1650 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_server.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_server.h new file mode 100644 index 0000000..76075b5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_server.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e79ce5f201c5eb664a9c68c8590c5fcbbc718828500a65808972b4805efbe178 +size 1356 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_store.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_store.h new file mode 100644 index 0000000..5dea3a4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_store.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01aa67abf07a8324216945b896c7e38f26c4272f1f35065343d758dbb3d0dcd3 +size 1538 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_system.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_system.h new file mode 100644 index 0000000..ce915a4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_system.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:122c7527178e9f948e633c94b2f258959b8a69c9b7d52a1acf7e73966ef68be1 +size 1367 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_uwp.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_uwp.h new file mode 100644 index 0000000..324c3f6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/platform/windows_uwp.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03b0a29b23a8ff1857482d42d18b5fb5daa6e893dec69040c5292b5859cf7307 +size 1844 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/version.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/version.h new file mode 100644 index 0000000..ead7e67 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/version.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2fbf18d14dd458c5fb0348639781ed97d53a50c870aecc947485349ddcb6f52 +size 356 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/version_number.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/version_number.h new file mode 100644 index 0000000..da88498 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/predef/version_number.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ebd97181c1b0bdbc62394ed12d27da90ba68c0171cdbf709393aa8956117ae95 +size 2105 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor.hpp new file mode 100644 index 0000000..b9e792a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ee0051bcf0b63ea43b3522051ba668ba7f8b0214fc3823f820313cc3fe40b39 +size 487 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic.hpp new file mode 100644 index 0000000..45ed136 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5dbea1a295244fd9a01e6a579bd57dbd7b74646efc1270fc9fdc080b46faa23 +size 803 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/add.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/add.hpp new file mode 100644 index 0000000..64488e2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/add.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:466664f4e4f2ed932b395693cddef7a8072c7a398ddbbc7fe72b70f9d797ffa0 +size 1858 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/dec.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/dec.hpp new file mode 100644 index 0000000..de25202 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/dec.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99211c529640ae5e97704ff3d4c3cc7973a75dcc9e3a9079cc9496ae35774230 +size 8323 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/detail/div_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/detail/div_base.hpp new file mode 100644 index 0000000..7882581 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/detail/div_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a628f938376712498624c3b6e8ea290274e927e49ddf89ddbdc7c7d8fc25012a +size 2568 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/div.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/div.hpp new file mode 100644 index 0000000..0218bf3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/div.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0cf354485570c4cd22e78815ccb3bf01a7efc5c5f863b07fb0a02662ba37d87 +size 1274 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/inc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/inc.hpp new file mode 100644 index 0000000..014ca32 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/inc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f46fafb970e6a2c535ff4179e13b234e1f05b78eefc695d4a4357aeb4f31c3c +size 8297 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/mod.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/mod.hpp new file mode 100644 index 0000000..7483da0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/mod.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b01b56af18bb08be0ea391af719335a0c3e05cc3ed2479a83790073277445fc3 +size 1274 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/mul.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/mul.hpp new file mode 100644 index 0000000..31f7ac9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/mul.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb869211ce96b1de503299012e17892bcfca24c3e9a2fec50538d7a23b11fa58 +size 2062 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/sub.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/sub.hpp new file mode 100644 index 0000000..9874ce4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/arithmetic/sub.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a64375e4072140c75d12f584010713a7da30998b61e582428f8ad3293bad2c0 +size 1808 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array.hpp new file mode 100644 index 0000000..fcdfb15 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1d9d503d12f7d1f84fe6b4c042e5456bf78bd41f6ec75018d73dc9a4d47a4ae +size 1600 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/data.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/data.hpp new file mode 100644 index 0000000..ce1ba8a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/data.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c9ba29785e03097acd1e9cffa28546484067cdb2e6e7c87b9c979fac8441ba5c +size 1158 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/detail/get_data.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/detail/get_data.hpp new file mode 100644 index 0000000..c735d06 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/detail/get_data.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8466784fdd63d5bbe43d9e9fed30678c379f70ea6bdf4a62fcb674bb94d14a7 +size 2164 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/elem.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/elem.hpp new file mode 100644 index 0000000..5c8d51a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/elem.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6bb8e1483c8e071ad03f6a09d71cddf88534984bc8391023da929d1fae3b4805 +size 1306 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/enum.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/enum.hpp new file mode 100644 index 0000000..147ad96 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/enum.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:545f6e3b25bdcb198a98ac94bff0dee1034b61251a69ea40e2a840ac99e0616b +size 1619 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/insert.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/insert.hpp new file mode 100644 index 0000000..b103109 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/insert.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4391db9d92f7ac85747aabc874cda10d4b3295bb34a1417db0da81e5bf923181 +size 3089 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/pop_back.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/pop_back.hpp new file mode 100644 index 0000000..c303db0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/pop_back.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb9d17db98e0a088914177654d2810789c81429ea7eb5343e3a9b360f557477f +size 1732 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/pop_front.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/pop_front.hpp new file mode 100644 index 0000000..6347d29 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/pop_front.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3912f5d2f45ca05044b8302fd82dd4f27cbd17c5b453e72fb3b9f93f9a089f90 +size 1811 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/push_back.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/push_back.hpp new file mode 100644 index 0000000..d87d968 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/push_back.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8d482791fc6dfc1f3ca0320889672a122810aa5550d78552a32f2d881f70ec2 +size 1729 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/push_front.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/push_front.hpp new file mode 100644 index 0000000..3ed4a19 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/push_front.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8920c38f100ec06fa42c176b4cc50052855edda96ea585a5f33123d3e5b7307f +size 1739 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/remove.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/remove.hpp new file mode 100644 index 0000000..22b806e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/remove.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b558e2422794f51e74c68ff693abffcc5286e169505c1e6fb5c15e6e95cb074 +size 2906 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/replace.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/replace.hpp new file mode 100644 index 0000000..7b077e0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/replace.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f62774db909ff95b066184afc55644606209f70ead278cb44e3b6d36714b677 +size 2725 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/reverse.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/reverse.hpp new file mode 100644 index 0000000..b8147d1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/reverse.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c9e08ca3cbe5bff53a773603cf45b4acbf310598edf011b1f4f2dc1b5e20eae7 +size 1378 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/size.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/size.hpp new file mode 100644 index 0000000..25d70a9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/size.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:27d20a936e02ccbc683835309cbf0ac91ad0ce1b28b309f3dffda497fff2296b +size 1158 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/to_list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/to_list.hpp new file mode 100644 index 0000000..2986b81 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/to_list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8cb7df6124e57baaaedcc31dcec9377864169e9cdc4cfd5c8da40c8bc12d47c7 +size 2012 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/to_seq.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/to_seq.hpp new file mode 100644 index 0000000..8321d86 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/to_seq.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:94afbbcf5b39babc43cfd093439aabe06d47c05904218f57740c921d1a0eadb7 +size 1977 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/to_tuple.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/to_tuple.hpp new file mode 100644 index 0000000..daf37c9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/array/to_tuple.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b18b071a7e81949e5374adb7dca43fd02e14ac8977832bd00595144d7501b38 +size 1298 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/assert_msg.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/assert_msg.hpp new file mode 100644 index 0000000..a650a53 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/assert_msg.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:686f2ca3f061858bf7bd7b9f5cb27d0d1d0817cf4f387bf7978f252d9d20114f +size 748 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/cat.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/cat.hpp new file mode 100644 index 0000000..2970ceb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/cat.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9f232dca396d537f103fd26b7fc4e2026aeb43cb476d069688be697c11a084bf +size 1018 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comma.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comma.hpp new file mode 100644 index 0000000..0a41e9f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comma.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:93aaaeeddf6ce0f0d02753a6e64bfe299ac9fd77e62c72da15e705f995c69c80 +size 743 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comma_if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comma_if.hpp new file mode 100644 index 0000000..6a299a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comma_if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e6183a66ed499fc42fa63c51b6d8e80fb38ed7ec988ae2663826beedf4a497ba +size 752 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison.hpp new file mode 100644 index 0000000..03b99d5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b0b4a9607138908fb6712a220d35d0955aab7bebedbafdecbb80bf44900264b +size 783 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/equal.hpp new file mode 100644 index 0000000..7292044 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:69a6f3ebb82ffbe0301adfcd0dbed6c0bbc11ec60d8ac6306f08e0ddca34c28a +size 1006 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/greater.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/greater.hpp new file mode 100644 index 0000000..9cc9be0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/greater.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c2ff62c33d4d942759d7e855c7943d4a4d85c61ad477dab94c977f028bbe6c5f +size 1141 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/greater_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/greater_equal.hpp new file mode 100644 index 0000000..298e905 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/greater_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90392fc12b2b76204683009bb24fc507a01e511b139a79330af05d6be343dc95 +size 1243 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/less.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/less.hpp new file mode 100644 index 0000000..b9755f8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/less.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eacf1018f2575270fcc50057fe83010b393f7b86affb1c325877718038463870 +size 1965 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/less_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/less_equal.hpp new file mode 100644 index 0000000..f7e20d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/less_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed0bc13771e84e7f12fc80e757bfe6c5c51d8500a6199dee7237b7f3f930b76c +size 1275 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/not_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/not_equal.hpp new file mode 100644 index 0000000..1eac00f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/comparison/not_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea09178b11926800cd3b44641525d3edc7c97dd3c0607edcdc95485a6fc0682c +size 64923 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/config/config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/config/config.hpp new file mode 100644 index 0000000..65dfa43 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/config/config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb34c61f7960e7182795647372c64105807e11651b5041f9a7989d1056106671 +size 5498 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/config/limits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/config/limits.hpp new file mode 100644 index 0000000..cd2f6a9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/config/limits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d06a6ecec66cc9c6e221f4fbb2b96ebe0f7ef01268340d20918856140e4c9e6 +size 878 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control.hpp new file mode 100644 index 0000000..acb26d4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59395810900373fe3b5cbe2292f739ffef4562f13c564d2f3e332bab1d6b80b6 +size 991 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/deduce_d.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/deduce_d.hpp new file mode 100644 index 0000000..a627c77 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/deduce_d.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f661a968fb5ebbb7eba07e79153d53650d4ae4264913e3ee385816e4d1e59741 +size 912 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/detail/dmc/while.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/detail/dmc/while.hpp new file mode 100644 index 0000000..b05bd57 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/detail/dmc/while.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:24a80ca0fd807fe1f9557e0046498620e221978a09f4b6dbae1b3b4c4e023fad +size 65769 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/detail/edg/while.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/detail/edg/while.hpp new file mode 100644 index 0000000..beca2ae --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/detail/edg/while.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e2d4c817647735e6ace2dc45285c9d82ce933fb6b49661d77c98715b10772b9 +size 48574 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/detail/msvc/while.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/detail/msvc/while.hpp new file mode 100644 index 0000000..2e9dcf0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/detail/msvc/while.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b77146b65e9e925cef8699476b8344a06ba8a0b0fbc37369be1e7d60141184e +size 31126 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/detail/while.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/detail/while.hpp new file mode 100644 index 0000000..714a04b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/detail/while.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52d897346181168e7a3107714b179afd6e7bb87d15e070d6bc9d6bba82d4e4da +size 67561 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/expr_if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/expr_if.hpp new file mode 100644 index 0000000..928ab58 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/expr_if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea4eb6d2414c35ad7c75fa9ca548a3f74046a8e7de758de4cd1f16ebda13dac6 +size 956 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/expr_iif.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/expr_iif.hpp new file mode 100644 index 0000000..5b9558f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/expr_iif.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:225dd9118c65de2e473e4cdec0aef9acc4b474216e683b4609bb1072dce32a10 +size 1224 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/if.hpp new file mode 100644 index 0000000..cfb08c2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ddb9af759ba3695b91dff747ce2fe18d768cdadf93ddd956884eff8333e4ee40 +size 906 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/iif.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/iif.hpp new file mode 100644 index 0000000..a8a2321 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/iif.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ccffe0f0bbc7ae9e4993a43d77fa0fd23b143d533148e462f1248e809208da04 +size 1325 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/while.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/while.hpp new file mode 100644 index 0000000..19d71a3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/control/while.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ebaccd191ef97db46ccdabe8b791adc9e0bb6c42fa1161fa98353fd2e6653cc +size 17561 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/debug.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/debug.hpp new file mode 100644 index 0000000..45bf19f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/debug.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2237ec07b25f574966b3df10fdafd9ea05596af3654001450a26f92f691a7b11 +size 784 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/debug/assert.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/debug/assert.hpp new file mode 100644 index 0000000..f6bf539 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/debug/assert.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d20ac6553e3748779bbf22048f46b22b4c49e8fd446ba3f76960055a5801f80 +size 1374 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/debug/error.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/debug/error.hpp new file mode 100644 index 0000000..63a29cb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/debug/error.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3cee86e4c00fb6e8572acf2efcf121f1b02dec3c89c4ab59d41f584920c79885 +size 1574 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/debug/line.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/debug/line.hpp new file mode 100644 index 0000000..f95be9e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/debug/line.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29f36591e6e49e176e4954063cea56f64090c38246cf89f82804b8e4edb9ac91 +size 1686 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/dec.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/dec.hpp new file mode 100644 index 0000000..c2f21f6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/dec.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4ddff6960518d75d6d2b0d783604ffb1848bdd93943be6b5bf46cf4eb554d47 +size 736 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/auto_rec.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/auto_rec.hpp new file mode 100644 index 0000000..4bf1b70 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/auto_rec.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32579802ad68f74fa08d059e2410633a164b83d0a51f50eab162cb6569ebb634 +size 26136 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/check.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/check.hpp new file mode 100644 index 0000000..5eb1a04 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/check.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f44f116a02d55b4e31df2dedb35a1e4e22ba1f62923882c29cf7d7f26497b78b +size 2183 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/dmc/auto_rec.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/dmc/auto_rec.hpp new file mode 100644 index 0000000..1da525e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/dmc/auto_rec.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c2ab6fc15b9fa80dca4899dd498d26ac99838711626ee38afb87e6fbc530e5bf +size 26466 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/is_binary.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/is_binary.hpp new file mode 100644 index 0000000..260804b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/is_binary.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4461a173cb87b7b18002d0b5dc70a709452049b057fc7fb94fa8b941ee89c41a +size 1241 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/is_nullary.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/is_nullary.hpp new file mode 100644 index 0000000..f735ec1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/is_nullary.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18cbabf0e597c46a8af0c8d9b5991aa72716a9a06b97b2541ad1108a5e31c051 +size 1248 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/is_unary.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/is_unary.hpp new file mode 100644 index 0000000..e58610d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/is_unary.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3345eae7795dbc2d74254ce14f5eadffcc03bcb580c6e10fb1439a57174e5015 +size 1227 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/null.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/null.hpp new file mode 100644 index 0000000..68a1fd9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/null.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:33b66a32f2f8e9c713e4d2bd0343e75d1b2e38dbb2eb95bb475773af50d47f4a +size 721 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/split.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/split.hpp new file mode 100644 index 0000000..49b3928 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/detail/split.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc2e56aad1de3bb6ea0be589e0454fd1084c4d631f0de100d860c8225889ba41 +size 1529 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/empty.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/empty.hpp new file mode 100644 index 0000000..326d06d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/empty.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:25316276e18b8025ee1260681a106bb60fd2a0595fdbb784a6b9a1f34e32b98e +size 742 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum.hpp new file mode 100644 index 0000000..9835d01 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5d39332ae802095cfc7adfb0d2ad8ad4ef0b014c411272b9b323b6fe7b64569 +size 739 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum_params.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum_params.hpp new file mode 100644 index 0000000..5e312e1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum_params.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7b5f2ebe844bb76c25d381be99c368cb4f9f1f355d9fbf8ef0074411c7f8db3 +size 760 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum_params_with_a_default.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum_params_with_a_default.hpp new file mode 100644 index 0000000..a325bed --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum_params_with_a_default.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76b35a1f9696e7f608255ba3e1a1ba0a99cb8caeec2b04ab2824c8a2b5a99951 +size 805 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum_params_with_defaults.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum_params_with_defaults.hpp new file mode 100644 index 0000000..139003a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum_params_with_defaults.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:534a616fa8441b69dfe026b641b8ccac09b020c031a5866adaf52e816421c3e7 +size 802 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum_shifted.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum_shifted.hpp new file mode 100644 index 0000000..99a69a5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum_shifted.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74d2ec26feb478240a1d9db100984afc4a7beb10246a5876a906fcb7ad59a2bd +size 763 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum_shifted_params.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum_shifted_params.hpp new file mode 100644 index 0000000..ae21083 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/enum_shifted_params.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d33676cf28d10ecffe70db46e9e9af04c23884af5680b1d0feb13a26debec151 +size 784 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/expand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/expand.hpp new file mode 100644 index 0000000..bbbbfdc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/expand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:476504473aa946bc632f28f3f607e5b3d84e459f93ea0c27f2322ab11c6a1497 +size 745 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/expr_if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/expr_if.hpp new file mode 100644 index 0000000..e26d247 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/expr_if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74609a2431533535955c9f26e5da601260ba4f0f2880516e769459259fdc9860 +size 745 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities.hpp new file mode 100644 index 0000000..476a659 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1fcad5ff6f5bed0f2955e396ccbee8ee3f5ea83a1a5b94a2f0412150cf76563d +size 1204 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/apply.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/apply.hpp new file mode 100644 index 0000000..0a1fcdc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/apply.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bf660c870290465795215bf7839e70dccb3350339da73f41aa7fe8111c0965ea +size 1475 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/detail/is_empty.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/detail/is_empty.hpp new file mode 100644 index 0000000..587704a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/detail/is_empty.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:25589de7caed4fbaad7e8f4cc4e4f3e4ef9734c48873876f68b7f164a70fbbde +size 1719 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/empty.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/empty.hpp new file mode 100644 index 0000000..f71ad2a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/empty.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e086fd6efde0fabbf12715c72a80d9fa2916d14bed6a6e8631cc3a9efd7d648 +size 567 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/expand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/expand.hpp new file mode 100644 index 0000000..8539809 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/expand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c3dcec5afba1e28fd48da9066b828c386c0149c2a7cf5b27e38ea2c1040ec1e +size 842 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/identity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/identity.hpp new file mode 100644 index 0000000..87cc370 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/identity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d23be5440b75e32ef9da08bd4cacb7016917a42bd4c30f61fa3d061fa1f645eb +size 759 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/intercept.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/intercept.hpp new file mode 100644 index 0000000..5f504ec --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/intercept.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f445e920c201b8b3dc8c2f0ef1c99e103af47aece465d2ec0d23572ca9bd93e +size 8913 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/is_1.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/is_1.hpp new file mode 100644 index 0000000..e62119d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/is_1.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c481a0e24bedd5902ef9729c3b32dcecb214975c940fc22402f4ccb6e8eb5ecf +size 946 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/is_empty.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/is_empty.hpp new file mode 100644 index 0000000..fbe73d6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/is_empty.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd944855298a0d8621d910883ba0f55822aa6f0f04c9039d342f01fe7c526903 +size 2544 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/is_empty_or_1.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/is_empty_or_1.hpp new file mode 100644 index 0000000..4385ded --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/is_empty_or_1.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49c6ef2d518b22877eca0db4157f7c0890f25e6d35b30527dde330a4c661b31c +size 1205 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/is_empty_variadic.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/is_empty_variadic.hpp new file mode 100644 index 0000000..fb9e79e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/is_empty_variadic.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2dad8983ff11affe13f203736552131e6ba1b75f5751fa16a1e9cec1b961017d +size 1780 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/overload.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/overload.hpp new file mode 100644 index 0000000..699398f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/facilities/overload.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:748c9c57121b5f80c1a93257f835fc2fc2d7127647ac2bd46714eeddb7a4dd47 +size 1150 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/for.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/for.hpp new file mode 100644 index 0000000..019a16c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/for.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e76e61bed538fd5049482c577e7377bfdc3d138d0522ad3a93b3bb25a9ab3b77 +size 736 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/identity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/identity.hpp new file mode 100644 index 0000000..84a91c1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/identity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e60eb53975fba657c6f099c0ceb23670388040680ee2b8b3f41c2bc8b6eb002 +size 751 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/if.hpp new file mode 100644 index 0000000..8d5a7a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e50196c6f8d1aec7063595f1502306de213db7cfe19c3d2f31188bb5ebc77a0 +size 730 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/inc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/inc.hpp new file mode 100644 index 0000000..0b110e8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/inc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfa9aea1844754bab45515c322a44d5dc8553f67db6358f01ba345dc9793bd18 +size 736 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iterate.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iterate.hpp new file mode 100644 index 0000000..d5bdce1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iterate.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c62ff19d47449b7519d2052aed158821cd126e9e620f46f6d74ebdd66106ba5 +size 747 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration.hpp new file mode 100644 index 0000000..c22688a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:740388173b56a4724c6cd310ae3712817dacd2a37d3d5c2791f3b8227409616b +size 852 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/lower1.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/lower1.hpp new file mode 100644 index 0000000..ac7a5e4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/lower1.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f6807bc3dc5b396c5b7671cbfa8aba047d23de90992725ebe0b21dc2885f594 +size 4079 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/lower2.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/lower2.hpp new file mode 100644 index 0000000..6b17113 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/lower2.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:651fe64976862de8042a0eb6136ee6ac4e0b4d73e59e1857a4dda03d9af9dbaf +size 4079 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/lower3.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/lower3.hpp new file mode 100644 index 0000000..c138719 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/lower3.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8ad1731d8d7a28528a5dfc3ce5abd2b2724bc60716647f15c7726b576e4c321 +size 4079 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/lower4.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/lower4.hpp new file mode 100644 index 0000000..506aa5c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/lower4.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ea66c700426341dbe5660de8dfc5ef39f79435ea2ac5e336b36d0bdeeb36c58 +size 4079 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/lower5.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/lower5.hpp new file mode 100644 index 0000000..79bb6ec --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/lower5.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8e1cdd298554a74102133d78b4ec356cce29457082f58af20bee564e54566d5 +size 4079 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/upper1.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/upper1.hpp new file mode 100644 index 0000000..3115dbb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/upper1.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01ae3dc6c78a5d2df6af21294df0a4e95e2b665ef368d8d357ea1fc2bd28a554 +size 4131 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/upper2.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/upper2.hpp new file mode 100644 index 0000000..acce982 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/upper2.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe33cf6945ee59b890fd363012b79f987a4071effd9fc20214b26cad54e46deb +size 4131 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/upper3.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/upper3.hpp new file mode 100644 index 0000000..bc6dafc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/upper3.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0dfdd2eb0568446fd14f27971f882726f62f463dbcecbcf94b99ec4af2de109a +size 4131 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/upper4.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/upper4.hpp new file mode 100644 index 0000000..5af2864 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/upper4.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce6b89a8f50ed4404bb5f5ab6cc83217044d6510a134d78f03a3b0ca0943aee0 +size 4131 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/upper5.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/upper5.hpp new file mode 100644 index 0000000..7062a27 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/bounds/upper5.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0615225c6dc06a324734fabe86cb18fbe3d5a4676d70dd8d948dd18123e6437 +size 4131 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/finish.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/finish.hpp new file mode 100644 index 0000000..dbce815 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/finish.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af1dc02e4a4d02b0d73bb1b7c3f8148b08f45a5c562156d918cb6d90aea3570d +size 3617 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/forward1.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/forward1.hpp new file mode 100644 index 0000000..73ff59a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/forward1.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ab95856c0b46cf525b2eef0b65692f3e7b9b02a2a53e73be20518450a3a90fd +size 54776 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/forward2.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/forward2.hpp new file mode 100644 index 0000000..ceb0cd2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/forward2.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26d1e9e8c809784b501cf4cc80685bd81ca5958148d0e0b21fbfbddd178af46d +size 54709 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/forward3.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/forward3.hpp new file mode 100644 index 0000000..22d2756 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/forward3.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e62c4a1a42c8bd8642a35b030dbd9ff07a2d04c97ca44107f40db11fee2ff53e +size 54709 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/forward4.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/forward4.hpp new file mode 100644 index 0000000..fe8f0e2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/forward4.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:760c1d8b74d24ca47effcca9a36ee1011a6b753144ec25296ae2d83a6c19c5d4 +size 54709 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/forward5.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/forward5.hpp new file mode 100644 index 0000000..73abb3f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/forward5.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46b92fccb4810f940c5cd0e70a7589474d42e949b96307b897a17f12acf632b0 +size 54709 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/reverse1.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/reverse1.hpp new file mode 100644 index 0000000..42565c1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/reverse1.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d4538ff16a50f497761c444e7f4182c0f86e7bbfa5de5da5d8afedbc715b353b +size 48331 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/reverse2.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/reverse2.hpp new file mode 100644 index 0000000..a28341e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/reverse2.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d911d867dcbc8a00eaf7deb6e3064b35f104cdb5cc7cd6049db289f332b6ebf +size 48331 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/reverse3.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/reverse3.hpp new file mode 100644 index 0000000..2a4b843 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/reverse3.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48a7fde0bc7644e9601c10103135393aca558807550cef737a5d8e9b4c773331 +size 48331 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/reverse4.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/reverse4.hpp new file mode 100644 index 0000000..4c94f13 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/reverse4.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bef16506b55ad28973c32a22f4f669052b8030e255794483b942f6c694d91f48 +size 48331 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/reverse5.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/reverse5.hpp new file mode 100644 index 0000000..3bdb48f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/iter/reverse5.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b8aceb8ac481f545ae187f6c1a14c9bab874db6fa54633618459ab20b26a481 +size 48331 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/local.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/local.hpp new file mode 100644 index 0000000..ac82723 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/local.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e8edcc5b860aed762df5a833ecb1a592e7603fa19a1c1a56aadd7bff7afff587 +size 20769 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/rlocal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/rlocal.hpp new file mode 100644 index 0000000..fb3d077 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/rlocal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11af18b2d0b852f3df90c01fc8865978e03f6ffa5622c1673493d8f42e87ee2a +size 17087 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/self.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/self.hpp new file mode 100644 index 0000000..681c418 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/self.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37af9536a486db33ee8e0822ef3fd01cf0d342b129a19fd90451137c27114094 +size 833 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/start.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/start.hpp new file mode 100644 index 0000000..de7c425 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/detail/start.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9693dc3998a90d39ad362bcfde9a8393e74ff4629e4f30f59f9b3681a7fd4555 +size 3617 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/iterate.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/iterate.hpp new file mode 100644 index 0000000..832df29 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/iterate.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49ebb8e91eb0d3230950086b94bd5c5b92957834a10e27f6c1f0197f4e83b85a +size 3706 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/local.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/local.hpp new file mode 100644 index 0000000..7182dc6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/local.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd6d9e858452afcfc9194fc9ba264a25536a4aa98dcd5a6a785a875cbf44c1ba +size 1129 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/self.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/self.hpp new file mode 100644 index 0000000..55dae19 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/iteration/self.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4bdaa291381f918396a75aebbd5c40c6bec2faf8281f1fd95b549ecd678d198d +size 820 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/library.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/library.hpp new file mode 100644 index 0000000..ba91a59 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/library.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58f28f468407ebd0b77123b152d881d42a79065a8fb8bb73fdddddd9331bb361 +size 1747 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/limits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/limits.hpp new file mode 100644 index 0000000..98be40d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/limits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10e2ee83ddea44561957e469243c1a4b1cef32fe50224417be81cc2653ca7645 +size 741 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list.hpp new file mode 100644 index 0000000..bea01f5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ec19d6963ebc2936d5e881577c8693b68fc96c09e70ecbd81a388dfc27fca8f +size 1352 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/adt.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/adt.hpp new file mode 100644 index 0000000..eb3c53b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/adt.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8c9b63e1be1dd34032d07c726b9b8676d1556b20ff1e05f542aa63da6aa05fd +size 2171 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/append.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/append.hpp new file mode 100644 index 0000000..95a9172 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/append.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:983ebb17e5c1350256ad51e188cb4262d9ef54fd8bdcb4619320e50c3471edb7 +size 1359 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/at.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/at.hpp new file mode 100644 index 0000000..d9f7234 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/at.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e658a21e5e27c6d43acded1cc29dcda5b475df18b2a9114220e334226d65cfa3 +size 1355 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/cat.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/cat.hpp new file mode 100644 index 0000000..08b5464 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/cat.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b61217b215ff05c9977c250a2523a8e018a07b0dbc7e4ab1c06c9e64b8735a76 +size 1586 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/detail/dmc/fold_left.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/detail/dmc/fold_left.hpp new file mode 100644 index 0000000..f63df13 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/detail/dmc/fold_left.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:277da8bc285adfb01b86f7cc2d423813e7b90d24d98e8c1ee60b173f6c8bff0a +size 68186 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/detail/edg/fold_left.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/detail/edg/fold_left.hpp new file mode 100644 index 0000000..260e10e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/detail/edg/fold_left.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11b4f0d262434f68bf0ad1f2ef34b5a1ccf1e9da15bd6b4c9936162d168f15f4 +size 84875 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/detail/edg/fold_right.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/detail/edg/fold_right.hpp new file mode 100644 index 0000000..f476a74 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/detail/edg/fold_right.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eca7ad79898a7e280a4abc1bdfff7b7ebe237f6e20b6ed8bff337288f2c427d9 +size 113960 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/detail/fold_left.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/detail/fold_left.hpp new file mode 100644 index 0000000..49c85a2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/detail/fold_left.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ec75b889d9ecc89068de4f8967aa69b01f8134686e10df64d265a92ae439eb0 +size 62809 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/detail/fold_right.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/detail/fold_right.hpp new file mode 100644 index 0000000..97366c1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/detail/fold_right.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95d60ae629111d523850d522f1b71ec5b98e605a4218116fbf2bcab33354a187 +size 29437 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/enum.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/enum.hpp new file mode 100644 index 0000000..5511f6b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/enum.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:abceb52752c4a1a33d3fd214b7512d0b0f8e3b636b6a9ec1806ab753ab8887d1 +size 1460 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/filter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/filter.hpp new file mode 100644 index 0000000..4e89990 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/filter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92443ed38a73d216356115366e10d584ee3dc1e8ef3db348d2d88a916bd07c8d +size 2538 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/first_n.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/first_n.hpp new file mode 100644 index 0000000..bc52b7a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/first_n.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e405b421cadfe8ca42975a8e0ef6de6cd07d8e0f5b2f9a4966abd700ca136bbf +size 2684 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/fold_left.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/fold_left.hpp new file mode 100644 index 0000000..32a87f9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/fold_left.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51794910277d9cf4c04234ef1fea50538266be08b7c15af0135f59de70c23774 +size 21383 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/fold_right.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/fold_right.hpp new file mode 100644 index 0000000..37c7f44 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/fold_right.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85860f4d224d9b278fdf42858edd309ae5621c55cc3cb7e91dc5a18ace775d20 +size 1326 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/for_each.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/for_each.hpp new file mode 100644 index 0000000..4c9875d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/for_each.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:066c897602fad2ee55c1be3fb9823a962079f4614b23c1cb14ba56b39a1fe9a6 +size 2089 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/for_each_i.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/for_each_i.hpp new file mode 100644 index 0000000..68529bb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/for_each_i.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c2e01a4af9a4d151fc0591c600dac3d43c9b313779191facfbc78368219aee73 +size 3289 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/for_each_product.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/for_each_product.hpp new file mode 100644 index 0000000..dd142c1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/for_each_product.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab2ae7b4ff597fd838b3fcf5c97132744d3e7521628b57b0d05e7555adfe5033 +size 13798 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/rest_n.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/rest_n.hpp new file mode 100644 index 0000000..a950396 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/rest_n.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14a035b55223b53e661863a6e3028019db200db2c99a9099ed11d1831c8d479d +size 2350 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/reverse.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/reverse.hpp new file mode 100644 index 0000000..e16fa9c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/reverse.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd9bd2e1a24599a8b0270089bdfcb01254596181579ac0ef9222c18151c15fb6 +size 1427 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/size.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/size.hpp new file mode 100644 index 0000000..5af49b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/size.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47a4f089753d0169dbecfe23906c93b2d67def5bc799f781362890f3685a4e63 +size 2468 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/to_array.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/to_array.hpp new file mode 100644 index 0000000..35500e2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/to_array.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82c24e8055762a99aa4f084246ef61c05b8ba67a57580063416cb2f87744238d +size 25793 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/to_seq.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/to_seq.hpp new file mode 100644 index 0000000..25df624 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/to_seq.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42d962e893387aac6bf8f748d02a46e810c28e9d7a65fa33bbbe4a2484401081 +size 1196 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/to_tuple.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/to_tuple.hpp new file mode 100644 index 0000000..45de91f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/to_tuple.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:969806dca613e4464f8171f048f50f72a0234b9fbd0879c1a51bb3d4803d96c3 +size 1738 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/transform.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/transform.hpp new file mode 100644 index 0000000..099afe2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/list/transform.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae34114b5b780a66f72e23000ac985bf95a58b6d9e700facc4b86ba550aa395d +size 2305 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical.hpp new file mode 100644 index 0000000..a6bc046 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc4fc3898e186f49f57b1051469ce95d6d066adceccdf1168834a739e6120b18 +size 977 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/and.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/and.hpp new file mode 100644 index 0000000..d55cdc3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/and.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2de99f30eda56fc4232fce3e4c9dc38de20b4bcdc76dbee46047e120d15359d +size 916 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/bitand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/bitand.hpp new file mode 100644 index 0000000..cb45fa6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/bitand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe547d1d47dd41d44e8a9f3eb964f0c91d6ee6da3b99f80ad784bffd0a61a6d2 +size 1415 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/bitnor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/bitnor.hpp new file mode 100644 index 0000000..e02872b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/bitnor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ad103ea010b594f5c446136029c4f89e4064015bed3ac5c1bb5ba1ad5f41e35 +size 1413 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/bitor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/bitor.hpp new file mode 100644 index 0000000..4a4a640 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/bitor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1665badffd8b690e7940d577244cae1e93d5f72be991e3f8b64168871f5a73a +size 1394 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/bitxor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/bitxor.hpp new file mode 100644 index 0000000..0873da0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/bitxor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34030bc463863cfc740f7e62f73acdb9b5e3be5bfe9127fe6d3e44eccd183b6e +size 1413 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/bool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/bool.hpp new file mode 100644 index 0000000..e388e74 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/bool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a7a4f260bc74e6f6c465bf556bffbb884ae971082b8288641997bc0622a5f511 +size 8153 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/compl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/compl.hpp new file mode 100644 index 0000000..58f89c1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/compl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d12c8c00c74fef902f84cfcfb899dea2bac16ce7c2fd038de84ce1cdc3b6df4 +size 1306 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/nor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/nor.hpp new file mode 100644 index 0000000..da79c19 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/nor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:adb7e209988de9b0e64dde03426752e00a78aa62245a844c5424977187194afe +size 916 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/not.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/not.hpp new file mode 100644 index 0000000..8f3907d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/not.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d05ec8aa9e209f9a08d433f4641c6ea8bc0b7079bf76419748d6879c7908a4e +size 865 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/or.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/or.hpp new file mode 100644 index 0000000..d33c03f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/or.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3aa8bda414899bac0b137d89beb65c7c11f1b31364ffecfe14c5afd231eaea29 +size 906 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/xor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/xor.hpp new file mode 100644 index 0000000..42c58c9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/logical/xor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03797d9a52046755ef1837c6086d1f4c509b6202fdab163da783e994dd35e360 +size 916 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/max.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/max.hpp new file mode 100644 index 0000000..0f66ab1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/max.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1815e97acfeaa25b0d3eda0fbd4b9b5c978d597d3c95cf9a2e58fbcfcfae164c +size 735 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/min.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/min.hpp new file mode 100644 index 0000000..f82c56c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/min.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1aa1e15ae8c108f04c81d004d75efbe5d8562e447958a101b552179f7972420e +size 735 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation.hpp new file mode 100644 index 0000000..2433925 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26a8737c6436d44b8011aae80fb0b465e3e1ca296de71f111c28d99e8015c90d +size 1044 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/comma.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/comma.hpp new file mode 100644 index 0000000..4d7fb88 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/comma.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76c39ab0338e79709faa68d8c5097317e93317ee8d9b71e27d3b4a4735f6d66f +size 520 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/comma_if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/comma_if.hpp new file mode 100644 index 0000000..bae0a19 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/comma_if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:33e2573e29b20c6026f156ea2ace78c311724eb6df949c1ce21e94f28d26ea4c +size 1012 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/detail/is_begin_parens.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/detail/is_begin_parens.hpp new file mode 100644 index 0000000..35593d5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/detail/is_begin_parens.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:310514fccb7ad34582cc5f2e1254742ed7dc604bdfda3ac3e28865d5b6bf2300 +size 1899 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/is_begin_parens.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/is_begin_parens.hpp new file mode 100644 index 0000000..fbe4493 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/is_begin_parens.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3bcb7a3f7322f34100216558b52e302cf6423b6e576bb42a7ea79a645d24e858 +size 1568 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/paren.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/paren.hpp new file mode 100644 index 0000000..633055e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/paren.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:27361f51a8a15d71e0e3994a546a20c0e667872e25585f4f8fa78b0c679ffe1f +size 826 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/paren_if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/paren_if.hpp new file mode 100644 index 0000000..a85092c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/paren_if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbda8e7757d14eaa1ac398237551aedfb6da39f04bcecae465645af9609d66ec +size 1612 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/remove_parens.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/remove_parens.hpp new file mode 100644 index 0000000..fe8bb7f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/punctuation/remove_parens.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1047568f1260e596b83a05fcd0ec4c72123b0f2f41bf28733283ecfb42d47f01 +size 1356 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat.hpp new file mode 100644 index 0000000..9e92a70 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4afc30370c1de2b7bd9d2a9670f901d4c5fadb26a5b5d6dd647bf78644df8e3d +size 745 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat_2nd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat_2nd.hpp new file mode 100644 index 0000000..10448c1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat_2nd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2cdfb443bf3b4c5ddc83ccceca8a5dd4cd0800b53170cf83bd0b5640bed90ec7 +size 753 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat_3rd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat_3rd.hpp new file mode 100644 index 0000000..2034863 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat_3rd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad636a053eaa2ea085ee103f53d08d14409590a18956b5fbc114e15d57f4e209 +size 753 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat_from_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat_from_to.hpp new file mode 100644 index 0000000..a2167ac --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat_from_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1acb4aa84e1021aa27ca6744476c9e57a1a4bfa334329f973517398cf906fdf7 +size 769 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat_from_to_2nd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat_from_to_2nd.hpp new file mode 100644 index 0000000..d5fde40 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat_from_to_2nd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a07ecddef28d3dac7080cd49724b42c05010d0d879f740d8e8afe9304392a6e5 +size 777 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat_from_to_3rd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat_from_to_3rd.hpp new file mode 100644 index 0000000..14f4504 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repeat_from_to_3rd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b003e2a8d9969334168d365ec6b401a0f55961a426852e19527d585391fee745 +size 777 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition.hpp new file mode 100644 index 0000000..0505400 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54371b71a3cde2bb38f5815c53bdbea09381e95827ee59f3239224f9bed905cc +size 1692 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/deduce_r.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/deduce_r.hpp new file mode 100644 index 0000000..34eb234 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/deduce_r.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be24cb8e4f991eaf910a7494392bcb5dc4ead46ae44df083c46d9abb4e5e0261 +size 917 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/deduce_z.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/deduce_z.hpp new file mode 100644 index 0000000..f22e06a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/deduce_z.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:31e3015353d51cc0fecc96819e3867b68080077a3a50f462cb9068440a66a608 +size 921 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/detail/dmc/for.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/detail/dmc/for.hpp new file mode 100644 index 0000000..d21bc50 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/detail/dmc/for.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28d1353b270e61149fa6cb03099263eda1b8a073fbc18349a6ee4bae449c3d6f +size 73395 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/detail/edg/for.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/detail/edg/for.hpp new file mode 100644 index 0000000..f68a1dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/detail/edg/for.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5ab1954efe8def7717cd47f441562d9f3936ae6c30894ceb18c5d1e401f33dd +size 63212 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/detail/for.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/detail/for.hpp new file mode 100644 index 0000000..d43eb00 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/detail/for.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:711f237d61dcd37fe78b0ef30a16ea1198e2f6dab95e496b7f52afae436420cb +size 72883 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/detail/msvc/for.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/detail/msvc/for.hpp new file mode 100644 index 0000000..ba556dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/detail/msvc/for.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cac300486c03780aa5ea74f9ae13c4ec23f3018b502cd9c00c62022b1df8146d +size 45252 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum.hpp new file mode 100644 index 0000000..24cbeca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e4f80200a9784526ee7c9f74972169840a73e0b36cd0098e606bddfac459f8e5 +size 3042 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_binary_params.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_binary_params.hpp new file mode 100644 index 0000000..7af70b3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_binary_params.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:366cb086c63619c44040a5a1c96fe04aff482696684c70b5e9078f2ed319cddc +size 2788 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_params.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_params.hpp new file mode 100644 index 0000000..44e429f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_params.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76fe006a17e57f4da23ffd81f10d1edbecd6fe4063aee2da2e219fc21623a627 +size 1528 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_params_with_a_default.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_params_with_a_default.hpp new file mode 100644 index 0000000..d345795 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_params_with_a_default.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e2bb50359d9885bc591250fc3f313d5232fc691451da5b7609c2e1bc1a652c3f +size 857 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_params_with_defaults.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_params_with_defaults.hpp new file mode 100644 index 0000000..7d6e105 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_params_with_defaults.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e0636a085c09f7ff7184b975bdc3dfb25fffb484df615b04050e2d834c0ef80e +size 778 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_shifted.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_shifted.hpp new file mode 100644 index 0000000..7bf3790 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_shifted.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb18955d7c3ce899d70cdddfbc80022e0193d10959f75c15692b1aeadc26cd5b +size 3636 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_shifted_binary_params.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_shifted_binary_params.hpp new file mode 100644 index 0000000..346b450 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_shifted_binary_params.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:538ff12836614fafc4dc586d8610cfb702a6b0a2940086ee74e0903caca59a9e +size 2983 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_shifted_params.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_shifted_params.hpp new file mode 100644 index 0000000..da732f7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_shifted_params.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe57cb7581a1e3b51a444148519b688c61c5d2b0f5ade045de91a8f161eef8ae +size 1885 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_trailing.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_trailing.hpp new file mode 100644 index 0000000..e79ab8c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_trailing.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91e06f97f9685c046079e3cf5146c7ca10975215577aa9f7aef1d1185104ad00 +size 3590 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_trailing_binary_params.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_trailing_binary_params.hpp new file mode 100644 index 0000000..d910171 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_trailing_binary_params.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6248f5cccdf27e539504d69b9fa52ee8446f4eb0ea66d3cc437708e006b2ce7b +size 2928 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_trailing_params.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_trailing_params.hpp new file mode 100644 index 0000000..bca044b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/enum_trailing_params.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b72eb935679d0b4fc2e409632c7cef183adde41a3375bb55f6a3682761b51a53 +size 1853 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/for.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/for.hpp new file mode 100644 index 0000000..0556ffc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/for.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:201e1cb70ff633b4e58e7e8e70cf4bc510675f8a1a237041c80999eedee05886 +size 17087 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/repeat.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/repeat.hpp new file mode 100644 index 0000000..d309dd1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/repeat.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fcc3aa0eb4ef33ea9566de54e8b754f43ba0133b97070e4fb67278e54a214c7a +size 60818 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/repeat_from_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/repeat_from_to.hpp new file mode 100644 index 0000000..8474368 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/repetition/repeat_from_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6beb88af78e3082743461ec97ed58f8dd3a5cab70d4b72a4c896659a72e6ab17 +size 5258 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/selection.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/selection.hpp new file mode 100644 index 0000000..3863676 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/selection.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c79c5c506a6c07390607751202927916245936c1b396f260fb9139b221d4fa8 +size 796 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/selection/max.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/selection/max.hpp new file mode 100644 index 0000000..f07fbc0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/selection/max.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b23b455b13d20f1c3aaf49b791ffc41f9bd2ea4b71d581ade9eb3e4a6c2356d6 +size 1248 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/selection/min.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/selection/min.hpp new file mode 100644 index 0000000..d0b7398 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/selection/min.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f774a8022674db62850ad452d4a4d4fe753c8c6e012b9ff2b5dfcd04bd4cdc6 +size 1248 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq.hpp new file mode 100644 index 0000000..91b31c5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95ed15826343ecacb6a4b3ea8111f4b8eecdb1e9ecdc7b070f5c443aef933c2b +size 2156 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/cat.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/cat.hpp new file mode 100644 index 0000000..23bec1c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/cat.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0815e1c972b1578bb42a5fa673349f566659abe4ddba4d2a94ce2d32a0dcc98d +size 1898 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/detail/binary_transform.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/detail/binary_transform.hpp new file mode 100644 index 0000000..f417382 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/detail/binary_transform.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e07b99eb956d87f2b73c740d0e370e30d760897a2e9155cb852d58674d570c2 +size 2625 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/detail/is_empty.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/detail/is_empty.hpp new file mode 100644 index 0000000..ccf3183 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/detail/is_empty.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c2ebe0d7ef93d6373c96c6711be7313f241c09fbe1fab601b74d5f9b4a6e0a84 +size 1593 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/detail/split.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/detail/split.hpp new file mode 100644 index 0000000..2c305f7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/detail/split.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1a9a791b98e1c7089654e6d28b103c58adca71b2cc7867bc16133f78324db452 +size 16712 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/detail/to_list_msvc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/detail/to_list_msvc.hpp new file mode 100644 index 0000000..39bd8fc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/detail/to_list_msvc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3dc7456dd66dfbe175f26dad6c1657de9e8d01651e80925f48686f5f48965a9 +size 2165 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/elem.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/elem.hpp new file mode 100644 index 0000000..fb6e539 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/elem.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be974867cb22a5c6f832a9a17b53b45db80d437ffb91b86e6a939528263a9805 +size 16226 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/enum.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/enum.hpp new file mode 100644 index 0000000..556b1fb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/enum.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b29d120716b4445b15ca9a7807030c94f76053c8182f9c17683d12a3c13545b +size 16273 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/filter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/filter.hpp new file mode 100644 index 0000000..8f76219 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/filter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ae788c5842572e7335633979829be6cfdb2fcdc455700bbed254563d5f7e829 +size 2881 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/first_n.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/first_n.hpp new file mode 100644 index 0000000..ee8622a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/first_n.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a22bae88681238d60be1409132c5d9aac7b90f4e3fbcfdfb2a92907b79664cc3 +size 1394 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/fold_left.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/fold_left.hpp new file mode 100644 index 0000000..9421a9f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/fold_left.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1060ebc408c3a5a6aefb8787f36e06770022321633dc668748daa1e2d4c9c6f3 +size 166466 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/fold_right.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/fold_right.hpp new file mode 100644 index 0000000..0cc2938 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/fold_right.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8b79c19f84a5dadb31a48cc4c03b9ad532de77d294c4725be4011a3695c10ef +size 37274 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/for_each.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/for_each.hpp new file mode 100644 index 0000000..d2870cd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/for_each.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0209b0bd49149953e45495198e0eab6bc9f0811984e588af5e327e33a389d28 +size 4554 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/for_each_i.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/for_each_i.hpp new file mode 100644 index 0000000..9b1d0e7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/for_each_i.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a6b32154a06b71866457d3957ebc3c7147dad0d788c69f45c241ca64f2eb006 +size 4807 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/for_each_product.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/for_each_product.hpp new file mode 100644 index 0000000..88490d7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/for_each_product.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:172a9d24f7ee5808a20e5485480a129030d5b6bee82d5289eb44cf173c01fde5 +size 12551 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/insert.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/insert.hpp new file mode 100644 index 0000000..1a1d7d7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/insert.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60c29e829060f78f720018334df96605bcc496e060c341bedac192316d1331d0 +size 1247 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/pop_back.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/pop_back.hpp new file mode 100644 index 0000000..30c1aec --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/pop_back.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6af47cb86990a2d1d42a1a7bcf6175ada4a2afb942d4db7e0510b16592ba0d1e +size 1273 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/pop_front.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/pop_front.hpp new file mode 100644 index 0000000..f72ac35 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/pop_front.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7c673b1686f6d0442050df8a5927ec6b0d109f351fda397dcde1ef6c1526cc8 +size 1100 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/push_back.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/push_back.hpp new file mode 100644 index 0000000..ee1d6fe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/push_back.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c10b37174a5811e611604ff7f415d4c79dd857d4372701b8bb387fdeb52ccd80 +size 792 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/push_front.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/push_front.hpp new file mode 100644 index 0000000..7856a44 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/push_front.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:545207a806fc767ce6edc2730ac92728d40ee030ad53c5627761a1c17673a440 +size 796 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/remove.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/remove.hpp new file mode 100644 index 0000000..1840d61 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/remove.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ccd28415c5e6bf5bfdfc31fdc9a46d224ab21e72a737069e992158c20e4fd5fa +size 1287 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/replace.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/replace.hpp new file mode 100644 index 0000000..bba8a2a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/replace.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:162265104c66288349cfc3b2bd103f90a3f48661bd8dfc80625d70bc35825b38 +size 1939 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/rest_n.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/rest_n.hpp new file mode 100644 index 0000000..080dab5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/rest_n.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0fa4e27639e8df39d92ce6c65f37cb4574d43f8916815eb1720ecef1b8401b69 +size 1899 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/reverse.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/reverse.hpp new file mode 100644 index 0000000..fd19c70 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/reverse.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:370bd99ab632ddc02f0facda52847d5f1eec9313eeaca5b0ffdf2f561546e833 +size 1721 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/seq.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/seq.hpp new file mode 100644 index 0000000..0b2546c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/seq.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba79028a69388267015b938b93db07805a86c1ca2c464d98a82e7f451e1c769d +size 1672 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/size.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/size.hpp new file mode 100644 index 0000000..fa23c90 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/size.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:711aba9bb64805f14e9abf9d4e782bd1b00806ed34d246aeb2a0f2eca8d1f969 +size 29224 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/subseq.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/subseq.hpp new file mode 100644 index 0000000..056fa6c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/subseq.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:916f3fe5ab4b074ef25863847da507f9d497d19687f8444752dff91f1279f679 +size 1225 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/to_array.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/to_array.hpp new file mode 100644 index 0000000..cd32283 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/to_array.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b15f61f6438afd243b59aaffdb9f30a9386ad3f9951c5492d63b6b3f9af036c +size 1194 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/to_list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/to_list.hpp new file mode 100644 index 0000000..386451b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/to_list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:411b0d74233f3b6a966ab1fc7b3236042ee028cb554b70d51b89cd0b87bb0cd1 +size 1975 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/to_tuple.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/to_tuple.hpp new file mode 100644 index 0000000..e072e63 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/to_tuple.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8519493553d633eece8c926c8ad995ec787009e760015dc513b0ada17c3afdb1 +size 1098 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/transform.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/transform.hpp new file mode 100644 index 0000000..9e4ddc8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/transform.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f199d1587caf695066fda580272e9abafda15857f7b59b94eb3060c42ea2e2d +size 2613 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/variadic_seq_to_seq.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/variadic_seq_to_seq.hpp new file mode 100644 index 0000000..f6da1db --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/seq/variadic_seq_to_seq.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6bb24ae09763fcfb0eedd74af3e978109ea2728163317b1dae2fa94e0a608eeb +size 1366 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot.hpp new file mode 100644 index 0000000..9548e44 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1cbc25ee635761229612fe1698619917d25ceccece91623360b5eeb4cf303a6c +size 733 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/counter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/counter.hpp new file mode 100644 index 0000000..b3beed6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/counter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60f6d0de706e361a6d1e5c5c9c9131ff9f1858448412bad109b9cf388b8cc319 +size 1029 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/counter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/counter.hpp new file mode 100644 index 0000000..972d8a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/counter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3f53a53c6fc06d26fbc51c70cb411219cb46132e5843f9c6fa8fdc97d8659fa +size 10660 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/def.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/def.hpp new file mode 100644 index 0000000..40805a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/def.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c109e9e53e6178b751de694d1437080fce54bfda935d52a5e0aa3310a5b51afd +size 2847 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/shared.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/shared.hpp new file mode 100644 index 0000000..5a44fba --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/shared.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28a9ff40adda63bedf764b62b4ce8fe6eed29031fab658caa2ce3039686a69f7 +size 10480 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/slot1.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/slot1.hpp new file mode 100644 index 0000000..e05cfe9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/slot1.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b51fc5790969e80fcce783f2c4e5cdc991182b69936e0555c838ffa154e47507 +size 10347 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/slot2.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/slot2.hpp new file mode 100644 index 0000000..9b43c19 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/slot2.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0f04328bd22f053aa65baf27f47a412f91aa0fbab07251975f5a0a2038b7de5 +size 10347 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/slot3.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/slot3.hpp new file mode 100644 index 0000000..cbe83b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/slot3.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc9d8375c272cc96c18fc8f01ac1847f00e4213c319d04485fe312f3d46b2a87 +size 10347 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/slot4.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/slot4.hpp new file mode 100644 index 0000000..790d9fd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/slot4.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d79885339e6a5e44fb485e0599b340cf2715fc406c69e24ed0916140c02606e5 +size 10347 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/slot5.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/slot5.hpp new file mode 100644 index 0000000..ac14ab5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/detail/slot5.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0ada1797f1e49cdc79cb0d9bfeacc0216b991b3291b67a78a693427f4ac6d0a +size 10347 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/slot.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/slot.hpp new file mode 100644 index 0000000..15e6142 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/slot/slot.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6075b9fe90cb229106dd78239114539f0396115516406b21d010870aa29d319f +size 1356 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/stringize.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/stringize.hpp new file mode 100644 index 0000000..0ae14f4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/stringize.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9155f42a7f94edebce1e01e42017a9f60da632a097a8a5446ea97a619fc18ad0 +size 1111 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple.hpp new file mode 100644 index 0000000..22f5379 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c48d9bec12d7b419e2dce0695330ba2ae4c51a70acb0772e42d01a26950eabbb +size 1261 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/detail/is_single_return.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/detail/is_single_return.hpp new file mode 100644 index 0000000..485ac1e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/detail/is_single_return.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae4dec89d4dd30b8ebb2d096a6bceb8b1bb3afa2c10d14e20004bbf6c6edae81 +size 1375 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/eat.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/eat.hpp new file mode 100644 index 0000000..24de02f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/eat.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:27fae151cf9837c32b863fe719e77350d455674751d4a6693275a8c2bafaaf53 +size 13281 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/elem.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/elem.hpp new file mode 100644 index 0000000..b350cc3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/elem.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9572f35119257f84830c732f878efebd3ada2eaa3bba01e72978381831d2bcd +size 53223 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/enum.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/enum.hpp new file mode 100644 index 0000000..0c27392 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/enum.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95a6871db72c42d5ba8d2f8bab2a2135b49a654e73f62b64ffac00aaa167e056 +size 1011 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/insert.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/insert.hpp new file mode 100644 index 0000000..f4ebe35 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/insert.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86f4a7458de9a1f111578ecc113cc3caaa4930881bcf1177d409b0c19ae617ce +size 1368 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/pop_back.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/pop_back.hpp new file mode 100644 index 0000000..63b8348 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/pop_back.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be3beff5d19e2027654ebc1b07fbc1ae17719e38a35dff8f5d1ff7fe0b2bbd1e +size 2054 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/pop_front.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/pop_front.hpp new file mode 100644 index 0000000..e09d9bc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/pop_front.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2aa7e15d5c90f2e91a9b3c96def57fcfe124d33b5f8d84095c139a2951e32ffc +size 2074 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/push_back.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/push_back.hpp new file mode 100644 index 0000000..83ca634 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/push_back.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:615ba4093de86c739f9c41ac8562dc2328d41cabe7355806de1f29787414a5aa +size 1192 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/push_front.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/push_front.hpp new file mode 100644 index 0000000..b2e0a56 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/push_front.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07ca2c9b39ca1072b60db4647a6403418e1a74d0283faa9d4b864be52b60e85a +size 1201 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/rem.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/rem.hpp new file mode 100644 index 0000000..cc50003 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/rem.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f005494450a56b343b37864910df502a2d543b87662c6741bdf63a7a2eea415 +size 25426 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/remove.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/remove.hpp new file mode 100644 index 0000000..42129fb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/remove.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34d2c68799fc2f0ee907e82ad02863b894b4c41fcac568b7b4bfb8d94d956c1e +size 2054 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/replace.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/replace.hpp new file mode 100644 index 0000000..361655a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/replace.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1e960960b894a465f93662e7abd01ac98fdd1f0a1cc2ef2699843822fa0d24e +size 1378 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/reverse.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/reverse.hpp new file mode 100644 index 0000000..77595aa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/reverse.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2870815c77286fa48e46c2e6525ecaa1fa3eeb01fa993de58d6a46d037bd33e6 +size 24280 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/size.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/size.hpp new file mode 100644 index 0000000..d10a2b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/size.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef80d3cbd83cd96928e45753884d02fe08d3c5b0c2be3b16a13e3380f9e4efd9 +size 1264 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/to_array.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/to_array.hpp new file mode 100644 index 0000000..20a58ba --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/to_array.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a698b094a210ae3beb03eaae100ca935f6ad164001ae4398c7911586325f5a6b +size 1978 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/to_list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/to_list.hpp new file mode 100644 index 0000000..3cebec0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/to_list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4cd3a38bbb3d4828549cf7a3500514dbb3e4aad15c6cb5af3a1eec4f37731e2d +size 29210 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/to_seq.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/to_seq.hpp new file mode 100644 index 0000000..32884ce --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/tuple/to_seq.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81fe049b377c8cffa8d310a1308596ecc20ad4dbe886b397257622bba4d2f607 +size 24645 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic.hpp new file mode 100644 index 0000000..d8dca60 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc472eb1ec588c24eee3267641347dc4f80087aabf800072dee7d41b9f61385e +size 1184 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/detail/is_single_return.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/detail/is_single_return.hpp new file mode 100644 index 0000000..01824fc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/detail/is_single_return.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a48a669bd166a544473eabda659c27b406e4dea028f13c979adc100e05347d90 +size 1400 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/elem.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/elem.hpp new file mode 100644 index 0000000..3373dc5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/elem.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b9103e25c174351d3f77bbc4ef5f36251315fa8872b767c809a575f3d0d9c30 +size 14196 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/size.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/size.hpp new file mode 100644 index 0000000..031221e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/size.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59e23106482d86de5785d6df1fe6d5298311173e214577aeb6482ede15d20c32 +size 2133 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/to_array.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/to_array.hpp new file mode 100644 index 0000000..83d7bb5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/to_array.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b428ab56849e074c10dc623e9b94a0d74ec800b731b7e9c6da0e6cd97ad05d5 +size 1419 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/to_list.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/to_list.hpp new file mode 100644 index 0000000..02e2fb7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/to_list.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bde031fb9b90dc507be1ce49ea01d54f935ca424f4ccc1ee64fe37530fb752df +size 1142 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/to_seq.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/to_seq.hpp new file mode 100644 index 0000000..6001362 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/to_seq.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b55f08055b6d35a6ca84f31dbb8890ac5cc92516428d13e3e945e53aa045393f +size 1136 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/to_tuple.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/to_tuple.hpp new file mode 100644 index 0000000..ef6a8c4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/variadic/to_tuple.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ddb149010befbb7e2563ddf9b403464080058887ef1ca82cb56ef6267159eff0 +size 1073 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/while.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/while.hpp new file mode 100644 index 0000000..435d316 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/while.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f122472259876404d1a5214c333b077ddf131797b0b712797ec94cf0f7d15a1 +size 739 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/wstringize.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/wstringize.hpp new file mode 100644 index 0000000..12958c4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/preprocessor/wstringize.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:019c772f9874140596a6f64a644cbada585a5bbe830539d77a9730c795b2a78d +size 1279 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/ref.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/ref.hpp new file mode 100644 index 0000000..fcb92aa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/ref.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49a206a271741704a834bd014312e4cf2e68586c1e35ec33a529e3d9d681386d +size 370 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex.h b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex.h new file mode 100644 index 0000000..d91e435 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9050c161b7a0f0bf9ae3a21e66218ea9ddb57deeb7202f0ae8cb313189e57611 +size 2174 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex.hpp new file mode 100644 index 0000000..7c8db11 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75b7a8d127f5f78426eed6902dd980fc37decf3ae958460c87baf82de11fdc7d +size 823 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/concepts.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/concepts.hpp new file mode 100644 index 0000000..40e49a5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/concepts.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad8da343310b406b3ce1a7ad7dbb928eccd580edab85430540f327fbf7b7608d +size 44854 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/config.hpp new file mode 100644 index 0000000..2cce10a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a14daa1b6a0be650272bbbeb6221a99ecb0b3520d4ec99dbfff2c1fb9236e7b +size 14292 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/config/borland.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/config/borland.hpp new file mode 100644 index 0000000..a8d86b0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/config/borland.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c15d7c5beac4bc7426cbb12edf1ab7ae8ad61aabed9470231f04fe139ba3bd7a +size 2238 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/config/cwchar.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/config/cwchar.hpp new file mode 100644 index 0000000..cc4088d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/config/cwchar.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ad615c3e4aeab471e0a9c9bc3e649f0d1962fdc73459bd19b46b54a7614ed83 +size 4082 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/icu.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/icu.hpp new file mode 100644 index 0000000..d57bca1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/icu.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:36400093329698d905d95888eed97c29060031d2bb6569c433a3547ea9e56a21 +size 41535 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/mfc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/mfc.hpp new file mode 100644 index 0000000..4adbcca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/mfc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10282d24d23327762f5d51cc8403c7caa200e7261d7335d2fa37f2be583c7753 +size 6559 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/pattern_except.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/pattern_except.hpp new file mode 100644 index 0000000..df30fe0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/pattern_except.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:405b2d3d38d522ac0c6897b99621838f4a78669ce5c4e7ce9a982402aedc3bf8 +size 2222 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/pending/object_cache.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/pending/object_cache.hpp new file mode 100644 index 0000000..5d30995 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/pending/object_cache.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:493c9f9d4482809f9b821889219d2b1ca2a11436e586b202ee0c42113a85425c +size 5252 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/pending/static_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/pending/static_mutex.hpp new file mode 100644 index 0000000..ed18a6a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/pending/static_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f3e47d7b7ffa35a6ab419a7ea2faf1bfe78b22ca312fd9b92da986a6e5e0059 +size 4328 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/pending/unicode_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/pending/unicode_iterator.hpp new file mode 100644 index 0000000..2cdb63d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/pending/unicode_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3adae4f631d7644f4c709453d35a973d6c4258894d0082b50187e5df17cbbdd4 +size 23785 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/regex_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/regex_traits.hpp new file mode 100644 index 0000000..3c68705 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/regex_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6474019a283f6212760c67f580c2e07c428dd9bcf5f64564bb99e371d01cb60c +size 733 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/user.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/user.hpp new file mode 100644 index 0000000..9c5dca9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/user.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae58d10b33039c2bf40c07fdb0f01aeb3983aede2eb1117536aa91d1d06f6001 +size 3242 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/basic_regex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/basic_regex.hpp new file mode 100644 index 0000000..ae63875 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/basic_regex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7de578dfbdc5b21f09f36d0e14442569ccd7ec632a6e3edbd480c1151f846db4 +size 23416 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/basic_regex_creator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/basic_regex_creator.hpp new file mode 100644 index 0000000..19eb394 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/basic_regex_creator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd542529ed3f53521b3f3ac0b5645f54c215318c2a4e69001d685dce3016360a +size 53533 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/basic_regex_parser.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/basic_regex_parser.hpp new file mode 100644 index 0000000..5914f9d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/basic_regex_parser.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:981f2e46be41205603ade8a177310666ef33821e6552aca4ed8aa4f38c7c8dad +size 112642 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/c_regex_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/c_regex_traits.hpp new file mode 100644 index 0000000..a7e507f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/c_regex_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05ff2ac8375947f29b7ddb6020e23a7127885a70b27061ca8454bb98bb7f9bf0 +size 5497 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/char_regex_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/char_regex_traits.hpp new file mode 100644 index 0000000..310d3a3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/char_regex_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa323f02d1fccf04bb99fc365156b981e06be55a735136e631668ddc92fd3ae2 +size 1726 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/cpp_regex_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/cpp_regex_traits.hpp new file mode 100644 index 0000000..4f62499 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/cpp_regex_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e497f916c75888791a6b3f0ee191175d3732bb4229db4700349d23460ea324c +size 39413 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/cregex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/cregex.hpp new file mode 100644 index 0000000..fd44771 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/cregex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9f584d9f385705ca5f236824974268a1db0ab259a7936c73e1b6297e0b6bc369 +size 10985 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/error_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/error_type.hpp new file mode 100644 index 0000000..de5a126 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/error_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ffc86ea881ebb1a0ee8c036af55954a7f2f0c2b9570b9e95dc3dde641e9f4df +size 1258 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/fileiter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/fileiter.hpp new file mode 100644 index 0000000..55c2ba8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/fileiter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c2ff1636bc00e18cec26a6b8598bbd7ef49e74c0e6301dfd34dd325fe5175cf7 +size 11225 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/instances.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/instances.hpp new file mode 100644 index 0000000..258cac3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/instances.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d77295e29b9c3fc24ca8dbcf19ea09dcb6bfe7ef10eb62857445d9dc6c1f61a +size 9076 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/iterator_category.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/iterator_category.hpp new file mode 100644 index 0000000..52a4352 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/iterator_category.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48bda4c4b31d0d7a272d17bb2cdb2dc4cdf3d17275cb6fa552f619e0fe9327fc +size 1960 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/iterator_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/iterator_traits.hpp new file mode 100644 index 0000000..61600ca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/iterator_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44089715261470ab0ff55b9fd9a7e598ff4245f4462ef766eec84984f7a82d37 +size 3802 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/match_flags.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/match_flags.hpp new file mode 100644 index 0000000..b5c75a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/match_flags.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb3822e747facee090b8a4489f6d587bc2d05ed24ce5fea1676d4f1f8c2e7c57 +size 6773 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/match_results.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/match_results.hpp new file mode 100644 index 0000000..789d566 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/match_results.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f13696bc8ed1eaab483827cb419fd2710c251d919a079f5dc1f71566b56c5c32 +size 22754 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/mem_block_cache.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/mem_block_cache.hpp new file mode 100644 index 0000000..ac54880 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/mem_block_cache.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97404c9b09862d1724fefdd7844a4579ca07e3d2dae645285c96fcd4195a0dd3 +size 3132 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/perl_matcher.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/perl_matcher.hpp new file mode 100644 index 0000000..faaeb52 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/perl_matcher.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab9349ebc14710ced50e03904e476a3d8ce5f6658e0bb6ff1b7916a53b52714c +size 18626 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/perl_matcher_common.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/perl_matcher_common.hpp new file mode 100644 index 0000000..d9f85eb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/perl_matcher_common.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:852c6f611a9aacb9e90e61b0204b57eb4ce1fc1d3dde79b7679301043f8edccb +size 30249 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/perl_matcher_non_recursive.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/perl_matcher_non_recursive.hpp new file mode 100644 index 0000000..30e01de --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/perl_matcher_non_recursive.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a694228a7b47fc7b428a21b5c871f9029609e179d3525a1880191048feef0710 +size 63225 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/perl_matcher_recursive.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/perl_matcher_recursive.hpp new file mode 100644 index 0000000..ff5680d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/perl_matcher_recursive.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d3d556305a08f6d317f847ba7c74ffa2c309edb959e631cf862c33697082ecc +size 34528 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/primary_transform.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/primary_transform.hpp new file mode 100644 index 0000000..d1b6c43 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/primary_transform.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c873c8b6b21256fee6818310763646fa68520cc6801a4bf1443acdd988b0ba84 +size 3347 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/protected_call.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/protected_call.hpp new file mode 100644 index 0000000..711aed8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/protected_call.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:beb39370b5c7e8beab8354c2996013c6fa3dfe808fc6be84753e19d9e70eb9f3 +size 1688 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regbase.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regbase.hpp new file mode 100644 index 0000000..cdefe1f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regbase.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:253bc5cc3d5eef86b67784619668163fc9b9d26efaf44a35a8b6e0d62aaae3c7 +size 5972 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex.hpp new file mode 100644 index 0000000..a12c1ce --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:153f995f1fbc1525fdb8134ed98a525873c95d4e37d88d91b6bcf7056f76a5ae +size 4590 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_format.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_format.hpp new file mode 100644 index 0000000..7029ae3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_format.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6808ed7b0e66b806983965f4201fa99a4971130e3aa8ed86d089d762f89360d8 +size 34103 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_fwd.hpp new file mode 100644 index 0000000..64fdcb6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7bf794daf8924de2694a3c764a2fe87689d2c6f51d267fa0f254a93874338532 +size 1646 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_grep.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_grep.hpp new file mode 100644 index 0000000..207ba8d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_grep.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7255dc6076ef676a8f1b5aa804a940bc834e82f49c15f0d19ad10184e5d2af14 +size 4879 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_iterator.hpp new file mode 100644 index 0000000..f7da6d5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d6225007799720a13ca4bde9e3930670988adc68ed71e1b49733ddf6899ec99 +size 6303 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_match.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_match.hpp new file mode 100644 index 0000000..6c5a3d2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_match.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1483aba7a319ef50f2709616e4015fc815b06c61fa924b5a504b3ff9c21dfcd0 +size 14475 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_merge.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_merge.hpp new file mode 100644 index 0000000..ecd31a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_merge.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e02e13b47459a1092c530d399ea047f4ae7bb1fe78e7f1beb3800dbaa9a6cd1 +size 2765 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_raw_buffer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_raw_buffer.hpp new file mode 100644 index 0000000..e867bd8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_raw_buffer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc12050498255a8a0eb3e8d4fa7036b3ed45e71d65afba17ea8281c3103d8004 +size 3686 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_replace.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_replace.hpp new file mode 100644 index 0000000..e78da66 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_replace.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0777192ecb9759436eef8b516f570d41a49aad8773b505dae850bfc4e6c8f319 +size 2925 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_search.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_search.hpp new file mode 100644 index 0000000..fa5621c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_search.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd1633d8b20623a692cbb84ece0bb41af23ac71d98fcf2f99093981f08455dbb +size 7097 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_split.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_split.hpp new file mode 100644 index 0000000..ba3293f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_split.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0dd48ef3ce83f0002bd7bfdfabc49651e45a42ddbdab67c3114c59f0cdb6c188 +size 4956 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_token_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_token_iterator.hpp new file mode 100644 index 0000000..b9083e2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_token_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67a197e3788f0e5b5fd85a167640690e5ef1f74be0d1756644092ab81f258b32 +size 12577 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_traits.hpp new file mode 100644 index 0000000..9599fb6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6b0775fc7e3827a92136aadd86446f0b8abc5bf0f5bcd10f29e813359517039 +size 4963 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_traits_defaults.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_traits_defaults.hpp new file mode 100644 index 0000000..072b3c6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_traits_defaults.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4bd73f13b55dd44e6ad2e6504bcc69541a5223e7b29784ec0fbefffba90210b6 +size 11568 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_workaround.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_workaround.hpp new file mode 100644 index 0000000..88d0d96 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/regex_workaround.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9cc5aad6c6518b05c759fb1b5d980b76e34e1658d0da31e2c3062b4ea14ab52a +size 6171 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/states.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/states.hpp new file mode 100644 index 0000000..64d3459 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/states.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f156797c0b009fcd25bf2d08ee5383dbee91fa62b5c20000f6c56cb89294b9e +size 11915 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/sub_match.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/sub_match.hpp new file mode 100644 index 0000000..0a5f60e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/sub_match.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e15999f2cc6345d4713c64d2dfb06155867f3cdc8aca9320e87a9b6b63de3894 +size 23153 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/syntax_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/syntax_type.hpp new file mode 100644 index 0000000..47f22d5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/syntax_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77b480dc539e79d0f77f2eea7ac5846650fe3b1d6670480fb2eb9c7e15d66c73 +size 4374 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/u32regex_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/u32regex_iterator.hpp new file mode 100644 index 0000000..bb66fc6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/u32regex_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d574316e733ae3205f1d6351c6ef6db463bcef757ae67d3c81adeeab8c5a49fa +size 6475 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/u32regex_token_iterator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/u32regex_token_iterator.hpp new file mode 100644 index 0000000..09b1f57 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/u32regex_token_iterator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e0a67641a13d39674a393f1f11f85236db757302578cadbfb23f8c31b780a860 +size 15064 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/w32_regex_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/w32_regex_traits.hpp new file mode 100644 index 0000000..ddef1ac --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex/v4/w32_regex_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e40d28f1ae12d87f423431550dacfee12b85510ecbda3093f0a8fdabfd10db0 +size 24437 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex_fwd.hpp new file mode 100644 index 0000000..89f2fa3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/regex_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e2a974f83614a8e48e04f2c468807467fc61fbe5b6a1470dbf0e99b4a433ba54 +size 693 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/shared_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/shared_ptr.hpp new file mode 100644 index 0000000..0d33b97 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/shared_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4a23223765c62c12e19cb1fe37d07d924735e0bce5ecef54ef03a9ebdd45c71 +size 525 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr.hpp new file mode 100644 index 0000000..64a7fb2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3081bbc99db3f8984c8f1f32b0206b83a07ac094073d45769d509f606df3cc12 +size 780 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/allocate_local_shared_array.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/allocate_local_shared_array.hpp new file mode 100644 index 0000000..59b1ff6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/allocate_local_shared_array.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aee208b887ecfa54fa0ad70f3a31593e3ee663d0608b9dfba96476109321496d +size 7960 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/allocate_shared_array.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/allocate_shared_array.hpp new file mode 100644 index 0000000..9b5c913 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/allocate_shared_array.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7286d6767db1ce95e636bc60612e1424260b028f2d9bb001a49dd913f4acf767 +size 17870 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/atomic_shared_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/atomic_shared_ptr.hpp new file mode 100644 index 0000000..507aec5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/atomic_shared_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:718bda057c31f33d76bd5e5dd8da5dc32adc5fd1e455c6d42911320af92486d7 +size 5681 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/bad_weak_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/bad_weak_ptr.hpp new file mode 100644 index 0000000..631e37f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/bad_weak_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1601a50142ca359791d1a9b7dcfca4fe88ef1aa2b41eec91dbabfc73feedb5c1 +size 1707 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count.hpp new file mode 100644 index 0000000..48196db --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3ca769a3261d7bda2df7153e0f48140104100231adacc7b27a057dc3ec042b6 +size 3041 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_gcc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_gcc.hpp new file mode 100644 index 0000000..c07e3e1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_gcc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9500e28df1d01bf3a62174c398207717d1cf8b3805654418e98851c823a09d2 +size 1473 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp new file mode 100644 index 0000000..c9e6a11 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b53a0cb9c643d297aec4cdb3839b84d72bda47a5fee298418e694ed5ebaab3ca +size 1519 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_nt.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_nt.hpp new file mode 100644 index 0000000..8052a61 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_nt.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a7ba5e790e715bdd4ec3fdadad5860c8608ec064541e82c79348e8cde4f981ce +size 1032 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_pt.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_pt.hpp new file mode 100644 index 0000000..795256d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_pt.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:31a83e6bd26ffb247e671401243cd2bf8b10d58cabbae3efeea9ba6dd53dd51a +size 1906 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_solaris.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_solaris.hpp new file mode 100644 index 0000000..d0ad2c6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_solaris.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba0efbe83659e941c9eb2223cd9b4c9f013b3fe47fc1849999f3e9de56fea758 +size 1157 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_spin.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_spin.hpp new file mode 100644 index 0000000..2193595 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_spin.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8e19e7989234c801cb6450b389ce36696b66f3194898e2a433a82babe8533ea +size 1151 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_std_atomic.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_std_atomic.hpp new file mode 100644 index 0000000..7730085 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_std_atomic.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:062f542cdaa5a8ce114555d57f3614f21a482e2d3cbff054e77c2317d9058a8b +size 1160 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_sync.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_sync.hpp new file mode 100644 index 0000000..83aa783 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_sync.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a9de5425067b88e0469f8b17222f341dff4621c1a1289fe5b946a42b5f33721 +size 1195 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_win32.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_win32.hpp new file mode 100644 index 0000000..ab91a0c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/atomic_count_win32.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbfb88deda246c4460d193563e06140caa61ddd84fb0e5c15947e87cfb5d2371 +size 1208 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/lightweight_mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/lightweight_mutex.hpp new file mode 100644 index 0000000..fe70c50 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/lightweight_mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:706069ff38c6d9dc0b5462b9ab21e7b4fd6b52c402f7e01c84faa1d2ff173f9b +size 1425 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/local_counted_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/local_counted_base.hpp new file mode 100644 index 0000000..8b2084c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/local_counted_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:24ea592db76d420ec950b2a45b2e44b32be3c05cae1ac02ec6670f722eb566df +size 3153 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/local_sp_deleter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/local_sp_deleter.hpp new file mode 100644 index 0000000..fbeefd9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/local_sp_deleter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b376d416be817160ac86df7a40e61327dedc2f2156bd84065539d6c6d3624b23 +size 1677 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/lwm_nop.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/lwm_nop.hpp new file mode 100644 index 0000000..a28e13d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/lwm_nop.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e88b3aece69bcfff89ca2db89b40571b7fb08f2848dda77bdb33acb3052f4ed7 +size 702 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/lwm_pthreads.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/lwm_pthreads.hpp new file mode 100644 index 0000000..e84b0df --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/lwm_pthreads.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39d96481855a03ae5371207be2528b18c090b28cb09b19060cd0afea41083298 +size 1753 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/lwm_win32_cs.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/lwm_win32_cs.hpp new file mode 100644 index 0000000..cfe5241 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/lwm_win32_cs.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77f225b3e7d9334b418925eccaafce94001b42d340fcc4ac512a8c5bf98ce7a4 +size 3281 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/operator_bool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/operator_bool.hpp new file mode 100644 index 0000000..c4de196 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/operator_bool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b128b7a53a79c38dc568b589d60bdabfd6998e0e085498aa8d8e77ecb3cc1cef +size 1731 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/quick_allocator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/quick_allocator.hpp new file mode 100644 index 0000000..b76f49d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/quick_allocator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:70c1eca92a89a5c898d59aa3b4d6966a0a37fc01c0e97fa7fba7eb55c2607a83 +size 5137 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/shared_count.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/shared_count.hpp new file mode 100644 index 0000000..40d21d5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/shared_count.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b5475e42563aa1ebd9067c5fbde7cecfe1005b777a3ccb88f851e8c8b7b74e9 +size 14141 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_convertible.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_convertible.hpp new file mode 100644 index 0000000..918af92 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_convertible.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:508477b4d745355008594bad136a0fcc735f6ce6e9ba81573babc3989ca10064 +size 2153 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base.hpp new file mode 100644 index 0000000..63d1113 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:460971bb769fb4636bac082f8390669f149a59d0cd537c0fdcc6e6d3013c1354 +size 3494 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp new file mode 100644 index 0000000..d32a8a2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:efdd6563330cf939e97c79d9fd353eb2463839f2de3dec03718ba326dfa7fb94 +size 3251 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp new file mode 100644 index 0000000..8053866 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fdcedca5ed41fa6d9c64e5dfb4e24d26bec5d1f68020bb1939bffdc2dc46c800 +size 3110 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_clang.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_clang.hpp new file mode 100644 index 0000000..1a20acf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_clang.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5043622e85491bb81986a5ab5ee17d54577be6ae2029c63c67248499466ad847 +size 3436 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp new file mode 100644 index 0000000..f4264d8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07adfcb87df3bce1404370a662c2f127592105dd81aec61f570b8a3a42abacba +size 3179 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp new file mode 100644 index 0000000..dc596a2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3693ce419abfa4748bfee3973360d7901656e115a739bacbbd45b033286e6d2 +size 3293 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp new file mode 100644 index 0000000..6ba3a51 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3bd35e22475f7040385e1ed80b43f1f9dd0efb8c9ddaa95000018caae77c322 +size 3774 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp new file mode 100644 index 0000000..2cd74ca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc58f4c838e66d098636741e0adc6942c2b46e5512823104e4cecfd7607d1d68 +size 3861 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp new file mode 100644 index 0000000..3fcb8c8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bac010145a5817920e04108536ee6b57a2f4db1db19fcc93c1e30cd4de4a8439 +size 3638 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp new file mode 100644 index 0000000..8b8e40d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42756e1cbdd3cd882a9004bc30d95755b7f4877880e40871d73e2dad5144810a +size 3613 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp new file mode 100644 index 0000000..67723c1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f755420f41271f8ac362decc28d317c41ed3091646c0ba0a92ef9f0b04242e0b +size 3701 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp new file mode 100644 index 0000000..55acfa1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73ee572d7e9d9ebc0ea2a6cb1b5bd3d04b841b9c033cbbc191cf1be1e35057fc +size 2255 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp new file mode 100644 index 0000000..97fb318 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3fb663ed7364253a728a6bb793acfb3172798b30834530943bd72889cdf7c2e6 +size 3447 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp new file mode 100644 index 0000000..4a0f134 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be071398671c312da28d123c23e866d11bd274c2b7f66ac0c23e4ad82c7f0ae3 +size 3551 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp new file mode 100644 index 0000000..03ad812 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9f25839e980fc42209a2a4dd4ee3d50c19783ec7651df1b4100649d11b77f1e8 +size 2676 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp new file mode 100644 index 0000000..5dc5a4b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e0d165243c8985b485bc2d4ea1e1b5f53a7484b64c66f404aca5954c93a4cd42 +size 2902 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp new file mode 100644 index 0000000..dbd01eb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd56f512318d16cfeced670c239c316712a40979db9bc2a311209d029d765198 +size 3124 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp new file mode 100644 index 0000000..041cb6c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9fe75ead522dbbbbeab4d54651d557cb8e61141442a014cb8bac5e5dcb32127a +size 3163 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp new file mode 100644 index 0000000..2036728 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97cd2ba0dbfce6af17f7fa009240a007181c9c772de637ad3722501a66e12570 +size 3458 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp new file mode 100644 index 0000000..a918a0e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ffcc367bdf8ac85429082d0d3d978e041d8b255791745879d4aaf18e8b7a8e6f +size 3102 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_impl.hpp new file mode 100644 index 0000000..709a6a7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_counted_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56c6abe414bd45b49591068126b9fca97d7afd7b849211753db082f2b3ff825a +size 6455 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_disable_deprecated.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_disable_deprecated.hpp new file mode 100644 index 0000000..fcb7228 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_disable_deprecated.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99892f31f173d1de78e5af7d9e2231e16c307ee8f93d0ada22cbc4f5d67801df +size 983 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_forward.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_forward.hpp new file mode 100644 index 0000000..e285caa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_forward.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:63e440d963541fcdb89b37f651508868656ecab7c265db7fc2224f27dc1a3eb7 +size 1180 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_has_sync.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_has_sync.hpp new file mode 100644 index 0000000..1b67bab --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_has_sync.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75da457cdc7c72a87328cb4a2b01d73d5d0af295509ab74b6a22531659de8136 +size 1605 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_interlocked.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_interlocked.hpp new file mode 100644 index 0000000..c0d2ac7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_interlocked.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b22e910b8381e7306eed7741da1a03b0b5f31ef789cb1acfe20cd1ff82fd326 +size 6567 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_noexcept.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_noexcept.hpp new file mode 100644 index 0000000..c152f8b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_noexcept.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac5afbfab96f459b1431f3b610a7bbbdae741efc3adbed0e1a0656c6a13488e4 +size 1185 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_nullptr_t.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_nullptr_t.hpp new file mode 100644 index 0000000..2473a2e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/sp_nullptr_t.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2dd97f75b2c1487171adc58855f41f5e5a0b0534a0e8e7603af72ba8c0eb6e52 +size 976 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock.hpp new file mode 100644 index 0000000..9e250d7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86a13976eb3d0a28257be0ba91e5f3b7a3ca00b1661b92c6be38c8e49a9b61fa +size 1909 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp new file mode 100644 index 0000000..200ced3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7c4fff3a9f0fc6e43f89affedf49d529f21ba7eaf336b7358abe5fc017ce5e7 +size 2557 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_nt.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_nt.hpp new file mode 100644 index 0000000..5da8752 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_nt.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a9ca59229aa06500e9821b614c790d15251e31ed66666064e14b786ccf84649 +size 1464 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_pool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_pool.hpp new file mode 100644 index 0000000..3a3efd6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_pool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:151ab5dd84fb410f0182afab573771bed459ed24147caf3ebfa2cf39b550ccb3 +size 2954 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_pt.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_pt.hpp new file mode 100644 index 0000000..b02bb81 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_pt.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e44a85dd82a286278ce691be41a73e44142878712a0b335b39405e5d1e1f298 +size 1314 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_std_atomic.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_std_atomic.hpp new file mode 100644 index 0000000..ce10adc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_std_atomic.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3080e6c0276b9701777d05e831bb008364a079d6a08438920baa3366668ec4b6 +size 1468 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_sync.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_sync.hpp new file mode 100644 index 0000000..f4ad5e7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_sync.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd585f2fcbd6b9a42edff63174a33bb1b453027aa64c0e81800c53ac40b4b8c6 +size 1491 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_w32.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_w32.hpp new file mode 100644 index 0000000..758c7c7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/spinlock_w32.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4446e0321c3ebf34c7c7b94f4a3424fbc9810d89fd419c050b63b13f2663c1cf +size 1962 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/yield_k.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/yield_k.hpp new file mode 100644 index 0000000..e28cbb7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/detail/yield_k.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f281adc425c20a98d8eaf7abc3bab43cdb82f532dd90186156a7be7faedbabe3 +size 3304 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/enable_shared_from_raw.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/enable_shared_from_raw.hpp new file mode 100644 index 0000000..1d69e61 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/enable_shared_from_raw.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73161035e0726e4ae9a25d3c3deee552f0604e28b0a394a94714603ffbb76603 +size 4517 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/enable_shared_from_this.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/enable_shared_from_this.hpp new file mode 100644 index 0000000..ee05c17 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/enable_shared_from_this.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:35f4bc2853c9c24d81c4d1d2538e783a73fb292ccf9acda82806dd9585fc52cf +size 2175 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/intrusive_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/intrusive_ptr.hpp new file mode 100644 index 0000000..24840b2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/intrusive_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e8dbf0df44819a7c16876f0af74f634483b3cfe6e76c76d6418354f2739c35bd +size 8347 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/intrusive_ref_counter.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/intrusive_ref_counter.hpp new file mode 100644 index 0000000..5cec3eb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/intrusive_ref_counter.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f8d9b4e62c70d83a28513d49fb3aaba8c445641b0a38f8e33d713add8f3501e3 +size 5817 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/local_shared_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/local_shared_ptr.hpp new file mode 100644 index 0000000..5e39098 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/local_shared_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a7887504b4d1d57764f8da55780ab815e8a7aa6e5834594f7470b8009b459f87 +size 18800 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_local_shared.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_local_shared.hpp new file mode 100644 index 0000000..24d3b8a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_local_shared.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c16c0ee7cff40a3e9b0f9a6eeff0006142024c46bf1eef2685348aba5d2cd1ac +size 576 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_local_shared_array.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_local_shared_array.hpp new file mode 100644 index 0000000..260d699 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_local_shared_array.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ec4209e46f9907a15f951fc839737eb88d12fc6b4411b1235a74e9a7875406f +size 1833 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_local_shared_object.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_local_shared_object.hpp new file mode 100644 index 0000000..6b50203 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_local_shared_object.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7d4ca19262a94a7ccfdda7b53211390af63fb8263fca85d143be8faa9283223 +size 4629 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_shared.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_shared.hpp new file mode 100644 index 0000000..a038392 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_shared.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff5adf6ba04373a6aaefb0c2af601f8eac2ad4c5e4330ee4b5349c276e515d52 +size 707 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_shared_array.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_shared_array.hpp new file mode 100644 index 0000000..21dca82 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_shared_array.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd5045e09e85281aec105e6f00c1e9313774944968a46017505525876ddaa90e +size 1715 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_shared_object.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_shared_object.hpp new file mode 100644 index 0000000..a1240f9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_shared_object.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:36ee2444e84f9d7aca2bb70752a62989f029c3d763b0092ef9173c602c13223e +size 24618 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_unique.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_unique.hpp new file mode 100644 index 0000000..af677a9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/make_unique.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f4304977dc2590e7a4147e1f14dcdaeff5a3bf3bee127d4c0af33c62bc7b64f +size 2103 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/owner_less.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/owner_less.hpp new file mode 100644 index 0000000..39ab2a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/owner_less.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ab6f311bc56a5bc1ff7cc1de21b45bdc05db942673a8b58ca94bfb0c08da344 +size 809 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/scoped_array.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/scoped_array.hpp new file mode 100644 index 0000000..625c70f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/scoped_array.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb2e656079efc11f342b067b829912e0995019b9608c7d95ab6ec84fda19cb7e +size 3301 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/scoped_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/scoped_ptr.hpp new file mode 100644 index 0000000..d6b9c48 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/scoped_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75c131252384b08dae1447bf37eeab27c152c0a0ece4d42b198249b06d10fc6b +size 4082 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/shared_array.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/shared_array.hpp new file mode 100644 index 0000000..a51befa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/shared_array.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56d21db2a7a79f319bc5cb74a950c3707b569d1c48ca696d8180f2e2acce19b2 +size 7250 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/shared_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/shared_ptr.hpp new file mode 100644 index 0000000..0a57f7b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/shared_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92c1999a29e2bd2208cc8562ac8c9ae579e9ff10ff7580855dbcd564906890d2 +size 30462 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/weak_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/weak_ptr.hpp new file mode 100644 index 0000000..e7a486c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/smart_ptr/weak_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6de130321915716fc59520123d69327b13705580459095eb36860c34d307a82 +size 5987 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/static_assert.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/static_assert.hpp new file mode 100644 index 0000000..530db74 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/static_assert.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52fb9e1150bfb923716ee72dd5add5045a2a56ee100487d0b42f80746e6ed49a +size 7243 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/swap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/swap.hpp new file mode 100644 index 0000000..becfd9a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/swap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78f53231db6d94208b9cdc388659d7dec9576f7a55f43957c69c0b2d2090e106 +size 374 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/api_config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/api_config.hpp new file mode 100644 index 0000000..73ab17b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/api_config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa6ad663585b883f33bf73f4e181a69fab2b7d2aaf19cc062d9f240c3040e0e4 +size 1832 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/config.hpp new file mode 100644 index 0000000..1ed0aed --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb7bf37b73356d4b796d8569173af1f394244d8fe6805e15b7aa16db8448e6e0 +size 1771 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/cygwin_error.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/cygwin_error.hpp new file mode 100644 index 0000000..16f25b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/cygwin_error.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77c019881d71c69692c6536b9487dee9122d00e3ac62dcfe6ae0775fe0e129a0 +size 1552 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/detail/config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/detail/config.hpp new file mode 100644 index 0000000..87bb578 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/detail/config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e0fd47115f577879a684f1afb3670a97495995e664cc1c2d292cda14098507d +size 1466 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/detail/generic_category.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/detail/generic_category.hpp new file mode 100644 index 0000000..d9e8477 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/detail/generic_category.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:35e50c753861f80eb8ef94e4d6548a0657329dcb7f9b55fea7d60c8bc8471513 +size 2200 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/detail/std_interoperability.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/detail/std_interoperability.hpp new file mode 100644 index 0000000..77987d5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/detail/std_interoperability.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d79c1b66a980ed588fa12037de1f4229d043769593ece4ae54159c52fe51857c +size 3707 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/detail/system_category_posix.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/detail/system_category_posix.hpp new file mode 100644 index 0000000..9b10ee3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/detail/system_category_posix.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f047811eab148feef20342a5614b85211abfd154ada441fa65abc8f4f9077814 +size 3200 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/detail/system_category_win32.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/detail/system_category_win32.hpp new file mode 100644 index 0000000..0e731c2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/detail/system_category_win32.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a44a7612eb7e787e841d5cb43f8110af5bfc7349edb2dda21158a2bb7756a5e +size 11422 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/error_code.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/error_code.hpp new file mode 100644 index 0000000..78ab61a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/error_code.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1ab7aeb2379a6435493e1e9498d99290ceffe23d555d301286b4fe10aafd3e3 +size 25483 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/linux_error.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/linux_error.hpp new file mode 100644 index 0000000..dd21180 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/linux_error.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48af768d6ca5a232a6aa65ec87b08fd6623d887900416cd7f7a7eb72d50200e2 +size 3415 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/system_error.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/system_error.hpp new file mode 100644 index 0000000..8e7e4eb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/system_error.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db1addf319105eb125aadbaca29fa325deb8d1bfb793cf4bd4760bda052419c6 +size 2630 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/windows_error.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/windows_error.hpp new file mode 100644 index 0000000..a3ee6d5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/system/windows_error.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b23b2421973448bb124b4aa202d4b20f48a1843c49449071a177096055d9f8bf +size 4930 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/throw_exception.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/throw_exception.hpp new file mode 100644 index 0000000..da61549 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/throw_exception.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0434f7e4f4ab54cfef6f50b7df0d735188e839f1cc6fa8c80b30da97a1db2cc +size 2994 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/tuple/detail/tuple_basic.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/tuple/detail/tuple_basic.hpp new file mode 100644 index 0000000..857f6d7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/tuple/detail/tuple_basic.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0edeb48bdd9ac3b10cc9c78cae6bf0b4027a941623b036582ca41bdc453a04d5 +size 32332 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/tuple/tuple.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/tuple/tuple.hpp new file mode 100644 index 0000000..6718932 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/tuple/tuple.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e6098f93fcec9b605d5c12e252c719acf28f23b00cc4803ef43e1d7782015095 +size 1946 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/tuple/tuple_comparison.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/tuple/tuple_comparison.hpp new file mode 100644 index 0000000..e614171 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/tuple/tuple_comparison.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e6cd6837eea28cb3214dd1c3da0af6170cf8cd39e21a45e626942b86068d0caf +size 5578 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/tuple/tuple_io.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/tuple/tuple_io.hpp new file mode 100644 index 0000000..faef095 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/tuple/tuple_io.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b76f74a3793489c9ee24440bbcd84ecfaeb698c5e2d318970a8304c2db076436 +size 9030 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type.hpp new file mode 100644 index 0000000..8d18af4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c4b3b417c1c11424334d738032aa405b6d514fb97eddc92b166bba22c9fd16c +size 481 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits.hpp new file mode 100644 index 0000000..1d9b2be --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:963988949b24c3edb1304bf888d1bf08f3fa8329f6ba04f3ff13131bf4fc2037 +size 7051 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_const.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_const.hpp new file mode 100644 index 0000000..5771f1c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_const.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e0097bd4b39041632548f9f7951edcfb229b908969120972560123366f3a114a +size 1439 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_cv.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_cv.hpp new file mode 100644 index 0000000..188e8a8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_cv.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1154473b47a9759875fcad90a66169783eef336226017c3a9f3b496a4331de3 +size 1399 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_lvalue_reference.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_lvalue_reference.hpp new file mode 100644 index 0000000..0f3e33c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_lvalue_reference.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1392be5d4821be7826c6cbce8658bfb8626a30f09d8a9a2480b31a7e23a6c40c +size 768 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_pointer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_pointer.hpp new file mode 100644 index 0000000..07dfd5d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_pointer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e679679dd0a54beba402a01d5784f8fcf11463b19c522eace9066925d759f45 +size 1501 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_reference.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_reference.hpp new file mode 100644 index 0000000..a979c52 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_reference.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f290cfa21db9b4a74cb034e1ba9acaf7fc1cc41697d9c374938306bdd411d579 +size 1709 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_rvalue_reference.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_rvalue_reference.hpp new file mode 100644 index 0000000..ad5b4d6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_rvalue_reference.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:63434c1016fed7cd6101cddc9577aab469f53958db1f1808d07b8ff0d3608c57 +size 2395 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_volatile.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_volatile.hpp new file mode 100644 index 0000000..0e7d600 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/add_volatile.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7cdb4a75b87025798455461fe1b0f5228091fb95765ebc0f281ececbb130e9e +size 1424 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/aligned_storage.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/aligned_storage.hpp new file mode 100644 index 0000000..d4c9b5f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/aligned_storage.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0760e2fc0ad37e21931ac91b9eac9d339ef5d829d148b9cf89d56835903763ac +size 3348 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/alignment_of.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/alignment_of.hpp new file mode 100644 index 0000000..66e6aa6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/alignment_of.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18171e6f8c694c62c550333b15011231890703be990690d975a6a4d8e2173af3 +size 3565 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/alignment_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/alignment_traits.hpp new file mode 100644 index 0000000..0786d7e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/alignment_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97bf6a4fcb2d3cfc0da802afce8cd21d9e0c3fc5b98d554df11a65bd456072de +size 573 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/arithmetic_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/arithmetic_traits.hpp new file mode 100644 index 0000000..7aa5e3d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/arithmetic_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d003dfd952ba7ed2f8157736c7e72be252f0ebad9c9dd47ce3cc00145d4e27e8 +size 862 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/array_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/array_traits.hpp new file mode 100644 index 0000000..ffdc33f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/array_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:12ac0c0aa3cce1bd04f0a34aa13bb150eac12022e34a1f6766b9c893d9ef530a +size 569 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/broken_compiler_spec.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/broken_compiler_spec.hpp new file mode 100644 index 0000000..234a35c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/broken_compiler_spec.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a551ec36af12738b762d70b0191336f777f451c86860422600f761af89bd92e3 +size 724 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/common_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/common_type.hpp new file mode 100644 index 0000000..bd63cc8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/common_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:720c62f5a497101034c6b6cbb14419413c14725c1188aa80a856ec87fa118f1e +size 4555 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/composite_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/composite_traits.hpp new file mode 100644 index 0000000..223e97d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/composite_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7cef5cebba55a7158d06a47b28f50e361dc179a34d38a6e532ae95b757eae72a +size 1001 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/conditional.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/conditional.hpp new file mode 100644 index 0000000..b1d5e75 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/conditional.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:72744e48a710e2645ecc6a696b150c63d45507cb33b8090fbc7cb8827b2a3ba7 +size 843 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/config.hpp new file mode 100644 index 0000000..cbb247f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7723f7f3c33829098ef1956eb9176af8800eaf3a9509aa8f5b38eba1565ee99 +size 708 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/conversion_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/conversion_traits.hpp new file mode 100644 index 0000000..d96f79c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/conversion_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7cc329b38b6b05eae5d519e230990961259962954142d815e517d8d58aee1c0 +size 658 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/copy_cv.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/copy_cv.hpp new file mode 100644 index 0000000..3f48296 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/copy_cv.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4c0fdb1476d4b7dc493fafbfe450196eb0891327043305485b54d33d0605fdb +size 1058 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/cv_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/cv_traits.hpp new file mode 100644 index 0000000..1528561 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/cv_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db4e332ea3ddb694d461a56860b532b9c2794099504874da2226f38398cd8122 +size 994 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/decay.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/decay.hpp new file mode 100644 index 0000000..c96cb1a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/decay.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd5243a2596de72a872a6e0991c244ed0a7d580ec7cc3aedbb43cf8f8fc2f9c0 +size 1496 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/declval.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/declval.hpp new file mode 100644 index 0000000..6da6bb3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/declval.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:661a695996abdf2523d92fa1d7aa90b676d3439bc7a5bd4c993705b579b2a235 +size 1899 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/bool_trait_def.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/bool_trait_def.hpp new file mode 100644 index 0000000..31a260b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/bool_trait_def.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:334a74db753ffc72ed97ca3eec2a35e16ab8d80ebaf00cfd8e478c09abb78c72 +size 4762 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/bool_trait_undef.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/bool_trait_undef.hpp new file mode 100644 index 0000000..a14e9d6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/bool_trait_undef.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b3491b5db3254634b5385cf17de1796a265164d93920fc73d91eae0de24709ee +size 929 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/common_arithmetic_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/common_arithmetic_type.hpp new file mode 100644 index 0000000..cfedb15 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/common_arithmetic_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:339d69604c3c67b9733f2bf8ea927bc06d35ed42a561ea591e1810bd63468bd4 +size 5585 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/common_type_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/common_type_impl.hpp new file mode 100644 index 0000000..fc3f145 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/common_type_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f36fccbd789530c29571cde32a9e5d751eb90af002dd64ac2875d318fa5588ec +size 3028 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/composite_member_pointer_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/composite_member_pointer_type.hpp new file mode 100644 index 0000000..6bfa36c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/composite_member_pointer_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3c9e8c0d5701d30bf51d1dd1bbfcf72522cf9d497947f525f5b0218a82cb6e5 +size 2823 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/composite_pointer_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/composite_pointer_type.hpp new file mode 100644 index 0000000..e307c3e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/composite_pointer_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d90268e6ccc39ecc612dfb63d50a94e94b370a400adfa9c5afd96831207d4e62 +size 3624 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/config.hpp new file mode 100644 index 0000000..e299c55 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2fa1533b7cbdacf56c6dd58ea5b14365fef82dfeff04afe12be78c512da826d2 +size 3250 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/detector.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/detector.hpp new file mode 100644 index 0000000..87a4a5d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/detector.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1fc85d1dd8021581645c53ff9bf1bc5f5284dad1aa42845218230d40e3fbccdc +size 915 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/has_binary_operator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/has_binary_operator.hpp new file mode 100644 index 0000000..4ad2951 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/has_binary_operator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:914d6d0e671cb49779e3aa306a64430ec970b237dffb69ae6cc94815042c3906 +size 12269 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/has_postfix_operator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/has_postfix_operator.hpp new file mode 100644 index 0000000..8e63c9f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/has_postfix_operator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bcf76d8b4e813ea3c8b55074c3de3a858f3b2582b40fca8b7abc733d8da486e8 +size 9991 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/has_prefix_operator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/has_prefix_operator.hpp new file mode 100644 index 0000000..b6c47ec --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/has_prefix_operator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e9d1d8a48ba53e0b1999c021e73b97ce41f236bfe22ac429c558ad29afed73dd +size 10881 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/ice_and.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/ice_and.hpp new file mode 100644 index 0000000..1990d24 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/ice_and.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8d4b441731865ee06d184101fe1ef8c06c7246ac9c5ca1d92a515a1f55e8993 +size 1190 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/ice_eq.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/ice_eq.hpp new file mode 100644 index 0000000..4aa4099 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/ice_eq.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2c78f1a567719a17dc1f66377611a55f591e32413c87b7dfa7d67f037813153 +size 1165 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/ice_not.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/ice_not.hpp new file mode 100644 index 0000000..62cf6c4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/ice_not.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a286473315334ded917fe458898f8632614f91d5a05271c7f09d7ae4f3665be +size 971 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/ice_or.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/ice_or.hpp new file mode 100644 index 0000000..2ffdf24 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/ice_or.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2792efb55ed5b4fe2c33e92126f8beed50151f0f5db2c3003a5f13113c1572bc +size 1192 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_function_cxx_03.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_function_cxx_03.hpp new file mode 100644 index 0000000..5877393 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_function_cxx_03.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b3e500269663eca5a3b03122b36be312bbf46e9b02c2e82d96841ce88a25a31e +size 3066 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_function_cxx_11.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_function_cxx_11.hpp new file mode 100644 index 0000000..5e21e67 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_function_cxx_11.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:066e84112265fdb38f4b789ff823496b1d1247096a16bf63434180418521439c +size 26932 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_function_msvc10_fix.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_function_msvc10_fix.hpp new file mode 100644 index 0000000..88f1cc1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_function_msvc10_fix.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:088bed0e2d8398dc0c6809dcda27c8cad17513b067ffcbfacedb99eac3be759a +size 1925 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_function_ptr_helper.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_function_ptr_helper.hpp new file mode 100644 index 0000000..02062ea --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_function_ptr_helper.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c103dc55ee096b1256f28eb0b4c298de6f4d37b5f29c9db2cfad7cbc2c1dde6b +size 37000 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_function_ptr_tester.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_function_ptr_tester.hpp new file mode 100644 index 0000000..df18f50 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_function_ptr_tester.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da772b6e1302da3a8d388773015b6b43e1ee798f0a0db35b3e092cef6b76ccf8 +size 40432 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_likely_lambda.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_likely_lambda.hpp new file mode 100644 index 0000000..3c46f77 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_likely_lambda.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40dba62b0a746a5a83471c91739445de1a919c3eb466e1de28ec176a612ecf93 +size 2574 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp new file mode 100644 index 0000000..0117b6c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd83ff71d05e05b57811da04d55e054feb72ae59ebdb48335425bfbefa541c97 +size 145750 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_mem_fun_pointer_tester.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_mem_fun_pointer_tester.hpp new file mode 100644 index 0000000..a160650 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_mem_fun_pointer_tester.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81c6b638e79b363c94da697b40219638fdf929deb004f2ab2fc1c19057bfdd19 +size 171760 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_member_function_pointer_cxx_03.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_member_function_pointer_cxx_03.hpp new file mode 100644 index 0000000..9bcf9a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_member_function_pointer_cxx_03.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:94f1e9604d9e0791ed6392ae64ed761cf6daddd7715a2c2e96c8d88e5b309553 +size 3665 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_member_function_pointer_cxx_11.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_member_function_pointer_cxx_11.hpp new file mode 100644 index 0000000..02019ad --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_member_function_pointer_cxx_11.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61cc2ca915bb307d3a4d30820e623f83fb856158825077b0355e6ea08341a857 +size 36246 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_rvalue_reference_msvc10_fix.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_rvalue_reference_msvc10_fix.hpp new file mode 100644 index 0000000..ed82485 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/is_rvalue_reference_msvc10_fix.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe5c2a7a85db6f37f0d5da916c2501c9c094fd6eb7b7e78fbf39e399032dcc3a +size 3510 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/mp_defer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/mp_defer.hpp new file mode 100644 index 0000000..3265bb3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/mp_defer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbb1ce339acebc6bdf6082f8419b03dced71de0784c5b5a371e98ed31fcc5208 +size 1359 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/template_arity_spec.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/template_arity_spec.hpp new file mode 100644 index 0000000..b5d9188 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/template_arity_spec.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39dfd8b7372361f5fec566f46bea85d5a29456d6c3a6de5a017db5c6d58fd673 +size 535 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/yes_no_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/yes_no_type.hpp new file mode 100644 index 0000000..8ca4da7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detail/yes_no_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8918499722cabda0f0b27436fda75b240674c610b4338fbfd32bca073b83f655 +size 726 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detected.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detected.hpp new file mode 100644 index 0000000..d86f88c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detected.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa2a63ed5cd905b54157b4639da8ee3d1d73eb11f3715fdd32d8901502da3a1a +size 569 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detected_or.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detected_or.hpp new file mode 100644 index 0000000..b6b732a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/detected_or.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d432cb13b2b59769a768f671dfe5f8c128b3f3c4dc64e23ddae3d22261be70fd +size 670 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/enable_if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/enable_if.hpp new file mode 100644 index 0000000..4a06ace --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/enable_if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a9aa733f2c0abdcc2f0adc282525fbb7b465a053971e286287a6d9b5de2cb1a +size 829 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/extent.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/extent.hpp new file mode 100644 index 0000000..ccfc7a9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/extent.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ed6749f534bb9ec9ebf73baaf88e5b4a24e410c3599fd1806d6aee3e5340c19 +size 3747 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/floating_point_promotion.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/floating_point_promotion.hpp new file mode 100644 index 0000000..d670a37 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/floating_point_promotion.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a9963916db2480641dbb71ae94d5ec5abe91eeac58a45aeccb3092e52626113b +size 1071 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/function_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/function_traits.hpp new file mode 100644 index 0000000..d850270 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/function_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50708cb1324635f5fd6eb87a3143423cd1f27626f045267baa5038fe634eb6a5 +size 4801 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_and.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_and.hpp new file mode 100644 index 0000000..3789807 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_and.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd711f4d2b9250f180320b742d562a0707cb1f32ee42a6717cb45a85d7cc3e79 +size 1572 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_and_assign.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_and_assign.hpp new file mode 100644 index 0000000..ef80a65 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_and_assign.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7fa25d79d2123b3cc469a090ffedd45b3660fe20fa9ceb63d9dfae793a72c19d +size 1841 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_or.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_or.hpp new file mode 100644 index 0000000..fbd61e8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_or.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e5ddd85e6f933416819fbd613b8eb36a4758a1f07eb3c40383fa5e41c3fedb1 +size 1569 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_or_assign.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_or_assign.hpp new file mode 100644 index 0000000..c1af129 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_or_assign.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61fe12aef4c90256d0d8d512e68f13c6ae8afe43cf8310227a7a3aeed11a966c +size 1839 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_xor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_xor.hpp new file mode 100644 index 0000000..1057a03 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_xor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fdd35c345e22b718742483943819bc13b64651e76faad05027ae7b3e8d9e1413 +size 1571 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_xor_assign.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_xor_assign.hpp new file mode 100644 index 0000000..014eed6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_bit_xor_assign.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1fcfdedbab2827e36aac30d19ccb82a502f014ef3b287ea9301b1a07daf3632d +size 1842 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_complement.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_complement.hpp new file mode 100644 index 0000000..09f6767 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_complement.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b2eb66d57039fb2a8a9bbce6d6b600309d7590f99611530112887f2a5c1e83de +size 936 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_dereference.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_dereference.hpp new file mode 100644 index 0000000..5de7bfe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_dereference.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2abe4d1d7c4a8271264f30324fc29dba7fe78596b13544388b53946de22efaea +size 16135 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_divides.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_divides.hpp new file mode 100644 index 0000000..11f0d35 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_divides.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55d230acee9fb04bfc9c98fdbfcb7e49f2be54d3a997a9d7106b44b2ad3ea6a6 +size 1156 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_divides_assign.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_divides_assign.hpp new file mode 100644 index 0000000..93d637e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_divides_assign.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afa96c4a73f5a75973f0d2a5c035d08894a5a72495535c6122503885dba76f2b +size 1513 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_equal_to.hpp new file mode 100644 index 0000000..5efef4b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64ad5dcd147ef5b07aadacde986b1ff9bb07c949c88b6c53627dd886e6ebda3d +size 1762 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_greater.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_greater.hpp new file mode 100644 index 0000000..cf97de5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_greater.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5f5545ac3f191f31f698e5a91374292fa7f7cf101998b50c23f473d21172368 +size 1756 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_greater_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_greater_equal.hpp new file mode 100644 index 0000000..ebedf93 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_greater_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62f86c3cc267dff31af92eed419276132b0e1bc527c7306e7d8b25b220c86549 +size 1775 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_left_shift.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_left_shift.hpp new file mode 100644 index 0000000..862d0a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_left_shift.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ff2ad89dd0d02066083614042214ae707a2c73aa5b069ae71feb23146ea752b +size 1581 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_left_shift_assign.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_left_shift_assign.hpp new file mode 100644 index 0000000..3db040a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_left_shift_assign.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c061aba22a4b14e84de5f1e6a4b5b7ea1f185da33cc248aba2a81f419573dda +size 1851 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_less.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_less.hpp new file mode 100644 index 0000000..0efa19c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_less.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de193961ed58d66de59b40d1a03db8e81e8d1f41c9ec1504de9f907e6c6f1d31 +size 1750 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_less_equal.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_less_equal.hpp new file mode 100644 index 0000000..9d32ee6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_less_equal.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82c395c2cfd84267272c9c6db924366ec897ee939f5ca3fb0b9aeb41d52fc34c +size 1769 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_logical_and.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_logical_and.hpp new file mode 100644 index 0000000..b74eae0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_logical_and.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dad29f6fc16da202b65e5098a3fc15b9e0826786021cd16d508e29eab740a094 +size 1212 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_logical_not.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_logical_not.hpp new file mode 100644 index 0000000..0423c46 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_logical_not.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af478f0ba0658464f3b25909b6903b370de899c39d8c66c40e477a3c45d93755 +size 998 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_logical_or.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_logical_or.hpp new file mode 100644 index 0000000..3d27292 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_logical_or.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:393c30fe008d3e150213f59c44baeae5cd395ea5a065cf7a8b615b951067386a +size 1208 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_minus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_minus.hpp new file mode 100644 index 0000000..14398f3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_minus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:103f622be5cf69f61efc623da83d0b3524cbd39f5af60acf1d68f9e9f3b33f94 +size 6502 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_minus_assign.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_minus_assign.hpp new file mode 100644 index 0000000..39afe20 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_minus_assign.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01b852fe1c27a5b0e474b3232a92cc949d4373afa5dd17afb3b342ccbc99e2d4 +size 6791 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_modulus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_modulus.hpp new file mode 100644 index 0000000..8ad960b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_modulus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8af0dde137bbed2e30d9cf8df05dc41a1dfdb260a3a8c4c4b3d676dd534bbc67 +size 1570 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_modulus_assign.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_modulus_assign.hpp new file mode 100644 index 0000000..9814fa2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_modulus_assign.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:205f4ad2acee9d8cbc8be653d97b7f3f718360296b3917cc8e9d93f7bb3bf738 +size 1841 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_multiplies.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_multiplies.hpp new file mode 100644 index 0000000..09ddf25 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_multiplies.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ddb055bed7b7151bbf2148a30c15689d0136108a53dd15044327f8c51e4e51ea +size 1162 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_multiplies_assign.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_multiplies_assign.hpp new file mode 100644 index 0000000..99d25d9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_multiplies_assign.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:57274cff15b0b2f2971b2340cb1406e1d742863ee9e75d1a91370ca1e2be2532 +size 1521 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_negate.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_negate.hpp new file mode 100644 index 0000000..4ce5155 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_negate.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b7dfeec82bd923d419afe3df8ae69e98adf239a7d1e1bc8249b465f6a0a00a8 +size 731 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_new_operator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_new_operator.hpp new file mode 100644 index 0000000..ef6283e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_new_operator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0704e59cd2c3fd5319d0e42e97c0f15ade282c08c4d2c62d811e097e3726dfea +size 5166 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_not_equal_to.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_not_equal_to.hpp new file mode 100644 index 0000000..7be04f2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_not_equal_to.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e9c904c44a907675c41322aa98df567c929d855523c2ced5051053abea6af8d +size 1774 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_nothrow_assign.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_nothrow_assign.hpp new file mode 100644 index 0000000..607b136 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_nothrow_assign.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:adb9656fee502aa821b6767e094927b455a194b2c95b1a0fcf99844059af91db +size 3766 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_nothrow_constructor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_nothrow_constructor.hpp new file mode 100644 index 0000000..02fa6fc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_nothrow_constructor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b20a0cdb1ef804b48ae6426e92aa440696f24e1599b0c783ecf387cc77a0b6e4 +size 2633 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_nothrow_copy.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_nothrow_copy.hpp new file mode 100644 index 0000000..38688e9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_nothrow_copy.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d75487a5b5b186538775cacf0fc6b1323521593c452a9ff9a235e70309a65dc7 +size 3045 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_nothrow_destructor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_nothrow_destructor.hpp new file mode 100644 index 0000000..be1ff2d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_nothrow_destructor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f675d095ecb35328dcca1785742ba80d0ebd462be9974d4c4de43f1c680e77a +size 2204 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_operator.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_operator.hpp new file mode 100644 index 0000000..864dfbc --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_operator.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:adff5a7d8b41587530d9942b337b1c79a5f043e0b40c5de2ef313cb2edc18f1a +size 2282 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_plus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_plus.hpp new file mode 100644 index 0000000..15f0bd3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_plus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45484449ad255131f7768c5bc36ba9fd58595ef67d501fb72c488ae7a4442821 +size 1800 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_plus_assign.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_plus_assign.hpp new file mode 100644 index 0000000..aa93cb2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_plus_assign.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9cc075a9dce9df5005d2c883fb74f183176983bb49e140e73bfa74c8a3efc8d8 +size 6873 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_post_decrement.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_post_decrement.hpp new file mode 100644 index 0000000..2caf98d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_post_decrement.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a9b3eddfe41b275f7828671b4f1ffa7e24a66b482d4394a683c9140b4236b88e +size 1932 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_post_increment.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_post_increment.hpp new file mode 100644 index 0000000..9f25634 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_post_increment.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e32e297f5cb824405d491b897b1909fdaff885933bea88160b3df40e32dea8a +size 1932 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_pre_decrement.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_pre_decrement.hpp new file mode 100644 index 0000000..9df91f4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_pre_decrement.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0246c6468400753b51d0af290be2c0f89377f9771b55180d532acb8b4eddb85 +size 1922 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_pre_increment.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_pre_increment.hpp new file mode 100644 index 0000000..b8c769b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_pre_increment.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0cc939dfc662a9c35c6e47e56503d1189a5dd64efb9764379e26f334836137a +size 1923 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_right_shift.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_right_shift.hpp new file mode 100644 index 0000000..332e10f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_right_shift.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95a1f03d19e116b3a61a5f5aec91b030919a9cbe989c8eb8337dce8dea4c4b17 +size 1584 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_right_shift_assign.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_right_shift_assign.hpp new file mode 100644 index 0000000..0b8b28a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_right_shift_assign.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af17bcb6ada2a8535d413451beda6218693c52dd50d3a52a991a3adc785879be +size 1854 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_assign.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_assign.hpp new file mode 100644 index 0000000..37afb8f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_assign.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a7346975c8016dbfbfb284070cf877ada39fec29bc3ffe2135f7b9b9ebd04075 +size 2208 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_constructor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_constructor.hpp new file mode 100644 index 0000000..a49176e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_constructor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:68e624633256edeb4c7642a656b8b10b4ca30bc22a4653bd0d9041ffc1a30e78 +size 2233 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_copy.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_copy.hpp new file mode 100644 index 0000000..26d03c5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_copy.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c456dfc611c41224cb86ed52cdc504240b5676b15ccb01907b1677b815d8a4c +size 2417 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_destructor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_destructor.hpp new file mode 100644 index 0000000..f20a8dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_destructor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a7ab268fbadb07751ec8af0c41d9d08e5248f62a33fcad0b36ba53a8cf066065 +size 1683 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_move_assign.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_move_assign.hpp new file mode 100644 index 0000000..86f7a10 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_move_assign.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab68b34ec3753ed849c6bf21bf03084ee75a9288bc59df0a8b5a6eedd8392170 +size 2666 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_move_constructor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_move_constructor.hpp new file mode 100644 index 0000000..9fc0e55 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_trivial_move_constructor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92156eba953564588dda4e8ad9f85838ecde7a215421c5cbbe1e57385b498903 +size 2939 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_unary_minus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_unary_minus.hpp new file mode 100644 index 0000000..270a5ff --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_unary_minus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f078b70f3a3fc3d28f37226850e1159fbf7f23e3e2c0b6fd2b55be04e1ac0669 +size 746 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_unary_plus.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_unary_plus.hpp new file mode 100644 index 0000000..f5bb9da --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_unary_plus.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:398bf6db3ed373117bd9b63594b7d8a3e87aa108ec5527660af92ab86a6c886a +size 690 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_virtual_destructor.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_virtual_destructor.hpp new file mode 100644 index 0000000..4b09f87 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/has_virtual_destructor.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5fd143c99c3ce4e2850e511e96c316c7c59fc337a71968166bbb419321524d5c +size 901 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/ice.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/ice.hpp new file mode 100644 index 0000000..b35a765 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/ice.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f8ec35f2c11fa849e9ce04164ecafe9108b32399fa9009f7c48586bed8d4d79b +size 768 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/integral_constant.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/integral_constant.hpp new file mode 100644 index 0000000..560b3ff --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/integral_constant.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc7f03edbae4296217543685f0ca327a6ed729268377b62026b57b8bc6078fb8 +size 2544 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/integral_promotion.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/integral_promotion.hpp new file mode 100644 index 0000000..f5fa10b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/integral_promotion.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1728cfec0f8819e5f9fb798024c37e74870d7a47be9b5c5b9e4f9935eb38a0a0 +size 6262 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/intrinsics.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/intrinsics.hpp new file mode 100644 index 0000000..ae459f3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/intrinsics.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:099331191588a8ce92b244819ac3294f0d8ac052f77b6ec6ddf9f95758606c3c +size 22016 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_abstract.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_abstract.hpp new file mode 100644 index 0000000..8d56fd9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_abstract.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a60091f7e3077f187ff7e1e67ad59e1a8a1d7f03f44eeefe16cd09f645d5981e +size 4501 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_arithmetic.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_arithmetic.hpp new file mode 100644 index 0000000..bd50dca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_arithmetic.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f937c0f8958d61efc196a30838fbfc085e6ed6a862fed86bec42e671e5ebe7f3 +size 778 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_array.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_array.hpp new file mode 100644 index 0000000..e349461 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_array.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:69816daa883727a251d0b8f4bce93fb1108a1b95706d54fb40e3beb9a5785d81 +size 1751 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_assignable.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_assignable.hpp new file mode 100644 index 0000000..273833e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_assignable.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:490a8e1ed5a76a3f77b5acdc22d2efc04a711aec867e070dfa5eafd0391b7603 +size 3925 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_base_and_derived.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_base_and_derived.hpp new file mode 100644 index 0000000..fa9d4c3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_base_and_derived.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:624d114045eccafa87df76bc041b223c7cfc4bca776f81e0bc90eb94ce03a9a3 +size 7993 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_base_of.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_base_of.hpp new file mode 100644 index 0000000..02bd091 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_base_of.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86715166c7ffb4dfc41d8f6ba3d3c87c8e0960ef36254d25324c44df4aac8172 +size 1500 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_base_of_tr1.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_base_of_tr1.hpp new file mode 100644 index 0000000..3481e1e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_base_of_tr1.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45489c82acee21a4cf30783ebaa422ffd0cd80f5d2f0bc8753f94a3436cc0196 +size 1486 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_class.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_class.hpp new file mode 100644 index 0000000..b476336 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_class.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db5ddec8ad15395bd4383f4265adad1f2d4e3cf51575a3ba2e4c8ebec6f5f12d +size 3595 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_complete.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_complete.hpp new file mode 100644 index 0000000..02adf8a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_complete.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5467734a28b3e70f19901e40dbc52b911d49db78ad5b7d6030f40d40e16de939 +size 2796 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_complex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_complex.hpp new file mode 100644 index 0000000..02b7ac8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_complex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:544480f21cd386a339efdeb9bde04e7c7769818c35fb124ade8db8bb656c455b +size 952 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_compound.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_compound.hpp new file mode 100644 index 0000000..5387861 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_compound.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76ca370248367ae8a31fe021bc86433742f2d6f39cad8d716dcde45881c666be +size 846 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_const.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_const.hpp new file mode 100644 index 0000000..d5e414f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_const.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:33dfdd4f82b6d9abec1a98fa2901b3112d4fba4db11e06a6cd1502274f9cb566 +size 1628 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_constructible.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_constructible.hpp new file mode 100644 index 0000000..9592da3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_constructible.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7afddfd2d42f27303b8cfeb24887e8dcdf014d934a525e1e5d3cda2154e0dbe1 +size 4343 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_convertible.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_convertible.hpp new file mode 100644 index 0000000..ae8936a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_convertible.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:22f80da4fe9cb179615339d5108f0606109f6c665fde7b0d5b2c79a333051303 +size 18660 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_copy_assignable.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_copy_assignable.hpp new file mode 100644 index 0000000..7fac34d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_copy_assignable.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbc0fc202c05a2bcedd1bda3e2354b2913d28363f71dc62959e48ede43b146a3 +size 4904 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_copy_constructible.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_copy_constructible.hpp new file mode 100644 index 0000000..9af9d2a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_copy_constructible.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dfaee898aa7a02c6d8297c47ccc2ba076939a8cba833ae3c022536395c94bcf4 +size 6813 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_default_constructible.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_default_constructible.hpp new file mode 100644 index 0000000..299c3c1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_default_constructible.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afa995ce9d71a0568b96b7dd5ae18a899a7744b25af0f56127044253c9810977 +size 4519 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_destructible.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_destructible.hpp new file mode 100644 index 0000000..17e03bf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_destructible.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:43faea468650f1ce5e19c2c380f028917feb778aacd192891946ff6826d6b217 +size 2565 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_detected.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_detected.hpp new file mode 100644 index 0000000..a8214b3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_detected.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11845c95bb85844e98c37fd29c4aab3b8a9dd40cd0d31f2341e379300253d15e +size 752 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_detected_convertible.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_detected_convertible.hpp new file mode 100644 index 0000000..f36257b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_detected_convertible.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40d660116b3e93b60c0f245d5a9447a6c32afc5742a3d0b76697d95d30fbeaf4 +size 815 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_detected_exact.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_detected_exact.hpp new file mode 100644 index 0000000..7a8230a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_detected_exact.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bdd5049a394eee756703a7c401d419d495d5a518116e9662a31915b121ef4aa2 +size 796 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_empty.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_empty.hpp new file mode 100644 index 0000000..9e95bd5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_empty.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:68d77f7444950e753f59f73ede2f1b808461062fc39469a374f12ad8ea649d82 +size 2998 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_enum.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_enum.hpp new file mode 100644 index 0000000..993d475 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_enum.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b8390edc5a7b81d1beb69058865eae9b2add8672069bc08afa10328a79e0a9bd +size 4986 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_final.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_final.hpp new file mode 100644 index 0000000..9759690 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_final.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:508b8b7ff4512402e6e5e45525a7d58419e711d33111336fd1c13974e2c49063 +size 868 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_float.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_float.hpp new file mode 100644 index 0000000..727fb60 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_float.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21db01f64bfdd9ee24d57a0191814601a064ea05bff5f6b1f6606d9029619fd7 +size 789 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_floating_point.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_floating_point.hpp new file mode 100644 index 0000000..a1d68b5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_floating_point.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a9d06be1269ab736f90908dbba242f998c4e4020add765ae7b669506ce2ffa0 +size 1374 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_function.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_function.hpp new file mode 100644 index 0000000..45cd3d1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_function.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f2b0be866c26e43af6d808c67b3f8146078a6be5284b17f198eb3fb41b98947 +size 808 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_fundamental.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_fundamental.hpp new file mode 100644 index 0000000..6e967b5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_fundamental.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8cf3a3ac24d17d6ae55b71b97efe4347b517c88ada49aa64f26c928011083ebe +size 994 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_integral.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_integral.hpp new file mode 100644 index 0000000..ac72f2d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_integral.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c7b11e7058b74413d9934cdf64b0e3ab354cb88bc1681899c8121a4cada0425 +size 3837 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_list_constructible.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_list_constructible.hpp new file mode 100644 index 0000000..b6d78b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_list_constructible.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0b1d66c18b4736cf84cbb3259e0167f27319ea29551409f03968839f826912c +size 1746 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_lvalue_reference.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_lvalue_reference.hpp new file mode 100644 index 0000000..d122fb6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_lvalue_reference.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f28f2092d4af57d3b42a452dc46e34bf5a21ab97a3e30e4828c417db4a8ef2c8 +size 2010 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_member_function_pointer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_member_function_pointer.hpp new file mode 100644 index 0000000..f293a2b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_member_function_pointer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6621df4e09e3480f9aed3ca4f50fb9a2a9ba3614a04406c1ab926e97fa49fb16 +size 825 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_member_object_pointer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_member_object_pointer.hpp new file mode 100644 index 0000000..7346d3b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_member_object_pointer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b58f49769dd5e3fdafbd2ed104fcde9fa29f9308019a4d8f92ce0ff3eec51139 +size 839 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_member_pointer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_member_pointer.hpp new file mode 100644 index 0000000..4629930 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_member_pointer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5291cf985ca7549400dfd82ecfb03c3e09c00ebc81e0cae22d75759081046b36 +size 1967 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_noncopyable.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_noncopyable.hpp new file mode 100644 index 0000000..4413ca0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_noncopyable.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4bbe939fce07ccb45e32aeb106a7f2fbd2c0cb8e005ec86076392599eab1b8a1 +size 1067 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_nothrow_move_assignable.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_nothrow_move_assignable.hpp new file mode 100644 index 0000000..8ebe498 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_nothrow_move_assignable.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3b3d460221f8de6e5b2d16e59fc74d0bb10ac530212cbceccaa326738c8e7c8 +size 3964 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_nothrow_move_constructible.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_nothrow_move_constructible.hpp new file mode 100644 index 0000000..16e0a2c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_nothrow_move_constructible.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6863a9bf0048e64b6e67734868292758e4eb9fae2ab85b5e3b2d75b57712e156 +size 4043 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_nothrow_swappable.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_nothrow_swappable.hpp new file mode 100644 index 0000000..5a96d65 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_nothrow_swappable.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c73bda83bafea169f3cecdcf7859cc52fd1a7c636d642c1f6cbd11487533536 +size 2405 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_object.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_object.hpp new file mode 100644 index 0000000..aada4f7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_object.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff789c4695215ca4f6b403c8cc4231ff489ce799b8f1aca4317875c7b4eebe8d +size 907 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_pod.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_pod.hpp new file mode 100644 index 0000000..2b8f701 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_pod.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75f2db547a494219e7584ac998dd84486e6558b7b804fcdb273bae5d3876693c +size 1809 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_pointer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_pointer.hpp new file mode 100644 index 0000000..ccead2d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_pointer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1d4f1c691928497519fb591c875d6661a5e58b826a8946d9e7ad8ef0392878f +size 1899 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_polymorphic.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_polymorphic.hpp new file mode 100644 index 0000000..6d4448e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_polymorphic.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8fac15eee3da5df7aecb179f55504ff4ad0848a8c12efb04bc77a2a0b9dc312c +size 3187 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_reference.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_reference.hpp new file mode 100644 index 0000000..bce852d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_reference.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:068dcf0a2c20efa45a587ad6c9b8d331f700d153cf35461da3d386fae1d10e35 +size 938 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_rvalue_reference.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_rvalue_reference.hpp new file mode 100644 index 0000000..62e2017 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_rvalue_reference.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48a7ff6930da2d3e6a79042f8105f8c70a6f39c6f202e98b4961f7b5fa5463f5 +size 981 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_same.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_same.hpp new file mode 100644 index 0000000..3679ae8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_same.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48296c6d7fffa9107258006507c4fd54f4dd15ac4de4053917e8bc3d2048e975 +size 1509 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_scalar.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_scalar.hpp new file mode 100644 index 0000000..969d88a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_scalar.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b1de36f8f54fbd342fae4dd7ce27fa26887e1150828121c3cb4618ed08287a6 +size 966 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_signed.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_signed.hpp new file mode 100644 index 0000000..caa675e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_signed.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6989bb571382565a633ee0e1afced2645a17aa146a011e9453b875e103f534c5 +size 6648 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_stateless.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_stateless.hpp new file mode 100644 index 0000000..5966a99 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_stateless.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a62f76c91a3a49cca0d3852d3b339e8aac1d2e73d20cf8fcbc283bd0d4f0991b +size 1127 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_union.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_union.hpp new file mode 100644 index 0000000..eb19cdd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_union.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa7b8d4e60bca1109e96c301e6fc1f379d1056aeb62a1ff659bba8da3d8f5459 +size 1075 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_unsigned.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_unsigned.hpp new file mode 100644 index 0000000..fc843c6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_unsigned.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a49796d168efaf99123d72f2a10ac8b8f097d51a5ffbedb609f11c148d94ca21 +size 6768 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_virtual_base_of.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_virtual_base_of.hpp new file mode 100644 index 0000000..cc507d4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_virtual_base_of.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:850e948036e6164395d795eddf05a8fd56fab4213643b9d54219461ed79d0df6 +size 6126 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_void.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_void.hpp new file mode 100644 index 0000000..ceb4fa4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_void.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e043155d858ee74fb856cfb228922e4b9fff5fbe6dc0cc4f3ad28bdf55ba2aa +size 890 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_volatile.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_volatile.hpp new file mode 100644 index 0000000..c77f959 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/is_volatile.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c81a9dbeacc47097d90c88c52aec98f4073456d25d3e567645b69dc4262a98d +size 1663 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/make_signed.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/make_signed.hpp new file mode 100644 index 0000000..9156d7b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/make_signed.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea2e0c94337a163bc87eaf1dd9c0f086b50ea304f833ce038f464c32226c2c14 +size 4621 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/make_unsigned.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/make_unsigned.hpp new file mode 100644 index 0000000..692891d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/make_unsigned.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8bf849ed921e4ed701f418ca8c290916a490b55f24d10ee309a4be77ad4522ae +size 4691 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/make_void.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/make_void.hpp new file mode 100644 index 0000000..b4175f0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/make_void.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f791e8956d2dbfbaa118aae3bb7e6efa0fb29780016ce4dcf2be7c4fa1c7fcf5 +size 1052 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/nonesuch.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/nonesuch.hpp new file mode 100644 index 0000000..d475262 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/nonesuch.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf7d52873bfa3925c2aaf7f330338163f3842e579ebd6e1284187376cac43f17 +size 702 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/object_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/object_traits.hpp new file mode 100644 index 0000000..f2fd33c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/object_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d867fa35a09908251c4437d49396375ff500cb69c09ad5294bd9c3b7474885ef +size 1441 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/promote.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/promote.hpp new file mode 100644 index 0000000..10f3433 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/promote.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:388919cc7b455522f1b49c172c3855a518f6bf557a7ce22cd6a30292e9abe5c8 +size 755 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/rank.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/rank.hpp new file mode 100644 index 0000000..f97d6dd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/rank.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97919bbf464fe0c23fe44ac0bfe786e1af948e85a718f0e4338a8a685ce852f9 +size 2577 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/reference_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/reference_traits.hpp new file mode 100644 index 0000000..47784c9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/reference_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21be71a3adc2544ac654b9e683bd992df482e800334e5a72a9a357d047363a4d +size 590 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_all_extents.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_all_extents.hpp new file mode 100644 index 0000000..8978ef5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_all_extents.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15f3d9fba8b832975b673e0e53a9126fc207fdd01e779b6ea71319ae026354fa +size 1883 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_bounds.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_bounds.hpp new file mode 100644 index 0000000..4a9d42b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_bounds.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a26fe9a563a5e6a0e7e8736fef937c90a137d9561c4820229bb6892c9ef69f97 +size 802 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_const.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_const.hpp new file mode 100644 index 0000000..18e0b3b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_const.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:33151b6f70c6f954ce230209dbc77aad94b0dc079961e9025d41ec1838f251e6 +size 1357 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_cv.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_cv.hpp new file mode 100644 index 0000000..1319820 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_cv.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4dc8fd5739ddd65b6a558c95941939cb0ab9cff356c028bc8a18792530d04d1e +size 1792 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_cv_ref.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_cv_ref.hpp new file mode 100644 index 0000000..6f9b854 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_cv_ref.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:33b4187033b2aa28c8c057522cae06284bed11d9f2691b962b3804281ee9395f +size 859 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_extent.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_extent.hpp new file mode 100644 index 0000000..6e1af53 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_extent.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50053ad662cb777e9323913d3ec0275e699b72fe499010b365fa38ea6e29eb4d +size 1789 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_pointer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_pointer.hpp new file mode 100644 index 0000000..1d8e8e6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_pointer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e0b898bb01e3acd0c5a0b79e3c33d62965f010a561946d538cc9752f985cfb9a +size 2203 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_reference.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_reference.hpp new file mode 100644 index 0000000..8b97d5c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_reference.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5556a8862b4134de42763ac42fae1958b7ab00a4897b89286ca0c3328be8308b +size 1783 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_volatile.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_volatile.hpp new file mode 100644 index 0000000..008de00 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/remove_volatile.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55792b123ad1789aa184175b491705bb3566ad98397c29c4b97de84c2c19dfdc +size 1396 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/same_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/same_traits.hpp new file mode 100644 index 0000000..d39690d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/same_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd3c7d28b1226eda25c25b0aa2badc635aa0fd16b28594461bfe30a48c42dc4b +size 586 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/transform_traits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/transform_traits.hpp new file mode 100644 index 0000000..ee5f858 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/transform_traits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8642fb03f15b60a13396e616466e0ccbc3d50904ff4dd0d26bbeb45ff182ceb +size 893 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/type_identity.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/type_identity.hpp new file mode 100644 index 0000000..a326f10 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/type_identity.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c9babe7d5bf2f7b6a711e226cb39af04ce3b7ba8fb18c2de71cf82a6a8960258 +size 636 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/type_with_alignment.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/type_with_alignment.hpp new file mode 100644 index 0000000..b890d79 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/type_traits/type_with_alignment.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1484b6ead726f9a093236dee047bd1d929f7c45ab201e98848deacb6ad5ff3b8 +size 10033 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/detail/fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/detail/fwd.hpp new file mode 100644 index 0000000..9ec511f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/detail/fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:378e1faa9514cffb78a6650c8a9800301dbfc328d07e1bd07d6488fa16e195a8 +size 1972 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/detail/implementation.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/detail/implementation.hpp new file mode 100644 index 0000000..82a6b58 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/detail/implementation.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eff494aeda40831e65e4eb2a823afca0cbaf05fbcf1d4138e4e548d7f4d42461 +size 163989 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/detail/map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/detail/map.hpp new file mode 100644 index 0000000..4fb17b7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/detail/map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5644b216146c8bc539bc3fb4d38fb3c13ccac473acd387f300ab6720bbe1473 +size 2473 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/detail/set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/detail/set.hpp new file mode 100644 index 0000000..2eb48e3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/detail/set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:065929928bd2acb221872a51d916da29ccb29528958308d13dfad2fa1c3aead0 +size 2399 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/unordered_map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/unordered_map.hpp new file mode 100644 index 0000000..9efc6e3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/unordered_map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1734d02d0f804a6a32cd57960fb8c9d6ccee08407063f9ad329e1ff98bb1153a +size 90040 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/unordered_map_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/unordered_map_fwd.hpp new file mode 100644 index 0000000..0ee440c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/unordered_map_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03ec7f713f2320950a0d5607a424979252dbefd2a26c5a1f8cc88468122b6d6a +size 2385 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/unordered_set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/unordered_set.hpp new file mode 100644 index 0000000..1f44456 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/unordered_set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c3bc8d11cf94be89bb963804aacef64f19126557dec6bae74386f5208cf64ae +size 69345 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/unordered_set_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/unordered_set_fwd.hpp new file mode 100644 index 0000000..5ef1a6a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered/unordered_set_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0a4a65473c91c6e4e039a218a241b792bb759d66ccd158b57c0b404560d6f439 +size 2206 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered_map.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered_map.hpp new file mode 100644 index 0000000..5c5b849 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered_map.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:879aa17098356b52a293d241f751720f8f74456601e0e39746f8464a14589561 +size 568 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered_set.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered_set.hpp new file mode 100644 index 0000000..1fb72bb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/unordered_set.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fcbf470ddf53d2d5af741e238608be2f6f9f84c45586bf96f1ecda4f02488c4f +size 568 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility.hpp new file mode 100644 index 0000000..eb476e0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc345a6ff4f0daf05ac964ee5713be7c8b0e5cc80b16f6ad4f0abb4c7dded017 +size 880 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/addressof.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/addressof.hpp new file mode 100644 index 0000000..7f68a69 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/addressof.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb86551a087e57d8efa1f1da683f90f5a0501d746f5a42340e86097c076f1169 +size 410 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/base_from_member.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/base_from_member.hpp new file mode 100644 index 0000000..d0e3e80 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/base_from_member.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:977d104af9562677a98180eaf38e7af754517bfe872d730d295b318aeeb2cec2 +size 5701 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/binary.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/binary.hpp new file mode 100644 index 0000000..759f817 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/binary.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19f8e6402d36d89050d92cd42d9de21d717a1f28074e828a7d66e03ce13590bf +size 47868 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/compare_pointees.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/compare_pointees.hpp new file mode 100644 index 0000000..59d3bc8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/compare_pointees.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a9ec852cd0595fcf45a04d06fc84c11efdb78b7f38a596bb6de2318cb2465f64 +size 2290 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/declval.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/declval.hpp new file mode 100644 index 0000000..de67043 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/declval.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1271ac48f7930722ed8f7a264d5b0d828e8ad68ce0f1fe2f9d03ac820ba3457b +size 384 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/detail/in_place_factory_prefix.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/detail/in_place_factory_prefix.hpp new file mode 100644 index 0000000..da3425d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/detail/in_place_factory_prefix.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe8ce4dd39e136b2d8fa31321fd57627d818664d924af90e7650002db8d72515 +size 1428 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/detail/in_place_factory_suffix.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/detail/in_place_factory_suffix.hpp new file mode 100644 index 0000000..52ca99b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/detail/in_place_factory_suffix.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:879d4dafd5f325960464ef671325c64ae8324b2093af4573a626f5b5e5be6e06 +size 793 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/detail/minstd_rand.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/detail/minstd_rand.hpp new file mode 100644 index 0000000..c6c6f71 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/detail/minstd_rand.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d08c4e6ea683db2a5ee6621c41078935eba84f752deed92c28f7dd0cdd685435 +size 1046 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/detail/result_of_iterate.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/detail/result_of_iterate.hpp new file mode 100644 index 0000000..1679d10 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/detail/result_of_iterate.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9491088782d9062d586b1cd9a15ef4a80fdff326a97d073af651b904008b10ba +size 8477 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/enable_if.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/enable_if.hpp new file mode 100644 index 0000000..ea14de9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/enable_if.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82ca441edd4f8c603b956b36c76f7db4b7b1287e4e9399e15b918ff64f480fcb +size 410 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/explicit_operator_bool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/explicit_operator_bool.hpp new file mode 100644 index 0000000..cc13b2c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/explicit_operator_bool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be708809716ceb97102f330bafb58a849e8d2e1a5fa1786cba3f6368760abe87 +size 462 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/identity_type.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/identity_type.hpp new file mode 100644 index 0000000..330e508 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/identity_type.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0dcb5c8f78fbd469389e39c2a439aa8f2632d525fcb17a6ab49ff8c69412467 +size 1672 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/in_place_factory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/in_place_factory.hpp new file mode 100644 index 0000000..1b65698 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/in_place_factory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e279cc3a1b7269a0116fbb1654a7a559360f7507fee3f0662a0d90d651a2a42 +size 2176 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/result_of.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/result_of.hpp new file mode 100644 index 0000000..31edb9a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/result_of.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6d73f76485589d5a664311d3ec75566fb16f790535ec7b3151dd9881bc54303 +size 7386 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/string_ref.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/string_ref.hpp new file mode 100644 index 0000000..d8f1571 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/string_ref.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81cf954d758e76d5b5d677685a8c0fa7162f62b1abe956a9ccbe2a693b21afe3 +size 22013 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/string_ref_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/string_ref_fwd.hpp new file mode 100644 index 0000000..7330f67 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/string_ref_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f75d10a1431685f5a63d35b252e6d603a48e6a9a428ed917d9d7c43e49b1870 +size 1086 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/string_view.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/string_view.hpp new file mode 100644 index 0000000..1658e83 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/string_view.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0eb53a4a8c7dcf22c55a951cabb7271fba953c5a8a5392841cea9514d4279e16 +size 31127 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/string_view_fwd.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/string_view_fwd.hpp new file mode 100644 index 0000000..4e62c1c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/string_view_fwd.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2d573b90d1c9af9679016397b577bcd83ea383b01b5f3df9fddc9027ed7e214 +size 1233 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/swap.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/swap.hpp new file mode 100644 index 0000000..1b333fe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/swap.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86d926c68f0e886ce02714450837ad08fd1fb12ec8ee64ba2df35dea43611600 +size 390 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/typed_in_place_factory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/typed_in_place_factory.hpp new file mode 100644 index 0000000..bf936ec --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/typed_in_place_factory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6241abd14ae83d7b18fd34cd90884d49292ec3175fa1bbf2bb202434b7e816e0 +size 2140 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/value_init.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/value_init.hpp new file mode 100644 index 0000000..5b2c8bb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/utility/value_init.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1adb619945d11a2b234ae436f37eccf4e5190a83f41e185a1bc0881928d16d9f +size 6369 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/version.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/version.hpp new file mode 100644 index 0000000..9dca5b5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/version.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c32466a31373f045a076982a9b4877137b58b8fb779c4b607924e76056aa3ce +size 1117 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/visit_each.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/visit_each.hpp new file mode 100644 index 0000000..973de81 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/visit_each.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d064c45f15a2f8ac056984994fd85d94b3321e29e74377065b72ba20760b0cc +size 690 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/access_rights.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/access_rights.hpp new file mode 100644 index 0000000..48e3336 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/access_rights.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50f028002990a73a26288de455587b288a0e435ce6eccf2cb3ddfe6868b00985 +size 2968 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/apc.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/apc.hpp new file mode 100644 index 0000000..77d829b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/apc.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed77502b300390b092c5fcfcf1fa8bf826c48b5fa50d47d491471e6e6e153786 +size 1073 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/basic_types.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/basic_types.hpp new file mode 100644 index 0000000..47ef7fa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/basic_types.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb44b57a2206c058104dc1bff6a0f389d9819b8e1ae8d5c6d2523abd7dc86d70 +size 7423 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/bcrypt.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/bcrypt.hpp new file mode 100644 index 0000000..02ff376 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/bcrypt.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9f67262a7b18e6bfb74655abf1e0ca47a4b2a0b459f07509e801f19d82372c39 +size 1953 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/character_code_conversion.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/character_code_conversion.hpp new file mode 100644 index 0000000..f003970 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/character_code_conversion.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:660bef939ea194024e4a9679ccfe695e66ceacb3b18a2f4cdcc9793c8f7ccc03 +size 3633 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/condition_variable.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/condition_variable.hpp new file mode 100644 index 0000000..f112192 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/condition_variable.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa098503dac0d2a8e4a03d074468ce7fda4c7be36a02b3d255d7d1f4fd691533 +size 3774 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/config.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/config.hpp new file mode 100644 index 0000000..2a5dcb9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/config.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e030780fab61ccc7891d3c9b34ee239a60464c964e3a3ea9abc474f00e93db7d +size 10254 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/critical_section.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/critical_section.hpp new file mode 100644 index 0000000..b81fcd8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/critical_section.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4bccb6ffe826691f02fd18d7491af60d7e45ea986d694c4099fac2237d6498af +size 6505 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/crypt.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/crypt.hpp new file mode 100644 index 0000000..f97689a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/crypt.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2582e834a4a6e84fd77339b704dee5accfdb99e54ce9dbb4e07753b2e83ea5b8 +size 5862 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/dbghelp.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/dbghelp.hpp new file mode 100644 index 0000000..e240a5e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/dbghelp.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:830f4b7e01be3894f015a7c98f72e2acd791fb35bf6bd0749f3ac56687a10196 +size 6485 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/debugapi.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/debugapi.hpp new file mode 100644 index 0000000..80e698a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/debugapi.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa1031a74ffc1501485d90422735a6d055905b2e91187a4f852e191ac27f2422 +size 1259 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/detail/cast_ptr.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/detail/cast_ptr.hpp new file mode 100644 index 0000000..adceedb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/detail/cast_ptr.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a95f5a0e99230e8ac0ab122ff282a190fd8b55991b87707bd860c760e1222d7 +size 824 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/directory_management.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/directory_management.hpp new file mode 100644 index 0000000..3598c4e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/directory_management.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c97425cacd77b7ad5039c337bfcba2b30eb31e410c0e038ee8912fff52a634f +size 3286 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/dll.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/dll.hpp new file mode 100644 index 0000000..faf6959 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/dll.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7f958845213302513f966e8829f283921ab09c2349e045c1c8e5e33dc647d0e6 +size 7243 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/environment.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/environment.hpp new file mode 100644 index 0000000..954f44a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/environment.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f32d710e4e807fd3a54b44f62bc8915453a40824274e2ffdde4b2e31ecfa731 +size 4345 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/error_codes.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/error_codes.hpp new file mode 100644 index 0000000..0743482 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/error_codes.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c19f36b16d273b202754876cbac09295034f5944dbafa6dbe6ca7ccd7d183c2 +size 218523 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/error_handling.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/error_handling.hpp new file mode 100644 index 0000000..d3a597d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/error_handling.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d7dae57f4a4c1b1e30e356df323867ab36fd10d9b78dc09333b97f72b6f321d +size 5175 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/event.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/event.hpp new file mode 100644 index 0000000..107f571 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/event.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de5d5fc4669dd7db2ee881114074ff0edf0d5517f92ad53ad336bce9ca0656ca +size 7312 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/file_management.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/file_management.hpp new file mode 100644 index 0000000..1c56d74 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/file_management.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29a0343f8575ae553f7ca4df3ff7ad97b84a6b179f7aa69c24b8f17da389533e +size 21799 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/file_mapping.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/file_mapping.hpp new file mode 100644 index 0000000..d956e77 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/file_mapping.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b8e5bcfe4a53e44fcbbab8318fd82d45cc6cc034cec9753e331179b8b9e6b63 +size 9529 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_current_process.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_current_process.hpp new file mode 100644 index 0000000..83d83ea --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_current_process.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2914aa900c54b7f2625bc245ba2d7d48f1fa6290e1efd5bf0f69167674070b79 +size 789 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_current_process_id.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_current_process_id.hpp new file mode 100644 index 0000000..45ed72c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_current_process_id.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f14f60a1b9b6fb02028c191d01c0af587e41f49d4be7065599adcbe8dc2059d9 +size 769 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_current_thread.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_current_thread.hpp new file mode 100644 index 0000000..1b0d517 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_current_thread.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:84e12d4bbe44a9230dea0ed4238ee975264fbb688dd239ef4e90b1005913a19a +size 783 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_current_thread_id.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_current_thread_id.hpp new file mode 100644 index 0000000..0ba2bcb --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_current_thread_id.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50a3b1896bb7022c93bc005ea1ba893e8e21959dcf905a162ea9926bc3407e55 +size 797 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_last_error.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_last_error.hpp new file mode 100644 index 0000000..dd03fc1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_last_error.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af4bd4425c6f5b0a99da9011ffcc7a7a451887f8b59b3a6d9d52f3b5a12fa261 +size 666 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_process_times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_process_times.hpp new file mode 100644 index 0000000..afebe1e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_process_times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e9b18ae32835ea3e98b89257b4b71084d121282b07559bf928d6551cad7d9eb5 +size 1468 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_system_directory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_system_directory.hpp new file mode 100644 index 0000000..9d460d8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_system_directory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c715deaa9653f2c5d60e249a62f5166558ed5fed2956f331f73bcc7ac64b8ce +size 1379 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_thread_times.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_thread_times.hpp new file mode 100644 index 0000000..6eecf87 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/get_thread_times.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5fb7b0eadff7fe0ff1e8afa382b79f4e6d53176a75f22c9e519c08829518eeb +size 1354 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/handle_info.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/handle_info.hpp new file mode 100644 index 0000000..7883986 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/handle_info.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b4cb315a37d5d555766db550643fc14a9c68be2b77dc684bd7981dd9bb01cdc +size 1385 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/handles.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/handles.hpp new file mode 100644 index 0000000..4084688 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/handles.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4518f9bc446df1c63581a9f7b08d98a06b5319b86fee3a9747100db3bf3be34b +size 2187 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/heap_memory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/heap_memory.hpp new file mode 100644 index 0000000..26ee526 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/heap_memory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ebb4c5425d9bc1a5fb58263768b14795ef52c5898c17f8c3f4b6922197145395 +size 2180 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/init_once.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/init_once.hpp new file mode 100644 index 0000000..5be7045 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/init_once.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ca4c71ec9dc1d8a58ed00161869fc093423111da61e2e7421a3142cd74294d5 +size 4009 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/jobs.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/jobs.hpp new file mode 100644 index 0000000..ed57c7e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/jobs.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c667c96e0e76e09fe29a413a35c160035c0f4cb4da24506fd740957ae6951810 +size 5502 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/limits.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/limits.hpp new file mode 100644 index 0000000..d50ee2b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/limits.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4ad29f8dfd161a2260f7ff0e1b38afed2f4a40ac74ac19fe814ffd9ef5fcfb3 +size 1193 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/local_memory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/local_memory.hpp new file mode 100644 index 0000000..cfc053d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/local_memory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53afd4eef35121870719f2e5e228f7701beb77c684be89eca3546005992caa07 +size 1262 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/memory.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/memory.hpp new file mode 100644 index 0000000..3c63ca8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/memory.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:70fe51126ee99a2395872839db95a24956fd76e0bd25bb5e745ab840a7c0ef74 +size 455 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/mutex.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/mutex.hpp new file mode 100644 index 0000000..ca1f3a2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/mutex.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7de1ef1416a1ea70a09ca9d8d255a73ab57372bb5f334bfbbf1329e2623826a7 +size 6234 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/overlapped.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/overlapped.hpp new file mode 100644 index 0000000..b87a04b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/overlapped.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:297e3a62e3d79c5cbb8e3f6f39cf648e707f1bc3a694fdfb0fb2a14209ab6b18 +size 1044 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/page_protection_flags.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/page_protection_flags.hpp new file mode 100644 index 0000000..105ffbe --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/page_protection_flags.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e58b4c557cb3dfda1260d3b0e31435c1cf86dadabbecd573f7ade027ecb1ac9c +size 1938 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/pipes.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/pipes.hpp new file mode 100644 index 0000000..6efc027 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/pipes.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:09435de87763bdf7aa381baf49b703bf3e77b8266aa1ac13c28f957efc1c717a +size 11145 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/priority_class.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/priority_class.hpp new file mode 100644 index 0000000..5fc3395 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/priority_class.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49227c0adb24a4ad43b9a28a11cfd976b3e7c84317ea28c9d35ae33dc851458d +size 2613 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/process.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/process.hpp new file mode 100644 index 0000000..edc2376 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/process.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1246fe30d9ecdaa84bd4da9488e47d4542af741d65da38fb9dcf0ff0b6f61bee +size 18145 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/security.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/security.hpp new file mode 100644 index 0000000..39316a6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/security.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1cfdb87785e6230162b3e164032c0c89b843e93e8604f7ca340d1d8a07fd64cf +size 2088 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/semaphore.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/semaphore.hpp new file mode 100644 index 0000000..c3bcae5 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/semaphore.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed20108da6d01c38e7975adda1ad56f7eaf0347e15cdf4e08b105a9aacfa26ef +size 6642 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/shell.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/shell.hpp new file mode 100644 index 0000000..3de5240 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/shell.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed4056ee998ad16469ad24bf8a544cb57e6752f87e82ccfc91e9b45958757a06 +size 6005 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/show_window.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/show_window.hpp new file mode 100644 index 0000000..0c7c190 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/show_window.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:013f1cf08f38ac01a4d23136538b75f5f0edcafd90da38ef49bbc9e2b279421e +size 4104 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/srw_lock.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/srw_lock.hpp new file mode 100644 index 0000000..1eabc71 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/srw_lock.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d4e762d012c3b22bda686319e9548b89d68377d436fc717b378f1ea407b3d3f0 +size 3258 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/stack_backtrace.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/stack_backtrace.hpp new file mode 100644 index 0000000..56a7825 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/stack_backtrace.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cfa3d6b7e82313d7d287f4ea31278cc89945b4c789ffaf761363ff80c926d764 +size 1416 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/synchronization.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/synchronization.hpp new file mode 100644 index 0000000..c68c62e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/synchronization.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b73e7275c727fbeafe543783f7aa4d29e58cb105906ef6575d3c2d51d83b4b56 +size 779 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/system.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/system.hpp new file mode 100644 index 0000000..57a10bd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/system.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2fa5d5133283b0a4913b2e7c87cea7a623cdd0716382e0218a301680a8bfe81b +size 2241 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/thread.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/thread.hpp new file mode 100644 index 0000000..6408889 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/thread.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e443edc24f6591e16e60a6f3f94ce278348e88d9de87c6707c517fc87875cc4a +size 1134 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/thread_pool.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/thread_pool.hpp new file mode 100644 index 0000000..571415b --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/thread_pool.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6dd003713d4146c395d05f0293f62bf9de31191999373eda2a21b403c7249dde +size 5241 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/time.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/time.hpp new file mode 100644 index 0000000..40efd3d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/time.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:93c0fa9dc55b440256664357e401a47e73a20e65ee4166f316b45130e0a77b55 +size 4332 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/timers.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/timers.hpp new file mode 100644 index 0000000..1a89dc3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/timers.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3901e9600700f2942375f8b00d6329582436e625de1220b38957a6b90979d6a6 +size 1143 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/tls.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/tls.hpp new file mode 100644 index 0000000..7643860 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/tls.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d742766dbc598f2e571b25169701511fe3ee44497619c70d9964a347990ef07 +size 1488 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/wait.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/wait.hpp new file mode 100644 index 0000000..f9033e7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/wait.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f5f8cc96b1e9126797345a7c71f0b61c12d23ecfb2adcf3bdaed5ed43b10645 +size 3553 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/waitable_timer.hpp b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/waitable_timer.hpp new file mode 100644 index 0000000..63a6f03 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/boost/winapi/waitable_timer.hpp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b3181d7643eaf64b23e60e2a10d1b162b3287d26579597284da3a4ebc8c32f8 +size 4980 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/serial/impl/unix.h b/Plugins/SenseGlove/Source/ThirdParty/include/serial/impl/unix.h new file mode 100644 index 0000000..36fc8f2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/serial/impl/unix.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5fb6fe5dc66aa262c4fcd602c677938bf9a65ddc2010c7b022c7aade1f36bc6 +size 4312 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/serial/impl/win.h b/Plugins/SenseGlove/Source/ThirdParty/include/serial/impl/win.h new file mode 100644 index 0000000..6145eaf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/serial/impl/win.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:416e11faeaae7df28f47e801a58cb1d9ac78d7413a43cb70830a2d1271a889fc +size 3899 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/serial/serial.h b/Plugins/SenseGlove/Source/ThirdParty/include/serial/serial.h new file mode 100644 index 0000000..8f4656c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/serial/serial.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4dcb008056f41fbb80357da817959e8cf5e2f6d04fb79a416b4fedd68a8a0d7 +size 23702 diff --git a/Plugins/SenseGlove/Source/ThirdParty/include/serial/v8stdint.h b/Plugins/SenseGlove/Source/ThirdParty/include/serial/v8stdint.h new file mode 100644 index 0000000..a662d12 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/include/serial/v8stdint.h @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1155ad61ee6583c90ce3abb174239fbb677627e8220fb8518c8d5e4d3d16e5d +size 2257 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/debug/libserial.a b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/debug/libserial.a new file mode 100644 index 0000000..e14f982 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/debug/libserial.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b934d7ffef60b7f545127257b83be50844e6b39bc2be284caf287aced3dcf2a +size 1201140 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/debug/libsgconnect.a b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/debug/libsgconnect.a new file mode 100644 index 0000000..ba35557 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/debug/libsgconnect.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3900644cfe60326eff031ea7a4072109ba20fcc93b7c90f7086911a38dc8409 +size 8998616 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/debug/libsgcore.a b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/debug/libsgcore.a new file mode 100644 index 0000000..8f32157 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/debug/libsgcore.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:27431542b6639bcf47a6db71e25cd726c808eba005db45716b8fc489a707f239 +size 15512404 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/release/libserial.a b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/release/libserial.a new file mode 100644 index 0000000..9f8b8c9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/release/libserial.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f1f4508e8fc48c72406b8e4877b0569a809217a6057368847acfbb9da10a839 +size 204780 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/release/libsgconnect.a b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/release/libsgconnect.a new file mode 100644 index 0000000..2a9a8ff --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/release/libsgconnect.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7976d77a6eb7359b3375706115c829b8b8f84f97fed42b5d62bf1a18c86abfc +size 1223238 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/release/libsgcore.a b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/release/libsgcore.a new file mode 100644 index 0000000..40ceab2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/arm64/release/libsgcore.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60d43482ddab6fb52e6cbe614c82c2bcc725a96cfdaa9b61e46cc5ac78a1bd01 +size 1945776 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/debug/libserial.a b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/debug/libserial.a new file mode 100644 index 0000000..bd17300 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/debug/libserial.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0351595c5bde877356168c83949ea72d3ea2691b90d016660c401004a3199d3e +size 1180964 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/debug/libsgconnect.a b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/debug/libsgconnect.a new file mode 100644 index 0000000..cea72d2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/debug/libsgconnect.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c2d7dd37ee3340e4dc476510ba6ec9c143ac7d77a5a17eee94b5be4001c15bf +size 8802496 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/debug/libsgcore.a b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/debug/libsgcore.a new file mode 100644 index 0000000..dd05f4e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/debug/libsgcore.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:abffb77b308e0d213f7120ddee20e0a025f87ba0b0cb058d63def96a3f6dd2e4 +size 15215764 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/release/libserial.a b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/release/libserial.a new file mode 100644 index 0000000..9eb8987 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/release/libserial.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39b2f39bd96834bc386d5f035ed3a863ae9517df9cf621c7cbb6341b7e29956b +size 196980 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/release/libsgconnect.a b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/release/libsgconnect.a new file mode 100644 index 0000000..9f42325 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/release/libsgconnect.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74e6ef5d07873d229ca3698220688c6e7757098ec6381cfa819cba1a8a6edb3e +size 1169478 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/release/libsgcore.a b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/release/libsgcore.a new file mode 100644 index 0000000..3819674 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/android/r25b/x64/release/libsgcore.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cfef8ac3890d2f3753437f3b211304eef574f306bcda5886f20556b7fcc6abab +size 1925088 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/debug/libserial.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/debug/libserial.a new file mode 100644 index 0000000..0d7ce13 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/debug/libserial.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0828434ae090a3d1c24b1b1f8ce5634f8d46713b3a1933a10c833f91743d109f +size 934754 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/debug/libsgconnect.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/debug/libsgconnect.a new file mode 100644 index 0000000..99bc9e4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/debug/libsgconnect.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:824f593e2756edf1a6f8597da4c1f6d86b6838278d7de62b6b5cd46a7889d35c +size 7985884 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/debug/libsgcore.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/debug/libsgcore.a new file mode 100644 index 0000000..53c5d4c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/debug/libsgcore.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:704912abf57b87df8767b13d8a2f26fea1ad254d13a99080e4c858ee8f9d0816 +size 12915592 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/release/libserial.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/release/libserial.a new file mode 100644 index 0000000..e36e362 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/release/libserial.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:950e5c4f5f2b6fe4b8d5c46783cb197167b7e52c61f4503abd8f6ea9873fcdf4 +size 204488 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/release/libsgconnect.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/release/libsgconnect.a new file mode 100644 index 0000000..dd17f7e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/release/libsgconnect.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:71ad516d3dd6efa1b99e921dee8df8a8a184e47348ef89811b6ddbac8e6411fa +size 1165080 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/release/libsgcore.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/release/libsgcore.a new file mode 100644 index 0000000..99d9c04 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/aarch64/release/libsgcore.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af269acdf6963ad84deb5ce47ca0d56ad385656c3a42b31638428108cbb24061 +size 1868250 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/debug/libserial.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/debug/libserial.a new file mode 100644 index 0000000..106e170 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/debug/libserial.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b39cdadcafde46ce084d12516fab761d57cb4742a342620cb39dd718342ac771 +size 907570 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/debug/libsgconnect.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/debug/libsgconnect.a new file mode 100644 index 0000000..9fffba9 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/debug/libsgconnect.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1a54cc743038d67f908291779d2992f6f8dc48c818ebeb4b4871302718881991 +size 7690528 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/debug/libsgcore.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/debug/libsgcore.a new file mode 100644 index 0000000..2708617 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/debug/libsgcore.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5153fdae1084f26b49f4f78d6bcb6d602dd829231009a7550ee0192adeade90b +size 12587376 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/release/libserial.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/release/libserial.a new file mode 100644 index 0000000..e435ea8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/release/libserial.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:073672db98f3abee30f184cbf98f4ee0cac1c3342ddd9d727a686c0a64a87e12 +size 195792 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/release/libsgconnect.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/release/libsgconnect.a new file mode 100644 index 0000000..134283e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/release/libsgconnect.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0746d48addfed2ccc89ac7d92d40e4666ecb814f7a80011f6c6ea4d4047a7f5f +size 1048738 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/release/libsgcore.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/release/libsgcore.a new file mode 100644 index 0000000..7095652 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v21/x86-64/release/libsgcore.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0e1e838e99b9d84ff55c273c0c0df017d1f726940293886120613a02c16b7fb +size 1856954 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/debug/libserial.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/debug/libserial.a new file mode 100644 index 0000000..138fc42 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/debug/libserial.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9aeebd82f3b53a1b4dbb3a17e9ca7beecb001f52a55694821faeed023e05da9e +size 1097926 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/debug/libsgconnect.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/debug/libsgconnect.a new file mode 100644 index 0000000..9158a7e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/debug/libsgconnect.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7de26952358d9cf66efd111c45fe654b2e7007329b42b64dbd75d6c27008e2a6 +size 8679318 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/debug/libsgcore.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/debug/libsgcore.a new file mode 100644 index 0000000..6930925 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/debug/libsgcore.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d723e1bda8c185ddf11354abf28ec8baf58652d066b542ca6b154c53a63f4284 +size 15165802 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/release/libserial.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/release/libserial.a new file mode 100644 index 0000000..e354d34 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/release/libserial.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01e571a6922f37e7c242e51e400a7ce3d0317a7717cceac6d230560d1f7e9e64 +size 205888 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/release/libsgconnect.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/release/libsgconnect.a new file mode 100644 index 0000000..6397a4f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/release/libsgconnect.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:301ed060b26246dddc26513f2b5de0a67b3a7d56d2c8e491ccc2ad355be82db3 +size 1170650 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/release/libsgcore.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/release/libsgcore.a new file mode 100644 index 0000000..941775c --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/aarch64/release/libsgcore.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c82ac042938c376d7ddd0b7d48ad03b04a13842881c882c20ecea93fc1d9dc9f +size 1896818 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/debug/libserial.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/debug/libserial.a new file mode 100644 index 0000000..d7889a2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/debug/libserial.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d80df4cb95a70019765501330796578dd0c0bbcf396614f4bc0c7217930d0f40 +size 1068878 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/debug/libsgconnect.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/debug/libsgconnect.a new file mode 100644 index 0000000..e4afc07 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/debug/libsgconnect.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c100e4817b28a3a4ebf6e657b64fd6ac37ebd808de8c1e59d66c7782c2eb6da5 +size 8378546 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/debug/libsgcore.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/debug/libsgcore.a new file mode 100644 index 0000000..60e5131 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/debug/libsgcore.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92ef9e510ebe66c2bbeb0bac0d993bd6d8b60a229a369815dfd5f3e63ff71039 +size 14806370 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/release/libserial.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/release/libserial.a new file mode 100644 index 0000000..51996ca --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/release/libserial.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1885945651f58c73ead6f778f2f0e387a5fe6aff6eda5fc675f7ec3d7385d0bc +size 195912 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/release/libsgconnect.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/release/libsgconnect.a new file mode 100644 index 0000000..61f0a9d --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/release/libsgconnect.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07b9996c12ed1bdc50c030446a92c14437f294cb70c13834eeabfe66f41c5dba +size 1051484 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/release/libsgcore.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/release/libsgcore.a new file mode 100644 index 0000000..6f4b9b6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v22/x86-64/release/libsgcore.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bbc8f4b945a41d3cdf7e1f2069b989c19c5ea91449fe1a2fd59c678a8473e741 +size 1877862 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/debug/libserial.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/debug/libserial.a new file mode 100644 index 0000000..ba95d4f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/debug/libserial.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:667f76b2d6ab6debc469cca23f02e66c4eba299c2de4df693b92926853fe3b4d +size 472052 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/debug/libsgconnect.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/debug/libsgconnect.a new file mode 100644 index 0000000..11da2e4 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/debug/libsgconnect.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0acc461b2a395d0c981c8a0a7fcbbd360116e2587829135f35abf17c0710355f +size 6817582 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/debug/libsgcore.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/debug/libsgcore.a new file mode 100644 index 0000000..37be0f1 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/debug/libsgcore.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58b396521debcbce92595dc4bb480d3acd78cb24bee5f3ef7b7fad9190b9ffca +size 10919838 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/release/libserial.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/release/libserial.a new file mode 100644 index 0000000..624d4fa --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/release/libserial.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30147fa1be38400374d1fe44fc625cd57866e22fb5e4533f676249ef7c4f4208 +size 149174 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/release/libsgconnect.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/release/libsgconnect.a new file mode 100644 index 0000000..09ccff7 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/release/libsgconnect.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ec11c08d3d130e4d3fbef8f7f4a026dab2355717323c76046a77c29bbccd6a5c +size 1240808 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/release/libsgcore.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/release/libsgcore.a new file mode 100644 index 0000000..8bd55d0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/aarch64/release/libsgcore.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee7cb1e722eebd21f7a99562fda78b0d806947cda5c543126bb49d465aa5aac7 +size 1984328 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/debug/libserial.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/debug/libserial.a new file mode 100644 index 0000000..9fb1ff6 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/debug/libserial.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3bb65160244f1158c1483168619a94dcad3cf85e77499161eae67c38892498ba +size 464580 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/debug/libsgconnect.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/debug/libsgconnect.a new file mode 100644 index 0000000..9ef4651 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/debug/libsgconnect.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c2b85e615b87b99215888481f11c1619690956367238dcd497a2d29668713e2a +size 6570312 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/debug/libsgcore.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/debug/libsgcore.a new file mode 100644 index 0000000..b25d49a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/debug/libsgcore.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9bcf033a453397ba59527061bbb9c0f614d9ce0cfca33e4372bf946954426235 +size 10690778 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/release/libserial.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/release/libserial.a new file mode 100644 index 0000000..d465e9a --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/release/libserial.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b02034858079b0ef8d47041a4c1400da4236c65e2c9d4e3ef7d83620e718e4c +size 142694 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/release/libsgconnect.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/release/libsgconnect.a new file mode 100644 index 0000000..b8ca54e --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/release/libsgconnect.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:534ce86201ca23b52d785467011438a9e586b244c1695a0737f35e1e216083c0 +size 1106906 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/release/libsgcore.a b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/release/libsgcore.a new file mode 100644 index 0000000..211c2b0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/linux/v23/x86-64/release/libsgcore.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7966e414ea7cc355e1fcb0c8820dc1eab3b5026cc23b28306429eca48cbcde9a +size 1942908 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/debug/serial.lib b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/debug/serial.lib new file mode 100644 index 0000000..fbe61d8 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/debug/serial.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e6b99e2e9a2239d52014c5d759a122a457ec7370dd263e325f9a8056ed3d7578 +size 1188592 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/debug/sgconnect.lib b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/debug/sgconnect.lib new file mode 100644 index 0000000..a817d92 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/debug/sgconnect.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da0c92d43cc1c2ce8a6ab1801452a7f96c1da66d78f75906fc9078441e44766b +size 14089624 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/debug/sgcore.lib b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/debug/sgcore.lib new file mode 100644 index 0000000..7f1f2a0 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/debug/sgcore.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19af95d6167df3d2fa22c72c4eb23e7b53f9a7688311978b593484033a5f2ce3 +size 21696752 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/release/serial.lib b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/release/serial.lib new file mode 100644 index 0000000..0a7bbbf --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/release/serial.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe8e6c9894c4f0a245e86d06cf4ff2a6b84ea263ca032df222b7320853eacf8c +size 351206 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/release/sgconnect.lib b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/release/sgconnect.lib new file mode 100644 index 0000000..7a1eca3 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/release/sgconnect.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b4b5916a2c7cfe76e1ad0f6800b1c6195b2aef22f396238a09c8ec5815afa9a +size 3003464 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/release/sgcore.lib b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/release/sgcore.lib new file mode 100644 index 0000000..702e405 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc142/release/sgcore.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91a3fa607dde7345626353e14ed23e32622ac8ce4e36b98cd0e39d958dc8ab72 +size 5216388 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/debug/serial.lib b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/debug/serial.lib new file mode 100644 index 0000000..2783d73 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/debug/serial.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e00c4580da86de13769688a6259b741f0971e2bf978d6014d570196aecec8f4f +size 1165006 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/debug/sgconnect.lib b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/debug/sgconnect.lib new file mode 100644 index 0000000..28e460f --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/debug/sgconnect.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49bfe2ff74df86d1c4cd619c4d5386f3cb9840fde7379ba18d5bb4e14fe8711a +size 14369400 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/debug/sgcore.lib b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/debug/sgcore.lib new file mode 100644 index 0000000..381fba2 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/debug/sgcore.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90c53571a214f62eab982100cd74ff1f9353d866a66beee26a07b206befd61f0 +size 21748356 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/release/serial.lib b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/release/serial.lib new file mode 100644 index 0000000..a42de76 --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/release/serial.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83bbbcbab4c8e0c9ec168221d393449897fa0655fdf2b5decf38e6f434cfd6d4 +size 340028 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/release/sgconnect.lib b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/release/sgconnect.lib new file mode 100644 index 0000000..0ed0ead --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/release/sgconnect.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79cbf7d019f623bcd858c7bde44c76f32101e15761be1c26433a8a1dabbb08ac +size 2878326 diff --git a/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/release/sgcore.lib b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/release/sgcore.lib new file mode 100644 index 0000000..daa72fd --- /dev/null +++ b/Plugins/SenseGlove/Source/ThirdParty/lib/win64/msvc143/release/sgcore.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4a740bd79f189f4fcfbe911425f180d216c6425c8e9c88588e424dff5255031 +size 4989778 diff --git a/Plugins/VRExpansionPlugin/Config/FilterPlugin.ini b/Plugins/VRExpansionPlugin/Config/FilterPlugin.ini new file mode 100644 index 0000000..ccebca2 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Config/FilterPlugin.ini @@ -0,0 +1,8 @@ +[FilterPlugin] +; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and +; may include "...", "*", and "?" wildcards to match directories, files, and individual characters respectively. +; +; Examples: +; /README.txt +; /Extras/... +; /Binaries/ThirdParty/*.dll diff --git a/Plugins/VRExpansionPlugin/Resources/Icon128.png b/Plugins/VRExpansionPlugin/Resources/Icon128.png new file mode 100644 index 0000000..23fec31 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Resources/Icon128.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb8f329acc9d0c2815d28349d5a4144ebd337f7e2a93819cf1a7c3cc9b06ecea +size 16085 diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Private/HandSocketComponentDetails.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Private/HandSocketComponentDetails.cpp new file mode 100644 index 0000000..4198f7c --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Private/HandSocketComponentDetails.cpp @@ -0,0 +1,849 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "HandSocketComponentDetails.h" +#include "HandSocketVisualizer.h" +//#include "PropertyEditing.h" +#include "Widgets/Text/STextBlock.h" +#include "Widgets/Input/SButton.h" +#include "PropertyHandle.h" +#include "DetailLayoutBuilder.h" +#include "DetailWidgetRow.h" +#include "DetailCategoryBuilder.h" +#include "IDetailsView.h" + +#include "Developer/AssetTools/Public/IAssetTools.h" +#include "Developer/AssetTools/Public/AssetToolsModule.h" +#include "Editor/ContentBrowser/Public/IContentBrowserSingleton.h" +#include "Editor/ContentBrowser/Public/ContentBrowserModule.h" +#include "AnimationUtils.h" +#include "AssetRegistry/AssetRegistryModule.h" +#include "UObject/SavePackage.h" +#include "Misc/MessageDialog.h" +#include "Widgets/Layout/SBorder.h" +#include "Widgets/Layout/SSeparator.h" +#include "Widgets/Layout/SUniformGridPanel.h" +#include "Widgets/Input/SEditableTextBox.h" +#include "Editor.h" +#include "EditorStyleSet.h" +#include "Styling/CoreStyle.h" + +#include "Animation/AnimData/AnimDataModel.h" + +#include "Editor/UnrealEdEngine.h" +#include "UnrealEdGlobals.h" + +#define LOCTEXT_NAMESPACE "HandSocketComponentDetails" + +FText SCreateHandAnimationDlg::LastUsedAssetPath; + +static bool PromptUserForAssetPath(FString& AssetPath, FString& AssetName) +{ + TSharedRef NewAnimDlg = SNew(SCreateHandAnimationDlg); + if (NewAnimDlg->ShowModal() != EAppReturnType::Cancel) + { + AssetPath = NewAnimDlg->GetFullAssetPath(); + AssetName = NewAnimDlg->GetAssetName(); + return true; + } + + return false; +} + +TWeakObjectPtr FHandSocketComponentDetails::SaveAnimationAsset(const FString& InAssetPath, const FString& InAssetName) +{ + + TWeakObjectPtr FinalAnimation; + + // Replace when this moves to custom display + if (!HandSocketComponent.IsValid()) + return FinalAnimation; + + /*if (!HandSocketComponent->HandVisualizerComponent)// || !HandSocketComponent->HandVisualizerComponent->SkeletalMesh || !HandSocketComponent->HandVisualizerComponent->SkeletalMesh->Skeleton) + { + return false; + }*/ + + if (!HandSocketComponent->HandTargetAnimation && (!HandSocketComponent->VisualizationMesh || !HandSocketComponent->VisualizationMesh->GetSkeleton())) + { + return FinalAnimation; + } + + // create the asset + FText InvalidPathReason; + bool const bValidPackageName = FPackageName::IsValidLongPackageName(InAssetPath, false, &InvalidPathReason); + if (bValidPackageName == false) + { + UE_LOG(LogAnimation, Log, TEXT("%s is an invalid asset path, prompting user for new asset path. Reason: %s"), *InAssetPath, *InvalidPathReason.ToString()); + } + + FString ValidatedAssetPath = InAssetPath; + FString ValidatedAssetName = InAssetName; + + UObject* Parent = bValidPackageName ? CreatePackage(*ValidatedAssetPath) : nullptr; + if (Parent == nullptr) + { + // bad or no path passed in, do the popup + if (PromptUserForAssetPath(ValidatedAssetPath, ValidatedAssetName) == false) + { + return FinalAnimation; + } + + Parent = CreatePackage(*ValidatedAssetPath); + } + + UObject* const Object = LoadObject(Parent, *ValidatedAssetName, nullptr, LOAD_Quiet, nullptr); + // if object with same name exists, warn user + if (Object) + { + EAppReturnType::Type ReturnValue = FMessageDialog::Open(EAppMsgType::YesNo, LOCTEXT("Error_AssetExist", "Asset with same name exists. Do you wish to overwrite it?")); + if (ReturnValue == EAppReturnType::No) + { + return FinalAnimation; // failed + } + } + + UAnimSequence* BaseAnimation = HandSocketComponent->HandTargetAnimation; + TArray LocalPoses; + + if (!BaseAnimation) + { + LocalPoses = HandSocketComponent->VisualizationMesh->GetSkeleton()->GetRefLocalPoses(); + } + + // If not, create new one now. + UAnimSequence* const NewSeq = NewObject(Parent, *ValidatedAssetName, RF_Public | RF_Standalone); + if (NewSeq) + { + // set skeleton + if (BaseAnimation) + { + NewSeq->SetSkeleton(BaseAnimation->GetSkeleton()); + } + else + { + NewSeq->SetSkeleton(HandSocketComponent->VisualizationMesh->GetSkeleton()); + } + + // Notify the asset registry + FAssetRegistryModule::AssetCreated(NewSeq); + //StartRecord(Component, NewSeq); + + //return true; + UAnimSequence* AnimationObject = NewSeq; + + IAnimationDataController& AnimController = AnimationObject->GetController(); + { + IAnimationDataController::FScopedBracket ScopedBracket(AnimController, LOCTEXT("SaveAnimationAsset_VRE", "Creating Animation Sequence based on hand pose")); + AnimationObject->ResetAnimation(); + if (BaseAnimation) + { + AnimationObject->BoneCompressionSettings = BaseAnimation->BoneCompressionSettings; + } + else + { + AnimationObject->BoneCompressionSettings = FAnimationUtils::GetDefaultAnimationBoneCompressionSettings(); + } + + AnimController.InitializeModel(); + AnimController.RemoveAllBoneTracks(false); + + + //checkf(MovieScene, TEXT("No Movie Scene found for SequencerDataModel")); + //AnimController.SetPlayLength(4.f); + AnimController.SetNumberOfFrames(FFrameNumber(1), false); + + // Set frame rate to 1 to 1 as we don't animate + AnimController.SetFrameRate(FFrameRate(1, 1)); + + TArray TrackNames; + const IAnimationDataModel* BaseDataModel = BaseAnimation ? BaseAnimation->GetController().GetModel() : nullptr; + + if (BaseAnimation) + { + if (BaseDataModel) + { + BaseDataModel->GetBoneTrackNames(TrackNames); + for (FName TrackName : TrackNames) + { + AnimController.AddBoneCurve(TrackName); + } + } + else + { + return FinalAnimation; + } + } + else + { + int numBones = HandSocketComponent->VisualizationMesh->GetRefSkeleton().GetNum(); + for (int i = 0; i < LocalPoses.Num() && i < numBones; ++i) + { + AnimController.AddBoneCurve(HandSocketComponent->VisualizationMesh->GetRefSkeleton().GetBoneName(i)); + //AnimController.AddBoneTrack(HandSocketComponent->VisualizationMesh->GetRefSkeleton().GetBoneName(i)); + } + } + + if (BaseAnimation) + { + AnimationObject->RetargetSource = BaseAnimation->RetargetSource; + } + else + { + AnimationObject->RetargetSource = HandSocketComponent->VisualizationMesh ? HandSocketComponent->VisualizationMesh->GetSkeleton()->GetRetargetSourceForMesh(HandSocketComponent->VisualizationMesh) : NAME_None; + } + + const IAnimationDataModel* DataModel = AnimController.GetModel(); + + /// SAVE POSE + if (BaseAnimation && DataModel && BaseDataModel) + { + for (int32 TrackIndex = 0; TrackIndex < /*DataModel->GetBoneAnimationTracks().Num()*/BaseDataModel->GetNumBoneTracks(); ++TrackIndex) + { + FName TrackName = TrackIndex < TrackNames.Num() ? TrackNames[TrackIndex] : NAME_None; + if (!BaseDataModel->IsValidBoneTrackName(TrackName)) + { + continue; + } + + FTransform FinalTrans = BaseDataModel->GetBoneTrackTransform(TrackName, 0); + //FTransform FinalTrans(Rot, Loc, Scale); + + FQuat DeltaQuat = FQuat::Identity; + for (FBPVRHandPoseBonePair& HandPair : HandSocketComponent->CustomPoseDeltas) + { + if (HandPair.BoneName == TrackName) + { + DeltaQuat = HandPair.DeltaPose; + break; + } + } + + FinalTrans.ConcatenateRotation(DeltaQuat); + FinalTrans.NormalizeRotation(); + + //FRawAnimSequenceTrack& RawNewTrack = DataModel->GetBoneTrackByIndex(TrackIndex).InternalTrackData; + AnimController.SetBoneTrackKeys(TrackName, { FinalTrans.GetTranslation() }, { FinalTrans.GetRotation() }, { FinalTrans.GetScale3D() }); + } + } + else if(DataModel) + { + USkeletalMesh* SkeletalMesh = HandSocketComponent->VisualizationMesh; + FReferenceSkeleton RefSkeleton = SkeletalMesh->GetRefSkeleton(); + USkeleton* AnimSkeleton = SkeletalMesh->GetSkeleton(); + + for (int32 TrackIndex = 0; TrackIndex < RefSkeleton.GetNum(); ++TrackIndex) + { + + FName TrackName = RefSkeleton.GetBoneName(TrackIndex); + if (!DataModel->IsValidBoneTrackName(TrackName)) + { + continue; + } + + int32 BoneTreeIndex = RefSkeleton.FindBoneIndex(TrackName); + + // verify if this bone exists in skeleton + //int32 BoneTreeIndex = DataModel->GetBoneTrackByIndex(TrackIndex).BoneTreeIndex; + + if (BoneTreeIndex != INDEX_NONE) + { + + int32 BoneIndex = BoneTreeIndex;//AnimSkeleton->GetMeshBoneIndexFromSkeletonBoneIndex(SkeletalMesh, BoneTreeIndex); + //int32 ParentIndex = SkeletalMesh->RefSkeleton.GetParentIndex(BoneIndex); + FTransform LocalTransform = LocalPoses[BoneIndex]; + + + FName BoneName = AnimSkeleton->GetReferenceSkeleton().GetBoneName(BoneIndex); + + FQuat DeltaQuat = FQuat::Identity; + for (FBPVRHandPoseBonePair& HandPair : HandSocketComponent->CustomPoseDeltas) + { + if (HandPair.BoneName == BoneName) + { + DeltaQuat = HandPair.DeltaPose; + } + } + + LocalTransform.ConcatenateRotation(DeltaQuat); + LocalTransform.NormalizeRotation(); + + AnimController.SetBoneTrackKeys(BoneName, { LocalTransform.GetTranslation() }, { LocalTransform.GetRotation() }, { LocalTransform.GetScale3D() }); + } + } + } + + AnimController.NotifyPopulated(); + } + /// END SAVE POSE + /// + /// + /// + + // init notifies + AnimationObject->InitializeNotifyTrack(); + //#TODO: 5.1, need to figure out what they replaced this with + //PRAGMA_DISABLE_DEPRECATION_WARNINGS + //AnimationObject->PostProcessSequence(); + //PRAGMA_ENABLE_DEPRECATION_WARNINGS + AnimationObject->MarkPackageDirty(); + + //if (bAutoSaveAsset) + { + UPackage* const Package = AnimationObject->GetOutermost(); + FString const PackageName = Package->GetName(); + FString const PackageFileName = FPackageName::LongPackageNameToFilename(PackageName, FPackageName::GetAssetPackageExtension()); + + double StartTime = FPlatformTime::Seconds(); + + FSavePackageArgs PackageArguments; + PackageArguments.SaveFlags = RF_Standalone; + PackageArguments.SaveFlags = SAVE_NoError; + UPackage::SavePackage(Package, NULL, *PackageFileName, PackageArguments); + //UPackage::SavePackage(Package, NULL, RF_Standalone, *PackageFileName, GError, nullptr, false, true, SAVE_NoError); + + double ElapsedTime = FPlatformTime::Seconds() - StartTime; + UE_LOG(LogAnimation, Log, TEXT("Animation Recorder saved %s in %0.2f seconds"), *PackageName, ElapsedTime); + } + + FinalAnimation = AnimationObject; + return FinalAnimation; + } + + return FinalAnimation; +} +TSharedRef< IDetailCustomization > FHandSocketComponentDetails::MakeInstance() +{ + return MakeShareable(new FHandSocketComponentDetails); +} + +void FHandSocketComponentDetails::OnHandRelativeUpdated(IDetailLayoutBuilder* LayoutBuilder) +{ + + if (!HandSocketComponent.IsValid()) + { + return; + } + + HandSocketComponent->Modify(); + if (AActor* Owner = HandSocketComponent->GetOwner()) + { + Owner->Modify(); + } + + TSharedPtr Visualizer = GUnrealEd->FindComponentVisualizer(HandSocketComponent->GetClass()); + FHandSocketVisualizer* HandVisualizer = (FHandSocketVisualizer*)Visualizer.Get(); + + if (HandVisualizer) + { + if (UHandSocketComponent* RefHand = HandVisualizer->GetCurrentlyEditingComponent()) + { + RefHand->HandRelativePlacement = HandSocketComponent->HandRelativePlacement; + } + } + + FComponentVisualizer::NotifyPropertyModified(HandSocketComponent.Get(), FindFProperty(UHandSocketComponent::StaticClass(), GET_MEMBER_NAME_CHECKED(UHandSocketComponent, HandRelativePlacement))); +} + +void FHandSocketComponentDetails::OnLeftDominantUpdated(IDetailLayoutBuilder* LayoutBuilder) +{ + + if (!HandSocketComponent.IsValid()) + { + return; + } + + // Default to always flipping this + //if (HandSocketComponent->bFlipForLeftHand) + { + FTransform relTrans = HandSocketComponent->GetRelativeTransform(); + FTransform HandPlacement = HandSocketComponent->GetHandRelativePlacement(); + + if (HandSocketComponent->bDecoupleMeshPlacement) + { + relTrans = FTransform::Identity; + } + + FTransform ReturnTrans = (HandPlacement * relTrans); + + HandSocketComponent->MirrorHandTransform(ReturnTrans, relTrans); + + HandSocketComponent->Modify(); + if (AActor* Owner = HandSocketComponent->GetOwner()) + { + Owner->Modify(); + } + ReturnTrans = ReturnTrans.GetRelativeTransform(relTrans); + HandSocketComponent->HandRelativePlacement = ReturnTrans; + + TSharedPtr Visualizer = GUnrealEd->FindComponentVisualizer(HandSocketComponent->GetClass()); + FHandSocketVisualizer* HandVisualizer = (FHandSocketVisualizer*)Visualizer.Get(); + + if (HandVisualizer) + { + if (UHandSocketComponent* RefHand = HandVisualizer->GetCurrentlyEditingComponent()) + { + RefHand->HandRelativePlacement = HandSocketComponent->HandRelativePlacement; + //FComponentVisualizer::NotifyPropertyModified(RefHand, FindFProperty(UHandSocketComponent::StaticClass(), GET_MEMBER_NAME_CHECKED(UHandSocketComponent, HandRelativePlacement))); + } + } + + FComponentVisualizer::NotifyPropertyModified(HandSocketComponent.Get(), FindFProperty(UHandSocketComponent::StaticClass(), GET_MEMBER_NAME_CHECKED(UHandSocketComponent, HandRelativePlacement))); + } +} + +void FHandSocketComponentDetails::OnLockedStateUpdated(IDetailLayoutBuilder* LayoutBuilder) +{ + + if (!HandSocketComponent.IsValid()) + { + return; + } + + if (HandSocketComponent->bDecoupleMeshPlacement) + { + //FTransform RelTrans = HandSocketComponent->GetRelativeTransform(); + //FTransform WorldTrans = HandSocketComponent->GetComponentTransform(); + //if (USceneComponent* ParentComp = HandSocketComponent->GetAttachParent()) + { + + HandSocketComponent->Modify(); + if (AActor* Owner = HandSocketComponent->GetOwner()) + { + Owner->Modify(); + } + + HandSocketComponent->HandRelativePlacement = HandSocketComponent->HandRelativePlacement * HandSocketComponent->GetRelativeTransform();// HandSocketComponent->GetComponentTransform(); + HandSocketComponent->bDecoupled = true; + + TSharedPtr Visualizer = GUnrealEd->FindComponentVisualizer(HandSocketComponent->GetClass()); + FHandSocketVisualizer* HandVisualizer = (FHandSocketVisualizer*)Visualizer.Get(); + + if (HandVisualizer) + { + if (UHandSocketComponent* RefHand = HandVisualizer->GetCurrentlyEditingComponent()) + { + RefHand->HandRelativePlacement = HandSocketComponent->HandRelativePlacement; + RefHand->bDecoupled = true; + //FComponentVisualizer::NotifyPropertyModified(RefHand, FindFProperty(UHandSocketComponent::StaticClass(), GET_MEMBER_NAME_CHECKED(UHandSocketComponent, HandRelativePlacement))); + } + } + } + } + else + { + //if (USceneComponent* ParentComp = HandSocketComponent->GetAttachParent()) + { + HandSocketComponent->Modify(); + if (AActor* Owner = HandSocketComponent->GetOwner()) + { + Owner->Modify(); + } + HandSocketComponent->HandRelativePlacement = HandSocketComponent->HandRelativePlacement.GetRelativeTransform(HandSocketComponent->GetRelativeTransform()); + HandSocketComponent->bDecoupled = false; + + TSharedPtr Visualizer = GUnrealEd->FindComponentVisualizer(HandSocketComponent->GetClass()); + FHandSocketVisualizer* HandVisualizer = (FHandSocketVisualizer*)Visualizer.Get(); + + if (HandVisualizer) + { + if (UHandSocketComponent* RefHand = HandVisualizer->GetCurrentlyEditingComponent()) + { + RefHand->HandRelativePlacement = HandSocketComponent->HandRelativePlacement; + RefHand->bDecoupled = false; + //FComponentVisualizer::NotifyPropertyModified(RefHand, FindFProperty(UHandSocketComponent::StaticClass(), GET_MEMBER_NAME_CHECKED(UHandSocketComponent, HandRelativePlacement))); + } + } + } + } + + TArray PropertiesToModify; + PropertiesToModify.Add(FindFProperty(UHandSocketComponent::StaticClass(), GET_MEMBER_NAME_CHECKED(UHandSocketComponent, HandRelativePlacement))); + PropertiesToModify.Add(FindFProperty(UHandSocketComponent::StaticClass(), GET_MEMBER_NAME_CHECKED(UHandSocketComponent, bDecoupled))); + FComponentVisualizer::NotifyPropertiesModified(HandSocketComponent.Get(), PropertiesToModify); +} + +void FHandSocketComponentDetails::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) +{ + // Hide the SplineCurves property + //TSharedPtr HandPlacementProperty = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UHandSocketComponent, HandRelativePlacement)); + //HandPlacementProperty->MarkHiddenByCustomization(); + + + TArray> ObjectsBeingCustomized; + DetailBuilder.GetObjectsBeingCustomized(ObjectsBeingCustomized); + + if (ObjectsBeingCustomized.Num() == 1) + { + UHandSocketComponent* CurrentHandSocket = Cast(ObjectsBeingCustomized[0]); + if (CurrentHandSocket != NULL) + { + if (HandSocketComponent != CurrentHandSocket) + { + TSharedPtr Visualizer = GUnrealEd->FindComponentVisualizer(CurrentHandSocket->GetClass()); + FHandSocketVisualizer* HandVisualizer = (FHandSocketVisualizer*)Visualizer.Get(); + + if (HandVisualizer) + { + HandVisualizer->CurrentlySelectedBoneIdx = INDEX_NONE; + HandVisualizer->CurrentlySelectedBone = NAME_None; + HandVisualizer->HandPropertyPath = FComponentPropertyPath(); + //HandVisualizer->OldHandSocketComp = CurrentHandSocket; + } + + HandSocketComponent = CurrentHandSocket; + } + } + } + + /*const TArray< TWeakObjectPtr >& SelectedObjects = DetailBuilder.GetSelectedObjects(); + for (int32 ObjectIndex = 0; ObjectIndex < SelectedObjects.Num(); ++ObjectIndex) + { + const TWeakObjectPtr& CurrentObject = SelectedObjects[ObjectIndex]; + if (CurrentObject.IsValid()) + { + UHandSocketComponent* CurrentHandSocket = Cast(CurrentObject.Get()); + if (CurrentHandSocket != NULL) + { + if (HandSocketComponent != CurrentHandSocket) + { + TSharedPtr Visualizer = GUnrealEd->FindComponentVisualizer(CurrentHandSocket->GetClass()); + FHandSocketVisualizer* HandVisualizer = (FHandSocketVisualizer*)Visualizer.Get(); + + if (HandVisualizer) + { + HandVisualizer->CurrentlySelectedBoneIdx = INDEX_NONE; + HandVisualizer->CurrentlySelectedBone = NAME_None; + HandVisualizer->HandPropertyPath = FComponentPropertyPath(); + //HandVisualizer->OldHandSocketComp = CurrentHandSocket; + } + + HandSocketComponent = CurrentHandSocket; + } + break; + } + } + }*/ + + DetailBuilder.HideCategory(FName("ComponentTick")); + DetailBuilder.HideCategory(FName("GameplayTags")); + DetailBuilder.HideCategory(FName("VRGripInterface")); + DetailBuilder.HideCategory(FName("VRGripInterface|Replication")); + DetailBuilder.HideCategory(FName("Tags")); + DetailBuilder.HideCategory(FName("AssetUserData")); + DetailBuilder.HideCategory(FName("Events")); + DetailBuilder.HideCategory(FName("Activation")); + DetailBuilder.HideCategory(FName("Cooking")); + DetailBuilder.HideCategory(FName("ComponentReplication")); + + TSharedPtr LockedLocationProperty = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UHandSocketComponent, bDecoupleMeshPlacement)); + TSharedPtr HandRelativePlacementProperty = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UHandSocketComponent, HandRelativePlacement)); + TSharedPtr LeftHandDominateProperty = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UHandSocketComponent, bLeftHandDominant)); + + FSimpleDelegate OnHandRelativeChangedDelegate = FSimpleDelegate::CreateSP(this, &FHandSocketComponentDetails::OnHandRelativeUpdated, &DetailBuilder); + HandRelativePlacementProperty->SetOnPropertyValueChanged(OnHandRelativeChangedDelegate); + + FSimpleDelegate OnLockedStateChangedDelegate = FSimpleDelegate::CreateSP(this, &FHandSocketComponentDetails::OnLockedStateUpdated, &DetailBuilder); + LockedLocationProperty->SetOnPropertyValueChanged(OnLockedStateChangedDelegate); + + FSimpleDelegate OnLeftDominateChangedDelegate = FSimpleDelegate::CreateSP(this, &FHandSocketComponentDetails::OnLeftDominantUpdated, &DetailBuilder); + LeftHandDominateProperty->SetOnPropertyValueChanged(OnLeftDominateChangedDelegate); + + TSharedPtr ShowVisualizationProperty = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UHandSocketComponent, bShowVisualizationMesh)); + + FSimpleDelegate OnShowVisChangedDelegate = FSimpleDelegate::CreateSP(this, &FHandSocketComponentDetails::OnUpdateShowMesh, &DetailBuilder); + ShowVisualizationProperty->SetOnPropertyValueChanged(OnShowVisChangedDelegate); + + DetailBuilder.EditCategory("Hand Animation") + .AddCustomRow(LOCTEXT("UpdateHandSocketRow", "Save Current Pose")) + .NameContent() + [ + SNew(STextBlock) + .Font(IDetailLayoutBuilder::GetDetailFont()) + .Text(LOCTEXT("UpdateHandSocketText", "Save Current Pose")) + ] + .ValueContent() + .MaxDesiredWidth(125.f) + .MinDesiredWidth(125.f) + [ + SNew(SButton) + .ContentPadding(2) + .VAlign(VAlign_Center) + .HAlign(HAlign_Center) + .OnClicked(this, &FHandSocketComponentDetails::OnUpdateSavePose) + [ + SNew(STextBlock) + .Font(IDetailLayoutBuilder::GetDetailFont()) + .Text(LOCTEXT("UpdateHandSocketButton", "Save")) + ] + ]; +} + +void FHandSocketComponentDetails::OnUpdateShowMesh(IDetailLayoutBuilder* LayoutBuilder) +{ + if (!HandSocketComponent.IsValid()) + return; + + TSharedPtr Visualizer = GUnrealEd->FindComponentVisualizer(HandSocketComponent->GetClass()); + FHandSocketVisualizer* HandVisualizer = (FHandSocketVisualizer*)Visualizer.Get(); + + if (HandVisualizer) + { + HandVisualizer->CurrentlySelectedBoneIdx = INDEX_NONE; + HandVisualizer->CurrentlySelectedBone = NAME_None; + HandVisualizer->HandPropertyPath = FComponentPropertyPath(); + } +} + +FReply FHandSocketComponentDetails::OnUpdateSavePose() +{ + if (HandSocketComponent.IsValid() && HandSocketComponent->CustomPoseDeltas.Num() > 0) + { + if (HandSocketComponent->HandTargetAnimation || HandSocketComponent->VisualizationMesh) + { + // Save Animation Pose here + FString AssetPath; + FString AssetName; + PromptUserForAssetPath(AssetPath, AssetName); + TWeakObjectPtr NewAnim = SaveAnimationAsset(AssetPath, AssetName); + + // Finally remove the deltas + if (NewAnim.IsValid()) + { + HandSocketComponent->Modify(); + if (AActor* Owner = HandSocketComponent->GetOwner()) + { + Owner->Modify(); + } + + HandSocketComponent->HandTargetAnimation = NewAnim.Get(); + HandSocketComponent->CustomPoseDeltas.Empty(); + HandSocketComponent->bUseCustomPoseDeltas = false; + + TSharedPtr Visualizer = GUnrealEd->FindComponentVisualizer(HandSocketComponent->GetClass()); + FHandSocketVisualizer* HandVisualizer = (FHandSocketVisualizer*)Visualizer.Get(); + + if (HandVisualizer) + { + if (UHandSocketComponent* RefHand = HandVisualizer->GetCurrentlyEditingComponent()) + { + RefHand->HandTargetAnimation = NewAnim.Get(); + RefHand->CustomPoseDeltas.Empty(); + RefHand->bUseCustomPoseDeltas = false; + /*TArray PropertiesToModify; + PropertiesToModify.Add(FindFProperty(UHandSocketComponent::StaticClass(), GET_MEMBER_NAME_CHECKED(UHandSocketComponent, HandTargetAnimation))); + PropertiesToModify.Add(FindFProperty(UHandSocketComponent::StaticClass(), GET_MEMBER_NAME_CHECKED(UHandSocketComponent, bUseCustomPoseDeltas))); + PropertiesToModify.Add(FindFProperty(UHandSocketComponent::StaticClass(), GET_MEMBER_NAME_CHECKED(UHandSocketComponent, CustomPoseDeltas))); + FComponentVisualizer::NotifyPropertiesModified(RefHand, PropertiesToModify);*/ + } + } + + // Modify all of the properties at once + TArray PropertiesToModify; + PropertiesToModify.Add(FindFProperty(UHandSocketComponent::StaticClass(), GET_MEMBER_NAME_CHECKED(UHandSocketComponent, HandTargetAnimation))); + PropertiesToModify.Add(FindFProperty(UHandSocketComponent::StaticClass(), GET_MEMBER_NAME_CHECKED(UHandSocketComponent, bUseCustomPoseDeltas))); + PropertiesToModify.Add(FindFProperty(UHandSocketComponent::StaticClass(), GET_MEMBER_NAME_CHECKED(UHandSocketComponent, CustomPoseDeltas))); + FComponentVisualizer::NotifyPropertiesModified(HandSocketComponent.Get(), PropertiesToModify); + } + } + } + + return FReply::Handled(); +} + +void SCreateHandAnimationDlg::Construct(const FArguments& InArgs) +{ + AssetPath = FText::FromString(FPackageName::GetLongPackagePath(InArgs._DefaultAssetPath.ToString())); + AssetName = FText::FromString(FPackageName::GetLongPackageAssetName(InArgs._DefaultAssetPath.ToString())); + + if (AssetPath.IsEmpty()) + { + AssetPath = LastUsedAssetPath; + // still empty? + if (AssetPath.IsEmpty()) + { + AssetPath = FText::FromString(TEXT("/Game")); + } + } + else + { + LastUsedAssetPath = AssetPath; + } + + if (AssetName.IsEmpty()) + { + // find default name for them + FAssetToolsModule& AssetToolsModule = FModuleManager::Get().LoadModuleChecked("AssetTools"); + FString OutPackageName, OutAssetName; + FString PackageName = AssetPath.ToString() + TEXT("/NewAnimation"); + + AssetToolsModule.Get().CreateUniqueAssetName(PackageName, TEXT(""), OutPackageName, OutAssetName); + AssetName = FText::FromString(OutAssetName); + } + + FPathPickerConfig PathPickerConfig; + PathPickerConfig.DefaultPath = AssetPath.ToString(); + PathPickerConfig.OnPathSelected = FOnPathSelected::CreateSP(this, &SCreateHandAnimationDlg::OnPathChange); + PathPickerConfig.bAddDefaultPath = true; + + FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked("ContentBrowser"); + + SWindow::Construct(SWindow::FArguments() + .Title(LOCTEXT("SCreateHandAnimationDlg_Title", "Create New Animation Object")) + .SupportsMinimize(false) + .SupportsMaximize(false) + //.SizingRule( ESizingRule::Autosized ) + .ClientSize(FVector2D(450, 450)) + [ + SNew(SVerticalBox) + + + SVerticalBox::Slot() // Add user input block + .Padding(2) + [ + SNew(SBorder) + .BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder")) + [ + SNew(SVerticalBox) + + + SVerticalBox::Slot() + .AutoHeight() + [ + SNew(STextBlock) + .Text(LOCTEXT("SelectPath", "Select Path to create animation")) + .Font(FCoreStyle::GetDefaultFontStyle("Regular", 14)) + ] + + + SVerticalBox::Slot() + .FillHeight(1) + .Padding(3) + [ + ContentBrowserModule.Get().CreatePathPicker(PathPickerConfig) + ] + + + SVerticalBox::Slot() + .AutoHeight() + [ + SNew(SSeparator) + ] + + + SVerticalBox::Slot() + .AutoHeight() + .Padding(3) + [ + SNew(SHorizontalBox) + + + SHorizontalBox::Slot() + .AutoWidth() + .Padding(0, 0, 10, 0) + .VAlign(VAlign_Center) + [ + SNew(STextBlock) + .Text(LOCTEXT("AnimationName", "Animation Name")) + ] + + + SHorizontalBox::Slot() + [ + SNew(SEditableTextBox) + .Text(AssetName) + .OnTextCommitted(this, &SCreateHandAnimationDlg::OnNameChange) + .MinDesiredWidth(250) + ] + ] + ] + ] + + + SVerticalBox::Slot() + .AutoHeight() + .HAlign(HAlign_Right) + .Padding(5) + [ + SNew(SUniformGridPanel) + .SlotPadding(FAppStyle::GetMargin("StandardDialog.SlotPadding")) + .MinDesiredSlotWidth(FAppStyle::GetFloat("StandardDialog.MinDesiredSlotWidth")) + .MinDesiredSlotHeight(FAppStyle::GetFloat("StandardDialog.MinDesiredSlotHeight")) + + SUniformGridPanel::Slot(0, 0) + [ + SNew(SButton) + .HAlign(HAlign_Center) + .ContentPadding(FAppStyle::GetMargin("StandardDialog.ContentPadding")) + .Text(LOCTEXT("OK", "OK")) + .OnClicked(this, &SCreateHandAnimationDlg::OnButtonClick, EAppReturnType::Ok) + ] + + SUniformGridPanel::Slot(1, 0) + [ + SNew(SButton) + .HAlign(HAlign_Center) + .ContentPadding(FAppStyle::GetMargin("StandardDialog.ContentPadding")) + .Text(LOCTEXT("Cancel", "Cancel")) + .OnClicked(this, &SCreateHandAnimationDlg::OnButtonClick, EAppReturnType::Cancel) + ] + ] + ]); +} + +void SCreateHandAnimationDlg::OnNameChange(const FText& NewName, ETextCommit::Type CommitInfo) +{ + AssetName = NewName; +} + +void SCreateHandAnimationDlg::OnPathChange(const FString& NewPath) +{ + AssetPath = FText::FromString(NewPath); + LastUsedAssetPath = AssetPath; +} + +FReply SCreateHandAnimationDlg::OnButtonClick(EAppReturnType::Type ButtonID) +{ + UserResponse = ButtonID; + + if (ButtonID != EAppReturnType::Cancel) + { + if (!ValidatePackage()) + { + // reject the request + return FReply::Handled(); + } + } + + RequestDestroyWindow(); + + return FReply::Handled(); +} + +/** Ensures supplied package name information is valid */ +bool SCreateHandAnimationDlg::ValidatePackage() +{ + FText Reason; + FString FullPath = GetFullAssetPath(); + + if (!FPackageName::IsValidLongPackageName(FullPath, false, &Reason) + || !FName(*AssetName.ToString()).IsValidObjectName(Reason)) + { + FMessageDialog::Open(EAppMsgType::Ok, Reason); + return false; + } + + return true; +} + +EAppReturnType::Type SCreateHandAnimationDlg::ShowModal() +{ + GEditor->EditorAddModalWindow(SharedThis(this)); + return UserResponse; +} + +FString SCreateHandAnimationDlg::GetAssetPath() +{ + return AssetPath.ToString(); +} + +FString SCreateHandAnimationDlg::GetAssetName() +{ + return AssetName.ToString(); +} + +FString SCreateHandAnimationDlg::GetFullAssetPath() +{ + return AssetPath.ToString() + "/" + AssetName.ToString(); +} + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Private/HandSocketVisualizer.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Private/HandSocketVisualizer.cpp new file mode 100644 index 0000000..89b851d --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Private/HandSocketVisualizer.cpp @@ -0,0 +1,484 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "HandSocketVisualizer.h" +#include "CanvasItem.h" +#include "CanvasTypes.h" +#include "SceneManagement.h" +//#include "UObject/Field.h" +#include "VRBPDatatypes.h" +#include "ScopedTransaction.h" +#include "Modules/ModuleManager.h" +#include "EditorViewportClient.h" +#include "Components/PoseableMeshComponent.h" +#include "Misc/PackageName.h" +//#include "Persona.h" + +IMPLEMENT_HIT_PROXY(HHandSocketVisProxy, HComponentVisProxy); +#define LOCTEXT_NAMESPACE "HandSocketVisualizer" + +bool FHandSocketVisualizer::VisProxyHandleClick(FEditorViewportClient* InViewportClient, HComponentVisProxy* VisProxy, const FViewportClick& Click) +{ + bool bEditing = false; + if (VisProxy && VisProxy->Component.IsValid()) + { + bEditing = true; + if (VisProxy->IsA(HHandSocketVisProxy::StaticGetType())) + { + + if( const UHandSocketComponent * HandComp = UpdateSelectedHandComponent(VisProxy)) + { + HHandSocketVisProxy* Proxy = (HHandSocketVisProxy*)VisProxy; + if (Proxy) + { + CurrentlySelectedBone = Proxy->TargetBoneName; + CurrentlySelectedBoneIdx = Proxy->BoneIdx; + TargetViewport = InViewportClient->Viewport; + } + } + } + } + + return bEditing; +} + + +bool FHandSocketVisualizer::GetCustomInputCoordinateSystem(const FEditorViewportClient* ViewportClient, FMatrix& OutMatrix) const +{ + if (TargetViewport == nullptr || TargetViewport != ViewportClient->Viewport) + { + return false; + } + + if (HandPropertyPath.IsValid() && CurrentlySelectedBone != NAME_None/* && CurrentlySelectedBone != "HandSocket"*/) + { + if (CurrentlySelectedBone == "HandSocket") + { + UHandSocketComponent* CurrentlyEditingComponent = GetCurrentlyEditingComponent(); + if (CurrentlyEditingComponent) + { + if (CurrentlyEditingComponent->bMirrorVisualizationMesh) + { + FTransform NewTrans = CurrentlyEditingComponent->GetRelativeTransform(); + NewTrans.Mirror(CurrentlyEditingComponent->GetAsEAxis(CurrentlyEditingComponent->MirrorAxis), CurrentlyEditingComponent->GetAsEAxis(CurrentlyEditingComponent->FlipAxis)); + + if (USceneComponent* ParentComp = CurrentlyEditingComponent->GetAttachParent()) + { + NewTrans = NewTrans * ParentComp->GetComponentTransform(); + } + + OutMatrix = FRotationMatrix::Make(NewTrans.GetRotation()); + } + } + + return false; + } + else if (CurrentlySelectedBone == "Visualizer") + { + if (UHandSocketComponent* CurrentlyEditingComponent = GetCurrentlyEditingComponent()) + { + + FTransform newTrans = FTransform::Identity; + if (CurrentlyEditingComponent->bDecoupleMeshPlacement) + { + if (USceneComponent* ParentComp = CurrentlyEditingComponent->GetAttachParent()) + { + newTrans = CurrentlyEditingComponent->HandRelativePlacement * ParentComp->GetComponentTransform(); + } + } + else + { + newTrans = CurrentlyEditingComponent->GetHandRelativePlacement() * CurrentlyEditingComponent->GetComponentTransform(); + } + + OutMatrix = FRotationMatrix::Make(newTrans.GetRotation()); + } + } + else + { + if (UHandSocketComponent* CurrentlyEditingComponent = GetCurrentlyEditingComponent()) + { + if (IsValid(CurrentlyEditingComponent->HandVisualizerComponent)) + { + FTransform newTrans = CurrentlyEditingComponent->HandVisualizerComponent->GetBoneTransform(CurrentlySelectedBoneIdx); + FQuat Rot = newTrans.GetRotation(); + if (!newTrans.GetRotation().ContainsNaN()) + { + Rot.Normalize(); + OutMatrix = FRotationMatrix::Make(Rot); + return true; + } + } + + return false; + } + } + + return true; + } + + return false; +} + +bool FHandSocketVisualizer::IsVisualizingArchetype() const +{ + return (HandPropertyPath.IsValid() && HandPropertyPath.GetParentOwningActor() && FActorEditorUtils::IsAPreviewOrInactiveActor(HandPropertyPath.GetParentOwningActor())); +} + +void FHandSocketVisualizer::DrawVisualizationHUD(const UActorComponent* Component, const FViewport* Viewport, const FSceneView* View, FCanvas* Canvas) +{ + if (TargetViewport == nullptr || TargetViewport != Viewport) + { + return; + } + + if (const UHandSocketComponent* HandComp = Cast(Component)) + { + if (CurrentlySelectedBone != NAME_None) + { + if (UHandSocketComponent* CurrentlyEditingComponent = GetCurrentlyEditingComponent()) + { + if (!IsValid(CurrentlyEditingComponent->HandVisualizerComponent)) + { + return; + } + + int32 XL; + int32 YL; + const FIntRect CanvasRect = Canvas->GetViewRect(); + + FPlane location = View->Project(CurrentlyEditingComponent->HandVisualizerComponent->GetBoneTransform(CurrentlySelectedBoneIdx).GetLocation()); + StringSize(GEngine->GetLargeFont(), XL, YL, *CurrentlySelectedBone.ToString()); + //const float DrawPositionX = location.X - XL; + //const float DrawPositionY = location.Y - YL; + const float DrawPositionX = FMath::FloorToFloat(CanvasRect.Min.X + (CanvasRect.Width() - XL) * 0.5f); + const float DrawPositionY = CanvasRect.Min.Y + 50.0f; + Canvas->DrawShadowedString(DrawPositionX, DrawPositionY, *CurrentlySelectedBone.ToString(), GEngine->GetLargeFont(), FLinearColor::Yellow); + + } + } + } +} + +void FHandSocketVisualizer::DrawVisualization(const UActorComponent* Component, const FSceneView* View, FPrimitiveDrawInterface* PDI) +{ + //UWorld* World = Component->GetWorld(); + //return World && (World->WorldType == EWorldType::EditorPreview || World->WorldType == EWorldType::Inactive); + + //cast the component into the expected component type + if (const UHandSocketComponent* HandComponent = Cast(Component)) + { + if (!HandComponent->HandVisualizerComponent) + return; + + //This is an editor only uproperty of our targeting component, that way we can change the colors if we can't see them against the background + const FLinearColor SelectedColor = FLinearColor::Yellow;//TargetingComponent->EditorSelectedColor; + const FLinearColor UnselectedColor = FLinearColor::White;//TargetingComponent->EditorUnselectedColor; + const FVector Location = HandComponent->HandVisualizerComponent->GetComponentLocation(); + float BoneScale = 1.0f - ((View->ViewLocation - Location).SizeSquared() / FMath::Square(100.0f)); + BoneScale = FMath::Clamp(BoneScale, 0.2f, 1.0f); + HHandSocketVisProxy* newHitProxy = new HHandSocketVisProxy(Component); + newHitProxy->TargetBoneName = "Visualizer"; + PDI->SetHitProxy(newHitProxy); + PDI->DrawPoint(Location, CurrentlySelectedBone == newHitProxy->TargetBoneName ? SelectedColor : FLinearColor::Red, 20.f * BoneScale, SDPG_Foreground); + PDI->SetHitProxy(NULL); + newHitProxy = nullptr; + + newHitProxy = new HHandSocketVisProxy(Component); + newHitProxy->TargetBoneName = "HandSocket"; + BoneScale = 1.0f - ((View->ViewLocation - HandComponent->GetComponentLocation()).SizeSquared() / FMath::Square(100.0f)); + BoneScale = FMath::Clamp(BoneScale, 0.2f, 1.0f); + PDI->SetHitProxy(newHitProxy); + PDI->DrawPoint(HandComponent->GetComponentLocation(), FLinearColor::Green, 20.f * BoneScale, SDPG_Foreground); + PDI->SetHitProxy(NULL); + newHitProxy = nullptr; + + if (HandComponent->bUseCustomPoseDeltas) + { + TArray BoneTransforms = HandComponent->HandVisualizerComponent->GetBoneSpaceTransforms(); + FTransform ParentTrans = HandComponent->HandVisualizerComponent->GetComponentTransform(); + // We skip root bone, moving the visualizer itself handles that + for (int i = 1; i < HandComponent->HandVisualizerComponent->GetNumBones(); i++) + { + + FName BoneName = HandComponent->HandVisualizerComponent->GetBoneName(i); + + if (HandComponent->bFilterBonesByPostfix) + { + if (BoneName.ToString().Right(2) != HandComponent->FilterPostfix) + { + // Skip visualizing this bone its the incorrect side + continue; + } + } + + if (HandComponent->BonesToSkip.Contains(BoneName)) + { + // Skip visualizing this bone as its in the ignore array + continue; + } + + FTransform BoneTransform = HandComponent->HandVisualizerComponent->GetBoneTransform(i); + FVector BoneLoc = BoneTransform.GetLocation(); + BoneScale = 1.0f - ((View->ViewLocation - BoneLoc).SizeSquared() / FMath::Square(100.0f)); + BoneScale = FMath::Clamp(BoneScale, 0.1f, 0.9f); + newHitProxy = new HHandSocketVisProxy(Component); + newHitProxy->TargetBoneName = BoneName; + newHitProxy->BoneIdx = i; + PDI->SetHitProxy(newHitProxy); + PDI->DrawPoint(BoneLoc, CurrentlySelectedBone == newHitProxy->TargetBoneName ? SelectedColor : UnselectedColor, 20.f * BoneScale, SDPG_Foreground); + PDI->SetHitProxy(NULL); + newHitProxy = nullptr; + } + } + + if (HandComponent->bShowRangeVisualization) + { + float RangeVisualization = HandComponent->OverrideDistance; + + if (RangeVisualization <= 0.0f) + { + if (USceneComponent* Parent = Cast(HandComponent->GetAttachParent())) + { + FStructProperty* ObjectProperty = CastField(Parent->GetClass()->FindPropertyByName("VRGripInterfaceSettings")); + + AActor* ParentsActor = nullptr; + if (!ObjectProperty) + { + ParentsActor = Parent->GetOwner(); + if (ParentsActor) + { + ObjectProperty = CastField(Parent->GetOwner()->GetClass()->FindPropertyByName("VRGripInterfaceSettings")); + } + } + + if (ObjectProperty) + { + UObject* Target = ParentsActor; + + if (Target == nullptr) + { + Target = Parent; + } + + if (const FBPInterfaceProperties* Curve = ObjectProperty->ContainerPtrToValuePtr(Target)) + { + if (HandComponent->SlotPrefix == "VRGripS") + { + RangeVisualization = Curve->SecondarySlotRange; + } + else + { + RangeVisualization = Curve->PrimarySlotRange; + } + } + } + } + } + + // Scale into our parents space as that is actually what the range is based on + FBox BoxToDraw = FBox::BuildAABB(FVector::ZeroVector, FVector(RangeVisualization) * HandComponent->GetAttachParent()->GetComponentScale()); + BoxToDraw.Min += HandComponent->GetComponentLocation(); + BoxToDraw.Max += HandComponent->GetComponentLocation(); + + DrawWireBox(PDI, BoxToDraw, FColor::Green, 0.0f); + } + } +} + +bool FHandSocketVisualizer::GetWidgetLocation(const FEditorViewportClient* ViewportClient, FVector& OutLocation) const +{ + if (TargetViewport == nullptr || TargetViewport != ViewportClient->Viewport) + { + return false; + } + + if (HandPropertyPath.IsValid() && CurrentlySelectedBone != NAME_None && CurrentlySelectedBone != "HandSocket") + { + if (CurrentlySelectedBone == "HandSocket") + { + return false; + } + else if (CurrentlySelectedBone == "Visualizer") + { + if (UHandSocketComponent* CurrentlyEditingComponent = GetCurrentlyEditingComponent()) + { + FTransform newTrans = FTransform::Identity; + if (CurrentlyEditingComponent->bDecoupleMeshPlacement) + { + if (USceneComponent* ParentComp = CurrentlyEditingComponent->GetAttachParent()) + { + newTrans = CurrentlyEditingComponent->HandRelativePlacement * ParentComp->GetComponentTransform(); + } + } + else + { + newTrans = CurrentlyEditingComponent->GetHandRelativePlacement() * CurrentlyEditingComponent->GetComponentTransform(); + } + + OutLocation = newTrans.GetLocation(); + } + } + else + { + if (UHandSocketComponent* CurrentlyEditingComponent = GetCurrentlyEditingComponent()) + { + if (IsValid(CurrentlyEditingComponent->HandVisualizerComponent)) + { + OutLocation = CurrentlyEditingComponent->HandVisualizerComponent->GetBoneTransform(CurrentlySelectedBoneIdx).GetLocation(); + } + else + { + return false; + } + } + } + + return true; + } + + return false; +} + +bool FHandSocketVisualizer::HandleInputDelta(FEditorViewportClient* ViewportClient, FViewport* Viewport, FVector& DeltaTranslate, FRotator& DeltaRotate, FVector& DeltaScale) +{ + + if (TargetViewport == nullptr || TargetViewport != Viewport) + { + return false; + } + + bool bHandled = false; + + if (HandPropertyPath.IsValid()) + { + if (CurrentlySelectedBone == "HandSocket" || CurrentlySelectedBone == NAME_None) + { + bHandled = false; + } + else if (CurrentlySelectedBone == "Visualizer") + { + const FScopedTransaction Transaction(LOCTEXT("ChangingComp", "ChangingComp")); + + UHandSocketComponent* CurrentlyEditingComponent = GetCurrentlyEditingComponent(); + if (!CurrentlyEditingComponent) + { + return false; + } + + CurrentlyEditingComponent->Modify(); + if (AActor* Owner = CurrentlyEditingComponent->GetOwner()) + { + Owner->Modify(); + } + bool bLevelEdit = ViewportClient->IsLevelEditorClient(); + + FTransform CurrentTrans = FTransform::Identity; + + if (CurrentlyEditingComponent->bDecoupleMeshPlacement) + { + if (USceneComponent* ParentComp = CurrentlyEditingComponent->GetAttachParent()) + { + CurrentTrans = CurrentlyEditingComponent->HandRelativePlacement * ParentComp->GetComponentTransform(); + } + } + else + { + CurrentTrans = CurrentlyEditingComponent->GetHandRelativePlacement() * CurrentlyEditingComponent->GetComponentTransform(); + } + + if (!DeltaTranslate.IsNearlyZero()) + { + CurrentTrans.AddToTranslation(DeltaTranslate); + } + + if (!DeltaRotate.IsNearlyZero()) + { + CurrentTrans.SetRotation(DeltaRotate.Quaternion() * CurrentTrans.GetRotation()); + } + + if (!DeltaScale.IsNearlyZero()) + { + CurrentTrans.MultiplyScale3D(DeltaScale); + } + + if (CurrentlyEditingComponent->bDecoupleMeshPlacement) + { + if (USceneComponent* ParentComp = CurrentlyEditingComponent->GetAttachParent()) + { + CurrentlyEditingComponent->HandRelativePlacement = CurrentTrans.GetRelativeTransform(ParentComp->GetComponentTransform()); + } + } + else + { + CurrentlyEditingComponent->HandRelativePlacement = CurrentTrans.GetRelativeTransform(CurrentlyEditingComponent->GetComponentTransform()); + } + + NotifyPropertyModified(CurrentlyEditingComponent, FindFProperty(UHandSocketComponent::StaticClass(), GET_MEMBER_NAME_CHECKED(UHandSocketComponent, HandRelativePlacement))); + //GEditor->RedrawLevelEditingViewports(true); + bHandled = true; + + } + else + { + UHandSocketComponent* CurrentlyEditingComponent = GetCurrentlyEditingComponent(); + if (!CurrentlyEditingComponent || !CurrentlyEditingComponent->HandVisualizerComponent) + { + return false; + } + + const FScopedTransaction Transaction(LOCTEXT("ChangingComp", "ChangingComp")); + + CurrentlyEditingComponent->Modify(); + if (AActor* Owner = CurrentlyEditingComponent->GetOwner()) + { + Owner->Modify(); + } + bool bLevelEdit = ViewportClient->IsLevelEditorClient(); + + FTransform BoneTrans = CurrentlyEditingComponent->HandVisualizerComponent->GetBoneTransform(CurrentlySelectedBoneIdx); + FTransform NewTrans = BoneTrans; + NewTrans.SetRotation(DeltaRotate.Quaternion() * NewTrans.GetRotation()); + + FQuat DeltaRotateMod = NewTrans.GetRelativeTransform(BoneTrans).GetRotation(); + bool bFoundBone = false; + for (FBPVRHandPoseBonePair& BonePair : CurrentlyEditingComponent->CustomPoseDeltas) + { + if (BonePair.BoneName == CurrentlySelectedBone) + { + bFoundBone = true; + BonePair.DeltaPose *= DeltaRotateMod; + break; + } + } + + if (!bFoundBone) + { + FBPVRHandPoseBonePair newBonePair; + newBonePair.BoneName = CurrentlySelectedBone; + newBonePair.DeltaPose *= DeltaRotateMod; + CurrentlyEditingComponent->CustomPoseDeltas.Add(newBonePair); + bFoundBone = true; + } + + if (bFoundBone) + { + NotifyPropertyModified(CurrentlyEditingComponent, FindFProperty(UHandSocketComponent::StaticClass(), GET_MEMBER_NAME_CHECKED(UHandSocketComponent, CustomPoseDeltas))); + } + + //GEditor->RedrawLevelEditingViewports(true); + bHandled = true; + } + } + + return bHandled; +} + +void FHandSocketVisualizer::EndEditing() +{ + HandPropertyPath = FComponentPropertyPath(); + CurrentlySelectedBone = NAME_None; + CurrentlySelectedBoneIdx = INDEX_NONE; + TargetViewport = nullptr; +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Private/VRExpansionEditor.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Private/VRExpansionEditor.cpp new file mode 100644 index 0000000..2161551 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Private/VRExpansionEditor.cpp @@ -0,0 +1,73 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "VRExpansionEditor.h" +#include "Editor/UnrealEdEngine.h" +#include "UnrealEdGlobals.h" +#include "Grippables/HandSocketComponent.h" +#include "PropertyEditorModule.h" +#include "HandSocketVisualizer.h" +#include "HandSocketComponentDetails.h" +#include "VRGlobalSettingsDetails.h" +#include "VRGlobalSettings.h" + + +IMPLEMENT_MODULE(FVRExpansionEditorModule, VRExpansionEditor); + +void FVRExpansionEditorModule::StartupModule() +{ + RegisterComponentVisualizer(UHandSocketComponent::StaticClass()->GetFName(), MakeShareable(new FHandSocketVisualizer)); + + // Register detail customizations + { + auto& PropertyModule = FModuleManager::LoadModuleChecked< FPropertyEditorModule >("PropertyEditor"); + + // Register our customization to be used by a class 'UMyClass' or 'AMyClass'. Note the prefix must be dropped. + PropertyModule.RegisterCustomClassLayout( + UHandSocketComponent::StaticClass()->GetFName(), + FOnGetDetailCustomizationInstance::CreateStatic(&FHandSocketComponentDetails::MakeInstance) + ); + + PropertyModule.RegisterCustomClassLayout( + UVRGlobalSettings::StaticClass()->GetFName(), + FOnGetDetailCustomizationInstance::CreateStatic(&FVRGlobalSettingsDetails::MakeInstance) + ); + + PropertyModule.NotifyCustomizationModuleChanged(); + } + +} + +void FVRExpansionEditorModule::ShutdownModule() +{ + if (GUnrealEd != NULL) + { + // Iterate over all class names we registered for + for (FName ClassName : RegisteredComponentClassNames) + { + GUnrealEd->UnregisterComponentVisualizer(ClassName); + } + } + + if (FModuleManager::Get().IsModuleLoaded("PropertyEditor")) + { + auto& PropertyModule = FModuleManager::LoadModuleChecked("PropertyEditor"); + + PropertyModule.UnregisterCustomClassLayout(UHandSocketComponent::StaticClass()->GetFName()); + PropertyModule.UnregisterCustomClassLayout(UVRGlobalSettings::StaticClass()->GetFName()); + } +} + +void FVRExpansionEditorModule::RegisterComponentVisualizer(FName ComponentClassName, TSharedPtr Visualizer) +{ + if (GUnrealEd != NULL) + { + GUnrealEd->RegisterComponentVisualizer(ComponentClassName, Visualizer); + } + + RegisteredComponentClassNames.Add(ComponentClassName); + + if (Visualizer.IsValid()) + { + Visualizer->OnRegister(); + } +} diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Private/VRGlobalSettingsDetails.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Private/VRGlobalSettingsDetails.cpp new file mode 100644 index 0000000..b774672 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Private/VRGlobalSettingsDetails.cpp @@ -0,0 +1,205 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "VRGlobalSettingsDetails.h" +#include "VRGlobalSettings.h" +//#include "PropertyEditing.h" +#include "Widgets/Text/STextBlock.h" +#include "Widgets/Input/SButton.h" +//#include "PropertyHandle.h" +#include "DetailLayoutBuilder.h" +#include "DetailWidgetRow.h" +#include "DetailCategoryBuilder.h" +#include "IDetailsView.h" + +//#include "Developer/AssetTools/Public/IAssetTools.h" +//#include "Developer/AssetTools/Public/AssetToolsModule.h" +//#include "Editor/ContentBrowser/Public/IContentBrowserSingleton.h" +//#include "Editor/ContentBrowser/Public/ContentBrowserModule.h" +//#include "AnimationUtils.h" + +#include "UObject/SavePackage.h" +#include "Misc/MessageDialog.h" +//#include "Widgets/Layout/SBorder.h" +//#include "Widgets/Layout/SSeparator.h" +//#include "Widgets/Layout/SUniformGridPanel.h" +//#include "Widgets/Input/SEditableTextBox.h" +#include "Editor.h" +#include "EditorStyleSet.h" +#include "Styling/CoreStyle.h" + +#include "Animation/AnimData/AnimDataModel.h" +#include "AssetRegistry/AssetRegistryModule.h" +#include "AssetRegistry/ARFilter.h" + +#include "FileHelpers.h" +#include "Engine/Engine.h" +#include "Editor/UnrealEdEngine.h" +#include "UnrealEdGlobals.h" + +#define LOCTEXT_NAMESPACE "VRGlobalSettingsDetails" + + +TSharedRef< IDetailCustomization > FVRGlobalSettingsDetails::MakeInstance() +{ + return MakeShareable(new FVRGlobalSettingsDetails); +} + +void FVRGlobalSettingsDetails::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) +{ + //DetailBuilder.HideCategory(FName("ComponentTick")); + //DetailBuilder.HideCategory(FName("GameplayTags")); + + + //TSharedPtr LockedLocationProperty = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UHandSocketComponent, bDecoupleMeshPlacement)); + + //FSimpleDelegate OnLockedStateChangedDelegate = FSimpleDelegate::CreateSP(this, &FVRGlobalSettingsDetails::OnLockedStateUpdated, &DetailBuilder); + //LockedLocationProperty->SetOnPropertyValueChanged(OnLockedStateChangedDelegate); + + DetailBuilder.EditCategory("Utilities") + .AddCustomRow(LOCTEXT("FixInvalidAnimationAssets", "Fix Invalid 5.2 Animation Assets")) + .NameContent() + [ + SNew(STextBlock) + .Font(IDetailLayoutBuilder::GetDetailFont()) + .Text(LOCTEXT("FixInvalidAnimationAssets", "Fix Invalid 5.2 Animation Assets")) + ] + .ValueContent() + .MaxDesiredWidth(125.f) + .MinDesiredWidth(125.f) + [ + SNew(SButton) + .ContentPadding(2) + .VAlign(VAlign_Center) + .HAlign(HAlign_Center) + .OnClicked(this, &FVRGlobalSettingsDetails::OnCorrectInvalidAnimationAssets) + [ + SNew(STextBlock) + .Font(IDetailLayoutBuilder::GetDetailFont()) + .Text(LOCTEXT("FixInvalidAnimationAssetsButton", "Fix Animation Assets")) + ] + ]; + + /*DetailBuilder.EditCategory("Utilities") + .AddCustomRow(LOCTEXT("Fix 5.4.0 Shadow Shader", "Fix Broken 5.4.0 Shadow Shader")) + .NameContent() + [ + SNew(STextBlock) + .Font(IDetailLayoutBuilder::GetDetailFont()) + .Text(LOCTEXT("Fix54ShadowShader", "Fix Broken 5.4.0 Shadow Shader")) + ] + .ValueContent() + .MaxDesiredWidth(125.f) + .MinDesiredWidth(125.f) + [ + SNew(SButton) + .ContentPadding(2) + .VAlign(VAlign_Center) + .HAlign(HAlign_Center) + .OnClicked(this, &FVRGlobalSettingsDetails::OnFixShadowShader) + [ + SNew(STextBlock) + .Font(IDetailLayoutBuilder::GetDetailFont()) + .Text(LOCTEXT("Fix54ShadowShaderButton", "Fix Broken 5.4.0 Shadow Shader")) + ] + ];*/ +} + +/*FReply FVRGlobalSettingsDetails::OnFixShadowShader() +{ +#if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION == 4 + FString EnginePath = FPaths::EngineDir(); + EnginePath += "/Shaders/Private/ShadowProjectionPixelShader.usf"; + + if (FPlatformFileManager::Get().GetPlatformFile().FileExists(*EnginePath)) + { + FString FileStr = ""; + if (FFileHelper::LoadFileToString(FileStr, *EnginePath)) + { + // Don't need to do anything complicated, the shader only contains one line with this define in it + FileStr = FileStr.Replace(TEXT("#if MOBILE_MULTI_VIEW || INSTANCED_STEREO"),TEXT("#if ((MOBILE_MULTI_VIEW || INSTANCED_STEREO) && SHADING_PATH_MOBILE)")); + + FFileHelper::SaveStringToFile(FileStr, *EnginePath); + + GEngine->Exec(GEngine->GetWorld(), TEXT("recompileshaders changed")); + UE_LOG(LogPath, Log, TEXT("ShadowProjectionPixelShader.usf resaved and recompiled!")); + return FReply::Handled(); + } + } + +#endif + + UE_LOG(LogPath, Error, TEXT("ShadowProjectionPixelShader.usf could not be found, edited, or the engine version is incorrect!")); + return FReply::Handled(); +}*/ + +FReply FVRGlobalSettingsDetails::OnCorrectInvalidAnimationAssets() +{ + + // Load the asset registry module + FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked< FAssetRegistryModule >(FName("AssetRegistry")); + IAssetRegistry& AssetRegistry = AssetRegistryModule.Get(); + TArray< FString > ContentPaths; + ContentPaths.Add(TEXT("/Game")); + AssetRegistry.ScanPathsSynchronous(ContentPaths); + + FARFilter Filter; + Filter.ClassPaths.Add(UAnimSequence::StaticClass()->GetClassPathName()); + //Filter.ClassNames.Add(UAnimSequence::StaticClass()->GetFName()); + Filter.bRecursiveClasses = true; + //if (!Path.IsEmpty()) + //{ + // Filter.PackagePaths.Add(*Path); + //} + Filter.bRecursivePaths = true; + + TArray< FAssetData > AssetList; + AssetRegistry.GetAssets(Filter, AssetList); + + // Iterate over retrieved blueprint assets + for (auto& Asset : AssetList) + { + // Check the anim sequence for invalid data + if (UAnimSequence* AnimSeq = Cast(Asset.GetAsset())) + { + IAnimationDataController& AnimController = AnimSeq->GetController(); + { + IAnimationDataController::FScopedBracket ScopedBracket(AnimController, LOCTEXT("FixAnimationAsset_VRE", "Fixing invalid anim sequences")); + const IAnimationDataModel* AnimModel = AnimController.GetModel(); + + FFrameRate FrameRate = AnimModel->GetFrameRate(); + //int32 NumFrames = AnimModel->GetNumberOfFrames(); + double FrameRateD = FrameRate.AsDecimal(); + + // I was saving with a below 1.0 frame rate and 1 frame + if (FrameRateD < 1.0f) + { + // We have an invalid frame rate for 5.2 + AnimController.SetFrameRate(FFrameRate(1, 1)); + AnimSeq->MarkPackageDirty(); + + UPackage* const Package = AnimSeq->GetOutermost(); + FString const PackageName = Package->GetName(); + FString const PackageFileName = FPackageName::LongPackageNameToFilename(PackageName, FPackageName::GetAssetPackageExtension()); + + double StartTime = FPlatformTime::Seconds(); + + FSavePackageArgs PackageArguments; + PackageArguments.SaveFlags = RF_Standalone; + PackageArguments.SaveFlags = SAVE_NoError; + UPackage::SavePackage(Package, NULL, *PackageFileName, PackageArguments); + //UPackage::SavePackage(Package, NULL, RF_Standalone, *PackageFileName, GError, nullptr, false, true, SAVE_NoError); + + double ElapsedTime = FPlatformTime::Seconds() - StartTime; + UE_LOG(LogAnimation, Log, TEXT("Animation re-saved %s in %0.2f seconds"), *PackageName, ElapsedTime); + } + + } + } + } + + + return FReply::Handled(); +} + + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Public/HandSocketComponentDetails.h b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Public/HandSocketComponentDetails.h new file mode 100644 index 0000000..603abd8 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Public/HandSocketComponentDetails.h @@ -0,0 +1,83 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Grippables/HandSocketComponent.h" +#include "IDetailCustomization.h" +#include "Input/Reply.h" +#include "Widgets/DeclarativeSyntaxSupport.h" +#include "Widgets/SWindow.h" + +class IDetailLayoutBuilder; + +class FHandSocketComponentDetails : public IDetailCustomization +{ +public: + /** Makes a new instance of this detail layout class for a specific detail view requesting it */ + static TSharedRef MakeInstance(); + + /** IDetailCustomization interface */ + virtual void CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) override; + //void SortCategories(const TMap& AllCategoryMap); + + // The selected hand component + TWeakObjectPtr HandSocketComponent; + FReply OnUpdateSavePose(); + TWeakObjectPtr SaveAnimationAsset(const FString& InAssetPath, const FString& InAssetName); + + void OnLockedStateUpdated(IDetailLayoutBuilder* LayoutBuilder); + void OnLeftDominantUpdated(IDetailLayoutBuilder* LayoutBuilder); + void OnHandRelativeUpdated(IDetailLayoutBuilder* LayoutBuilder); + void OnUpdateShowMesh(IDetailLayoutBuilder* LayoutBuilder); + + FHandSocketComponentDetails() + { + } +}; + +class SCreateHandAnimationDlg : public SWindow +{ +public: + SLATE_BEGIN_ARGS(SCreateHandAnimationDlg) + { + } + + SLATE_ARGUMENT(FText, DefaultAssetPath) + SLATE_END_ARGS() + + SCreateHandAnimationDlg() + : UserResponse(EAppReturnType::Cancel) + { + } + + void Construct(const FArguments& InArgs); + +public: + /** Displays the dialog in a blocking fashion */ + EAppReturnType::Type ShowModal(); + + /** Gets the resulting asset path */ + FString GetAssetPath(); + + /** Gets the resulting asset name */ + FString GetAssetName(); + + /** Gets the resulting full asset path (path+'/'+name) */ + FString GetFullAssetPath(); + +protected: + void OnPathChange(const FString& NewPath); + void OnNameChange(const FText& NewName, ETextCommit::Type CommitInfo); + FReply OnButtonClick(EAppReturnType::Type ButtonID); + + bool ValidatePackage(); + + EAppReturnType::Type UserResponse; + FText AssetPath; + FText AssetName; + + static FText LastUsedAssetPath; + +}; + diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Public/HandSocketVisualizer.h b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Public/HandSocketVisualizer.h new file mode 100644 index 0000000..d4fb707 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Public/HandSocketVisualizer.h @@ -0,0 +1,95 @@ +#pragma once + +#include "ComponentVisualizer.h" +#include "Grippables/HandSocketComponent.h" +#include "ActorEditorUtils.h" + +class FEditorViewportClient; + +/**Base class for clickable targeting editing proxies*/ +struct VREXPANSIONEDITOR_API HHandSocketVisProxy : public HComponentVisProxy +{ + DECLARE_HIT_PROXY(); + + HHandSocketVisProxy(const UActorComponent* InComponent) + : HComponentVisProxy(InComponent, HPP_Wireframe) + { + BoneIdx = 0; + TargetBoneName = NAME_None; + } + + uint32 BoneIdx; + FName TargetBoneName; +}; + +class VREXPANSIONEDITOR_API FHandSocketVisualizer : public FComponentVisualizer +{ +public: + FHandSocketVisualizer() + { + CurrentlySelectedBone = NAME_None; + CurrentlySelectedBoneIdx = INDEX_NONE; + HandPropertyPath = FComponentPropertyPath(); + TargetViewport = nullptr; + } + + virtual ~FHandSocketVisualizer() + { + + } + + UPROPERTY() + FComponentPropertyPath HandPropertyPath; + + FName CurrentlySelectedBone; + uint32 CurrentlySelectedBoneIdx; + + UPROPERTY() + FViewport* TargetViewport; + + UHandSocketComponent* GetCurrentlyEditingComponent() const + { + return Cast(HandPropertyPath.GetComponent());; + } + + const UHandSocketComponent* UpdateSelectedHandComponent(HComponentVisProxy* VisProxy) + { + const UHandSocketComponent* HandComp = CastChecked(VisProxy->Component.Get()); + UHandSocketComponent* OldHandComp = Cast(HandPropertyPath.GetComponent()); + AActor* OldOwningActor = HandPropertyPath.GetParentOwningActor(); + HandPropertyPath = FComponentPropertyPath(HandComp); + AActor* NewOwningActor = HandPropertyPath.GetParentOwningActor(); + + if (HandPropertyPath.IsValid()) + { + if (OldOwningActor != NewOwningActor || OldHandComp != HandComp) + { + // Reset selection state if we are selecting a different actor to the one previously selected + CurrentlySelectedBoneIdx = INDEX_NONE; + CurrentlySelectedBone = NAME_None; + } + + return HandComp; + } + + HandPropertyPath = FComponentPropertyPath(); + return nullptr; + } + + bool SaveAnimationAsset(const FString& InAssetPath, const FString& InAssetName); + + + bool GetCustomInputCoordinateSystem(const FEditorViewportClient* ViewportClient, FMatrix& OutMatrix) const override; + + bool IsVisualizingArchetype() const override; + + virtual void DrawVisualization(const UActorComponent* Component, const FSceneView* View, FPrimitiveDrawInterface* PDI) override; + virtual void DrawVisualizationHUD(const UActorComponent* Component, const FViewport* Viewport, const FSceneView* View, FCanvas* Canvas) override; + virtual bool VisProxyHandleClick(FEditorViewportClient* InViewportClient, HComponentVisProxy* VisProxy, const FViewportClick& Click) override; + bool GetWidgetLocation(const FEditorViewportClient* ViewportClient, FVector& OutLocation) const override; + bool HandleInputDelta(FEditorViewportClient* ViewportClient, FViewport* Viewport, FVector& DeltaTranslate, FRotator& DeltaRotate, FVector& DeltaScale) override; + virtual void EndEditing() override; + +private: + +}; diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Public/VRExpansionEditor.h b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Public/VRExpansionEditor.h new file mode 100644 index 0000000..caf41a3 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Public/VRExpansionEditor.h @@ -0,0 +1,19 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "Runtime/Core/Public/Modules/ModuleInterface.h" + +#include "ComponentVisualizer.h" + +class FVRExpansionEditorModule : public IModuleInterface +{ +public: + + virtual void StartupModule() override; + virtual void ShutdownModule() override; + void RegisterComponentVisualizer(FName ComponentClassName, TSharedPtr Visualizer); + + /** Array of component class names we have registered, so we know what to unregister afterwards */ + TArray RegisteredComponentClassNames; +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Public/VRGlobalSettingsDetails.h b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Public/VRGlobalSettingsDetails.h new file mode 100644 index 0000000..3266b3a --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/Public/VRGlobalSettingsDetails.h @@ -0,0 +1,33 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "IDetailCustomization.h" +#include "Input/Reply.h" +#include "Widgets/DeclarativeSyntaxSupport.h" +#include "Widgets/SWindow.h" + +class IDetailLayoutBuilder; + +class FVRGlobalSettingsDetails : public IDetailCustomization +{ +public: + /** Makes a new instance of this detail layout class for a specific detail view requesting it */ + static TSharedRef MakeInstance(); + + /** IDetailCustomization interface */ + virtual void CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) override; + + FReply OnCorrectInvalidAnimationAssets(); + + FReply OnFixShadowShader(); + + void OnLockedStateUpdated(IDetailLayoutBuilder* LayoutBuilder); + + + FVRGlobalSettingsDetails() + { + } +}; + diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/VRExpansionEditor.Build.cs b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/VRExpansionEditor.Build.cs new file mode 100644 index 0000000..92b9300 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionEditor/VRExpansionEditor.Build.cs @@ -0,0 +1,62 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +using System.IO; + +namespace UnrealBuildTool.Rules +{ + public class VRExpansionEditor : ModuleRules + { + + public VRExpansionEditor(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; + + PublicIncludePaths.AddRange( + new string[] { + // ... add public include paths required here ... + } + ); + + PrivateIncludePaths.AddRange( + new string[] { + // ... add other private include paths required here ... + } + ); + + PublicDependencyModuleNames.AddRange( + new string[] + { + // ... add other public dependencies that you statically link with here ... + "Engine", + "Core", + "CoreUObject", + "VRExpansionPlugin", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "UnrealEd", + "BlueprintGraph", + "AnimGraph", + "AnimGraphRuntime", + "SlateCore", + "Slate", + "InputCore", + "Engine", + "UnrealEd", + "EditorStyle", + "AssetRegistry" + } + ); + + DynamicallyLoadedModuleNames.AddRange( + new string[] + { + // ... add any modules that your module loads dynamically here ... + } + ); + } + } +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/CharacterMovementCompTypes.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/CharacterMovementCompTypes.cpp new file mode 100644 index 0000000..300790d --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/CharacterMovementCompTypes.cpp @@ -0,0 +1,527 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +/*============================================================================= + Movement.cpp: Character movement implementation + +=============================================================================*/ + +#include "CharacterMovementCompTypes.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(CharacterMovementCompTypes) + +#include "VRBaseCharacterMovementComponent.h" +#include "VRBPDatatypes.h" +#include "VRBaseCharacter.h" +#include "VRRootComponent.h" +#include "VRPlayerController.h" + +FSavedMove_VRBaseCharacter::FSavedMove_VRBaseCharacter() : FSavedMove_Character() +{ + VRCapsuleLocation = FVector::ZeroVector; + LFDiff = FVector::ZeroVector; + VRCapsuleRotation = FRotator::ZeroRotator; + VRReplicatedMovementMode = EVRConjoinedMovementModes::C_MOVE_MAX;// _None; +} + +uint8 FSavedMove_VRBaseCharacter::GetCompressedFlags() const +{ + // Fills in 01 and 02 for Jump / Crouch + uint8 Result = FSavedMove_Character::GetCompressedFlags(); + + // Not supporting custom movement mode directly at this time by replicating custom index + // We use 4 bits for this so a maximum of 16 elements + //Result |= (uint8)VRReplicatedMovementMode << 2; + + // This takes up custom_2 + /*if (bWantsToSnapTurn) + { + Result |= FLAG_SnapTurn; + }*/ + + // Reserved_1, and Reserved_2, Flag_Custom_0 and Flag_Custom_1 are used up + // By the VRReplicatedMovementMode packing + + + // only custom_2 and custom_3 are left currently + return Result; +} + +bool FSavedMove_VRBaseCharacter::CanCombineWith(const FSavedMovePtr& NewMove, ACharacter* Character, float MaxDelta) const +{ + FSavedMove_VRBaseCharacter* nMove = (FSavedMove_VRBaseCharacter*)NewMove.Get(); + + if (!nMove || (VRReplicatedMovementMode != nMove->VRReplicatedMovementMode)) + return false; + + if (!ConditionalValues.MoveActionArray.CanCombine() || !nMove->ConditionalValues.MoveActionArray.CanCombine()) + return false; + + if (!ConditionalValues.CustomVRInputVector.IsZero() || !nMove->ConditionalValues.CustomVRInputVector.IsZero()) + return false; + + if (!ConditionalValues.RequestedVelocity.IsZero() || !nMove->ConditionalValues.RequestedVelocity.IsZero()) + return false; + + // Hate this but we really can't combine if I am sending a new capsule height + if (!FMath::IsNearlyEqual(CapsuleHeight, nMove->CapsuleHeight)) + return false; + + if (!LFDiff.IsZero() && !nMove->LFDiff.IsZero() && !FVector::Coincident(LFDiff.GetSafeNormal(), nMove->LFDiff.GetSafeNormal(), AccelDotThresholdCombine)) + return false; + + return FSavedMove_Character::CanCombineWith(NewMove, Character, MaxDelta); +} + + +bool FSavedMove_VRBaseCharacter::IsImportantMove(const FSavedMovePtr& LastAckedMove) const +{ + // Auto important if toggled climbing + if (VRReplicatedMovementMode != EVRConjoinedMovementModes::C_MOVE_MAX)//_None) + return true; + + if (!ConditionalValues.CustomVRInputVector.IsZero()) + return true; + + if (!ConditionalValues.RequestedVelocity.IsZero()) + return true; + + if (ConditionalValues.MoveActionArray.MoveActions.Num() > 0) + return true; + + // #TODO: What to do here? + // This is debatable, however it will ALWAYS be non zero realistically and only really effects step ups for the most part + //if (!LFDiff.IsNearlyZero()) + //return true; + + // Else check parent class + return FSavedMove_Character::IsImportantMove(LastAckedMove); +} + +void FSavedMove_VRBaseCharacter::SetInitialPosition(ACharacter* C) +{ + // See if we can get the VR capsule location + //if (AVRBaseCharacter * VRC = Cast(C)) + //{ + if (UVRBaseCharacterMovementComponent* moveComp = Cast(C->GetMovementComponent())) + { + + // Saving this out early because it will be wiped before the PostUpdate gets the values + //ConditionalValues.MoveAction.MoveAction = moveComp->MoveAction.MoveAction; + + VRReplicatedMovementMode = moveComp->VRReplicatedMovementMode; + + if (moveComp->HasRequestedVelocity()) + ConditionalValues.RequestedVelocity = moveComp->RequestedVelocity; + else + ConditionalValues.RequestedVelocity = FVector::ZeroVector; + + // Throw out the Z value of the headset, its not used anyway for movement + // Instead, re-purpose it to be the capsule half height + if (AVRBaseCharacter* BaseChar = Cast(C)) + { + if (BaseChar->GetVRReplicateCapsuleHeight()) + CapsuleHeight = BaseChar->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight(); + else + CapsuleHeight = 0.0f; + } + else + CapsuleHeight = 0.0f; + } + else + { + VRReplicatedMovementMode = EVRConjoinedMovementModes::C_MOVE_MAX;//None; + ConditionalValues.CustomVRInputVector = FVector::ZeroVector; + ConditionalValues.RequestedVelocity = FVector::ZeroVector; + } + //} + //else + //{ + // VRReplicatedMovementMode = EVRConjoinedMovementModes::C_MOVE_MAX;//None; + // ConditionalValues.CustomVRInputVector = FVector::ZeroVector; + //} + + FSavedMove_Character::SetInitialPosition(C); +} + +void FSavedMove_VRBaseCharacter::CombineWith(const FSavedMove_Character* OldMove, ACharacter* InCharacter, APlayerController* PC, const FVector& OldStartLocation) +{ + UCharacterMovementComponent* CharMovement = InCharacter->GetCharacterMovement(); + + // to combine move, first revert pawn position to PendingMove start position, before playing combined move on client + CharMovement->UpdatedComponent->SetWorldLocationAndRotation(OldStartLocation, OldMove->StartRotation, false, nullptr, CharMovement->GetTeleportType()); + CharMovement->Velocity = OldMove->StartVelocity; + + CharMovement->SetBase(OldMove->StartBase.Get(), OldMove->StartBoneName); + CharMovement->CurrentFloor = OldMove->StartFloor; + + // Now that we have reverted to the old position, prepare a new move from that position, + // using our current velocity, acceleration, and rotation, but applied over the combined time from the old and new move. + + // Combine times for both moves + DeltaTime += OldMove->DeltaTime; + + //FSavedMove_VRBaseCharacter * BaseSavedMove = (FSavedMove_VRBaseCharacter *)NewMove.Get(); + FSavedMove_VRBaseCharacter* BaseSavedMovePending = (FSavedMove_VRBaseCharacter*)OldMove; + + if (/*BaseSavedMove && */BaseSavedMovePending) + { + LFDiff.X += BaseSavedMovePending->LFDiff.X; + LFDiff.Y += BaseSavedMovePending->LFDiff.Y; + } + + // Roll back jump force counters. SetInitialPosition() below will copy them to the saved move. + // Changes in certain counters like JumpCurrentCount don't allow move combining, so no need to roll those back (they are the same). + InCharacter->JumpForceTimeRemaining = OldMove->JumpForceTimeRemaining; + InCharacter->JumpKeyHoldTime = OldMove->JumpKeyHoldTime; + + // Merge if we had valid mergable move actions + ConditionalValues.MoveActionArray.MoveActions.Append(BaseSavedMovePending->ConditionalValues.MoveActionArray.MoveActions); +} + +void FSavedMove_VRBaseCharacter::PostUpdate(ACharacter* C, EPostUpdateMode PostUpdateMode) +{ + FSavedMove_Character::PostUpdate(C, PostUpdateMode); + + // See if we can get the VR capsule location + //if (AVRBaseCharacter * VRC = Cast(C)) + //{ + if (UVRBaseCharacterMovementComponent* moveComp = Cast(C->GetMovementComponent())) + { + ConditionalValues.CustomVRInputVector = moveComp->CustomVRInputVector; + ConditionalValues.MoveActionArray = moveComp->MoveActionArray; + moveComp->MoveActionArray.Clear(); + + if (!moveComp->bUseClientControlRotation) + { + if (const USceneComponent* UpdatedComponent = moveComp->UpdatedComponent) + { + SavedControlRotation = UpdatedComponent->GetComponentRotation().Clamp(); + } + } + } + + + //} + /*if (ConditionalValues.MoveAction.MoveAction != EVRMoveAction::VRMOVEACTION_None) + { + // See if we can get the VR capsule location + if (AVRBaseCharacter * VRC = Cast(C)) + { + if (UVRBaseCharacterMovementComponent * moveComp = Cast(VRC->GetMovementComponent())) + { + // This is cleared out in perform movement so I need to save it before applying below + EVRMoveAction tempAction = ConditionalValues.MoveAction.MoveAction; + ConditionalValues.MoveAction = moveComp->MoveAction; + ConditionalValues.MoveAction.MoveAction = tempAction; + } + else + { + ConditionalValues.MoveAction.Clear(); + } + } + else + { + ConditionalValues.MoveAction.Clear(); + } + }*/ +} + +void FSavedMove_VRBaseCharacter::Clear() +{ + VRReplicatedMovementMode = EVRConjoinedMovementModes::C_MOVE_MAX;// None; + + VRCapsuleLocation = FVector::ZeroVector; + VRCapsuleRotation = FRotator::ZeroRotator; + LFDiff = FVector::ZeroVector; + CapsuleHeight = 0.0f; + + ConditionalValues.CustomVRInputVector = FVector::ZeroVector; + ConditionalValues.RequestedVelocity = FVector::ZeroVector; + ConditionalValues.MoveActionArray.Clear(); + //ConditionalValues.MoveAction.Clear(); + + FSavedMove_Character::Clear(); +} + +void FSavedMove_VRBaseCharacter::PrepMoveFor(ACharacter* Character) +{ + UVRBaseCharacterMovementComponent* BaseCharMove = Cast(Character->GetCharacterMovement()); + + if (BaseCharMove) + { + BaseCharMove->MoveActionArray = ConditionalValues.MoveActionArray; + //BaseCharMove->MoveAction = ConditionalValues.MoveAction; + BaseCharMove->CustomVRInputVector = ConditionalValues.CustomVRInputVector;//this->CustomVRInputVector; + BaseCharMove->VRReplicatedMovementMode = this->VRReplicatedMovementMode; + } + + if (!ConditionalValues.RequestedVelocity.IsZero()) + { + BaseCharMove->RequestedVelocity = ConditionalValues.RequestedVelocity; + BaseCharMove->SetHasRequestedVelocity(true); + } + else + { + BaseCharMove->SetHasRequestedVelocity(false); + } + + FSavedMove_Character::PrepMoveFor(Character); +} + +FVRCharacterScopedMovementUpdate::FVRCharacterScopedMovementUpdate(USceneComponent* Component, EScopedUpdate::Type ScopeBehavior, bool bRequireOverlapsEventFlagToQueueOverlaps) + : FScopedMovementUpdate(Component, ScopeBehavior, bRequireOverlapsEventFlagToQueueOverlaps) +{ + UVRRootComponent* RootComponent = Cast(Owner); + if (RootComponent) + { + InitialVRTransform = RootComponent->OffsetComponentToWorld; + } +} + +void FVRCharacterScopedMovementUpdate::RevertMove() +{ + bool bTransformIsDirty = IsTransformDirty(); + + FScopedMovementUpdate::RevertMove(); + + UVRRootComponent* RootComponent = Cast(Owner); + if (RootComponent) + { + // If the base class was going to miss bad overlaps, ie: the offsetcomponent to world is different but the transform isn't + if (!bTransformIsDirty && !IsDeferringUpdates() && !InitialVRTransform.Equals(RootComponent->OffsetComponentToWorld)) + { + RootComponent->UpdateOverlaps(); + } + + // Fix offset + RootComponent->GenerateOffsetToWorld(); + } +} + + +FVRCharacterNetworkMoveData::FVRCharacterNetworkMoveData() : FCharacterNetworkMoveData() +{ + VRCapsuleLocation = FVector::ZeroVector; + LFDiff = FVector::ZeroVector; + CapsuleHeight = 0.f; + VRCapsuleRotation = 0.f; + ReplicatedMovementMode = EVRConjoinedMovementModes::C_MOVE_MAX; +} + +FVRCharacterNetworkMoveData::~FVRCharacterNetworkMoveData() +{ +} + +void FVRCharacterNetworkMoveData::ClientFillNetworkMoveData(const FSavedMove_Character& ClientMove, ENetworkMoveType MoveType) +{ + // Handles the movement base itself now + FCharacterNetworkMoveData::ClientFillNetworkMoveData(ClientMove, MoveType); + + // I know that we overloaded this, so it should be our base type + if (const FSavedMove_VRBaseCharacter* SavedMove = (const FSavedMove_VRBaseCharacter*)(&ClientMove)) + { + ReplicatedMovementMode = SavedMove->VRReplicatedMovementMode; + ConditionalMoveReps = SavedMove->ConditionalValues; + + // #TODO: Roll these into the conditionals + VRCapsuleLocation = SavedMove->VRCapsuleLocation; + LFDiff = SavedMove->LFDiff; + CapsuleHeight = SavedMove->CapsuleHeight; + VRCapsuleRotation = FRotator::CompressAxisToShort(SavedMove->VRCapsuleRotation.Yaw); + } +} + +bool FVRCharacterNetworkMoveData::Serialize(UCharacterMovementComponent& CharacterMovement, FArchive& Ar, UPackageMap* PackageMap, ENetworkMoveType MoveType) +{ + NetworkMoveType = MoveType; + + bool bLocalSuccess = true; + const bool bIsSaving = Ar.IsSaving(); + + Ar << TimeStamp; + + // Handle switching the acceleration rep + // Can't use SerializeOptionalValue here as I don't want to bitwise compare floats + bool bRepAccel = bIsSaving ? !Acceleration.IsNearlyZero() : false; + Ar.SerializeBits(&bRepAccel, 1); + + if (bRepAccel) + { + Acceleration.NetSerialize(Ar, PackageMap, bLocalSuccess); + } + else + { + if (!bIsSaving) + { + Acceleration = FVector::ZeroVector; + } + } + + //Location.NetSerialize(Ar, PackageMap, bLocalSuccess); + + uint16 Yaw = bIsSaving ? FRotator::CompressAxisToShort(ControlRotation.Yaw) : 0; + uint16 Pitch = bIsSaving ? FRotator::CompressAxisToShort(ControlRotation.Pitch) : 0; + uint16 Roll = bIsSaving ? FRotator::CompressAxisToShort(ControlRotation.Roll) : 0; + bool bRepYaw = Yaw != 0; + + ACharacter* CharacterOwner = CharacterMovement.GetCharacterOwner(); + + bool bRepRollAndPitch = false; + + if (AVRBaseCharacter* BaseChar = Cast(CharacterOwner)) + { + if (BaseChar->VRMovementReference && !BaseChar->VRMovementReference->bUseClientControlRotation) + { + bRepRollAndPitch = (Roll != 0 || Pitch != 0); + } + } + else + { + bool bCanRepRollAndPitch = (CharacterOwner && (CharacterOwner->bUseControllerRotationRoll || CharacterOwner->bUseControllerRotationPitch)); + bRepRollAndPitch = bCanRepRollAndPitch && (Roll != 0 || Pitch != 0); + } + + Ar.SerializeBits(&bRepRollAndPitch, 1); + + if (bRepRollAndPitch) + { + // Reversed the order of these + uint32 Rotation32 = 0; + uint32 Yaw32 = bIsSaving ? Yaw : 0; + + if (bIsSaving) + { + Rotation32 = (((uint32)Roll) << 16) | ((uint32)Pitch); + Ar.SerializeIntPacked(Rotation32); + } + else + { + Ar.SerializeIntPacked(Rotation32); + + // Reversed the order of these so it costs less to replicate + Pitch = (Rotation32 & 65535); + Roll = (Rotation32 >> 16); + } + } + + uint32 Yaw32 = bIsSaving ? Yaw : 0; + + Ar.SerializeBits(&bRepYaw, 1); + if (bRepYaw) + { + Ar.SerializeIntPacked(Yaw32); + Yaw = (uint16)Yaw32; + } + + if (!bIsSaving) + { + ControlRotation.Yaw = bRepYaw ? FRotator::DecompressAxisFromShort(Yaw) : 0; + ControlRotation.Pitch = bRepRollAndPitch ? FRotator::DecompressAxisFromShort(Pitch) : 0; + ControlRotation.Roll = bRepRollAndPitch ? FRotator::DecompressAxisFromShort(Roll) : 0; + } + + // ControlRotation : FRotator handles each component zero/non-zero test; it uses a single signal bit for zero/non-zero, and uses 16 bits per component if non-zero. + //ControlRotation.NetSerialize(Ar, PackageMap, bLocalSuccess); + + SerializeOptionalValue(bIsSaving, Ar, CompressedMoveFlags, 0); + SerializeOptionalValue(bIsSaving, Ar, MovementMode, MOVE_Walking); + VRCapsuleLocation.NetSerialize(Ar, PackageMap, bLocalSuccess); + Ar << VRCapsuleRotation; + + // Location is only used for error checking, so only save for the final move. + //if (MoveType == ENetworkMoveType::NewMove) + //{ + Location.NetSerialize(Ar, PackageMap, bLocalSuccess); + //} + + // Movement base needs to always send now since they allow for relative based velocity + SerializeOptionalValue(bIsSaving, Ar, MovementBase, nullptr); + SerializeOptionalValue(bIsSaving, Ar, MovementBaseBoneName, NAME_None); + + bool bHasReplicatedMovementMode = ReplicatedMovementMode != EVRConjoinedMovementModes::C_MOVE_MAX; + Ar.SerializeBits(&bHasReplicatedMovementMode, 1); + + if (bHasReplicatedMovementMode) + { + // Increased to 6 bits for 64 total elements instead of 16 + Ar.SerializeBits(&ReplicatedMovementMode, 6); + } + else if(!bIsSaving) + { + ReplicatedMovementMode = EVRConjoinedMovementModes::C_MOVE_MAX; + } + + // Rep out our custom move settings + ConditionalMoveReps.NetSerialize(Ar, PackageMap, bLocalSuccess); + + //VRCapsuleLocation.NetSerialize(Ar, PackageMap, bLocalSuccess); + if (AVRBaseCharacter* VRChar = Cast(CharacterOwner)) + { + if (!VRChar->bRetainRoomscale) + { + SerializePackedVector<10000, 32>(LFDiff, Ar); + } + else + { + SerializePackedVector<100, 30>(LFDiff, Ar); + } + } + else + { + SerializePackedVector<100, 30>(LFDiff, Ar); + } + + bool bHasCapsuleHeight = CapsuleHeight > 0.f; + Ar.SerializeBits(&bHasCapsuleHeight, 1); + + if (bHasCapsuleHeight) + { + // This is 0.0 - 512.0, using compression to get it smaller, 8 bits = max 256 + 1 bit for sign and 7 bits precision for 128 / full 2 digit precision + if (Ar.IsSaving()) + { + WriteFixedCompressedFloat<1024, 18>(CapsuleHeight, Ar); + } + else + { + ReadFixedCompressedFloat<1024, 18>(CapsuleHeight, Ar); + } + } + + //LFDiff.NetSerialize(Ar, PackageMap, bLocalSuccess); + //Ar << VRCapsuleRotation; + + return !Ar.IsError(); +} + + +void FVRCharacterMoveResponseDataContainer::ServerFillResponseData(const UCharacterMovementComponent& CharacterMovement, const FClientAdjustment& PendingAdjustment) +{ + FCharacterMoveResponseDataContainer::ServerFillResponseData(CharacterMovement, PendingAdjustment); + + if (const UVRBaseCharacterMovementComponent* BaseMovecomp = Cast(&CharacterMovement)) + { + // #TODO: This is set in the pending adjustment now in 5.1 + //bHasRotation = CharacterMovement.ShouldCorrectRotation(); + bHasRotation = !BaseMovecomp->bUseClientControlRotation; + } +} + +FScopedMeshBoneUpdateOverrideVR::FScopedMeshBoneUpdateOverrideVR(USkeletalMeshComponent* Mesh, EKinematicBonesUpdateToPhysics::Type OverrideSetting) + : MeshRef(Mesh) +{ + if (MeshRef) + { + // Save current state. + SavedUpdateSetting = MeshRef->KinematicBonesUpdateType; + // Override bone update setting. + MeshRef->KinematicBonesUpdateType = OverrideSetting; + } +} + +FScopedMeshBoneUpdateOverrideVR::~FScopedMeshBoneUpdateOverrideVR() +{ + if (MeshRef) + { + // Restore bone update flag. + MeshRef->KinematicBonesUpdateType = SavedUpdateSetting; + } +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripMotionControllerComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripMotionControllerComponent.cpp new file mode 100644 index 0000000..5bcf7aa --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripMotionControllerComponent.cpp @@ -0,0 +1,8593 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "GripMotionControllerComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GripMotionControllerComponent) + +#include "VRExpansionFunctionLibrary.h" +#include "IHeadMountedDisplay.h" +#include "HeadMountedDisplayTypes.h" +#include "Misc/ScopeLock.h" +#include "Net/UnrealNetwork.h" +#include "PrimitiveSceneInfo.h" +#include "Engine/World.h" +#include "PrimitiveSceneProxy.h" +#include "GameFramework/WorldSettings.h" +#include "IXRSystemAssets.h" +#include "Components/StaticMeshComponent.h" +#include "MotionDelayBuffer.h" +#include "UObject/VRObjectVersion.h" +#include "UObject/UObjectGlobals.h" // for FindObject<> +#include "IXRTrackingSystem.h" +#include "IXRSystemAssets.h" +#include "DrawDebugHelpers.h" +#include "TimerManager.h" +#include "VRBaseCharacter.h" +#include "VRCharacter.h" +#include "VRRootComponent.h" +#include "VRGlobalSettings.h" +#include "Math/DualQuat.h" +#include "IIdentifiableXRDevice.h" // for FXRDeviceId +#include "XRMotionControllerBase.h" // for GetHandEnumForSourceName() +//#include "XRDeviceVisualizationComponent.h" // For visualization component + +#include "Physics/Experimental/PhysScene_Chaos.h" + +#include "GripScripts/GS_Default.h" +#include "GripScripts/GS_LerpToHand.h" + +#include "PhysicsPublic.h" +#include "PhysicsEngine/BodySetup.h" +#include "PhysicsEngine/ConstraintDrives.h" +#include "PhysicsReplication.h" +#include "PhysicsEngine/PhysicsAsset.h" + +#include "Chaos/ParticleHandle.h" +#include "Chaos/KinematicGeometryParticles.h" +#include "Chaos/PBDJointConstraintTypes.h" +#include "Chaos/PBDConstraintBaseData.h" +#include "Chaos/PBDJointConstraintData.h" +#include "Chaos/Sphere.h" +#include "PhysicsProxy/SingleParticlePhysicsProxy.h" +#include "Chaos/ChaosConstraintSettings.h" +#include "Chaos/PhysicsObject.h" +#include "PhysicsEngine/PhysicsObjectExternalInterface.h" +#include "Chaos/PhysicsObjectInterface.h" + +#include "Misc/CollisionIgnoreSubsystem.h" + +#include "Features/IModularFeatures.h" + +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + +DEFINE_LOG_CATEGORY(LogVRMotionController); +//For UE4 Profiler ~ Stat +DECLARE_CYCLE_STAT(TEXT("TickGrip ~ TickingGrip"), STAT_TickGrip, STATGROUP_TickGrip); +DECLARE_CYCLE_STAT(TEXT("GetGripWorldTransform ~ GettingTransform"), STAT_GetGripTransform, STATGROUP_TickGrip); + +// MAGIC NUMBERS +// Constraint multipliers for angular, to avoid having to have two sets of stiffness/damping variables +const float ANGULAR_STIFFNESS_MULTIPLIER = 1.5f; +const float ANGULAR_DAMPING_MULTIPLIER = 1.4f; +const float ANGULAR_STIFFNESS_MULTIPLIER_CHAOS = 0.45f; +const float ANGULAR_DAMPING_MULTIPLIER_CHAOS = 0.45f; + +// Multiplier for the Interactive Hybrid With Physics grip - When not colliding increases stiffness by this value +const float HYBRID_PHYSICS_GRIP_MULTIPLIER = 10.0f; + +namespace { + /** This is to prevent destruction of motion controller components while they are + in the middle of being accessed by the render thread */ + FCriticalSection CritSect; + +} // anonymous namespace + +namespace GripUEMotionController { + // A scoped lock that must be explicitly locked and will unlock upon destruction if locked. + // Convenient if you only sometimes want to lock and the scopes are complicated. + class FScopeLockOptional + { + public: + FScopeLockOptional() + { + } + + void Lock(FCriticalSection* InSynchObject) + { + SynchObject = InSynchObject; + SynchObject->Lock(); + } + + /** Destructor that performs a release on the synchronization object. */ + ~FScopeLockOptional() + { + Unlock(); + } + + void Unlock() + { + if (SynchObject) + { + SynchObject->Unlock(); + SynchObject = nullptr; + } + } + + private: + /** Copy constructor( hidden on purpose). */ + FScopeLockOptional(const FScopeLockOptional& InScopeLock); + + /** Assignment operator (hidden on purpose). */ + FScopeLockOptional& operator=(FScopeLockOptional& InScopeLock) + { + return *this; + } + + private: + + // Holds the synchronization object to aggregate and scope manage. + FCriticalSection* SynchObject = nullptr; + }; +} + + // CVars +namespace GripMotionControllerCvars +{ + static int32 DrawDebugGripCOM = 0; + FAutoConsoleVariableRef CVarDrawCOMDebugSpheres( + TEXT("vr.DrawDebugCenterOfMassForGrips"), + DrawDebugGripCOM, + TEXT("When on, will draw debug speheres for physics grips COM.\n") + TEXT("0: Disable, 1: Enable"), + ECVF_Default); +} + + //============================================================================= +UGripMotionControllerComponent::UGripMotionControllerComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + PrimaryComponentTick.bCanEverTick = true; + PrimaryComponentTick.bStartWithTickEnabled = true; + PrimaryComponentTick.TickGroup = TG_PrePhysics; + PrimaryComponentTick.bTickEvenWhenPaused = true; + + PlayerIndex = 0; + MotionSource = IMotionController::LeftHandSourceId; + //Hand = EControllerHand::Left; + bDisableLowLatencyUpdate = false; + bHasAuthority = false; + bIgnoreTrackingStatus = false; + bUseWithoutTracking = false; + ClientAuthConflictResolutionMethod = EVRClientAuthConflictResolutionMode::VRGRIP_CONFLICT_First; + bAlwaysSendTickGrip = false; + bAutoActivate = true; + + SetIsReplicatedByDefault(true); + + // Epic never initializes this variable, so I need to + CurrentTrackingStatus = ETrackingStatus::NotTracked; + + // Default 100 htz update rate, same as the 100htz update rate of rep_notify, will be capped to 90/45 though because of vsync on HMD + //bReplicateControllerTransform = true; + ControllerNetUpdateRate = 100.0f; // 100 htz is default + ControllerNetUpdateCount = 0.0f; + bReplicateWithoutTracking = false; + bLerpingPosition = false; + bSmoothReplicatedMotion = false; + bReppedOnce = false; + bScaleTracking = false; + TrackingScaler = FVector(1.0f); + bLimitMinHeight = false; + MinimumHeight = 0.0f; + bLimitMaxHeight = false; + MaximumHeight = 240.0f; + //bOffsetByHMD = false; + bLeashToHMD = false; + LeashRange = 300.0f; + bConstrainToPivot = false; + + bSmoothHandTracking = false; + bWasSmoothingHand = false; + bSmoothWithEuroLowPassFunction = true; + LastSmoothRelativeTransform = FTransform::Identity; + SmoothingSpeed = 20.0f; + EuroSmoothingParams.MinCutoff = 0.1f; + EuroSmoothingParams.DeltaCutoff = 10.f; + EuroSmoothingParams.CutoffSlope = 10.f; + + bIsPostTeleport = false; + + GripIDIncrementer = INVALID_VRGRIP_ID; + + // Pivot Variables + CustomPivotComponentSocketName = NAME_None; + bSkipPivotTransformAdjustment = false; + + bOffsetByControllerProfile = true; + CurrentControllerProfileTransform = FTransform::Identity; + + DefaultGripScript = nullptr; + DefaultGripScriptClass = UGS_Default::StaticClass(); + //DisplayComponentReference = nullptr; + + VelocityCalculationType = EVRVelocityType::VRLOCITY_Default; + LastRelativePosition = FTransform::Identity; + bSampleVelocityInWorldSpace = false; + VelocitySamples = 30.f; + + bProjectNonSimulatingGrips = false; + EndPhysicsTickFunction.TickGroup = TG_EndPhysics; + EndPhysicsTickFunction.bCanEverTick = true; + EndPhysicsTickFunction.bStartWithTickEnabled = false; +} + +void UGripMotionControllerComponent::RegisterEndPhysicsTick(bool bRegister) +{ + if (bRegister != EndPhysicsTickFunction.IsTickFunctionRegistered()) + { + if (bRegister) + { + if (SetupActorComponentTickFunction(&EndPhysicsTickFunction)) + { + EndPhysicsTickFunction.Target = this; + // Make sure our EndPhysicsTick gets called after physics simulation is finished + UWorld* World = GetWorld(); + if (World != nullptr) + { + EndPhysicsTickFunction.AddPrerequisite(World, World->EndPhysicsTickFunction); + } + } + } + else + { + EndPhysicsTickFunction.UnRegisterTickFunction(); + } + } +} + +void UGripMotionControllerComponent::EndPhysicsTickComponent(FGripComponentEndPhysicsTickFunction& ThisTickFunction) +{ + + if (!IsValid(this)) + return; + + // Now check if we should turn off any post physics ticking + FTransform baseTrans = this->GetAttachParent()->GetComponentTransform().Inverse(); + + for (int i = 0; i < LocallyGrippedObjects.Num(); ++i) + { + if (!LocallyGrippedObjects[i].GrippedObject || !IsValid(LocallyGrippedObjects[i].GrippedObject)) + continue; // Skip, don't process this + + if (LocallyGrippedObjects[i].GrippedObject && IsValid(LocallyGrippedObjects[i].GrippedObject) && LocallyGrippedObjects[i].GrippedObject->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + bool bSampleRelativeTransform = bProjectNonSimulatingGrips; + + if (!bSampleRelativeTransform) + { + EGripInterfaceTeleportBehavior TeleportBehavior = IVRGripInterface::Execute_TeleportBehavior(LocallyGrippedObjects[i].GrippedObject); + bSampleRelativeTransform = TeleportBehavior == EGripInterfaceTeleportBehavior::DeltaTeleportation; + } + + if (bSampleRelativeTransform) + { + switch(LocallyGrippedObjects[i].GripTargetType) + { + case EGripTargetType::ActorGrip: + { + if (AActor* Actor = Cast(LocallyGrippedObjects[i].GrippedObject)) + { + if (UPrimitiveComponent* root = Cast(Actor->GetRootComponent())) + { + LocallyGrippedObjects[i].LastWorldTransform = root->GetComponentTransform() * baseTrans; + LocallyGrippedObjects[i].bSetLastWorldTransform = true; + } + } + }break; + case EGripTargetType::ComponentGrip: + { + if (UPrimitiveComponent* root = Cast(LocallyGrippedObjects[i].GrippedObject)) + { + LocallyGrippedObjects[i].LastWorldTransform = root->GetComponentTransform() * baseTrans; + LocallyGrippedObjects[i].bSetLastWorldTransform = true; + } + }break; + } + } + } + } + + for (int i = 0; i < GrippedObjects.Num(); ++i) + { + if (!GrippedObjects[i].GrippedObject || !IsValid(GrippedObjects[i].GrippedObject)) + continue; // Skip, don't process this + + if (GrippedObjects[i].GrippedObject->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + bool bSampleRelativeTransform = bProjectNonSimulatingGrips; + + if (!bSampleRelativeTransform) + { + EGripInterfaceTeleportBehavior TeleportBehavior = IVRGripInterface::Execute_TeleportBehavior(GrippedObjects[i].GrippedObject); + bSampleRelativeTransform = TeleportBehavior == EGripInterfaceTeleportBehavior::DeltaTeleportation; + } + + if (bSampleRelativeTransform) + { + switch (GrippedObjects[i].GripTargetType) + { + case EGripTargetType::ActorGrip: + { + if (AActor* Actor = Cast(GrippedObjects[i].GrippedObject)) + { + if (UPrimitiveComponent* root = Cast(Actor->GetRootComponent())) + { + GrippedObjects[i].LastWorldTransform = root->GetComponentTransform() * baseTrans; + GrippedObjects[i].bSetLastWorldTransform = true; + } + } + }break; + case EGripTargetType::ComponentGrip: + { + if (UPrimitiveComponent* root = Cast(GrippedObjects[i].GrippedObject)) + { + GrippedObjects[i].LastWorldTransform = root->GetComponentTransform() * baseTrans; + GrippedObjects[i].bSetLastWorldTransform = true; + } + }break; + } + } + } + } +} + +void FGripComponentEndPhysicsTickFunction::ExecuteTick(float DeltaTime, enum ELevelTick TickType, ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent) +{ + QUICK_SCOPE_CYCLE_COUNTER(FGripComponentEndPhysicsTickFunction_ExecuteTick); + CSV_SCOPED_TIMING_STAT_EXCLUSIVE(Physics); + + if (Target && IsValid(Target)) + { + FActorComponentTickFunction::ExecuteTickHelper(Target, /*bTickInEditor=*/ false, DeltaTime, TickType, [this](float DilatedTime) + { + Target->EndPhysicsTickComponent(*this); + }); + } +} + +FString FGripComponentEndPhysicsTickFunction::DiagnosticMessage() +{ + return TEXT("GripComponentEndPhysicsTickFunction"); +} + +FName FGripComponentEndPhysicsTickFunction::DiagnosticContext(bool bDetailed) +{ + return FName(TEXT("GripComponentEndPhysicsTick")); +} + + +//============================================================================= +UGripMotionControllerComponent::~UGripMotionControllerComponent() +{ + // Moved view extension destruction to BeginDestroy like the new controllers + // Epic had it listed as a crash in the private bug tracker I guess. +} + +void UGripMotionControllerComponent::NewControllerProfileLoaded() +{ + GetCurrentProfileTransform(false); +} + +void UGripMotionControllerComponent::GetCurrentProfileTransform(bool bBindToNoticationDelegate) +{ + if (bOffsetByControllerProfile) + { + UVRGlobalSettings* VRSettings = GetMutableDefault(); + + if (VRSettings == nullptr) + return; + + EControllerHand HandType; + this->GetHandType(HandType); + + FTransform NewControllerProfileTransform = FTransform::Identity; + + if (HandType == EControllerHand::Left || HandType == EControllerHand::AnyHand || !VRSettings->bUseSeperateHandTransforms) + { + NewControllerProfileTransform = VRSettings->CurrentControllerProfileTransform; + } + else if (HandType == EControllerHand::Right) + { + NewControllerProfileTransform = VRSettings->CurrentControllerProfileTransformRight; + } + + if (bBindToNoticationDelegate && !NewControllerProfileEvent_Handle.IsValid()) + { + NewControllerProfileEvent_Handle = VRSettings->OnControllerProfileChangedEvent.AddUObject(this, &UGripMotionControllerComponent::NewControllerProfileLoaded); + } + + if (!NewControllerProfileTransform.Equals(CurrentControllerProfileTransform)) + { + FTransform OriginalControllerProfileTransform = CurrentControllerProfileTransform; + CurrentControllerProfileTransform = NewControllerProfileTransform; + + // Auto adjust for FPS testing pawns + if (!bTracked && bUseWithoutTracking) + { + this->SetRelativeTransform(CurrentControllerProfileTransform * (OriginalControllerProfileTransform.Inverse() * this->GetRelativeTransform())); + } + + OnControllerProfileTransformChanged.Broadcast(CurrentControllerProfileTransform.Inverse() * OriginalControllerProfileTransform, CurrentControllerProfileTransform); + } + } +} + +void UGripMotionControllerComponent::InitializeComponent() +{ + Super::InitializeComponent(); + + if (!DefaultGripScript && DefaultGripScriptClass) + DefaultGripScript = NewObject(this, DefaultGripScriptClass); //DefaultGripScriptClass.GetDefaultObject(); + else + DefaultGripScript = NewObject(this, UGS_Default::StaticClass()); +} + +void UGripMotionControllerComponent::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + Super::EndPlay(EndPlayReason); + + // Cancel end physics tick + RegisterEndPhysicsTick(false); + + if (NewControllerProfileEvent_Handle.IsValid()) + { + UVRGlobalSettings* VRSettings = GetMutableDefault(); + if (VRSettings != nullptr) + { + VRSettings->OnControllerProfileChangedEvent.Remove(NewControllerProfileEvent_Handle); + NewControllerProfileEvent_Handle.Reset(); + } + } + + for (int i = 0; i < GrippedObjects.Num(); i++) + { + DestroyPhysicsHandle(GrippedObjects[i]); + + if (/*HasGripAuthority(GrippedObjects[i]) || */IsServer()) + { + DropObjectByInterface(nullptr, GrippedObjects[i].GripID); + } + else + { + if (IsValid(GrippedObjects[i].GrippedObject)) + { + bool bSimulateOnDrop = true; + if (GrippedObjects[i].GrippedObject->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + bSimulateOnDrop = IVRGripInterface::Execute_SimulateOnDrop(GrippedObjects[i].GrippedObject); + } + + NotifyDrop(GrippedObjects[i], bSimulateOnDrop); + } + } + } + GrippedObjects.Empty(); + + for (int i = 0; i < LocallyGrippedObjects.Num(); i++) + { + DestroyPhysicsHandle(LocallyGrippedObjects[i]); + + if (/*HasGripAuthority(LocallyGrippedObjects[i]) || */IsServer()) + { + DropObjectByInterface(nullptr, LocallyGrippedObjects[i].GripID); + } + else + { + if (IsValid(LocallyGrippedObjects[i].GrippedObject)) + { + bool bSimulateOnDrop = true; + if (LocallyGrippedObjects[i].GrippedObject->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + bSimulateOnDrop = IVRGripInterface::Execute_SimulateOnDrop(LocallyGrippedObjects[i].GrippedObject); + } + + NotifyDrop(LocallyGrippedObjects[i], bSimulateOnDrop); + } + } + } + LocallyGrippedObjects.Empty(); + + for (int i = 0; i < PhysicsGrips.Num(); i++) + { + DestroyPhysicsHandle(&PhysicsGrips[i]); + } + PhysicsGrips.Empty(); + + // Clear any timers that we are managing + if (UWorld * myWorld = GetWorld()) + { + myWorld->GetTimerManager().ClearAllTimersForObject(this); + } + + ObjectsWaitingForSocketUpdate.Empty(); +} + +void UGripMotionControllerComponent::OnUnregister() +{ + Super::OnUnregister(); +} + +void UGripMotionControllerComponent::BeginDestroy() +{ + Super::BeginDestroy(); + + if (GripViewExtension.IsValid()) + { + { + // This component could be getting accessed from the render thread so it needs to wait + // before clearing MotionControllerComponent and allowing the destructor to continue + FScopeLock ScopeLock(&CritSect); + GripViewExtension->MotionControllerComponent = NULL; + } + + GripViewExtension.Reset(); + } +} + +void UGripMotionControllerComponent::BeginPlay() +{ + Super::BeginPlay(); +} + +void UGripMotionControllerComponent::CreateRenderState_Concurrent(FRegisterComponentContext* Context) +{ + + // Don't bother updating this stuff if we aren't local or using them + if (bHasAuthority && !bDisableLowLatencyUpdate && IsActive()) + { + LateUpdateParams.GripRenderThreadRelativeTransform = GetRelativeTransform(); + LateUpdateParams.GripRenderThreadComponentScale = GetComponentScale(); + LateUpdateParams.GripRenderThreadProfileTransform = CurrentControllerProfileTransform; + LateUpdateParams.GripRenderThreadLastLocationForLateUpdate = LastLocationForLateUpdate; + + LateUpdateParams.bRenderSmoothHandTracking = bSmoothHandTracking; + if (LateUpdateParams.bRenderSmoothHandTracking) + { + if (UWorld* world = GetWorld()) + { + LateUpdateParams.RenderLastDeltaTime = world->GetDeltaSeconds(); + } + + LateUpdateParams.bRenderSmoothWithEuroLowPassFunction = bSmoothWithEuroLowPassFunction; + + if (LateUpdateParams.bRenderSmoothWithEuroLowPassFunction) + { + LateUpdateParams.RenderEuroSmoothingParams = EuroSmoothingParams; + } + else + { + LateUpdateParams.RenderSmoothingSpeed = SmoothingSpeed; + LateUpdateParams.RenderLastSmoothRelativeTransform = LastSmoothRelativeTransform; + } + } + } + + Super::Super::CreateRenderState_Concurrent(Context); +} + +void UGripMotionControllerComponent::SendRenderTransform_Concurrent() +{ + // Don't bother updating this stuff if we aren't local or using them + if (bHasAuthority && !bDisableLowLatencyUpdate && IsActive()) + { + struct FPrimitiveUpdateRenderThreadRelativeTransformParams + { + FRenderTrackingParams LateUpdateParams; + }; + + FPrimitiveUpdateRenderThreadRelativeTransformParams UpdateParams; + UpdateParams.LateUpdateParams.GripRenderThreadRelativeTransform = GetRelativeTransform(); + UpdateParams.LateUpdateParams.GripRenderThreadComponentScale = GetComponentScale(); + UpdateParams.LateUpdateParams.GripRenderThreadProfileTransform = CurrentControllerProfileTransform; + UpdateParams.LateUpdateParams.GripRenderThreadLastLocationForLateUpdate = LastLocationForLateUpdate; + + UpdateParams.LateUpdateParams.bRenderSmoothHandTracking = bSmoothHandTracking; + if (UpdateParams.LateUpdateParams.bRenderSmoothHandTracking) + { + if (UWorld* world = GetWorld()) + { + UpdateParams.LateUpdateParams.RenderLastDeltaTime = world->GetDeltaSeconds(); + } + + UpdateParams.LateUpdateParams.bRenderSmoothWithEuroLowPassFunction = bSmoothWithEuroLowPassFunction; + + if (UpdateParams.LateUpdateParams.bRenderSmoothWithEuroLowPassFunction) + { + UpdateParams.LateUpdateParams.RenderEuroSmoothingParams = EuroSmoothingParams; + } + else + { + UpdateParams.LateUpdateParams.RenderSmoothingSpeed = SmoothingSpeed; + UpdateParams.LateUpdateParams.RenderLastSmoothRelativeTransform = LastSmoothRelativeTransform; + } + } + + ENQUEUE_RENDER_COMMAND(UpdateRTRelativeTransformCommand)( + [UpdateParams, this](FRHICommandListImmediate& RHICmdList) + { + LateUpdateParams = UpdateParams.LateUpdateParams; + }); + } + + // Skip bases motion controllers implementation, we don't want to double update to the render thread + Super::Super::SendRenderTransform_Concurrent(); +} + +FBPActorPhysicsHandleInformation * UGripMotionControllerComponent::GetPhysicsGrip(const FBPActorGripInformation & GripInfo) +{ + return PhysicsGrips.FindByKey(GripInfo); +} + +FBPActorPhysicsHandleInformation* UGripMotionControllerComponent::GetPhysicsGrip(const uint8 GripID) +{ + return PhysicsGrips.FindByKey(GripID); +} + +bool UGripMotionControllerComponent::GetPhysicsGripIndex(const FBPActorGripInformation & GripInfo, int & index) +{ + index = PhysicsGrips.IndexOfByKey(GripInfo); + return index != INDEX_NONE; +} + +FBPActorPhysicsHandleInformation * UGripMotionControllerComponent::CreatePhysicsGrip(const FBPActorGripInformation & GripInfo) +{ + FBPActorPhysicsHandleInformation * HandleInfo = PhysicsGrips.FindByKey(GripInfo); + + if (HandleInfo) + { + DestroyPhysicsHandle(HandleInfo); + return HandleInfo; + } + + FBPActorPhysicsHandleInformation NewInfo; + NewInfo.HandledObject = GripInfo.GrippedObject; + NewInfo.GripID = GripInfo.GripID; + + int index = PhysicsGrips.Add(NewInfo); + + return &PhysicsGrips[index]; +} + + +//============================================================================= +void UGripMotionControllerComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // Don't ever replicate these, they are getting replaced by my custom send anyway + DISABLE_REPLICATED_PRIVATE_PROPERTY(USceneComponent, RelativeLocation); + DISABLE_REPLICATED_PRIVATE_PROPERTY(USceneComponent, RelativeRotation); + DISABLE_REPLICATED_PRIVATE_PROPERTY(USceneComponent, RelativeScale3D); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UGripMotionControllerComponent, GrippedObjects, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UGripMotionControllerComponent, ControllerNetUpdateRate, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UGripMotionControllerComponent, bSmoothReplicatedMotion, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UGripMotionControllerComponent, bReplicateWithoutTracking, PushModelParams); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_SkipOwner, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + // Skipping the owner with this as the owner will use the controllers location directly + DOREPLIFETIME_WITH_PARAMS_FAST(UGripMotionControllerComponent, ReplicatedControllerTransform, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(UGripMotionControllerComponent, LocallyGrippedObjects, PushModelParamsWithCondition); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithConditionOwnerOnly{ COND_OwnerOnly, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UGripMotionControllerComponent, LocalTransactionBuffer, PushModelParamsWithConditionOwnerOnly); +// DOREPLIFETIME(UGripMotionControllerComponent, bReplicateControllerTransform); +} + +/*void UGripMotionControllerComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) +{ + Super::PreReplication(ChangedPropertyTracker); + + // Don't ever replicate these, they are getting replaced by my custom send anyway + DOREPLIFETIME_ACTIVE_OVERRIDE(USceneComponent, RelativeLocation, false); + DOREPLIFETIME_ACTIVE_OVERRIDE(USceneComponent, RelativeRotation, false); + DOREPLIFETIME_ACTIVE_OVERRIDE(USceneComponent, RelativeScale3D, false); +}*/ + +void UGripMotionControllerComponent::Server_SendControllerTransform_Implementation(FBPVRComponentPosRep NewTransform) +{ + // Store new transform and trigger OnRep_Function + ReplicatedControllerTransform = NewTransform; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, ReplicatedControllerTransform, this); +#endif + + // Server should no longer call this RPC itself, but if is using non tracked then it will so keeping auth check + if(!bHasAuthority) + OnRep_ReplicatedControllerTransform(); +} + +bool UGripMotionControllerComponent::Server_SendControllerTransform_Validate(FBPVRComponentPosRep NewTransform) +{ + return true; + // Optionally check to make sure that player is inside of their bounds and deny it if they aren't? +} + +void UGripMotionControllerComponent::FGripViewExtension::BeginRenderViewFamily(FSceneViewFamily& InViewFamily) +{ + if (!MotionControllerComponent) + { + return; + } + + // Set up the late update state for the controller component + LateUpdate.Setup(MotionControllerComponent->CalcNewComponentToWorld(FTransform()), MotionControllerComponent, false); +} + +void UGripMotionControllerComponent::GetPhysicsVelocities(const FBPActorGripInformation &Grip, FVector &CurAngularVelocity, FVector &CurLinearVelocity) +{ + UPrimitiveComponent * primComp = Grip.GetGrippedComponent();//Grip.Component; + AActor * pActor = Grip.GetGrippedActor(); + + if (!primComp && pActor) + primComp = Cast(pActor->GetRootComponent()); + + if (!primComp) + { + CurAngularVelocity = FVector::ZeroVector; + CurLinearVelocity = FVector::ZeroVector; + return; + } + + // TMP #TODO: Fix when 5.4 bug is fixed + if (!primComp->IsSimulatingPhysics()) + { + CurLinearVelocity = Grip.LinVel; + CurAngularVelocity = Grip.RotVel; + return; + } + + CurAngularVelocity = primComp->GetPhysicsAngularVelocityInDegrees(); + CurLinearVelocity = primComp->GetPhysicsLinearVelocity(); +} + +bool UGripMotionControllerComponent::GetPhysicsConstraintForce(const FBPActorGripInformation& Grip, FVector& AngularForce, FVector& LinearForce) +{ + if (FBPActorPhysicsHandleInformation * PhysHandle = GetPhysicsGrip(Grip.GripID)) + { + if (PhysHandle->HandleData2.IsValid()) + { + FPhysicsInterface::GetForce(PhysHandle->HandleData2, LinearForce, AngularForce); + return true; + } + } + + return false; +} + +void UGripMotionControllerComponent::GetGripMass(const FBPActorGripInformation& Grip, float& Mass) +{ + UPrimitiveComponent* primComp = Grip.GetGrippedComponent();//Grip.Component; + AActor* pActor = Grip.GetGrippedActor(); + + if (!primComp && pActor) + primComp = Cast(pActor->GetRootComponent()); + + if (!primComp || !primComp->IsSimulatingPhysics()) + { + Mass = 0.f; + return; + } + + Mass = primComp->GetMass(); +} + +FTransform UGripMotionControllerComponent::GetGrippedObjectTransform(const FBPActorGripInformation& Grip) +{ + FTransform returnTrans = FTransform::Identity; + + if (!IsValid(Grip.GrippedObject)) + { + return returnTrans; + } + + if (Grip.GripTargetType == EGripTargetType::ActorGrip) + { + if (AActor* GrippedActor = Cast(Grip.GrippedObject)) + { + returnTrans = GrippedActor->GetActorTransform(); + } + } + else + { + if (UPrimitiveComponent* GrippedComp = Cast(Grip.GrippedObject)) + { + returnTrans = GrippedComp->GetComponentTransform(); + } + } + + return returnTrans; +} + +void UGripMotionControllerComponent::GetGripByActor(FBPActorGripInformation &Grip, AActor * ActorToLookForGrip, EBPVRResultSwitch &Result) +{ + if (!ActorToLookForGrip) + { + Result = EBPVRResultSwitch::OnFailed; + return; + } + + FBPActorGripInformation * GripInfo = GrippedObjects.FindByKey(ActorToLookForGrip); + if(!GripInfo) + GripInfo = LocallyGrippedObjects.FindByKey(ActorToLookForGrip); + + if (GripInfo) + { + Grip = *GripInfo;// GrippedObjects[i]; + Result = EBPVRResultSwitch::OnSucceeded; + return; + } + + Result = EBPVRResultSwitch::OnFailed; +} + +void UGripMotionControllerComponent::GetGripByComponent(FBPActorGripInformation &Grip, UPrimitiveComponent * ComponentToLookForGrip, EBPVRResultSwitch &Result) +{ + if (!ComponentToLookForGrip) + { + Result = EBPVRResultSwitch::OnFailed; + return; + } + + FBPActorGripInformation * GripInfo = GrippedObjects.FindByKey(ComponentToLookForGrip); + if(!GripInfo) + GripInfo = LocallyGrippedObjects.FindByKey(ComponentToLookForGrip); + + if (GripInfo) + { + Grip = *GripInfo;// GrippedObjects[i]; + Result = EBPVRResultSwitch::OnSucceeded; + return; + } + + Result = EBPVRResultSwitch::OnFailed; +} + +void UGripMotionControllerComponent::GetGripByObject(FBPActorGripInformation &Grip, UObject * ObjectToLookForGrip, EBPVRResultSwitch &Result) +{ + if (!ObjectToLookForGrip) + { + Result = EBPVRResultSwitch::OnFailed; + return; + } + + FBPActorGripInformation * GripInfo = GrippedObjects.FindByKey(ObjectToLookForGrip); + if(!GripInfo) + GripInfo = LocallyGrippedObjects.FindByKey(ObjectToLookForGrip); + + if (GripInfo) + { + Grip = *GripInfo;// GrippedObjects[i]; + Result = EBPVRResultSwitch::OnSucceeded; + return; + } + + Result = EBPVRResultSwitch::OnFailed; +} + +FBPActorGripInformation * UGripMotionControllerComponent::GetGripPtrByID(uint8 IDToLookForGrip) +{ + if (IDToLookForGrip == INVALID_VRGRIP_ID) + { + return nullptr; + } + + FBPActorGripInformation* GripInfo = GrippedObjects.FindByKey(IDToLookForGrip); + if (!GripInfo) + GripInfo = LocallyGrippedObjects.FindByKey(IDToLookForGrip); + + return GripInfo; +} + +void UGripMotionControllerComponent::GetGripByID(FBPActorGripInformation &Grip, uint8 IDToLookForGrip, EBPVRResultSwitch &Result) +{ + if (IDToLookForGrip == INVALID_VRGRIP_ID) + { + Result = EBPVRResultSwitch::OnFailed; + return; + } + + FBPActorGripInformation * GripInfo = GrippedObjects.FindByKey(IDToLookForGrip); + if (!GripInfo) + GripInfo = LocallyGrippedObjects.FindByKey(IDToLookForGrip); + + if (GripInfo) + { + Grip = *GripInfo;// GrippedObjects[i]; + Result = EBPVRResultSwitch::OnSucceeded; + return; + } + + Result = EBPVRResultSwitch::OnFailed; +} + +void UGripMotionControllerComponent::SetGripHybridLock(const FBPActorGripInformation& Grip, EBPVRResultSwitch& Result, bool bIsLocked) +{ + int fIndex = GrippedObjects.Find(Grip); + + FBPActorGripInformation* GripInformation = nullptr; + + if (fIndex != INDEX_NONE) + { + GripInformation = &GrippedObjects[fIndex]; + } + else + { + fIndex = LocallyGrippedObjects.Find(Grip); + + if (fIndex != INDEX_NONE) + { + GripInformation = &LocallyGrippedObjects[fIndex]; + } + } + + if (GripInformation != nullptr) + { + GripInformation->bLockHybridGrip = bIsLocked; + Result = EBPVRResultSwitch::OnSucceeded; + return; + } + + Result = EBPVRResultSwitch::OnFailed; +} + +void UGripMotionControllerComponent::SetGripPaused(const FBPActorGripInformation &Grip, EBPVRResultSwitch &Result, bool bIsPaused, bool bNoConstraintWhenPaused) +{ + int fIndex = GrippedObjects.Find(Grip); + + FBPActorGripInformation * GripInformation = nullptr; + + if (fIndex != INDEX_NONE) + { + GripInformation = &GrippedObjects[fIndex]; + } + else + { + fIndex = LocallyGrippedObjects.Find(Grip); + + if (fIndex != INDEX_NONE) + { + GripInformation = &LocallyGrippedObjects[fIndex]; + } + } + + if (GripInformation != nullptr) + { + if (bNoConstraintWhenPaused) + { + if (bIsPaused) + { + if (FBPActorPhysicsHandleInformation * PhysHandle = GetPhysicsGrip(*GripInformation)) + { + DestroyPhysicsHandle(*GripInformation); + } + } + else + { + ReCreateGrip(*GripInformation); + } + } + + GripInformation->bIsPaused = bIsPaused; + Result = EBPVRResultSwitch::OnSucceeded; + return; + } + + Result = EBPVRResultSwitch::OnFailed; +} + +void UGripMotionControllerComponent::SetPausedTransform(const FBPActorGripInformation &Grip, const FTransform & PausedTransform, bool bTeleport) +{ + + FBPActorGripInformation * GripInformation = nullptr; + + int fIndex = GrippedObjects.Find(Grip); + + if (fIndex != INDEX_NONE) + { + GripInformation = &GrippedObjects[fIndex]; + } + else + { + fIndex = LocallyGrippedObjects.Find(Grip); + + if (fIndex != INDEX_NONE) + { + GripInformation = &LocallyGrippedObjects[fIndex]; + } + } + + if (GripInformation != nullptr && GripInformation->GrippedObject != nullptr) + { + if (bTeleport) + { + FTransform ProxyTrans = PausedTransform; + TeleportMoveGrip_Impl(*GripInformation, true, true, ProxyTrans); + } + else + { + if (FBPActorPhysicsHandleInformation * PhysHandle = GetPhysicsGrip(GrippedObjects[fIndex])) + { + UpdatePhysicsHandleTransform(*GripInformation, PausedTransform); + } + else + { + if (GripInformation->GripTargetType == EGripTargetType::ActorGrip) + { + GripInformation->GetGrippedActor()->SetActorTransform(PausedTransform); + } + else + { + GripInformation->GetGrippedComponent()->SetWorldTransform(PausedTransform); + } + } + } + } +} + + + + +void UGripMotionControllerComponent::SetGripCollisionType(const FBPActorGripInformation &Grip, EBPVRResultSwitch &Result, EGripCollisionType NewGripCollisionType) +{ + int fIndex = GrippedObjects.Find(Grip); + + if (fIndex != INDEX_NONE) + { + GrippedObjects[fIndex].GripCollisionType = NewGripCollisionType; + ReCreateGrip(GrippedObjects[fIndex]); + DIRTY_GRIPPED_OBJECTS(); + Result = EBPVRResultSwitch::OnSucceeded; + return; + } + else + { + fIndex = LocallyGrippedObjects.Find(Grip); + + if (fIndex != INDEX_NONE) + { + LocallyGrippedObjects[fIndex].GripCollisionType = NewGripCollisionType; + + if (IsLocallyControlled() && !IsServer() && !IsTornOff() && LocallyGrippedObjects[fIndex].GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive) + { + FBPActorGripInformation GripInfo = LocallyGrippedObjects[fIndex]; + Server_NotifyLocalGripAddedOrChanged(GripInfo); + } + + ReCreateGrip(LocallyGrippedObjects[fIndex]); + DIRTY_LOCALLY_GRIPPED_OBJECTS(); + + Result = EBPVRResultSwitch::OnSucceeded; + return; + } + } + + Result = EBPVRResultSwitch::OnFailed; +} + +void UGripMotionControllerComponent::SetGripLateUpdateSetting(const FBPActorGripInformation &Grip, EBPVRResultSwitch &Result, EGripLateUpdateSettings NewGripLateUpdateSetting) +{ + int fIndex = GrippedObjects.Find(Grip); + + if (fIndex != INDEX_NONE) + { + GrippedObjects[fIndex].GripLateUpdateSetting = NewGripLateUpdateSetting; + DIRTY_GRIPPED_OBJECTS(); + Result = EBPVRResultSwitch::OnSucceeded; + return; + } + else + { + fIndex = LocallyGrippedObjects.Find(Grip); + + if (fIndex != INDEX_NONE) + { + LocallyGrippedObjects[fIndex].GripLateUpdateSetting = NewGripLateUpdateSetting; + + if (IsLocallyControlled() && !IsServer() && !IsTornOff() && LocallyGrippedObjects[fIndex].GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive) + { + FBPActorGripInformation GripInfo = LocallyGrippedObjects[fIndex]; + Server_NotifyLocalGripAddedOrChanged(GripInfo); + } + + DIRTY_LOCALLY_GRIPPED_OBJECTS(); + Result = EBPVRResultSwitch::OnSucceeded; + return; + } + } + + Result = EBPVRResultSwitch::OnFailed; +} + +void UGripMotionControllerComponent::SetGripRelativeTransform( + const FBPActorGripInformation &Grip, + EBPVRResultSwitch &Result, + const FTransform & NewRelativeTransform + ) +{ + int fIndex = GrippedObjects.Find(Grip); + + if (fIndex != INDEX_NONE) + { + GrippedObjects[fIndex].RelativeTransform = NewRelativeTransform; + if (FBPActorPhysicsHandleInformation * HandleInfo = GetPhysicsGrip(Grip)) + { + UpdatePhysicsHandle(Grip.GripID, true); + NotifyGripTransformChanged(Grip); + } + + DIRTY_GRIPPED_OBJECTS(); + + Result = EBPVRResultSwitch::OnSucceeded; + return; + } + else + { + fIndex = LocallyGrippedObjects.Find(Grip); + + if (fIndex != INDEX_NONE) + { + LocallyGrippedObjects[fIndex].RelativeTransform = NewRelativeTransform; + if (FBPActorPhysicsHandleInformation * HandleInfo = GetPhysicsGrip(Grip)) + { + UpdatePhysicsHandle(Grip.GripID, true); + NotifyGripTransformChanged(Grip); + } + + if (IsLocallyControlled() && !IsServer() && !IsTornOff() && LocallyGrippedObjects[fIndex].GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive) + { + FBPActorGripInformation GripInfo = LocallyGrippedObjects[fIndex]; + Server_NotifyLocalGripAddedOrChanged(GripInfo); + } + + DIRTY_LOCALLY_GRIPPED_OBJECTS(); + + Result = EBPVRResultSwitch::OnSucceeded; + return; + } + } + + Result = EBPVRResultSwitch::OnFailed; +} + +void UGripMotionControllerComponent::SetGripAdditionTransform( + const FBPActorGripInformation &Grip, + EBPVRResultSwitch &Result, + const FTransform & NewAdditionTransform, bool bMakeGripRelative + ) +{ + int fIndex = GrippedObjects.Find(Grip); + + if (fIndex != INDEX_NONE) + { + GrippedObjects[fIndex].AdditionTransform = CreateGripRelativeAdditionTransform(Grip, NewAdditionTransform, bMakeGripRelative); + DIRTY_GRIPPED_OBJECTS(); + + Result = EBPVRResultSwitch::OnSucceeded; + return; + } + else + { + fIndex = LocallyGrippedObjects.Find(Grip); + + if (fIndex != INDEX_NONE) + { + LocallyGrippedObjects[fIndex].AdditionTransform = CreateGripRelativeAdditionTransform(Grip, NewAdditionTransform, bMakeGripRelative); + DIRTY_LOCALLY_GRIPPED_OBJECTS(); + + Result = EBPVRResultSwitch::OnSucceeded; + return; + } + } + Result = EBPVRResultSwitch::OnFailed; +} + +void UGripMotionControllerComponent::SetGripStiffnessAndDamping( + const FBPActorGripInformation &Grip, + EBPVRResultSwitch &Result, + float NewStiffness, float NewDamping, bool bAlsoSetAngularValues, float OptionalAngularStiffness, float OptionalAngularDamping + ) +{ + Result = EBPVRResultSwitch::OnFailed; + int fIndex = GrippedObjects.Find(Grip); + + if (fIndex != INDEX_NONE) + { + GrippedObjects[fIndex].Stiffness = NewStiffness; + GrippedObjects[fIndex].Damping = NewDamping; + + if (bAlsoSetAngularValues) + { + GrippedObjects[fIndex].AdvancedGripSettings.PhysicsSettings.AngularStiffness = OptionalAngularStiffness; + GrippedObjects[fIndex].AdvancedGripSettings.PhysicsSettings.AngularDamping = OptionalAngularDamping; + } + + DIRTY_GRIPPED_OBJECTS(); + + Result = EBPVRResultSwitch::OnSucceeded; + SetGripConstraintStiffnessAndDamping(&GrippedObjects[fIndex]); + //return; + } + else + { + fIndex = LocallyGrippedObjects.Find(Grip); + + if (fIndex != INDEX_NONE) + { + LocallyGrippedObjects[fIndex].Stiffness = NewStiffness; + LocallyGrippedObjects[fIndex].Damping = NewDamping; + + if (bAlsoSetAngularValues) + { + LocallyGrippedObjects[fIndex].AdvancedGripSettings.PhysicsSettings.AngularStiffness = OptionalAngularStiffness; + LocallyGrippedObjects[fIndex].AdvancedGripSettings.PhysicsSettings.AngularDamping = OptionalAngularDamping; + } + + if (IsLocallyControlled() && !IsServer() && !IsTornOff() && LocallyGrippedObjects[fIndex].GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive) + { + FBPActorGripInformation GripInfo = LocallyGrippedObjects[fIndex]; + Server_NotifyLocalGripAddedOrChanged(GripInfo); + } + + DIRTY_LOCALLY_GRIPPED_OBJECTS(); + + Result = EBPVRResultSwitch::OnSucceeded; + SetGripConstraintStiffnessAndDamping(&LocallyGrippedObjects[fIndex]); + // return; + } + } +} + +FTransform UGripMotionControllerComponent::CreateGripRelativeAdditionTransform_BP( + const FBPActorGripInformation &GripToSample, + const FTransform & AdditionTransform, + bool bGripRelative +) +{ + return CreateGripRelativeAdditionTransform(GripToSample, AdditionTransform, bGripRelative); +} + +bool UGripMotionControllerComponent::GripObject( + UObject * ObjectToGrip, + const FTransform &WorldOffset, + bool bWorldOffsetIsRelative, + FName OptionalSnapToSocketName, + FName OptionalBoneToGripName, + EGripCollisionType GripCollisionType, + EGripLateUpdateSettings GripLateUpdateSetting, + EGripMovementReplicationSettings GripMovementReplicationSetting, + float GripStiffness, + float GripDamping, + bool bIsSlotGrip) +{ + + // Skip if we are traveling + if (IsTravelingOrNullWorld()) + return false; + + if (UPrimitiveComponent * PrimComp = Cast(ObjectToGrip)) + { + return GripComponent(PrimComp, WorldOffset, bWorldOffsetIsRelative, OptionalSnapToSocketName, OptionalBoneToGripName, GripCollisionType,GripLateUpdateSetting,GripMovementReplicationSetting,GripStiffness,GripDamping, bIsSlotGrip); + } + else if (AActor * Actor = Cast(ObjectToGrip)) + { + return GripActor(Actor, WorldOffset, bWorldOffsetIsRelative, OptionalSnapToSocketName, OptionalBoneToGripName, GripCollisionType, GripLateUpdateSetting, GripMovementReplicationSetting, GripStiffness, GripDamping, bIsSlotGrip); + } + + return false; +} + +bool UGripMotionControllerComponent::DropObject( + UObject* ObjectToDrop, + uint8 GripIDToDrop, + bool bSimulate, + FVector OptionalAngularVelocity, + FVector OptionalLinearVelocity) +{ + if (IsValid(ObjectToDrop)) + { + FBPActorGripInformation * GripInfo = GrippedObjects.FindByKey(ObjectToDrop); + if (!GripInfo) + GripInfo = LocallyGrippedObjects.FindByKey(ObjectToDrop); + + if (GripInfo != nullptr && IsValid(GripInfo->GrippedObject)) + { + return DropGrip_Implementation(*GripInfo, bSimulate, OptionalAngularVelocity, OptionalLinearVelocity); + } + } + else if (GripIDToDrop != INVALID_VRGRIP_ID) + { + FBPActorGripInformation * GripInfo = GrippedObjects.FindByKey(GripIDToDrop); + if (!GripInfo) + GripInfo = LocallyGrippedObjects.FindByKey(GripIDToDrop); + + if (GripInfo != nullptr && IsValid(GripInfo->GrippedObject)) + { + return DropGrip_Implementation(*GripInfo, bSimulate, OptionalAngularVelocity, OptionalLinearVelocity); + } + } + + return false; +} + +bool UGripMotionControllerComponent::GripObjectByInterface(UObject* ObjectToGrip, const FTransform &WorldOffset, bool bWorldOffsetIsRelative, FName OptionalBoneToGripName, FName OptionalSnapToSocketName, bool bIsSlotGrip) +{ + // Skip if we are traveling + if (IsTravelingOrNullWorld()) + return false; + + if (!IsValid(ObjectToGrip)) + { + return false; + } + + if (UPrimitiveComponent * PrimComp = Cast(ObjectToGrip)) + { + AActor * Owner = PrimComp->GetOwner(); + + if (!IsValid(Owner)) + return false; + + if (PrimComp->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + EGripCollisionType CollisionType = IVRGripInterface::Execute_GetPrimaryGripType(PrimComp, bIsSlotGrip); + + float Stiffness; + float Damping; + IVRGripInterface::Execute_GetGripStiffnessAndDamping(PrimComp, Stiffness, Damping); + + return GripComponent(PrimComp, WorldOffset, bWorldOffsetIsRelative, OptionalSnapToSocketName, + OptionalBoneToGripName, + CollisionType, + IVRGripInterface::Execute_GripLateUpdateSetting(PrimComp), + IVRGripInterface::Execute_GripMovementReplicationType(PrimComp), + Stiffness, + Damping, + bIsSlotGrip + ); + } + else if (Owner->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + EGripCollisionType CollisionType = IVRGripInterface::Execute_GetPrimaryGripType(Owner, bIsSlotGrip); + + float Stiffness; + float Damping; + IVRGripInterface::Execute_GetGripStiffnessAndDamping(Owner, Stiffness, Damping); + + return GripActor(Owner, WorldOffset, bWorldOffsetIsRelative, OptionalSnapToSocketName, + OptionalBoneToGripName, + CollisionType, + IVRGripInterface::Execute_GripLateUpdateSetting(Owner), + IVRGripInterface::Execute_GripMovementReplicationType(Owner), + Stiffness, + Damping, + bIsSlotGrip + ); + /*return GripComponent(PrimComp, WorldOffset, bWorldOffsetIsRelative, OptionalSnapToSocketName, + OptionalBoneToGripName, + CollisionType, + IVRGripInterface::Execute_GripLateUpdateSetting(Owner), + IVRGripInterface::Execute_GripMovementReplicationType(Owner), + Stiffness, + Damping, + bIsSlotGrip + );*/ + } + else + { + // No interface, no grip + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController GripObjectByInterface was called on an object that doesn't implement the interface and doesn't have a parent that implements the interface!")); + return false; + } + } + else if (AActor * Actor = Cast(ObjectToGrip)) + { + UPrimitiveComponent * root = Cast(Actor->GetRootComponent()); + + if (!IsValid(root)) + return false; + + if (root->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + EGripCollisionType CollisionType = IVRGripInterface::Execute_GetPrimaryGripType(root, bIsSlotGrip); + + float Stiffness; + float Damping; + IVRGripInterface::Execute_GetGripStiffnessAndDamping(root, Stiffness, Damping); + + return GripComponent(root, WorldOffset, bWorldOffsetIsRelative, OptionalSnapToSocketName, + OptionalBoneToGripName, + CollisionType, + IVRGripInterface::Execute_GripLateUpdateSetting(root), + IVRGripInterface::Execute_GripMovementReplicationType(root), + Stiffness, + Damping, + bIsSlotGrip + ); + /*return GripActor(Actor, WorldOffset, bWorldOffsetIsRelative, OptionalSnapToSocketName, + OptionalBoneToGripName, + CollisionType, + IVRGripInterface::Execute_GripLateUpdateSetting(root), + IVRGripInterface::Execute_GripMovementReplicationType(root), + Stiffness, + Damping, + bIsSlotGrip + );*/ + } + else if (Actor->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + EGripCollisionType CollisionType = IVRGripInterface::Execute_GetPrimaryGripType(Actor, bIsSlotGrip); + + float Stiffness; + float Damping; + IVRGripInterface::Execute_GetGripStiffnessAndDamping(Actor, Stiffness, Damping); + + return GripActor(Actor, WorldOffset, bWorldOffsetIsRelative, OptionalSnapToSocketName, + OptionalBoneToGripName, + CollisionType, + IVRGripInterface::Execute_GripLateUpdateSetting(Actor), + IVRGripInterface::Execute_GripMovementReplicationType(Actor), + Stiffness, + Damping, + bIsSlotGrip + ); + } + else + { + // No interface, no grip + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController GripObjectByInterface was called on an object that doesn't implement the interface and doesn't have a parent that implements the interface!")); + return false; + } + } + + return false; +} + +bool UGripMotionControllerComponent::DropObjectByInterface(UObject* ObjectToDrop, uint8 GripIDToDrop, FVector OptionalAngularVelocity, FVector OptionalLinearVelocity) +{ + return DropObjectByInterface_Implementation(ObjectToDrop, GripIDToDrop, OptionalAngularVelocity, OptionalLinearVelocity, false); +} + +bool UGripMotionControllerComponent::DropObjectByInterface_Implementation(UObject* ObjectToDrop, uint8 GripIDToDrop, FVector OptionalAngularVelocity, FVector OptionalLinearVelocity, bool bSkipNotify) +{ + + FBPActorGripInformation * GripInfo = nullptr; + if (IsValid(ObjectToDrop)) + { + GripInfo = GrippedObjects.FindByKey(ObjectToDrop); + if (!GripInfo) + GripInfo = LocallyGrippedObjects.FindByKey(ObjectToDrop); + } + else if (GripIDToDrop != INVALID_VRGRIP_ID) + { + GripInfo = GrippedObjects.FindByKey(GripIDToDrop); + if (!GripInfo) + GripInfo = LocallyGrippedObjects.FindByKey(GripIDToDrop); + } + + if (GripInfo == nullptr || !IsValid(GripInfo->GrippedObject)) + { + return false; + } + + if (UPrimitiveComponent * PrimComp = Cast(GripInfo->GrippedObject)) + { + AActor * Owner = PrimComp->GetOwner(); + + if (!Owner) + return false; + + if (PrimComp->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + return DropGrip_Implementation(*GripInfo, IVRGripInterface::Execute_SimulateOnDrop(PrimComp), OptionalAngularVelocity, OptionalLinearVelocity, bSkipNotify); + //return DropComponent(PrimComp, IVRGripInterface::Execute_SimulateOnDrop(PrimComp), OptionalAngularVelocity, OptionalLinearVelocity); + } + else if (Owner->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + return DropGrip_Implementation(*GripInfo, IVRGripInterface::Execute_SimulateOnDrop(Owner), OptionalAngularVelocity, OptionalLinearVelocity, bSkipNotify); + //return DropComponent(PrimComp, IVRGripInterface::Execute_SimulateOnDrop(Owner), OptionalAngularVelocity, OptionalLinearVelocity); + } + else + { + // Allowing for failsafe dropping here. + return DropGrip_Implementation(*GripInfo, true, OptionalAngularVelocity, OptionalLinearVelocity, bSkipNotify); + //return DropComponent(PrimComp, true, OptionalAngularVelocity, OptionalLinearVelocity); + } + } + else if (AActor * Actor = Cast(GripInfo->GrippedObject)) + { + UPrimitiveComponent * root = Cast(Actor->GetRootComponent()); + + if (!IsValid(root)) + return false; + + if (root->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + return DropGrip_Implementation(*GripInfo, IVRGripInterface::Execute_SimulateOnDrop(root), OptionalAngularVelocity, OptionalLinearVelocity, bSkipNotify); + } + else if (Actor->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + return DropGrip_Implementation(*GripInfo, IVRGripInterface::Execute_SimulateOnDrop(Actor), OptionalAngularVelocity, OptionalLinearVelocity, bSkipNotify); + } + else + { + // Failsafe drop here + return DropGrip_Implementation(*GripInfo, true, OptionalAngularVelocity, OptionalLinearVelocity, bSkipNotify); + } + } + + return false; +} + +bool UGripMotionControllerComponent::GripActor( + AActor* ActorToGrip, + const FTransform &WorldOffset, + bool bWorldOffsetIsRelative, + FName OptionalSnapToSocketName, + FName OptionalBoneToGripName, + EGripCollisionType GripCollisionType, + EGripLateUpdateSettings GripLateUpdateSetting, + EGripMovementReplicationSettings GripMovementReplicationSetting, + float GripStiffness, + float GripDamping, + bool bIsSlotGrip) +{ + // Skip if we are traveling + if (IsTravelingOrNullWorld()) + return false; + + bool bIsLocalGrip = (GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive || GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep); + + if (!IsServer() && !bIsLocalGrip) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController grab function was called on the client side as a replicated grip")); + return false; + } + + if (!ActorToGrip || !IsValid(ActorToGrip)) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController grab function was passed an invalid or pending kill actor")); + return false; + } + + if (GetIsObjectHeld(ActorToGrip)) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController grab function was passed an already gripped actor")); + return false; + } + + UPrimitiveComponent *root = Cast(ActorToGrip->GetRootComponent()); + + if (!root) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController tried to grip an actor without a UPrimitiveComponent Root")); + return false; // Need a primitive root + } + + // Has to be movable to work + if (root->Mobility != EComponentMobility::Movable && (GripCollisionType != EGripCollisionType::CustomGrip && GripCollisionType != EGripCollisionType::EventsOnly)) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController tried to grip an actor set to static mobility not with a Custom Grip")); + return false; // It is not movable, can't grip it + } + + FBPAdvGripSettings AdvancedGripSettings; + UObject * ObjectToCheck = NULL; // Used if having to calculate the transform + //bool bIgnoreHandRotation = false; + + TArray HoldingControllers; + bool bIsHeld = false; + bool bHadOriginalSettings = false; + bool bOriginalGravity = false; + bool bOriginalReplication = false; + + if (root->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + if(IVRGripInterface::Execute_DenyGripping(root, this)) + return false; // Interface is saying not to grip it right now + + IVRGripInterface::Execute_IsHeld(root, HoldingControllers, bIsHeld); + bool bAllowMultipleGrips = IVRGripInterface::Execute_AllowsMultipleGrips(root); + if (bIsHeld && !bAllowMultipleGrips) + { + return false; // Can't multiple grip this object + } + else if (bIsHeld) + { + // If we are held by multiple controllers then lets copy our original values from the first one + if (HoldingControllers[0].HoldingController != nullptr) + { + FBPActorGripInformation* gripInfo = HoldingControllers[0].HoldingController->GetGripPtrByID(HoldingControllers[0].GripID); + + if (gripInfo != nullptr) + { + bHadOriginalSettings = true; + bOriginalGravity = gripInfo->bOriginalGravity; + bOriginalReplication = gripInfo->bOriginalReplicatesMovement; + } + } + } + + AdvancedGripSettings = IVRGripInterface::Execute_AdvancedGripSettings(root); + ObjectToCheck = root; + } + else if (ActorToGrip->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + if(IVRGripInterface::Execute_DenyGripping(ActorToGrip, this)) + return false; // Interface is saying not to grip it right now + + IVRGripInterface::Execute_IsHeld(ActorToGrip, HoldingControllers, bIsHeld); + bool bAllowMultipleGrips = IVRGripInterface::Execute_AllowsMultipleGrips(ActorToGrip); + if (bIsHeld && !bAllowMultipleGrips) + { + return false; // Can't multiple grip this object + } + else if (bIsHeld) + { + // If we are held by multiple controllers then lets copy our original values from the first one + if (HoldingControllers[0].HoldingController != nullptr) + { + FBPActorGripInformation* gripInfo = HoldingControllers[0].HoldingController->GetGripPtrByID(HoldingControllers[0].GripID); + + if (gripInfo != nullptr) + { + bHadOriginalSettings = true; + bOriginalGravity = gripInfo->bOriginalGravity; + bOriginalReplication = gripInfo->bOriginalReplicatesMovement; + } + } + } + + AdvancedGripSettings = IVRGripInterface::Execute_AdvancedGripSettings(ActorToGrip); + ObjectToCheck = ActorToGrip; + } + + // So that events caused by sweep and the like will trigger correctly + ActorToGrip->AddTickPrerequisiteComponent(this); + + FBPActorGripInformation newActorGrip; + newActorGrip.GripID = GetNextGripID(bIsLocalGrip); + newActorGrip.GripCollisionType = GripCollisionType; + newActorGrip.GrippedObject = ActorToGrip; + if (bHadOriginalSettings) + { + newActorGrip.bOriginalReplicatesMovement = bOriginalReplication; + newActorGrip.bOriginalGravity = bOriginalGravity; + } + else + { + newActorGrip.bOriginalReplicatesMovement = ActorToGrip->IsReplicatingMovement(); + newActorGrip.bOriginalGravity = root->IsGravityEnabled(); + } + newActorGrip.Stiffness = GripStiffness; + newActorGrip.Damping = GripDamping; + newActorGrip.AdvancedGripSettings = AdvancedGripSettings; + newActorGrip.ValueCache.bWasInitiallyRepped = true; // Set this true on authority side so we can skip a function call on tick + newActorGrip.bIsSlotGrip = bIsSlotGrip; + newActorGrip.GrippedBoneName = OptionalBoneToGripName; + newActorGrip.SlotName = OptionalSnapToSocketName; + + // Ignore late update setting if it doesn't make sense with the grip + switch(newActorGrip.GripCollisionType) + { + case EGripCollisionType::ManipulationGrip: + case EGripCollisionType::ManipulationGripWithWristTwist: + { + newActorGrip.GripLateUpdateSetting = EGripLateUpdateSettings::LateUpdatesAlwaysOff; // Late updates are bad for this grip + }break; + + default: + { + newActorGrip.GripLateUpdateSetting = GripLateUpdateSetting; + }break; + } + + if (GripMovementReplicationSetting == EGripMovementReplicationSettings::KeepOriginalMovement) + { + if (ActorToGrip->IsReplicatingMovement()) + { + newActorGrip.GripMovementReplicationSetting = EGripMovementReplicationSettings::ForceServerSideMovement; + } + else + { + newActorGrip.GripMovementReplicationSetting = EGripMovementReplicationSettings::ForceClientSideMovement; + } + } + else + newActorGrip.GripMovementReplicationSetting = GripMovementReplicationSetting; + + newActorGrip.GripTargetType = EGripTargetType::ActorGrip; + + if (OptionalSnapToSocketName.IsValid() && WorldOffset.Equals(FTransform::Identity) && root->DoesSocketExist(OptionalSnapToSocketName)) + { + // I inverse it so that laying out the sockets makes sense + FTransform sockTrans = root->GetSocketTransform(OptionalSnapToSocketName, ERelativeTransformSpace::RTS_Component); + sockTrans.SetScale3D(FVector(1.f) / root->GetComponentScale()); // Prep this so that the inverse works correctly + newActorGrip.RelativeTransform = sockTrans.Inverse(); + newActorGrip.bIsSlotGrip = true; // Set this to a slot grip + + ObjectToCheck = NULL; // Null it back out, socketed grips don't use this + + newActorGrip.SlotName = OptionalSnapToSocketName; + } + else if (bWorldOffsetIsRelative) + { + if (bSkipPivotTransformAdjustment && IsValid(CustomPivotComponent) && !bIsSlotGrip) + { + newActorGrip.RelativeTransform = (WorldOffset * this->GetComponentTransform()).GetRelativeTransform(CustomPivotComponent->GetComponentTransform()); + } + else + { + newActorGrip.RelativeTransform = WorldOffset; + } + } + else + { + newActorGrip.RelativeTransform = WorldOffset.GetRelativeTransform(GetPivotTransform()); + } + + if (!bIsLocalGrip) + { + int32 Index = GrippedObjects.Add(newActorGrip); + DIRTY_GRIPPED_OBJECTS(); + + if (Index != INDEX_NONE) + NotifyGrip(GrippedObjects[Index]); + //NotifyGrip(newActorGrip); + } + else + { + if (!IsLocallyControlled()) + { + LocalTransactionBuffer.Add(newActorGrip); +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, LocalTransactionBuffer, this); +#endif + } + + int32 Index = LocallyGrippedObjects.Add(newActorGrip); + DIRTY_LOCALLY_GRIPPED_OBJECTS(); + + if (Index != INDEX_NONE) + { + if (!IsLocallyControlled()) + { + if (!HandleGripReplication(LocallyGrippedObjects[Index])) + { + return true; + } + } + else + { + if (!NotifyGrip(LocallyGrippedObjects[Index])) + { + return true; + } + } + + if (bIsLocalGrip && IsLocallyControlled() && !IsServer() && !IsTornOff() && newActorGrip.GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive) + { + Index = LocallyGrippedObjects.IndexOfByKey(newActorGrip.GripID); + if (Index != INDEX_NONE) + { + FBPActorGripInformation GripInfo = LocallyGrippedObjects[Index]; + Server_NotifyLocalGripAddedOrChanged(GripInfo); + } + } + } + } + //NotifyGrip(newActorGrip); + + return true; +} + +bool UGripMotionControllerComponent::DropActor(AActor* ActorToDrop, bool bSimulate, FVector OptionalAngularVelocity, FVector OptionalLinearVelocity) +{ + if (!ActorToDrop) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController drop function was passed an invalid actor")); + return false; + } + + FBPActorGripInformation * GripToDrop = LocallyGrippedObjects.FindByKey(ActorToDrop); + + if(GripToDrop) + return DropGrip_Implementation(*GripToDrop, bSimulate, OptionalAngularVelocity, OptionalLinearVelocity); + + if (!IsServer()) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController drop function was called on the client side with a replicated grip")); + return false; + } + + GripToDrop = GrippedObjects.FindByKey(ActorToDrop); + if (GripToDrop) + return DropGrip_Implementation(*GripToDrop, bSimulate, OptionalAngularVelocity, OptionalLinearVelocity); + + return false; +} + +bool UGripMotionControllerComponent::GripComponent( + UPrimitiveComponent* ComponentToGrip, + const FTransform &WorldOffset, + bool bWorldOffsetIsRelative, + FName OptionalSnapToSocketName, + FName OptionalBoneToGripName, + EGripCollisionType GripCollisionType, + EGripLateUpdateSettings GripLateUpdateSetting, + EGripMovementReplicationSettings GripMovementReplicationSetting, + float GripStiffness, + float GripDamping, + bool bIsSlotGrip + ) +{ + // Skip if we are traveling + if (IsTravelingOrNullWorld()) + return false; + + bool bIsLocalGrip = (GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive || GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep); + + if (!IsServer() && !bIsLocalGrip) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController grab function was called on the client side with a replicating grip")); + return false; + } + + if (!ComponentToGrip || !IsValid(ComponentToGrip)) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController grab function was passed an invalid or pending kill component")); + return false; + } + + if (GetIsObjectHeld(ComponentToGrip)) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController grab function was passed an already gripped component")); + return false; + } + + // Has to be movable to work + if (ComponentToGrip->Mobility != EComponentMobility::Movable && (GripCollisionType != EGripCollisionType::CustomGrip && GripCollisionType != EGripCollisionType::EventsOnly)) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController tried to grip a component set to static mobility not in CustomGrip mode")); + return false; // It is not movable, can't grip it + } + + FBPAdvGripSettings AdvancedGripSettings; + UObject * ObjectToCheck = NULL; + //bool bIgnoreHandRotation = false; + + TArray HoldingControllers; + bool bIsHeld = false; + bool bHadOriginalSettings = false; + bool bOriginalGravity = false; + bool bOriginalReplication = false; + + if (ComponentToGrip->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + if(IVRGripInterface::Execute_DenyGripping(ComponentToGrip, this)) + return false; // Interface is saying not to grip it right now + + IVRGripInterface::Execute_IsHeld(ComponentToGrip, HoldingControllers, bIsHeld); + bool bAllowMultipleGrips = IVRGripInterface::Execute_AllowsMultipleGrips(ComponentToGrip); + if (bIsHeld && !bAllowMultipleGrips) + { + return false; // Can't multiple grip this object + } + else if(bIsHeld) + { + // If we are held by multiple controllers then lets copy our original values from the first one + if (HoldingControllers[0].HoldingController != nullptr) + { + FBPActorGripInformation gripInfo; + EBPVRResultSwitch result; + HoldingControllers[0].HoldingController->GetGripByID(gripInfo, HoldingControllers[0].GripID, result); + + if (result != EBPVRResultSwitch::OnFailed) + { + bHadOriginalSettings = true; + bOriginalGravity = gripInfo.bOriginalGravity; + bOriginalReplication = gripInfo.bOriginalReplicatesMovement; + } + } + } + + + AdvancedGripSettings = IVRGripInterface::Execute_AdvancedGripSettings(ComponentToGrip); + ObjectToCheck = ComponentToGrip; + } + + //ComponentToGrip->IgnoreActorWhenMoving(this->GetOwner(), true); + // So that events caused by sweep and the like will trigger correctly + + ComponentToGrip->AddTickPrerequisiteComponent(this); + + FBPActorGripInformation newComponentGrip; + newComponentGrip.GripID = GetNextGripID(bIsLocalGrip); + newComponentGrip.GripCollisionType = GripCollisionType; + newComponentGrip.GrippedObject = ComponentToGrip; + + if (bHadOriginalSettings) + { + newComponentGrip.bOriginalReplicatesMovement = bOriginalReplication; + newComponentGrip.bOriginalGravity = bOriginalGravity; + } + else + { + if (ComponentToGrip->GetOwner()) + newComponentGrip.bOriginalReplicatesMovement = ComponentToGrip->GetOwner()->IsReplicatingMovement(); + + newComponentGrip.bOriginalGravity = ComponentToGrip->IsGravityEnabled(); + } + newComponentGrip.Stiffness = GripStiffness; + newComponentGrip.Damping = GripDamping; + newComponentGrip.AdvancedGripSettings = AdvancedGripSettings; + newComponentGrip.GripTargetType = EGripTargetType::ComponentGrip; + newComponentGrip.ValueCache.bWasInitiallyRepped = true; // Set this true on authority side so we can skip a function call on tick + newComponentGrip.bIsSlotGrip = bIsSlotGrip; + newComponentGrip.GrippedBoneName = OptionalBoneToGripName; + newComponentGrip.SlotName = OptionalSnapToSocketName; + + // Ignore late update setting if it doesn't make sense with the grip + switch (newComponentGrip.GripCollisionType) + { + case EGripCollisionType::ManipulationGrip: + case EGripCollisionType::ManipulationGripWithWristTwist: + { + newComponentGrip.GripLateUpdateSetting = EGripLateUpdateSettings::LateUpdatesAlwaysOff; // Late updates are bad for this grip + }break; + + default: + { + newComponentGrip.GripLateUpdateSetting = GripLateUpdateSetting; + }break; + } + + + if (GripMovementReplicationSetting == EGripMovementReplicationSettings::KeepOriginalMovement) + { + if (ComponentToGrip->GetOwner()) + { + if (ComponentToGrip->GetOwner()->IsReplicatingMovement()) + { + newComponentGrip.GripMovementReplicationSetting = EGripMovementReplicationSettings::ForceServerSideMovement; + } + else + { + newComponentGrip.GripMovementReplicationSetting = EGripMovementReplicationSettings::ForceClientSideMovement; + } + } + else + newComponentGrip.GripMovementReplicationSetting = EGripMovementReplicationSettings::ForceClientSideMovement; + } + else + newComponentGrip.GripMovementReplicationSetting = GripMovementReplicationSetting; + + if (OptionalSnapToSocketName.IsValid() && WorldOffset.Equals(FTransform::Identity) && ComponentToGrip->DoesSocketExist(OptionalSnapToSocketName)) + { + // I inverse it so that laying out the sockets makes sense + FTransform sockTrans = ComponentToGrip->GetSocketTransform(OptionalSnapToSocketName, ERelativeTransformSpace::RTS_Component); + sockTrans.SetScale3D(FVector(1.f) / ComponentToGrip->GetComponentScale()); // Prep this so that the inverse works correctly + newComponentGrip.RelativeTransform = sockTrans.Inverse(); + newComponentGrip.bIsSlotGrip = true; // Set this to a slot grip + + ObjectToCheck = NULL; // Null it out, socketed grips don't use this + } + else if (bWorldOffsetIsRelative) + { + if (bSkipPivotTransformAdjustment && IsValid(CustomPivotComponent) && !bIsSlotGrip) + { + newComponentGrip.RelativeTransform = (WorldOffset * this->GetComponentTransform()).GetRelativeTransform(CustomPivotComponent->GetComponentTransform()); + } + else + { + newComponentGrip.RelativeTransform = WorldOffset; + } + } + else + { + newComponentGrip.RelativeTransform = WorldOffset.GetRelativeTransform(GetPivotTransform()); + } + + if (!bIsLocalGrip) + { + int32 Index = GrippedObjects.Add(newComponentGrip); + DIRTY_GRIPPED_OBJECTS(); + + if (Index != INDEX_NONE) + NotifyGrip(GrippedObjects[Index]); + + //NotifyGrip(newComponentGrip); + } + else + { + if (!IsLocallyControlled()) + { + LocalTransactionBuffer.Add(newComponentGrip); +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, LocalTransactionBuffer, this); +#endif + } + + int32 Index = LocallyGrippedObjects.Add(newComponentGrip); + DIRTY_LOCALLY_GRIPPED_OBJECTS(); + + if (Index != INDEX_NONE) + { + if (!IsLocallyControlled()) + { + if (!HandleGripReplication(LocallyGrippedObjects[Index])) + { + return true; + } + } + else + { + if (!NotifyGrip(LocallyGrippedObjects[Index])) + { + return true; + } + } + + if (bIsLocalGrip && IsLocallyControlled() && !IsServer() && !IsTornOff() && newComponentGrip.GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive) + { + Index = LocallyGrippedObjects.IndexOfByKey(newComponentGrip.GripID); + if (Index != INDEX_NONE) + { + FBPActorGripInformation GripInfo = LocallyGrippedObjects[Index]; + Server_NotifyLocalGripAddedOrChanged(GripInfo); + } + } + } + } + + return true; +} + +bool UGripMotionControllerComponent::DropComponent(UPrimitiveComponent * ComponentToDrop, bool bSimulate, FVector OptionalAngularVelocity, FVector OptionalLinearVelocity) +{ + FBPActorGripInformation *GripInfo; + + // First check for it in the local grips + GripInfo = LocallyGrippedObjects.FindByKey(ComponentToDrop); + + if (GripInfo != nullptr) + { + return DropGrip_Implementation(*GripInfo, bSimulate, OptionalAngularVelocity, OptionalLinearVelocity); + } + + // If we aren't the server then fail out + if (!IsServer()) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController drop function was called on the client side for a replicated grip")); + return false; + } + + // Now check in the server auth gripsop) + GripInfo = GrippedObjects.FindByKey(ComponentToDrop); + + if (GripInfo != nullptr) + { + return DropGrip_Implementation(*GripInfo, bSimulate, OptionalAngularVelocity, OptionalLinearVelocity); + } + else + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController drop function was passed an invalid component")); + return false; + } + + //return false; +} + +bool UGripMotionControllerComponent::DropGrip(const FBPActorGripInformation& Grip, bool bSimulate, FVector OptionalAngularVelocity, FVector OptionalLinearVelocity) +{ + return DropGrip_Implementation(Grip, bSimulate, OptionalAngularVelocity, OptionalLinearVelocity); +} + +bool UGripMotionControllerComponent::DropGrip_Implementation(const FBPActorGripInformation &Grip, bool bSimulate, FVector OptionalAngularVelocity, FVector OptionalLinearVelocity, bool bSkipNotify) +{ + int FoundIndex = 0; + bool bIsServer = IsServer(); + bool bWasLocalGrip = false; + if (!LocallyGrippedObjects.Find(Grip, FoundIndex)) // This auto checks if Actor and Component are valid in the == operator + { + if (!bIsServer) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController drop function was called on the client side for a replicated grip")); + return false; + } + + if (!GrippedObjects.Find(Grip, FoundIndex)) // This auto checks if Actor and Component are valid in the == operator + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController drop function was passed an invalid drop")); + return false; + } + + bWasLocalGrip = false; + } + else + bWasLocalGrip = true; + + if (bWasLocalGrip && bIsServer) + { + for (int i = LocalTransactionBuffer.Num() - 1; i >= 0; i--) + { + if (LocalTransactionBuffer[i].GripID == Grip.GripID) + LocalTransactionBuffer.RemoveAt(i); + } +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, LocalTransactionBuffer, this); +#endif + } + + UPrimitiveComponent * PrimComp = nullptr; + + AActor * pActor = nullptr; + if (bWasLocalGrip) + { + PrimComp = LocallyGrippedObjects[FoundIndex].GetGrippedComponent(); + pActor = LocallyGrippedObjects[FoundIndex].GetGrippedActor(); + } + else + { + PrimComp = GrippedObjects[FoundIndex].GetGrippedComponent(); + pActor = GrippedObjects[FoundIndex].GetGrippedActor(); + } + + if (!PrimComp && pActor) + PrimComp = Cast(pActor->GetRootComponent()); + + if(!PrimComp) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController drop function was passed an invalid drop or CleanUpBadGrip wascalled")); + //return false; + } + else + { + if (bSimulate && (!OptionalLinearVelocity.IsNearlyZero() || !OptionalAngularVelocity.IsNearlyZero())) + { + if (Grip.GripCollisionType != EGripCollisionType::EventsOnly) + { + // Need to set simulation in all of these cases, including if it isn't the root component (simulation isn't replicated on non roots) + if (!Grip.AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings || !Grip.AdvancedGripSettings.PhysicsSettings.bSkipSettingSimulating) + { + if (PrimComp->IsSimulatingPhysics() != bSimulate) + { + PrimComp->SetSimulatePhysics(bSimulate); + } + } + } + + // Had to move in front of deletion to properly set velocity + if (PrimComp->IsSimulatingPhysics()) + { + PrimComp->SetPhysicsLinearVelocity(OptionalLinearVelocity); + PrimComp->SetPhysicsAngularVelocityInDegrees(OptionalAngularVelocity); + } + } + } + + if (bWasLocalGrip) + { + // Store out a local copy so we can't get funky issues with the engine dropping the grip out from under us + FBPActorGripInformation GripInfo = LocallyGrippedObjects[FoundIndex]; + + if (IsLocallyControlled() && !IsServer()) //GetNetMode() == ENetMode::NM_Client) + { + if (!IsTornOff()) + { + FTransform_NetQuantize TransformAtDrop = FTransform::Identity; + + switch (GripInfo.GripTargetType) + { + case EGripTargetType::ActorGrip: + { + if (AActor * GrippedActor = GripInfo.GetGrippedActor()) + { + TransformAtDrop = GrippedActor->GetActorTransform(); + } + }; break; + case EGripTargetType::ComponentGrip: + { + if (UPrimitiveComponent * GrippedPrim = GripInfo.GetGrippedComponent()) + { + TransformAtDrop = GrippedPrim->GetComponentTransform(); + } + }break; + default:break; + } + + if(!bSkipNotify) + Server_NotifyLocalGripRemoved(GripInfo.GripID, TransformAtDrop, OptionalAngularVelocity, OptionalLinearVelocity); + } + + // Double check we didn't lose the grip (seems to be possible in UE5 from the Server RPC above being ran on the client) + if (LocallyGrippedObjects.Num() > 0 && LocallyGrippedObjects.Find(GripInfo, FoundIndex)) + { + // Have to call this ourselves + Drop_Implementation(GripInfo, bSimulate); + } + } + else // Server notifyDrop it + { + NotifyDrop(GripInfo, bSimulate); + } + } + else + NotifyDrop(GrippedObjects[FoundIndex], bSimulate); + + //GrippedObjects.RemoveAt(FoundIndex); + return true; +} + +bool UGripMotionControllerComponent::DropAndSocketObject(const FTransform_NetQuantize & RelativeTransformToParent, UObject * ObjectToDrop, uint8 GripIDToDrop, USceneComponent * SocketingParent, FName OptionalSocketName, bool bWeldBodies) +{ + if (!SocketingParent) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController drop and socket function was passed an invalid socketing parent")); + return false; + } + + if (!ObjectToDrop && GripIDToDrop == INVALID_VRGRIP_ID) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController drop and socket function was passed an invalid object")); + return false; + } + + bool bWasLocalGrip = false; + FBPActorGripInformation * GripInfo = nullptr; + + if (ObjectToDrop) + GripInfo = LocallyGrippedObjects.FindByKey(ObjectToDrop); + else if (GripIDToDrop != INVALID_VRGRIP_ID) + GripInfo = LocallyGrippedObjects.FindByKey(GripIDToDrop); + + if(GripInfo) // This auto checks if Actor and Component are valid in the == operator + { + bWasLocalGrip = true; + } + else + { + if (!IsServer()) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController drop and socket function was called on the client side for a replicated grip")); + return false; + } + + if(ObjectToDrop) + GripInfo = GrippedObjects.FindByKey(ObjectToDrop); + else if(GripIDToDrop != INVALID_VRGRIP_ID) + GripInfo = GrippedObjects.FindByKey(GripIDToDrop); + + if(GripInfo) // This auto checks if Actor and Component are valid in the == operator + { + bWasLocalGrip = false; + } + else + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController drop and socket function was passed an invalid drop")); + return false; + } + } + + if(GripInfo) + return DropAndSocketGrip_Implementation(*GripInfo, SocketingParent, OptionalSocketName, RelativeTransformToParent, bWeldBodies); + + return false; +} + +bool UGripMotionControllerComponent::DropAndSocketGrip(const FBPActorGripInformation& GripToDrop, USceneComponent* SocketingParent, FName OptionalSocketName, const FTransform_NetQuantize& RelativeTransformToParent, bool bWeldBodies) +{ + return DropAndSocketGrip_Implementation(GripToDrop, SocketingParent, OptionalSocketName, RelativeTransformToParent, bWeldBodies); +} + +bool UGripMotionControllerComponent::DropAndSocketGrip_Implementation(const FBPActorGripInformation & GripToDrop, USceneComponent * SocketingParent, FName OptionalSocketName, const FTransform_NetQuantize & RelativeTransformToParent, bool bWeldBodies, bool bSkipServerNotify) +{ + if (!SocketingParent || !IsValid(SocketingParent)) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController drop and socket function was passed an invalid socketing parent")); + return false; + } + + bool bWasLocalGrip = false; + FBPActorGripInformation * GripInfo = nullptr; + + GripInfo = LocallyGrippedObjects.FindByKey(GripToDrop); + if (GripInfo) // This auto checks if Actor and Component are valid in the == operator + { + bWasLocalGrip = true; + } + else + { + if (!IsServer()) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController drop and socket function was called on the client side for a replicated grip")); + return false; + } + + GripInfo = GrippedObjects.FindByKey(GripToDrop); + + if (GripInfo) // This auto checks if Actor and Component are valid in the == operator + { + bWasLocalGrip = false; + } + else + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController drop and socket function was passed an invalid drop")); + return false; + } + } + + UPrimitiveComponent * PrimComp = nullptr; + + AActor * pActor = nullptr; + + PrimComp = GripInfo->GetGrippedComponent(); + pActor = GripInfo->GetGrippedActor(); + + if (!PrimComp && pActor) + PrimComp = Cast(pActor->GetRootComponent()); + + if (!PrimComp) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController drop and socket function was passed an invalid drop or CleanUpBadGrip wascalled")); + //return false; + } + + UObject * GrippedObject = GripInfo->GrippedObject; + + if (!GrippedObject || !IsValid(GrippedObject)) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController drop and socket function was passed an invalid or pending kill gripped object")); + return false; + } + + int PhysicsHandleIndex = INDEX_NONE; + GetPhysicsGripIndex(*GripInfo, PhysicsHandleIndex); + + if (bWasLocalGrip) + { + if (IsLocallyControlled() && !IsServer()) + { + if (!IsTornOff() && !bSkipServerNotify) + { + Server_NotifyDropAndSocketGrip(GripInfo->GripID, SocketingParent, OptionalSocketName, RelativeTransformToParent, bWeldBodies); + } + + OnSocketingObject.Broadcast(*GripInfo, SocketingParent, OptionalSocketName, RelativeTransformToParent, bWeldBodies); + Socket_Implementation(GrippedObject, (PhysicsHandleIndex != INDEX_NONE), SocketingParent, OptionalSocketName, RelativeTransformToParent, bWeldBodies); + + // Have to call this ourselves + DropAndSocket_Implementation(*GripInfo); + } + else // Server notifyDrop it + { + //Socket_Implementation(GrippedObject, (PhysicsHandleIndex != INDEX_NONE), SocketingParent, OptionalSocketName, RelativeTransformToParent, bWeldBodies); + NotifyDropAndSocket(*GripInfo, SocketingParent, OptionalSocketName, RelativeTransformToParent, bWeldBodies); + } + } + else + { + //Socket_Implementation(GrippedObject, (PhysicsHandleIndex != INDEX_NONE), SocketingParent, OptionalSocketName, RelativeTransformToParent, bWeldBodies); + NotifyDropAndSocket(*GripInfo, SocketingParent, OptionalSocketName, RelativeTransformToParent, bWeldBodies); + } + + //GrippedObjects.RemoveAt(FoundIndex); + return true; +} + +void UGripMotionControllerComponent::SetSocketTransform(UObject* ObjectToSocket, /*USceneComponent * SocketingParent,*/ const FTransform_NetQuantize RelativeTransformToParent/*, FName OptionalSocketName, bool bWeldBodies*/) +{ + if (ObjectsWaitingForSocketUpdate.RemoveSingle(ObjectToSocket) < 1) + { + // I know that technically it should never happen that the pointers get reset with a uproperty + // But does it really hurt to add this pathway anyway? + for (int i = ObjectsWaitingForSocketUpdate.Num() - 1; i >= 0; --i) + { + if (ObjectsWaitingForSocketUpdate[i] == nullptr) + ObjectsWaitingForSocketUpdate.RemoveAt(i); + } + + return; + } + + if (!ObjectToSocket || !IsValid(ObjectToSocket)) + return; + + /*FAttachmentTransformRules TransformRule = FAttachmentTransformRules::KeepWorldTransform;//KeepWorldTransform; + TransformRule.bWeldSimulatedBodies = bWeldBodies;*/ + + if (UPrimitiveComponent * root = Cast(ObjectToSocket)) + { + //root->AttachToComponent(SocketingParent, TransformRule, OptionalSocketName); + //root->SetRelativeTransform(RelativeTransformToParent); + + if(root->GetAttachParent()) + root->SetRelativeTransform(RelativeTransformToParent); + } + else if (AActor * pActor = Cast(ObjectToSocket)) + { + //pActor->AttachToComponent(SocketingParent, TransformRule, OptionalSocketName); + //pActor->SetActorRelativeTransform(RelativeTransformToParent); + + if(pActor->GetAttachParentActor()) + pActor->SetActorRelativeTransform(RelativeTransformToParent); + } +} + + +bool UGripMotionControllerComponent::Server_NotifyDropAndSocketGrip_Validate(uint8 GripID, USceneComponent * SocketingParent, FName OptionalSocketName, const FTransform_NetQuantize & RelativeTransformToParent, bool bWeldBodies) +{ + return true; +} + +void UGripMotionControllerComponent::Server_NotifyDropAndSocketGrip_Implementation(uint8 GripID, USceneComponent * SocketingParent, FName OptionalSocketName, const FTransform_NetQuantize & RelativeTransformToParent, bool bWeldBodies) +{ + FBPActorGripInformation FoundGrip; + EBPVRResultSwitch Result; + + GetGripByID(FoundGrip, GripID, Result); + + if (Result == EBPVRResultSwitch::OnFailed) + return; + + int PhysicsHandleIndex = INDEX_NONE; + GetPhysicsGripIndex(FoundGrip, PhysicsHandleIndex); + + if (FoundGrip.GrippedObject) + { + OnSocketingObject.Broadcast(FoundGrip, SocketingParent, OptionalSocketName, RelativeTransformToParent, bWeldBodies); + Socket_Implementation(FoundGrip.GrippedObject, (PhysicsHandleIndex != INDEX_NONE), SocketingParent, OptionalSocketName, RelativeTransformToParent, bWeldBodies); + } + + if (!DropAndSocketGrip_Implementation(FoundGrip, SocketingParent, OptionalSocketName, RelativeTransformToParent, bWeldBodies, true)) + { + DropGrip_Implementation(FoundGrip, false, FVector::ZeroVector, FVector::ZeroVector, true); + } + +} + +void UGripMotionControllerComponent::Socket_Implementation(UObject * ObjectToSocket, bool bWasSimulating, USceneComponent * SocketingParent, FName OptionalSocketName, const FTransform_NetQuantize & RelativeTransformToParent, bool bWeldBodies) +{ + // Check for valid objects + if (!SocketingParent || !SocketingParent->IsValidLowLevelFast() || !ObjectToSocket || !ObjectToSocket->IsValidLowLevelFast()) + { + if (!SocketingParent || !SocketingParent->IsValidLowLevelFast()) + { + UE_LOG(LogVRMotionController, Error, TEXT("VRGripMotionController Socket_Implementation was called with an invalid Socketing Parent object")); + } + else + { + UE_LOG(LogVRMotionController, Error, TEXT("VRGripMotionController Socket_Implementation was called with an invalid Object to Socket")); + } + return; + } + + FAttachmentTransformRules TransformRule = FAttachmentTransformRules::KeepWorldTransform;//KeepWorldTransform; + TransformRule.bWeldSimulatedBodies = bWeldBodies; + + //UPrimitiveComponent * ParentPrim = Cast(SocketingParent); + + if (UPrimitiveComponent * root = Cast(ObjectToSocket)) + { + if (FBodyInstance* rBodyInstance = root->GetBodyInstance()) + { + if (rBodyInstance->OnRecalculatedMassProperties().IsBoundToObject(this)) + { + rBodyInstance->OnRecalculatedMassProperties().RemoveAll(this); + } + } + + // Stop simulation for socketing + if (bWasSimulating || root->IsSimulatingPhysics()) + { + root->SetSimulatePhysics(false); + bWasSimulating = true; + } + + root->AttachToComponent(SocketingParent, TransformRule, OptionalSocketName); + root->SetRelativeTransform(RelativeTransformToParent); + } + else if (AActor * pActor = Cast(ObjectToSocket)) + { + + if (UPrimitiveComponent * rootComp = Cast(pActor->GetRootComponent())) + { + if (FBodyInstance* rBodyInstance = rootComp->GetBodyInstance()) + { + if (rBodyInstance->OnRecalculatedMassProperties().IsBoundToObject(this)) + { + rBodyInstance->OnRecalculatedMassProperties().RemoveAll(this); + } + } + + if (bWasSimulating || rootComp->IsSimulatingPhysics()) + { + // Stop simulation for socketing + rootComp->SetSimulatePhysics(false); + bWasSimulating = true; + } + } + + pActor->AttachToComponent(SocketingParent, TransformRule, OptionalSocketName); + pActor->SetActorRelativeTransform(RelativeTransformToParent); + + //if (!bRetainOwnership) + //pActor->SetOwner(nullptr); + } + + // It had a physics handle or was simulating, I need to delay a tick and set the transform to ensure it skips a race condition + // I may need to consider running the entire attachment in here instead in the future + if (bWasSimulating) + { + ObjectsWaitingForSocketUpdate.Add(ObjectToSocket); + GetWorld()->GetTimerManager().SetTimerForNextTick(FTimerDelegate::CreateUObject(this, &UGripMotionControllerComponent::SetSocketTransform, ObjectToSocket, /*SocketingParent, */RelativeTransformToParent/*, OptionalSocketName, bWeldBodies*/)); + } +} + +void UGripMotionControllerComponent::NotifyDropAndSocket_Implementation(const FBPActorGripInformation &NewDrop, USceneComponent* SocketingParent, FName OptionalSocketName, const FTransform_NetQuantize& RelativeTransformToParent, bool bWeldBodies) +{ + // Don't do this if we are the owning player on a local grip, there is no filter for multicast to not send to owner + if ((NewDrop.GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive || + NewDrop.GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep) && + IsLocallyControlled() && + !IsServer()) + { + + // If we still have the grip then the server is asking us to drop it even though it is locally controlled + if (FBPActorGripInformation * GripInfo = GetGripPtrByID(NewDrop.GripID)) + { + DropAndSocketGrip_Implementation(*GripInfo, SocketingParent, OptionalSocketName, RelativeTransformToParent, bWeldBodies, true); + } + return; + } + + int PhysicsHandleIndex = INDEX_NONE; + GetPhysicsGripIndex(NewDrop, PhysicsHandleIndex); + + if (NewDrop.GrippedObject) + { + OnSocketingObject.Broadcast(NewDrop, SocketingParent, OptionalSocketName, RelativeTransformToParent, bWeldBodies); + Socket_Implementation(NewDrop.GrippedObject, (PhysicsHandleIndex != INDEX_NONE), SocketingParent, OptionalSocketName, RelativeTransformToParent, bWeldBodies); + } + + DropAndSocket_Implementation(NewDrop); +} + +void UGripMotionControllerComponent::DropAndSocket_Implementation(const FBPActorGripInformation &NewDrop) +{ + UGripMotionControllerComponent * HoldingController = nullptr; + bool bIsHeld = false; + + DestroyPhysicsHandle(NewDrop); + + bool bHadGripAuthority = HasGripAuthority(NewDrop); + + UPrimitiveComponent *root = NULL; + AActor * pActor = NULL; + + switch (NewDrop.GripTargetType) + { + case EGripTargetType::ActorGrip: + //case EGripTargetType::InteractibleActorGrip: + { + pActor = NewDrop.GetGrippedActor(); + + if (pActor) + { + root = Cast(pActor->GetRootComponent()); + + pActor->RemoveTickPrerequisiteComponent(this); + //this->IgnoreActorWhenMoving(pActor, false); + + if (APawn* OwningPawn = Cast(GetOwner())) + { + OwningPawn->MoveIgnoreActorRemove(pActor); + + // Clearing owner out here + // Now I am setting the owner to the owning pawn if we are one + // This makes sure that some special replication needs are taken care of + // Only doing this for actor grips + // #TODO: Add the removal back in? + //pActor->SetOwner(nullptr); + } + + if (root) + { + //root->IgnoreActorWhenMoving(this->GetOwner(), false); + + // Attachment already handles both of these + //root->UpdateComponentToWorld(); // This fixes the late update offset + //root->SetSimulatePhysics(false); + + if ((NewDrop.AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings && NewDrop.AdvancedGripSettings.PhysicsSettings.bTurnOffGravityDuringGrip) || + (NewDrop.GripMovementReplicationSetting == EGripMovementReplicationSettings::ForceServerSideMovement && !IsServer())) + root->SetEnableGravity(NewDrop.bOriginalGravity); + + // Stop Physics sim for socketing + root->SetSimulatePhysics(false); + } + + if (IsServer()) //&& !bSkipFullDrop) + { + pActor->SetReplicateMovement(NewDrop.bOriginalReplicatesMovement); + } + + if (pActor->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + IVRGripInterface::Execute_SetHeld(pActor, this, NewDrop.GripID, false); + + if(NewDrop.SecondaryGripInfo.bHasSecondaryAttachment || SecondaryGripIDs.Contains(NewDrop.GripID)) + { + IVRGripInterface::Execute_OnSecondaryGripRelease(pActor, this, NewDrop.SecondaryGripInfo.SecondaryAttachment, NewDrop); + OnSecondaryGripRemoved.Broadcast(NewDrop); + } + + SecondaryGripIDs.Remove(NewDrop.GripID); + + TArray GripScripts; + if (IVRGripInterface::Execute_GetGripScripts(pActor, GripScripts)) + { + for (UVRGripScriptBase* Script : GripScripts) + { + if (Script) + { + if (NewDrop.SecondaryGripInfo.bHasSecondaryAttachment) + Script->OnSecondaryGripRelease(this, NewDrop.SecondaryGripInfo.SecondaryAttachment, NewDrop); + + Script->OnGripRelease(this, NewDrop, true); + } + } + } + + IVRGripInterface::Execute_OnGripRelease(pActor, this, NewDrop, true); + if (IVRGripInterface* GripInterface = Cast(pActor)) + { + GripInterface->Native_NotifyThrowGripDelegates(this, false, NewDrop, true); + } + + } + } + }break; + + case EGripTargetType::ComponentGrip: + //case EGripTargetType::InteractibleComponentGrip: + { + root = NewDrop.GetGrippedComponent(); + if (root) + { + pActor = root->GetOwner(); + + root->RemoveTickPrerequisiteComponent(this); + //root->IgnoreActorWhenMoving(this->GetOwner(), false); + + // Attachment already handles both of these + //root->UpdateComponentToWorld(); + //root->SetSimulatePhysics(false); + + if ((NewDrop.AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings && NewDrop.AdvancedGripSettings.PhysicsSettings.bTurnOffGravityDuringGrip) || + (NewDrop.GripMovementReplicationSetting == EGripMovementReplicationSettings::ForceServerSideMovement && !IsServer())) + root->SetEnableGravity(NewDrop.bOriginalGravity); + + // Stop Physics sim for socketing + root->SetSimulatePhysics(false); + + if (pActor) + { + if (IsServer() && root == pActor->GetRootComponent()) //&& !bSkipFullDrop) + { + pActor->SetReplicateMovement(NewDrop.bOriginalReplicatesMovement); + } + + if (pActor->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + IVRGripInterface::Execute_OnChildGripRelease(pActor, this, NewDrop, true); + } + } + + if (root->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + IVRGripInterface::Execute_SetHeld(root, this, NewDrop.GripID, false); + + if (NewDrop.SecondaryGripInfo.bHasSecondaryAttachment || SecondaryGripIDs.Contains(NewDrop.GripID)) + { + IVRGripInterface::Execute_OnSecondaryGripRelease(root, this, NewDrop.SecondaryGripInfo.SecondaryAttachment, NewDrop); + OnSecondaryGripRemoved.Broadcast(NewDrop); + } + + SecondaryGripIDs.Remove(NewDrop.GripID); + + TArray GripScripts; + if (IVRGripInterface::Execute_GetGripScripts(root, GripScripts)) + { + for (UVRGripScriptBase* Script : GripScripts) + { + if (Script) + { + if (NewDrop.SecondaryGripInfo.bHasSecondaryAttachment) + Script->OnSecondaryGripRelease(this, NewDrop.SecondaryGripInfo.SecondaryAttachment, NewDrop); + + Script->OnGripRelease(this, NewDrop, true); + } + } + } + + IVRGripInterface::Execute_OnGripRelease(root, this, NewDrop, true); + if (IVRGripInterface* GripInterface = Cast(root)) + { + GripInterface->Native_NotifyThrowGripDelegates(this, false, NewDrop, true); + } + } + + // Call on child grip release on attached parent component + if (root->GetAttachParent() && root->GetAttachParent()->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + IVRGripInterface::Execute_OnChildGripRelease(root->GetAttachParent(), this, NewDrop, true); + } + } + }break; + } + + // Copy over the information instead of working with a reference for the OnDroppedBroadcast + FBPActorGripInformation DropBroadcastData = NewDrop; + + int fIndex = 0; + if (LocallyGrippedObjects.Find(NewDrop, fIndex)) + { + DIRTY_LOCALLY_GRIPPED_OBJECTS(); + + if (HasGripAuthority(NewDrop) || IsServer()) + { + LocallyGrippedObjects.RemoveAt(fIndex); + } + else + { + LocallyGrippedObjects[fIndex].bIsPendingKill = true; + LocallyGrippedObjects[fIndex].bIsPaused = true; // Pause it instead of dropping, dropping can corrupt the array in rare cases + } + } + else + { + fIndex = 0; + if (GrippedObjects.Find(NewDrop, fIndex)) + { + DIRTY_GRIPPED_OBJECTS(); + if (HasGripAuthority(NewDrop) || IsServer()) + { + GrippedObjects.RemoveAt(fIndex); + } + else + { + GrippedObjects[fIndex].bIsPendingKill = true; + GrippedObjects[fIndex].bIsPaused = true; // Pause it instead of dropping, dropping can corrupt the array in rare cases + } + } + } + + // Broadcast a new drop + OnDroppedObject.Broadcast(DropBroadcastData, true); +} + + +// No longer an RPC, now is called from RepNotify so that joining clients also correctly set up grips +bool UGripMotionControllerComponent::NotifyGrip(FBPActorGripInformation &NewGrip, bool bIsReInit) +{ + UPrimitiveComponent *root = NULL; + AActor *pActor = NULL; + + bool bRootHasInterface = false; + bool bActorHasInterface = false; + + if (!NewGrip.GrippedObject || !NewGrip.GrippedObject->IsValidLowLevelFast()) + return false; + + if (!NewGrip.AdvancedGripSettings.bDisallowLerping && !bIsReInit && NewGrip.GripCollisionType != EGripCollisionType::EventsOnly && NewGrip.GripCollisionType != EGripCollisionType::CustomGrip) + { + // Init lerping + InitializeLerpToHand(NewGrip); + } + + switch (NewGrip.GripTargetType) + { + case EGripTargetType::ActorGrip: + //case EGripTargetType::InteractibleActorGrip: + { + pActor = NewGrip.GetGrippedActor(); + + if (pActor) + { + root = Cast(pActor->GetRootComponent()); + + if (root->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + bRootHasInterface = true; + } + if (pActor->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + // Actor grip interface is checked after component + bActorHasInterface = true; + } + + if (APawn* OwningPawn = Cast(GetOwner())) + { + if (NewGrip.GripCollisionType != EGripCollisionType::EventsOnly) + { + OwningPawn->MoveIgnoreActorAdd(pActor); + } + + // Now I am setting the owner to the owning pawn if we are one + // This makes sure that some special replication needs are taken care of + // Only doing this for actor grips + if (NewGrip.AdvancedGripSettings.bSetOwnerOnGrip) + { + if (IsServer()) + { + pActor->SetOwner(OwningPawn); + } + } + } + + if (!bIsReInit && bActorHasInterface) + { + IVRGripInterface::Execute_SetHeld(pActor, this, NewGrip.GripID, true); + + TArray GripScripts; + if (IVRGripInterface::Execute_GetGripScripts(pActor, GripScripts)) + { + for (UVRGripScriptBase* Script : GripScripts) + { + if (Script) + { + Script->OnGrip(this, NewGrip); + } + } + } + + uint8 GripID = NewGrip.GripID; + IVRGripInterface::Execute_OnGrip(pActor, this, NewGrip); + if (!LocallyGrippedObjects.Contains(GripID) && !GrippedObjects.Contains(GripID)) + { + return false; + } + + // Now check for c++ specific implementation and throw the native event if we need too + if (IVRGripInterface* GripInterface = Cast(pActor)) + { + GripInterface->Native_NotifyThrowGripDelegates(this, true, NewGrip, false); + + if (!LocallyGrippedObjects.Contains(GripID) && !GrippedObjects.Contains(GripID)) + { + return false; + } + } + + } + + if (root) + { + if (NewGrip.GripCollisionType != EGripCollisionType::EventsOnly) + { + // Have to turn off gravity locally + if ((NewGrip.AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings && NewGrip.AdvancedGripSettings.PhysicsSettings.bTurnOffGravityDuringGrip) || + (NewGrip.GripMovementReplicationSetting == EGripMovementReplicationSettings::ForceServerSideMovement && !IsServer())) + root->SetEnableGravity(false); + } + //root->IgnoreActorWhenMoving(this->GetOwner(), true); + } + + + } + else + return false; + + if (bActorHasInterface && !EndPhysicsTickFunction.IsTickFunctionRegistered()) + { + if (bProjectNonSimulatingGrips) + { + RegisterEndPhysicsTick(true); + } + else + { + EGripInterfaceTeleportBehavior TeleportBehavior = IVRGripInterface::Execute_TeleportBehavior(pActor); + + if (TeleportBehavior == EGripInterfaceTeleportBehavior::DeltaTeleportation) + { + RegisterEndPhysicsTick(true); + } + } + } + + }break; + + case EGripTargetType::ComponentGrip: + //case EGripTargetType::InteractibleComponentGrip: + { + root = NewGrip.GetGrippedComponent(); + + if (root) + { + pActor = root->GetOwner(); + + if (root->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + bRootHasInterface = true; + } + if (pActor->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + // Actor grip interface is checked after component + bActorHasInterface = true; + } + + if (!bIsReInit && bRootHasInterface) + { + IVRGripInterface::Execute_SetHeld(root, this, NewGrip.GripID, true); + + TArray GripScripts; + if (IVRGripInterface::Execute_GetGripScripts(root, GripScripts)) + { + for (UVRGripScriptBase* Script : GripScripts) + { + if (Script) + { + Script->OnGrip(this, NewGrip); + } + } + } + + uint8 GripID = NewGrip.GripID; + IVRGripInterface::Execute_OnGrip(root, this, NewGrip); + if (!LocallyGrippedObjects.Contains(GripID) && !GrippedObjects.Contains(GripID)) + { + return false; + } + + // Now throw the native event if it implements the native interface + if (IVRGripInterface* GripInterface = Cast(root)) + { + //GripInterface->Execute_OnGrip(root, this, NewGrip); + GripInterface->Native_NotifyThrowGripDelegates(this, true, NewGrip, false); + + if (!LocallyGrippedObjects.Contains(GripID) && !GrippedObjects.Contains(GripID)) + { + return false; + } + + } + + } + + if (pActor) + { + /*if (APawn* OwningPawn = Cast(GetOwner())) + { + OwningPawn->MoveIgnoreActorAdd(root->GetOwner()); + }*/ + + if (!bIsReInit && bActorHasInterface) + { + uint8 GripID = NewGrip.GripID; + IVRGripInterface::Execute_OnChildGrip(pActor, this, NewGrip); + if (!LocallyGrippedObjects.Contains(GripID) && !GrippedObjects.Contains(GripID)) + { + return false; + } + } + + } + + // Call OnChildGrip for attached grip parent + if (!bIsReInit && root->GetAttachParent() && root->GetAttachParent()->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + uint8 GripID = NewGrip.GripID; + IVRGripInterface::Execute_OnChildGrip(root->GetAttachParent(), this, NewGrip); + if (!LocallyGrippedObjects.Contains(GripID) && !GrippedObjects.Contains(GripID)) + { + return false; + } + } + + if (NewGrip.GripCollisionType != EGripCollisionType::EventsOnly) + { + if ((NewGrip.AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings && NewGrip.AdvancedGripSettings.PhysicsSettings.bTurnOffGravityDuringGrip) || + (NewGrip.GripMovementReplicationSetting == EGripMovementReplicationSettings::ForceServerSideMovement && !IsServer())) + root->SetEnableGravity(false); + } + + //root->IgnoreActorWhenMoving(this->GetOwner(), true); + } + else + return false; + + if (bRootHasInterface && !EndPhysicsTickFunction.IsTickFunctionRegistered()) + { + if (bProjectNonSimulatingGrips) + { + RegisterEndPhysicsTick(true); + } + else + { + EGripInterfaceTeleportBehavior TeleportBehavior = IVRGripInterface::Execute_TeleportBehavior(root); + + if (TeleportBehavior == EGripInterfaceTeleportBehavior::DeltaTeleportation) + { + RegisterEndPhysicsTick(true); + } + } + } + + }break; + } + + switch (NewGrip.GripMovementReplicationSetting) + { + case EGripMovementReplicationSettings::ForceClientSideMovement: + case EGripMovementReplicationSettings::ClientSide_Authoritive: + case EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep: + { + if (NewGrip.GripCollisionType != EGripCollisionType::EventsOnly) + { + if (IsServer() && pActor && ((NewGrip.GripTargetType == EGripTargetType::ActorGrip) || (root && root == pActor->GetRootComponent()))) + { + pActor->SetReplicateMovement(false); + } + if (root) + { + // #TODO: This is a hack until Epic fixes their new physics replication code + // It forces the replication target to null on grip if we aren't repping movement. + + if (UWorld* World = GetWorld()) + { + if (FPhysScene* PhysScene = World->GetPhysicsScene()) + { + if (IPhysicsReplication* PhysicsReplication = PhysScene->GetPhysicsReplication()) + { + FBodyInstance* BI = root->GetBodyInstance(NewGrip.GrippedBoneName); + if (BI && BI->IsInstanceSimulatingPhysics()) + { + PhysicsReplication->RemoveReplicatedTarget(root); + //PhysicsReplication->SetReplicatedTarget(this, BoneName, UpdatedState); + } + } + } + } + } + } + + }break; + + case EGripMovementReplicationSettings::ForceServerSideMovement: + { + if (NewGrip.GripCollisionType != EGripCollisionType::EventsOnly) + { + if (IsServer() && pActor && ((NewGrip.GripTargetType == EGripTargetType::ActorGrip) || (root && root == pActor->GetRootComponent()))) + { + pActor->SetReplicateMovement(true); + } + } + }break; + + case EGripMovementReplicationSettings::KeepOriginalMovement: + default: + {}break; + } + + bool bHasMovementAuthority = HasGripMovementAuthority(NewGrip); + + switch (NewGrip.GripCollisionType) + { + case EGripCollisionType::InteractiveCollisionWithPhysics: + case EGripCollisionType::LockedConstraint: + case EGripCollisionType::ManipulationGrip: + case EGripCollisionType::ManipulationGripWithWristTwist: + { + if (bHasMovementAuthority) + { + SetUpPhysicsHandle(NewGrip); + } + } break; + + + case EGripCollisionType::InteractiveHybridCollisionWithPhysics: + { + if (bHasMovementAuthority) + { + SetUpPhysicsHandle(NewGrip); + } + } break; + + // Skip collision intersects with these types, they dont need it + case EGripCollisionType::EventsOnly: + case EGripCollisionType::CustomGrip: + { + // Should have never been turning off physics here, simulating is a valid custom grip state + //if (root) + //root->SetSimulatePhysics(false); + + } break; + + case EGripCollisionType::AttachmentGrip: + { + if (IsValid(root)) + root->SetSimulatePhysics(false); + + // Move it to the correct location automatically + if (bHasMovementAuthority) + { + if (!NewGrip.bIsLerping) + { + TeleportMoveGrip(NewGrip); + } + } + + if (bHasMovementAuthority || IsServer()) + { + FName BoneName = IsValid(CustomPivotComponent) ? CustomPivotComponentSocketName : NAME_None; + root->AttachToComponent(IsValid(CustomPivotComponent) ? CustomPivotComponent.Get() : this, FAttachmentTransformRules(EAttachmentRule::KeepWorld, true), BoneName); + } + + }break; + + case EGripCollisionType::PhysicsOnly: + case EGripCollisionType::SweepWithPhysics: + case EGripCollisionType::InteractiveHybridCollisionWithSweep: + case EGripCollisionType::InteractiveCollisionWithSweep: + default: + { + + if (IsValid(root)) + { + if (root->IsSimulatingPhysics()) + { + root->SetSimulatePhysics(false); + } + // #TODO Remove the ELSE below when chaos is fixed for body welding without simulation + else + { + root->SetSimulatePhysics(true); // Forces it to weld children + root->SetSimulatePhysics(false); // Stop it + } + + if(root->GetAttachParent()) + { + root->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform); + } + } + + // Move it to the correct location automatically + if (bHasMovementAuthority) + { + if (!NewGrip.bIsLerping) + { + TeleportMoveGrip(NewGrip); + } + } + } break; + + } + + if (!bIsReInit) + { + // TMP #TODO: Remove when 5.4 velocity bug is fixed + if (IsValid(root)) + { + // Set initial world transform for velocity + NewGrip.LastVelWorldTrans = root->GetComponentTransform(); + } + + // Broadcast a new grip + OnGrippedObject.Broadcast(NewGrip); + if (!LocallyGrippedObjects.Contains(NewGrip.GripID) && !GrippedObjects.Contains(NewGrip.GripID)) + { + return false; + } + } + + return true; +} + +void UGripMotionControllerComponent::InitializeLerpToHand(FBPActorGripInformation & GripInformation) +{ + const UVRGlobalSettings& VRSettings = *GetDefault(); + + if (!VRSettings.bUseGlobalLerpToHand || VRSettings.LerpDuration <= 0.f) + return; + + if (VRSettings.bSkipLerpToHandIfHeld && GripInformation.GrippedObject && GripInformation.GrippedObject->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + bool bIsHeld = false; + TArray HoldingControllers; + // Check if a different controller is holding it + IVRGripInterface::Execute_IsHeld(GripInformation.GrippedObject, HoldingControllers, bIsHeld); + + if (HoldingControllers.Num() > 0) + { + for (FBPGripPair& ControllerPair : HoldingControllers) + { + if (ControllerPair.HoldingController && ControllerPair.HoldingController != this) + { + FBPActorGripInformation Grip; + EBPVRResultSwitch Result; + ControllerPair.HoldingController->GetGripByID(Grip, ControllerPair.GripID, Result); + + if (Result != EBPVRResultSwitch::OnFailed) + { + if (Grip.IsValid()) + { + // We are skipping lerping now + GripInformation.bIsLerping = false; + return; + } + } + } + } + } + } + + EBPVRResultSwitch Result; + TSubclassOf Class = UGS_LerpToHand::StaticClass(); + UVRGripScriptBase::GetGripScriptByClass(GripInformation.GrippedObject, Class, Result); + if (Result == EBPVRResultSwitch::OnSucceeded) + { + return; + } + + if (USceneComponent* PrimParent = Cast(GripInformation.GrippedObject)) + { + if (GripInformation.GrippedBoneName != NAME_None) + { + GripInformation.OnGripTransform = PrimParent->GetSocketTransform(GripInformation.GrippedBoneName); + } + else + { + GripInformation.OnGripTransform = PrimParent->GetComponentTransform(); + } + } + else if (AActor* ParentActor = Cast(GripInformation.GrippedObject)) + { + GripInformation.OnGripTransform = ParentActor->GetActorTransform(); + } + + FTransform TargetTransform = GripInformation.RelativeTransform * this->GetPivotTransform(); + float Distance = FVector::Dist(GripInformation.OnGripTransform.GetLocation(), TargetTransform.GetLocation()); + if (VRSettings.MinDistanceForLerp > 0.0f && Distance < VRSettings.MinDistanceForLerp) + { + // Don't init + GripInformation.bIsLerping = false; + //OnLerpToHandFinished.Broadcast(GripInformation); + return; + } + else + { + float LerpScaler = 1.0f; + float DistanceToSpeed = Distance / VRSettings.LerpDuration; + if (DistanceToSpeed < VRSettings.MinSpeedForLerp) + { + LerpScaler = VRSettings.MinSpeedForLerp / DistanceToSpeed; + } + else if (VRSettings.MaxSpeedForLerp > 0.f && DistanceToSpeed > VRSettings.MaxSpeedForLerp) + { + LerpScaler = VRSettings.MaxSpeedForLerp / DistanceToSpeed; + } + else + { + LerpScaler = 1.0f; + } + + // Get the modified lerp speed + GripInformation.LerpSpeed = ((1.f / VRSettings.LerpDuration) * LerpScaler); + GripInformation.bIsLerping = true; + GripInformation.CurrentLerpTime = 0.0f; + } + + GripInformation.CurrentLerpTime = 0.0f; +} + +void UGripMotionControllerComponent::HandleGlobalLerpToHand(FBPActorGripInformation& GripInformation, FTransform& WorldTransform, float DeltaTime) +{ + UVRGlobalSettings* VRSettings = GetMutableDefault(); + + if (!VRSettings->bUseGlobalLerpToHand || !GripInformation.bIsLerping) + return; + + EBPVRResultSwitch Result; + TSubclassOf Class = UGS_LerpToHand::StaticClass(); + UVRGripScriptBase * LerpScript = UVRGripScriptBase::GetGripScriptByClass(GripInformation.GrippedObject, Class, Result); + if (Result == EBPVRResultSwitch::OnSucceeded && LerpScript && LerpScript->IsScriptActive()) + { + return; + } + + if (VRSettings->LerpDuration <= 0.f) + { + GripInformation.bIsLerping = false; + GripInformation.CurrentLerpTime = 0.f; + OnLerpToHandFinished.Broadcast(GripInformation); + return; + } + + FTransform NA = GripInformation.OnGripTransform;//root->GetComponentTransform(); + float Alpha = 0.0f; + + GripInformation.CurrentLerpTime += DeltaTime * GripInformation.LerpSpeed; + float OrigAlpha = FMath::Clamp(GripInformation.CurrentLerpTime, 0.f, 1.0f); + Alpha = OrigAlpha; + + if (VRSettings->bUseCurve) + { + if (FRichCurve* richCurve = VRSettings->OptionalCurveToFollow.GetRichCurve()) + { + /*if (CurrentLerpTime > richCurve->GetLastKey().Time) + { + // Stop lerping + OnLerpToHandFinished.Broadcast(); + CurrentLerpTime = 0.0f; + bIsActive = false; + return true; + } + else*/ + { + Alpha = FMath::Clamp(richCurve->Eval(Alpha), 0.f, 1.f); + //CurrentLerpTime += DeltaTime; + } + } + } + + FTransform NB = WorldTransform; + NA.NormalizeRotation(); + NB.NormalizeRotation(); + + // Quaternion interpolation + if (VRSettings->LerpInterpolationMode == EVRLerpInterpolationMode::QuatInterp) + { + WorldTransform.Blend(NA, NB, Alpha); + } + + // Euler Angle interpolation + else if (VRSettings->LerpInterpolationMode == EVRLerpInterpolationMode::EulerInterp) + { + WorldTransform.SetTranslation(FMath::Lerp(NA.GetTranslation(), NB.GetTranslation(), Alpha)); + WorldTransform.SetScale3D(FMath::Lerp(NA.GetScale3D(), NB.GetScale3D(), Alpha)); + + FRotator A = NA.Rotator(); + FRotator B = NB.Rotator(); + WorldTransform.SetRotation(FQuat(A + (Alpha * (B - A)))); + } + // Dual quaternion interpolation + else + { + if ((NB.GetRotation() | NA.GetRotation()) < 0.0f) + { + NB.SetRotation(NB.GetRotation() * -1.0f); + } + WorldTransform = (FDualQuat(NA) * (1 - Alpha) + FDualQuat(NB) * Alpha).Normalized().AsFTransform(FMath::Lerp(NA.GetScale3D(), NB.GetScale3D(), Alpha)); + } + + // Turn it off if we need to + if (OrigAlpha >= 1.0f) + { + GripInformation.CurrentLerpTime = 0.0f; + GripInformation.bIsLerping = false; + + if (bConstrainToPivot) + { + DestroyPhysicsHandle(GripInformation, false); + SetUpPhysicsHandle(GripInformation); + } + + + OnLerpToHandFinished.Broadcast(GripInformation); + } +} + +void UGripMotionControllerComponent::CancelGlobalLerpToHand(uint8 GripID) +{ + FBPActorGripInformation* GripToUse = nullptr; + if (GripID != INVALID_VRGRIP_ID) + { + GripToUse = GrippedObjects.FindByKey(GripID); + if (!GripToUse) + { + GripToUse = LocallyGrippedObjects.FindByKey(GripID); + } + + if (GripToUse) + { + GripToUse->bIsLerping = false; + + if (bConstrainToPivot) + { + DestroyPhysicsHandle(*GripToUse, false); + SetUpPhysicsHandle(*GripToUse); + } + + GripToUse->CurrentLerpTime = 0.0f; + OnLerpToHandFinished.Broadcast(*GripToUse); + } + } +} + +void UGripMotionControllerComponent::NotifyDrop_Implementation(const FBPActorGripInformation &NewDrop, bool bSimulate) +{ + // Don't do this if we are the owning player on a local grip, there is no filter for multicast to not send to owner + if ((NewDrop.GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive || + NewDrop.GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep) && + IsLocallyControlled() && + !IsServer()) + { + // If we still have the grip then the server is asking us to drop it even though it is locally controlled + if (FBPActorGripInformation * GripInfo = GetGripPtrByID(NewDrop.GripID)) + { + DropGrip_Implementation(*GripInfo, bSimulate, FVector::ZeroVector, FVector::ZeroVector, true); + } + + return; + } + + Drop_Implementation(NewDrop, bSimulate); +} + +void UGripMotionControllerComponent::Drop_Implementation(const FBPActorGripInformation &NewDrop, bool bSimulate) +{ + bool bSkipFullDrop = false; + bool bHadAnotherSelfGrip = false; + TArray HoldingControllers; + bool bIsHeld = false; + + // Check if a different controller is holding it + if(NewDrop.GrippedObject && NewDrop.GrippedObject->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + IVRGripInterface::Execute_IsHeld(NewDrop.GrippedObject, HoldingControllers, bIsHeld); + + if (bIsHeld && (!HoldingControllers.Contains(this) || HoldingControllers.Num() > 1)) + { + // Skip the full drop if held + bSkipFullDrop = true; + } + else // Now check for this same hand with duplicate grips on this object + { + for (int i = 0; i < LocallyGrippedObjects.Num(); ++i) + { + if (LocallyGrippedObjects[i].GrippedObject == NewDrop.GrippedObject && LocallyGrippedObjects[i].GripID != NewDrop.GripID) + { + bSkipFullDrop = true; + bHadAnotherSelfGrip = true; + } + } + for (int i = 0; i < GrippedObjects.Num(); ++i) + { + if (GrippedObjects[i].GrippedObject == NewDrop.GrippedObject && GrippedObjects[i].GripID != NewDrop.GripID) + { + bSkipFullDrop = true; + bHadAnotherSelfGrip = true; + } + } + } + + DestroyPhysicsHandle(NewDrop, bHadAnotherSelfGrip); + + bool bHadGripAuthority = HasGripAuthority(NewDrop); + + UPrimitiveComponent *root = NULL; + AActor * pActor = NULL; + + switch (NewDrop.GripTargetType) + { + case EGripTargetType::ActorGrip: + //case EGripTargetType::InteractibleActorGrip: + { + pActor = NewDrop.GetGrippedActor(); + + if (pActor) + { + root = Cast(pActor->GetRootComponent()); + + if (!bSkipFullDrop) + { + + pActor->RemoveTickPrerequisiteComponent(this); + //this->IgnoreActorWhenMoving(pActor, false); + + if (NewDrop.GripCollisionType != EGripCollisionType::EventsOnly) + { + if (APawn * OwningPawn = Cast(GetOwner())) + { + OwningPawn->MoveIgnoreActorRemove(pActor); + + // Clearing owner out here + // Now I am setting the owner to the owning pawn if we are one + // This makes sure that some special replication needs are taken care of + // Only doing this for actor grips + // #TODO: Add the removal back in? + //pActor->SetOwner(nullptr); + } + } + + if (root) + { + + if (NewDrop.GripCollisionType == EGripCollisionType::AttachmentGrip && (HasGripAuthority(NewDrop) || IsServer())) + root->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform); + + //root->IgnoreActorWhenMoving(this->GetOwner(), false); + + if (NewDrop.GripCollisionType != EGripCollisionType::EventsOnly) + { + if (IsServer() || bHadGripAuthority || !NewDrop.bOriginalReplicatesMovement || !pActor->GetIsReplicated()) + { + if (!NewDrop.AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings || !NewDrop.AdvancedGripSettings.PhysicsSettings.bSkipSettingSimulating) + { + if (root->IsSimulatingPhysics() != bSimulate) + { + root->SetSimulatePhysics(bSimulate); + } + + if (bSimulate) + root->WakeAllRigidBodies(); + } + } + + root->UpdateComponentToWorld(); // This fixes the late update offset + } + + /*if (NewDrop.GrippedBoneName == NAME_None) + { + root->SetSimulatePhysics(bSimulate); + root->UpdateComponentToWorld(); // This fixes the late update offset + if (bSimulate) + root->WakeAllRigidBodies(); + } + else + { + USkeletalMeshComponent * skele = Cast(root); + if (skele) + { + skele->SetAllBodiesBelowSimulatePhysics(NewDrop.GrippedBoneName, bSimulate); + root->UpdateComponentToWorld(); // This fixes the late update offset + } + else + { + root->SetSimulatePhysics(bSimulate); + root->UpdateComponentToWorld(); // This fixes the late update offset + if (bSimulate) + root->WakeAllRigidBodies(); + } + }*/ + + if (NewDrop.GripCollisionType != EGripCollisionType::EventsOnly) + { + if ((NewDrop.AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings && NewDrop.AdvancedGripSettings.PhysicsSettings.bTurnOffGravityDuringGrip) || + (NewDrop.GripMovementReplicationSetting == EGripMovementReplicationSettings::ForceServerSideMovement && !IsServer())) + root->SetEnableGravity(NewDrop.bOriginalGravity); + } + } + } + + if (IsServer() && !bSkipFullDrop) + { + pActor->SetReplicateMovement(NewDrop.bOriginalReplicatesMovement); + } + + if (pActor->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + IVRGripInterface::Execute_SetHeld(pActor, this, NewDrop.GripID, false); + + if (NewDrop.SecondaryGripInfo.bHasSecondaryAttachment || SecondaryGripIDs.Contains(NewDrop.GripID)) + { + IVRGripInterface::Execute_OnSecondaryGripRelease(pActor, this, NewDrop.SecondaryGripInfo.SecondaryAttachment, NewDrop); + OnSecondaryGripRemoved.Broadcast(NewDrop); + } + + SecondaryGripIDs.Remove(NewDrop.GripID); + + TArray GripScripts; + if (IVRGripInterface::Execute_GetGripScripts(pActor, GripScripts)) + { + for (UVRGripScriptBase* Script : GripScripts) + { + if (Script) + { + if (NewDrop.SecondaryGripInfo.bHasSecondaryAttachment) + Script->OnSecondaryGripRelease(this, NewDrop.SecondaryGripInfo.SecondaryAttachment, NewDrop); + + Script->OnGripRelease(this, NewDrop, false); + } + } + } + + IVRGripInterface::Execute_OnGripRelease(pActor, this, NewDrop, false); + if (IVRGripInterface* GripInterface = Cast(pActor)) + { + //GripInterface->Execute_OnGripRelease(pActor, this, NewDrop, false); + GripInterface->Native_NotifyThrowGripDelegates(this, false, NewDrop, false); + } + } + } + }break; + + case EGripTargetType::ComponentGrip: + //case EGripTargetType::InteractibleComponentGrip: + { + root = NewDrop.GetGrippedComponent(); + if (root) + { + pActor = root->GetOwner(); + + if (!bSkipFullDrop) + { + root->RemoveTickPrerequisiteComponent(this); + + /*if (APawn* OwningPawn = Cast(GetOwner())) + { + OwningPawn->MoveIgnoreActorRemove(pActor); + }*/ + + if (NewDrop.GripCollisionType == EGripCollisionType::AttachmentGrip && (HasGripAuthority(NewDrop) || IsServer())) + root->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform); + + //root->IgnoreActorWhenMoving(this->GetOwner(), false); + + if (NewDrop.GripCollisionType != EGripCollisionType::EventsOnly) + { + // Need to set simulation in all of these cases, including if it isn't the root component (simulation isn't replicated on non roots) + if (IsServer() || bHadGripAuthority || !NewDrop.bOriginalReplicatesMovement || (pActor && (pActor->GetRootComponent() != root || !pActor->GetIsReplicated()))) + { + if (!NewDrop.AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings || !NewDrop.AdvancedGripSettings.PhysicsSettings.bSkipSettingSimulating) + { + if (root->IsSimulatingPhysics() != bSimulate) + { + root->SetSimulatePhysics(bSimulate); + } + + if (bSimulate) + root->WakeAllRigidBodies(); + } + } + + root->UpdateComponentToWorld(); // This fixes the late update offset + } + /*if (NewDrop.GrippedBoneName == NAME_None) + { + root->SetSimulatePhysics(bSimulate); + root->UpdateComponentToWorld(); // This fixes the late update offset + if (bSimulate) + root->WakeAllRigidBodies(); + } + else + { + USkeletalMeshComponent * skele = Cast(root); + if (skele) + { + skele->SetAllBodiesBelowSimulatePhysics(NewDrop.GrippedBoneName, bSimulate); + root->UpdateComponentToWorld(); // This fixes the late update offset + } + else + { + root->SetSimulatePhysics(bSimulate); + root->UpdateComponentToWorld(); // This fixes the late update offset + if (bSimulate) + root->WakeAllRigidBodies(); + } + }*/ + + if (NewDrop.GripCollisionType != EGripCollisionType::EventsOnly) + { + if ((NewDrop.AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings && NewDrop.AdvancedGripSettings.PhysicsSettings.bTurnOffGravityDuringGrip) || + (NewDrop.GripMovementReplicationSetting == EGripMovementReplicationSettings::ForceServerSideMovement && !IsServer())) + root->SetEnableGravity(NewDrop.bOriginalGravity); + } + } + + if (pActor) + { + if (IsServer() && root == pActor->GetRootComponent() && !bSkipFullDrop) + { + pActor->SetReplicateMovement(NewDrop.bOriginalReplicatesMovement); + } + + if (pActor->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + IVRGripInterface::Execute_OnChildGripRelease(pActor, this, NewDrop, false); + } + + } + + if (root->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + IVRGripInterface::Execute_SetHeld(root, this, NewDrop.GripID, false); + + if (NewDrop.SecondaryGripInfo.bHasSecondaryAttachment || SecondaryGripIDs.Contains(NewDrop.GripID)) + { + IVRGripInterface::Execute_OnSecondaryGripRelease(root, this, NewDrop.SecondaryGripInfo.SecondaryAttachment, NewDrop); + OnSecondaryGripRemoved.Broadcast(NewDrop); + } + + SecondaryGripIDs.Remove(NewDrop.GripID); + + TArray GripScripts; + if (IVRGripInterface::Execute_GetGripScripts(root, GripScripts)) + { + for (UVRGripScriptBase* Script : GripScripts) + { + if (Script) + { + if (NewDrop.SecondaryGripInfo.bHasSecondaryAttachment) + Script->OnSecondaryGripRelease(this, NewDrop.SecondaryGripInfo.SecondaryAttachment, NewDrop); + + Script->OnGripRelease(this, NewDrop, false); + } + } + } + + IVRGripInterface::Execute_OnGripRelease(root, this, NewDrop, false); + if (IVRGripInterface* GripInterface = Cast(root)) + { + GripInterface->Native_NotifyThrowGripDelegates(this, false, NewDrop, false); + } + + } + + // Call on child grip release on attached parent component + if (root->GetAttachParent() && root->GetAttachParent()->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + IVRGripInterface::Execute_OnChildGripRelease(root->GetAttachParent(), this, NewDrop, false); + } + } + }break; + } + + + switch (NewDrop.GripMovementReplicationSetting) + { + case EGripMovementReplicationSettings::ForceClientSideMovement: + case EGripMovementReplicationSettings::ClientSide_Authoritive: + case EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep: + { + if (NewDrop.GripCollisionType != EGripCollisionType::EventsOnly) + { + if (root) + { + // #TODO: This is a hack until Epic fixes their new physics replication code + // It forces the replication target to null on grip if we aren't repping movement. + if (UWorld * World = GetWorld()) + { + if (FPhysScene * PhysScene = World->GetPhysicsScene()) + { + if (IPhysicsReplication* PhysicsReplication = PhysScene->GetPhysicsReplication()) + { + FBodyInstance* BI = root->GetBodyInstance(NewDrop.GrippedBoneName); + if (BI && BI->IsInstanceSimulatingPhysics()) + { + PhysicsReplication->RemoveReplicatedTarget(root); + //PhysicsReplication->SetReplicatedTarget(this, BoneName, UpdatedState); + } + } + } + } + } + } + + }break; + + }; + + // Copy over the information instead of working with a reference for the OnDroppedBroadcast + FBPActorGripInformation DropBroadcastData = NewDrop; + + int fIndex = 0; + if (LocallyGrippedObjects.Find(NewDrop, fIndex)) + { + DIRTY_LOCALLY_GRIPPED_OBJECTS(); + + if (HasGripAuthority(NewDrop) || IsServer()) + { + LocallyGrippedObjects.RemoveAt(fIndex); + } + else + { + LocallyGrippedObjects[fIndex].bIsPendingKill = true; + LocallyGrippedObjects[fIndex].bIsPaused = true; // Pause it instead of dropping, dropping can corrupt the array in rare cases + } + } + else + { + fIndex = 0; + if (GrippedObjects.Find(NewDrop, fIndex)) + { + DIRTY_GRIPPED_OBJECTS(); + if (HasGripAuthority(NewDrop) || IsServer()) + { + GrippedObjects.RemoveAt(fIndex); + } + else + { + GrippedObjects[fIndex].bIsPendingKill = true; + GrippedObjects[fIndex].bIsPaused = true; // Pause it instead of dropping, dropping can corrupt the array in rare cases + } + } + } + + // Broadcast a new drop + OnDroppedObject.Broadcast(DropBroadcastData, false); + + + // Now check if we should turn off any post physics ticking + if (EndPhysicsTickFunction.IsTickFunctionRegistered()) + { + bool bNeedsPhysicsTick = false; + + if (LocallyGrippedObjects.Num() > 0 || GrippedObjects.Num() > 0) + { + if (bProjectNonSimulatingGrips) + { + bNeedsPhysicsTick = true; + } + else + { + + for (int i = 0; i < LocallyGrippedObjects.Num(); ++i) + { + if (IsValid(LocallyGrippedObjects[i].GrippedObject) && LocallyGrippedObjects[i].GrippedObject->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + if (LocallyGrippedObjects[i].GripCollisionType != EGripCollisionType::CustomGrip && LocallyGrippedObjects[i].GripCollisionType != EGripCollisionType::EventsOnly) + { + EGripInterfaceTeleportBehavior TeleportBehavior = IVRGripInterface::Execute_TeleportBehavior(LocallyGrippedObjects[i].GrippedObject); + if (TeleportBehavior == EGripInterfaceTeleportBehavior::DeltaTeleportation) + { + bNeedsPhysicsTick = true; + break; + } + } + } + } + + if (!bNeedsPhysicsTick) + { + for (int i = 0; i < GrippedObjects.Num(); ++i) + { + if (IsValid(GrippedObjects[i].GrippedObject) && GrippedObjects[i].GrippedObject->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + if (GrippedObjects[i].GripCollisionType != EGripCollisionType::CustomGrip && GrippedObjects[i].GripCollisionType != EGripCollisionType::EventsOnly) + { + EGripInterfaceTeleportBehavior TeleportBehavior = IVRGripInterface::Execute_TeleportBehavior(GrippedObjects[i].GrippedObject); + if (TeleportBehavior == EGripInterfaceTeleportBehavior::DeltaTeleportation) + { + bNeedsPhysicsTick = true; + break; + } + } + } + } + } + } + } + + if (!bNeedsPhysicsTick) + { + RegisterEndPhysicsTick(false); + } + } +} + +bool UGripMotionControllerComponent::BP_IsLocallyControlled() +{ + return IsLocallyControlled(); +} + +bool UGripMotionControllerComponent::BP_HasGripAuthority(const FBPActorGripInformation &Grip) +{ + return HasGripAuthority(Grip); +} + +bool UGripMotionControllerComponent::BP_HasGripAuthorityForObject(const UObject * ObjToCheck) +{ + return HasGripAuthority(ObjToCheck); +} + +bool UGripMotionControllerComponent::BP_HasGripMovementAuthority(const FBPActorGripInformation &Grip) +{ + return HasGripMovementAuthority(Grip); +} + +bool UGripMotionControllerComponent::AddSecondaryAttachmentPoint(UObject * GrippedObjectToAddAttachment, USceneComponent * SecondaryPointComponent, const FTransform & OriginalTransform, bool bTransformIsAlreadyRelative, float LerpToTime,/* float SecondarySmoothingScaler,*/ bool bIsSlotGrip, FName SecondarySlotName) +{ + if (!GrippedObjectToAddAttachment || !SecondaryPointComponent || (!GrippedObjects.Num() && !LocallyGrippedObjects.Num())) + return false; + + FBPActorGripInformation * GripToUse = nullptr; + + GripToUse = LocallyGrippedObjects.FindByKey(GrippedObjectToAddAttachment); + + // Search replicated grips if not found in local + if (!GripToUse) + { + // Replicated grips need to be called from server side + if (!IsServer()) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController add secondary attachment function was called on the client side with a replicated grip")); + return false; + } + + GripToUse = GrippedObjects.FindByKey(GrippedObjectToAddAttachment); + } + + if (GripToUse) + { + return AddSecondaryAttachmentToGrip(*GripToUse, SecondaryPointComponent, OriginalTransform, bTransformIsAlreadyRelative, LerpToTime, bIsSlotGrip, SecondarySlotName); + } + + return false; +} + +bool UGripMotionControllerComponent::AddSecondaryAttachmentToGripByID(const uint8 GripID, USceneComponent* SecondaryPointComponent, const FTransform& OriginalTransform, bool bTransformIsAlreadyRelative, float LerpToTime, bool bIsSlotGrip, FName SecondarySlotName) +{ + FBPActorGripInformation* GripToUse = nullptr; + if (GripID != INVALID_VRGRIP_ID) + { + GripToUse = GrippedObjects.FindByKey(GripID); + if (!GripToUse) + { + GripToUse = LocallyGrippedObjects.FindByKey(GripID); + } + + if (GripToUse) + { + return AddSecondaryAttachmentToGrip(*GripToUse, SecondaryPointComponent, OriginalTransform, bTransformIsAlreadyRelative, LerpToTime, bIsSlotGrip, SecondarySlotName); + } + } + + return false; +} + +bool UGripMotionControllerComponent::AddSecondaryAttachmentToGrip(const FBPActorGripInformation & GripToAddAttachment, USceneComponent * SecondaryPointComponent, const FTransform &OriginalTransform, bool bTransformIsAlreadyRelative, float LerpToTime, bool bIsSlotGrip, FName SecondarySlotName) +{ + if (!SecondaryPointComponent) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController add secondary attachment function was called with a bad secondary component target!")); + return false; + } + + FBPActorGripInformation* GripToUse = nullptr; + bool bWasLocal = false; + if (GripToAddAttachment.GrippedObject && GripToAddAttachment.GripID != INVALID_VRGRIP_ID) + { + GripToUse = GrippedObjects.FindByKey(GripToAddAttachment.GripID); + if (!GripToUse) + { + GripToUse = LocallyGrippedObjects.FindByKey(GripToAddAttachment.GripID); + bWasLocal = true; + } + } + + if (!GripToUse || GripToUse->GripID == INVALID_VRGRIP_ID) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController add secondary attachment function was called with a bad grip! It was not valid / found.")); + return false; + } + + if (!GripToUse->GrippedObject) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController add secondary attachment function was called with a bad grip (gripped object invalid)!")); + return false; + } + + // Replicated grips need to be called from server side + if (!bWasLocal && !IsServer()) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController add secondary attachment function was called on the client side with a replicated grip")); + return false; + } + + bool bGrippedObjectIsInterfaced = GripToUse->GrippedObject->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass()); + + if (bGrippedObjectIsInterfaced) + { + ESecondaryGripType SecondaryType = IVRGripInterface::Execute_SecondaryGripType(GripToUse->GrippedObject); + + if (SecondaryType == ESecondaryGripType::SG_None) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController add secondary attachment function was called on an interface object set to SG_None!")); + return false; + } + } + + UPrimitiveComponent * root = nullptr; + + switch (GripToUse->GripTargetType) + { + case EGripTargetType::ActorGrip: + { + AActor * pActor = GripToUse->GetGrippedActor(); + + if (pActor) + { + root = Cast(pActor->GetRootComponent()); + } + } + break; + case EGripTargetType::ComponentGrip: + { + root = GripToUse->GetGrippedComponent(); + } + break; + } + + if (!root) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController add secondary attachment function was unable to get root component or gripped component.")); + return false; + } + + if (bTransformIsAlreadyRelative) + GripToUse->SecondaryGripInfo.SecondaryRelativeTransform = OriginalTransform; + else + GripToUse->SecondaryGripInfo.SecondaryRelativeTransform = OriginalTransform.GetRelativeTransform(root->GetComponentTransform()); + + GripToUse->SecondaryGripInfo.SecondaryAttachment = SecondaryPointComponent; + GripToUse->SecondaryGripInfo.bHasSecondaryAttachment = true; + GripToUse->SecondaryGripInfo.SecondaryGripDistance = 0.0f; + GripToUse->SecondaryGripInfo.SecondarySlotName = SecondarySlotName; + + /*const UVRGlobalSettings& VRSettings = *GetDefault(); + GripToUse->AdvancedGripSettings.SecondaryGripSettings.SecondarySmoothing.CutoffSlope = VRSettings.OneEuroCutoffSlope; + GripToUse->AdvancedGripSettings.SecondaryGripSettings.SecondarySmoothing.DeltaCutoff = VRSettings.OneEuroDeltaCutoff; + GripToUse->AdvancedGripSettings.SecondaryGripSettings.SecondarySmoothing.MinCutoff = VRSettings.OneEuroMinCutoff; + + GripToUse->AdvancedGripSettings.SecondaryGripSettings.SecondarySmoothing.ResetSmoothingFilter();*/ + // GripToUse->SecondaryGripInfo.SecondarySmoothingScaler = FMath::Clamp(SecondarySmoothingScaler, 0.01f, 1.0f); + GripToUse->SecondaryGripInfo.bIsSlotGrip = bIsSlotGrip; + + if (GripToUse->SecondaryGripInfo.GripLerpState == EGripLerpState::EndLerp) + LerpToTime = 0.0f; + + if (LerpToTime > 0.0f) + { + GripToUse->SecondaryGripInfo.LerpToRate = LerpToTime; + GripToUse->SecondaryGripInfo.GripLerpState = EGripLerpState::StartLerp; + GripToUse->SecondaryGripInfo.curLerp = LerpToTime; + } + + if (bGrippedObjectIsInterfaced) + { + SecondaryGripIDs.Add(GripToUse->GripID); + + IVRGripInterface::Execute_OnSecondaryGrip(GripToUse->GrippedObject, this, SecondaryPointComponent, *GripToUse); + + TArray GripScripts; + if (IVRGripInterface::Execute_GetGripScripts(GripToUse->GrippedObject, GripScripts)) + { + for (UVRGripScriptBase* Script : GripScripts) + { + if (Script) + { + Script->OnSecondaryGrip(this, SecondaryPointComponent, *GripToUse); + } + } + } + } + + if (GripToUse->GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive && !IsServer() && !IsTornOff()) + { + Server_NotifySecondaryAttachmentChanged(GripToUse->GripID, GripToUse->SecondaryGripInfo); + } + + if (bWasLocal) + { + DIRTY_LOCALLY_GRIPPED_OBJECTS(); + } + else + { + DIRTY_GRIPPED_OBJECTS(); + } + + OnSecondaryGripAdded.Broadcast(*GripToUse); + GripToUse = nullptr; + + return true; +} + +bool UGripMotionControllerComponent::RemoveSecondaryAttachmentPoint(UObject * GrippedObjectToRemoveAttachment, float LerpToTime) +{ + if (!GrippedObjectToRemoveAttachment || (!GrippedObjects.Num() && !LocallyGrippedObjects.Num())) + return false; + + FBPActorGripInformation * GripToUse = nullptr; + + // Duplicating the logic for each array for now + GripToUse = LocallyGrippedObjects.FindByKey(GrippedObjectToRemoveAttachment); + + // Check replicated grips if it wasn't found in local + if (!GripToUse) + { + if (!IsServer()) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController remove secondary attachment function was called on the client side for a replicating grip")); + return false; + } + + GripToUse = GrippedObjects.FindByKey(GrippedObjectToRemoveAttachment); + } + + // Handle the grip if it was found + if (GripToUse && GripToUse->GrippedObject) + { + return RemoveSecondaryAttachmentFromGrip(*GripToUse, LerpToTime); + } + + return false; +} +bool UGripMotionControllerComponent::RemoveSecondaryAttachmentFromGripByID(const uint8 GripID, float LerpToTime) +{ + FBPActorGripInformation* GripToUse = nullptr; + if (GripID != INVALID_VRGRIP_ID) + { + GripToUse = GrippedObjects.FindByKey(GripID); + if (!GripToUse) + { + GripToUse = LocallyGrippedObjects.FindByKey(GripID); + } + + if (GripToUse) + { + return RemoveSecondaryAttachmentFromGrip(*GripToUse, LerpToTime); + } + } + + return false; +} + +bool UGripMotionControllerComponent::RemoveSecondaryAttachmentFromGrip(const FBPActorGripInformation & GripToRemoveAttachment, float LerpToTime) +{ + FBPActorGripInformation* GripToUse = nullptr; + bool bWasLocal = false; + if (GripToRemoveAttachment.GrippedObject && GripToRemoveAttachment.GripID != INVALID_VRGRIP_ID) + { + GripToUse = GrippedObjects.FindByKey(GripToRemoveAttachment.GripID); + if (!GripToUse) + { + GripToUse = LocallyGrippedObjects.FindByKey(GripToRemoveAttachment.GripID); + bWasLocal = true; + } + } + + if (GripToUse && !bWasLocal && !IsServer()) + { + UE_LOG(LogVRMotionController, Warning, TEXT("VRGripMotionController remove secondary attachment function was called on the client side for a replicating grip")); + return false; + } + + // Handle the grip if it was found + if (GripToUse && GripToUse->GrippedObject && GripToUse->GripID != INVALID_VRGRIP_ID) + { + SecondaryGripIDs.Remove(GripToUse->GripID); + + if (GripToUse->SecondaryGripInfo.GripLerpState == EGripLerpState::StartLerp) + LerpToTime = 0.0f; + + //if (LerpToTime > 0.0f) + //{ + UPrimitiveComponent * primComp = nullptr; + + switch (GripToUse->GripTargetType) + { + case EGripTargetType::ComponentGrip: + { + primComp = GripToUse->GetGrippedComponent(); + }break; + case EGripTargetType::ActorGrip: + { + AActor * pActor = GripToUse->GetGrippedActor(); + if (pActor) + primComp = Cast(pActor->GetRootComponent()); + } break; + } + + bool bGripObjectHasInterface = GripToUse->GrippedObject->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass()); + + ESecondaryGripType SecondaryType = ESecondaryGripType::SG_None; + if (bGripObjectHasInterface) + { + SecondaryType = IVRGripInterface::Execute_SecondaryGripType(GripToUse->GrippedObject); + //else if (SecondaryType == ESecondaryGripType::SG_FreeWithScaling || SecondaryType == ESecondaryGripType::SG_SlotOnlyWithScaling) + //LerpToTime = 0.0f; + } + + if (primComp) + { + switch (SecondaryType) + { + // All of these retain the position on release + case ESecondaryGripType::SG_FreeWithScaling_Retain: + case ESecondaryGripType::SG_SlotOnlyWithScaling_Retain: + case ESecondaryGripType::SG_Free_Retain: + case ESecondaryGripType::SG_SlotOnly_Retain: + case ESecondaryGripType::SG_ScalingOnly: + { + GripToUse->RelativeTransform = primComp->GetComponentTransform().GetRelativeTransform(GetPivotTransform()); + GripToUse->SecondaryGripInfo.LerpToRate = 0.0f; + GripToUse->SecondaryGripInfo.GripLerpState = EGripLerpState::NotLerping; + }break; + default: + { + if (LerpToTime > 0.0f) + { + // #TODO: This had a hitch in it just prior to lerping back, fix it eventually and allow lerping from scaling secondaries + //GripToUse->RelativeTransform.SetScale3D(GripToUse->RelativeTransform.GetScale3D() * FVector(GripToUse->SecondaryScaler)); + GripToUse->SecondaryGripInfo.LerpToRate = LerpToTime; + GripToUse->SecondaryGripInfo.GripLerpState = EGripLerpState::EndLerp; + GripToUse->SecondaryGripInfo.curLerp = LerpToTime; + } + }break; + } + + } + else + { + GripToUse->SecondaryGripInfo.LerpToRate = 0.0f; + GripToUse->SecondaryGripInfo.GripLerpState = EGripLerpState::NotLerping; + } + + if (bGripObjectHasInterface) + { + IVRGripInterface::Execute_OnSecondaryGripRelease(GripToUse->GrippedObject, this, GripToUse->SecondaryGripInfo.SecondaryAttachment, *GripToUse); + + TArray GripScripts; + if (IVRGripInterface::Execute_GetGripScripts(GripToUse->GrippedObject, GripScripts)) + { + for (UVRGripScriptBase* Script : GripScripts) + { + if (Script) + { + Script->OnSecondaryGripRelease(this, GripToUse->SecondaryGripInfo.SecondaryAttachment, *GripToUse); + } + } + } + } + + GripToUse->SecondaryGripInfo.SecondaryAttachment = nullptr; + GripToUse->SecondaryGripInfo.bHasSecondaryAttachment = false; + + if (GripToUse->GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive && !IsServer()) + { + switch (SecondaryType) + { + // All of these retain the position on release + case ESecondaryGripType::SG_FreeWithScaling_Retain: + case ESecondaryGripType::SG_SlotOnlyWithScaling_Retain: + case ESecondaryGripType::SG_Free_Retain: + case ESecondaryGripType::SG_SlotOnly_Retain: + case ESecondaryGripType::SG_ScalingOnly: + { + if (!IsTornOff()) + Server_NotifySecondaryAttachmentChanged_Retain(GripToUse->GripID, GripToUse->SecondaryGripInfo, GripToUse->RelativeTransform); + }break; + default: + { + if (!IsTornOff()) + Server_NotifySecondaryAttachmentChanged(GripToUse->GripID, GripToUse->SecondaryGripInfo); + }break; + } + + } + + if (bWasLocal) + { + DIRTY_LOCALLY_GRIPPED_OBJECTS(); + } + else + { + DIRTY_GRIPPED_OBJECTS(); + } + + SecondaryGripIDs.Remove(GripToUse->GripID); + OnSecondaryGripRemoved.Broadcast(*GripToUse); + GripToUse = nullptr; + return true; + } + + return false; +} + +bool UGripMotionControllerComponent::TeleportMoveGrippedActor(AActor * GrippedActorToMove, bool bTeleportPhysicsGrips) +{ + if (!GrippedActorToMove || (!GrippedObjects.Num() && !LocallyGrippedObjects.Num())) + return false; + + FBPActorGripInformation * GripInfo = LocallyGrippedObjects.FindByKey(GrippedActorToMove); + if (!GripInfo) + GrippedObjects.FindByKey(GrippedActorToMove); + + if (GripInfo) + { + return TeleportMoveGrip(*GripInfo, bTeleportPhysicsGrips); + } + + return false; +} + +bool UGripMotionControllerComponent::TeleportMoveGrippedComponent(UPrimitiveComponent * ComponentToMove, bool bTeleportPhysicsGrips) +{ + if (!ComponentToMove || (!GrippedObjects.Num() && !LocallyGrippedObjects.Num())) + return false; + + FBPActorGripInformation * GripInfo = LocallyGrippedObjects.FindByKey(ComponentToMove); + if (!GripInfo) + GrippedObjects.FindByKey(ComponentToMove); + + if (GripInfo) + { + return TeleportMoveGrip(*GripInfo, bTeleportPhysicsGrips); + } + + return false; +} + +void UGripMotionControllerComponent::TeleportMoveGrips(bool bTeleportPhysicsGrips, bool bIsForPostTeleport) +{ + FTransform EmptyTransform = FTransform::Identity; + for (FBPActorGripInformation& GripInfo : LocallyGrippedObjects) + { + TeleportMoveGrip_Impl(GripInfo, bTeleportPhysicsGrips, bIsForPostTeleport, EmptyTransform); + } + + for (FBPActorGripInformation& GripInfo : GrippedObjects) + { + TeleportMoveGrip_Impl(GripInfo, bTeleportPhysicsGrips, bIsForPostTeleport, EmptyTransform); + } +} + +bool UGripMotionControllerComponent::TeleportMoveGrip(FBPActorGripInformation &Grip, bool bTeleportPhysicsGrips, bool bIsForPostTeleport) +{ + FTransform EmptyTransform = FTransform::Identity; + return TeleportMoveGrip_Impl(Grip, bTeleportPhysicsGrips, bIsForPostTeleport, EmptyTransform); +} + +bool UGripMotionControllerComponent::TeleportMoveGrip_Impl(FBPActorGripInformation &Grip, bool bTeleportPhysicsGrips, bool bIsForPostTeleport, FTransform & OptionalTransform) +{ + bool bHasMovementAuthority = HasGripMovementAuthority(Grip); + + if (!bHasMovementAuthority) + return false; + + UPrimitiveComponent * PrimComp = NULL; + AActor * actor = NULL; + + // Check if either implements the interface + bool bRootHasInterface = false; + bool bActorHasInterface = false; + + switch (Grip.GripTargetType) + { + case EGripTargetType::ActorGrip: + //case EGripTargetType::InteractibleActorGrip: + { + actor = Grip.GetGrippedActor(); + if (actor) + { + PrimComp = Cast(actor->GetRootComponent()); + if (actor->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + bActorHasInterface = true; + } + } + }break; + + case EGripTargetType::ComponentGrip: + //case EGripTargetType::InteractibleComponentGrip: + { + PrimComp = Grip.GetGrippedComponent(); + + if (PrimComp) + { + actor = PrimComp->GetOwner(); + if (PrimComp->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + bRootHasInterface = true; + } + } + + }break; + + } + + if (!PrimComp || !actor || !IsValid(actor) || !IsValid(PrimComp)) + return false; + + // Only use with actual teleporting + + EGripInterfaceTeleportBehavior TeleportBehavior = EGripInterfaceTeleportBehavior::TeleportAllComponents; + bool bSimulateOnDrop = false; + + // Check for interaction interface + if (bRootHasInterface) + { + TeleportBehavior = IVRGripInterface::Execute_TeleportBehavior(PrimComp); + bSimulateOnDrop = IVRGripInterface::Execute_SimulateOnDrop(PrimComp); + } + else if (bActorHasInterface) + { + // Actor grip interface is checked after component + TeleportBehavior = IVRGripInterface::Execute_TeleportBehavior(actor); + bSimulateOnDrop = IVRGripInterface::Execute_SimulateOnDrop(actor); + } + + if (bIsForPostTeleport) + { + if (TeleportBehavior == EGripInterfaceTeleportBehavior::OnlyTeleportRootComponent) + { + if (AActor * owner = PrimComp->GetOwner()) + { + if (PrimComp != owner->GetRootComponent()) + { + return false; + } + } + } + else if (TeleportBehavior == EGripInterfaceTeleportBehavior::DropOnTeleport) + { + if (IsServer() || + Grip.GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive || + Grip.GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep) + { + DropObjectByInterface(nullptr, Grip.GripID); + } + + return false; // Didn't teleport + } + else if (TeleportBehavior == EGripInterfaceTeleportBehavior::DontTeleport) + { + return false; // Didn't teleport + } + } + else + { + switch (TeleportBehavior) + { + case EGripInterfaceTeleportBehavior::DontTeleport: + case EGripInterfaceTeleportBehavior::DropOnTeleport: + { + return false; + }break; + default:break; + } + } + + // We don't teleport these two grip types at all + if (Grip.GripCollisionType == EGripCollisionType::AttachmentGrip || Grip.GripCollisionType == EGripCollisionType::EventsOnly) + { + return false; + } + + FTransform WorldTransform; + FTransform ParentTransform = GetPivotTransform(); + + FBPActorGripInformation copyGrip = Grip; + + if (!OptionalTransform.Equals(FTransform::Identity)) + { + WorldTransform = OptionalTransform; + } + else + { + TArray Scripts; + + if (bRootHasInterface) + { + IVRGripInterface::Execute_GetGripScripts(PrimComp, Scripts); + } + else if (bActorHasInterface) + { + IVRGripInterface::Execute_GetGripScripts(actor, Scripts); + } + + bool bForceADrop = false; + bool bHadValidWorldTransform = GetGripWorldTransform(Scripts, 0.0f, WorldTransform, ParentTransform, copyGrip, actor, PrimComp, bRootHasInterface, bActorHasInterface, true, bForceADrop); + + if (!bHadValidWorldTransform) + return false; + } + + if (!WorldTransform.IsValid()) + { + UE_LOG(LogVRMotionController, Warning, TEXT("Something went wrong, TeleportGrip_Impl's target transform contained NAN.")); + return false; + } + + // Saving this out prior as we are still setting our physics thread to the correct value, the delta is only applied to the object + FTransform physicsTrans = WorldTransform; + if (TeleportBehavior == EGripInterfaceTeleportBehavior::DeltaTeleportation && !Grip.LastWorldTransform.Equals(FTransform::Identity)) + { + FTransform baseTrans = this->GetAttachParent()->GetComponentTransform(); + WorldTransform = Grip.LastWorldTransform * baseTrans; + + //physicsTrans = WorldTransform; + + // Cancel out all other holding controllers teleport operations, we hit first + if (!Grip.bSkipNextTeleportCheck && (bRootHasInterface || bActorHasInterface)) + { + TArray HoldingControllers; + bool bIsHeld = false; + IVRGripInterface::Execute_IsHeld(Grip.GrippedObject, HoldingControllers, bIsHeld); + + for (FBPGripPair pair : HoldingControllers) + { + if (pair.HoldingController && pair.HoldingController != this && pair.HoldingController->bIsPostTeleport) + { + FBPActorGripInformation* pGrip = pair.HoldingController->GetGripPtrByID(pair.GripID); + + if (pGrip) + { + pGrip->bSkipNextTeleportCheck = true; + } + } + } + } + } + + // Run some error checks and logging against the resulting transform + if (!WorldTransform.IsValid()) + { + if (WorldTransform.ContainsNaN()) + { + UE_LOG(LogVRMotionController, Error, TEXT("Failed to teleport grip, bad transform, NaN detected with object: %s"), *Grip.GrippedObject->GetName()); + return false; + } + else if (!WorldTransform.GetRotation().IsNormalized()) + { + WorldTransform.NormalizeRotation(); + + if (!WorldTransform.IsValid()) + { + UE_LOG(LogVRMotionController, Error, TEXT("Failed to teleport grip, bad transform, rotation normalization issue: %s"), *Grip.GrippedObject->GetName()); + return false; + } + else + { + UE_LOG(LogVRMotionController, Error, TEXT("Error during teleport grip, rotation not normalized for object: %s"), *Grip.GrippedObject->GetName()); + } + } + } + + // Need to use WITH teleport for this function so that the velocity isn't updated and without sweep so that they don't collide + FBPActorPhysicsHandleInformation * Handle = GetPhysicsGrip(Grip); + + if (!Handle) + { + PrimComp->SetWorldTransform(WorldTransform, bSweepGripTeleports, nullptr, ETeleportType::TeleportPhysics); + } + else if (Handle && FPhysicsInterface::IsValid(Handle->KinActorData2) && bTeleportPhysicsGrips) + { + + // Don't try to autodrop on next tick, let the physx constraint update its local frame first + if (HasGripAuthority(Grip)) + Grip.bSkipNextConstraintLengthCheck = true; + + if (Grip.bSkipNextTeleportCheck) + { + Grip.bSkipNextTeleportCheck = false; + } + else + { + PrimComp->SetWorldTransform(WorldTransform, bSweepGripTeleports, nullptr, ETeleportType::TeleportPhysics); + } + + // Zero out our scale now that we are working outside of physx + physicsTrans.SetScale3D(FVector(1.0f)); + + if (Grip.bIsLerping || !bConstrainToPivot) + { + FBodyInstance* pInstance = PrimComp->GetBodyInstance(); + FPhysicsActorHandle ActorHandle = Handle->KinActorData2; + FTransform newTrans = Handle->COMPosition * (Handle->RootBoneRotation * physicsTrans); + if (pInstance && pInstance->IsValidBodyInstance()) + { + if (FPhysScene* PhysicalScene = pInstance->GetPhysicsScene()) + { + //FPhysicsCommand::ExecuteWrite(ActorHandle, [&](const FPhysicsActorHandle& Actor) + FPhysicsCommand::ExecuteWrite(PhysicalScene, [&]() + { + if (FPhysicsInterface::IsValid(ActorHandle)) + { + FPhysicsInterface::SetKinematicTarget_AssumesLocked(ActorHandle, newTrans); + FPhysicsInterface::SetGlobalPose_AssumesLocked(ActorHandle, newTrans); + } + }); + } + } + } + } + + // TMP #TODO: Remove with 5.4 bug with velocity is fixed + // Reset our last world transform velocity as typically we don't want to accumulate teleport speeds into it. + Grip.LastVelWorldTrans = PrimComp->GetComponentTransform(); + + return true; +} + +void UGripMotionControllerComponent::PostTeleportMoveGrippedObjects() +{ + if (!GrippedObjects.Num() && !LocallyGrippedObjects.Num()) + return; + + this->bIsPostTeleport = true; +} + + +void UGripMotionControllerComponent::Deactivate() +{ + Super::Deactivate(); + + if (IsActive() == false && GripViewExtension.IsValid()) + { + { + // This component could be getting accessed from the render thread so it needs to wait + // before clearing MotionControllerComponent + FScopeLock ScopeLock(&CritSect); + GripViewExtension->MotionControllerComponent = NULL; + } + + GripViewExtension.Reset(); + } +} + +void UGripMotionControllerComponent::OnAttachmentChanged() +{ + if (AVRCharacter* CharacterOwner = Cast(this->GetOwner())) + { + AttachChar = CharacterOwner; + } + else + { + AttachChar = nullptr; + } + + Super::OnAttachmentChanged(); +} + +void UGripMotionControllerComponent::OnRep_ReplicatedControllerTransform() +{ + //ReplicatedControllerTransform.Unpack(); + + if (IsServer() && HasTrackingParameters()) + { + // Ensure that the client is sending valid boundries + ApplyTrackingParameters(ReplicatedControllerTransform.Position, true, false); + } + + if (bSmoothReplicatedMotion) + { + if (bReppedOnce) + { + bLerpingPosition = true; + ControllerNetUpdateCount = 0.0f; + LastUpdatesRelativePosition = this->GetRelativeLocation(); + LastUpdatesRelativeRotation = this->GetRelativeRotation(); + + if (bUseExponentialSmoothing) + { + FVector OldToNewVector = ReplicatedControllerTransform.Position - LastUpdatesRelativePosition; + float NewDistance = OldToNewVector.SizeSquared(); + + // Too far, snap to the new value + if (NewDistance >= FMath::Square(NetworkNoSmoothUpdateDistance)) + { + SetRelativeLocationAndRotation(ReplicatedControllerTransform.Position, ReplicatedControllerTransform.Rotation); + bLerpingPosition = false; + } + // Outside of the buffer distance, snap within buffer and keep smoothing from there + else if (NewDistance >= FMath::Square(NetworkMaxSmoothUpdateDistance)) + { + FVector Offset = (OldToNewVector.Size() - NetworkMaxSmoothUpdateDistance) * OldToNewVector.GetSafeNormal(); + SetRelativeLocation(LastUpdatesRelativePosition + Offset); + } + } + } + else + { + SetRelativeLocationAndRotation(ReplicatedControllerTransform.Position, ReplicatedControllerTransform.Rotation); + bReppedOnce = true; + } + } + else + SetRelativeLocationAndRotation(ReplicatedControllerTransform.Position, ReplicatedControllerTransform.Rotation); +} + +void UGripMotionControllerComponent::UpdateTracking(float DeltaTime) +{ + // Server/remote clients don't set the controller position in VR + // Don't call positional checks and don't create the late update scene view + if (bHasAuthority) + { + if (bOffsetByControllerProfile && !NewControllerProfileEvent_Handle.IsValid()) + { + GetCurrentProfileTransform(true); + } + + FVector Position = GetRelativeLocation(); + FRotator Orientation = GetRelativeRotation(); + + if (!bUseWithoutTracking) + { + if (!GripViewExtension.IsValid() && GEngine) + { + GripViewExtension = FSceneViewExtensions::NewExtension(this); + } + + float WorldToMeters = GetWorld() ? GetWorld()->GetWorldSettings()->WorldToMeters : 100.0f; + ETrackingStatus LastTrackingStatus = CurrentTrackingStatus; + const bool bNewTrackedState = GripPollControllerState_GameThread(Position, Orientation, bProvidedLinearVelocity, LinearVelocity, bProvidedAngularVelocity, AngularVelocityAsAxisAndLength, bProvidedLinearAcceleration, LinearAcceleration, WorldToMeters); + + // if controller tracking just kicked in or we haven't started rendering in the (possibly present) + // visualization component. + if (!bTracked && bNewTrackedState) + { + OnActivateVisualizationComponent.Broadcast(true); + } + + + bTracked = bNewTrackedState && (bIgnoreTrackingStatus || CurrentTrackingStatus != ETrackingStatus::NotTracked); + if (bTracked) + { + if (bSmoothHandTracking) + { + FTransform CalcedTransform = FTransform(Orientation, Position, this->GetRelativeScale3D()); + + if (bSmoothWithEuroLowPassFunction) + { + SetRelativeTransform(EuroSmoothingParams.RunFilterSmoothing(CalcedTransform, DeltaTime)); + } + else + { + if (SmoothingSpeed <= 0.f || LastSmoothRelativeTransform.Equals(FTransform::Identity)) + { + SetRelativeTransform(CalcedTransform); + LastSmoothRelativeTransform = CalcedTransform; + } + else + { + const float Alpha = FMath::Clamp(DeltaTime * SmoothingSpeed, 0.f, 1.f); + LastSmoothRelativeTransform.Blend(LastSmoothRelativeTransform, CalcedTransform, Alpha); + SetRelativeTransform(LastSmoothRelativeTransform); + } + } + + bWasSmoothingHand = true; + } + else + { + if (bWasSmoothingHand) + { + // Clear the smoothing information so that we start with a fresh log when its enabled again + LastSmoothRelativeTransform = FTransform::Identity; + EuroSmoothingParams.ResetSmoothingFilter(); + + bWasSmoothingHand = false; + } + + SetRelativeTransform(FTransform(Orientation, Position, this->GetRelativeScale3D())); + } + } + + // if controller tracking just changed + if (LastTrackingStatus != CurrentTrackingStatus) + { + OnTrackingChanged.Broadcast(CurrentTrackingStatus); + } + } + + if (!bTracked && !bUseWithoutTracking) + return; // Don't update anything including location + + // Don't bother with any of this if not replicating transform + if (GetIsReplicated() && (bTracked || bReplicateWithoutTracking)) + { + FVector RelLoc = GetRelativeLocation(); + FRotator RelRot = GetRelativeRotation(); + + // Don't rep if no changes + if (!RelLoc.Equals(ReplicatedControllerTransform.Position) || !RelRot.Equals(ReplicatedControllerTransform.Rotation)) + { + ControllerNetUpdateCount += DeltaTime; + if (ControllerNetUpdateCount >= (1.0f / ControllerNetUpdateRate)) + { + ControllerNetUpdateCount = 0.0f; + + // Tracked doesn't matter, already set the relative location above in that case + ReplicatedControllerTransform.Position = RelLoc; + ReplicatedControllerTransform.Rotation = RelRot; + +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, ReplicatedControllerTransform, this); +#endif + + // I would keep the torn off check here, except this can be checked on tick if they + // Set 100 htz updates, and in the TornOff case, it actually can't hurt any besides some small + // Perf difference. + if (!IsServer()/* && !IsTornOff()*/) + { + AVRBaseCharacter* OwningChar = Cast(GetOwner()); + if (OverrideSendTransform != nullptr && OwningChar != nullptr) + { + (OwningChar->* (OverrideSendTransform))(ReplicatedControllerTransform); + } + else + Server_SendControllerTransform(ReplicatedControllerTransform); + } + } + } + } + } + else + { + // Clear the view extension if active after unpossessing, just in case + if (GripViewExtension.IsValid()) + { + { + // This component could be getting accessed from the render thread so it needs to wait + // before clearing MotionControllerComponent and allowing the destructor to continue + FScopeLock ScopeLock(&CritSect); + GripViewExtension->MotionControllerComponent = NULL; + } + + GripViewExtension.Reset(); + } + + // Run any networked smoothing + RunNetworkedSmoothing(DeltaTime); + } +} + +void UGripMotionControllerComponent::RunNetworkedSmoothing(float DeltaTime) +{ + if (bLerpingPosition) + { + if (!bUseExponentialSmoothing) + { + ControllerNetUpdateCount += DeltaTime; + float LerpVal = FMath::Clamp(ControllerNetUpdateCount / (1.0f / ControllerNetUpdateRate), 0.0f, 1.0f); + + if (LerpVal >= 1.0f) + { + SetRelativeLocationAndRotation(ReplicatedControllerTransform.Position, ReplicatedControllerTransform.Rotation); + + // Stop lerping, wait for next update if it is delayed or lost then it will hitch here + // Actual prediction might be something to consider in the future, but rough to do in VR + // considering the speed and accuracy of movements + // would like to consider sub stepping but since there is no server rollback...not sure how useful it would be + // and might be perf taxing enough to not make it worth it. + bLerpingPosition = false; + ControllerNetUpdateCount = 0.0f; + } + else + { + // Removed variables to speed this up a bit + SetRelativeLocationAndRotation( + FMath::Lerp(LastUpdatesRelativePosition, (FVector)ReplicatedControllerTransform.Position, LerpVal), + FMath::Lerp(LastUpdatesRelativeRotation, ReplicatedControllerTransform.Rotation, LerpVal) + ); + } + } + else // Exponential Smoothing + { + if (InterpolationSpeed <= 0.f) + { + SetRelativeLocationAndRotation((FVector)ReplicatedControllerTransform.Position, ReplicatedControllerTransform.Rotation); + bLerpingPosition = false; + return; + } + + const float Alpha = FMath::Clamp(DeltaTime * InterpolationSpeed, 0.f, 1.f); + + FTransform NA = FTransform(GetRelativeRotation(), GetRelativeLocation(), FVector(1.0f)); + FTransform NB = FTransform(ReplicatedControllerTransform.Rotation, (FVector)ReplicatedControllerTransform.Position, FVector(1.0f)); + NA.NormalizeRotation(); + NB.NormalizeRotation(); + + NA.Blend(NA, NB, Alpha); + + // If we are nearly equal then snap to final position + if (NA.EqualsNoScale(NB)) + { + SetRelativeLocationAndRotation(ReplicatedControllerTransform.Position, ReplicatedControllerTransform.Rotation); + bLerpingPosition = false; + } + else // Else just keep going + { + SetRelativeLocationAndRotation(NA.GetTranslation(), NA.Rotator()); + } + } + } +} + +void UGripMotionControllerComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) +{ + // Skip if we are traveling + if (IsTravelingOrNullWorld()) + return; + + // Skip motion controller tick, we override a lot of things that it does and we don't want it to perform the same functions + Super::Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + if (!IsActive()) + return; + + // Moved this here instead of in the polling function, it was ticking once per frame anyway so no loss of perf + // It doesn't need to be there and now I can pre-check + // Also epics implementation in the polling function didn't work anyway as it was based off of playercontroller which is not the owner of this controller + + // Cache state from the game thread for use on the render thread + // No need to check if in game thread here as tick always is + bHasAuthority = IsLocallyControlled(); + + // No longer updating in character, was a waste as it wouldn't scope this component anyway + UpdateTracking(DeltaTime); + + /*if (!bUpdateInCharacterMovement) + { + UpdateTracking(DeltaTime); + } + else if (AttachChar.IsValid()) + { + UCharacterMovementComponent* CharMove = AttachChar->GetCharacterMovement(); + if (!CharMove || !CharMove->IsComponentTickEnabled() || !CharMove->IsActive() || (GetWorld()->IsPaused() && !AttachChar->GetCharacterMovement()->PrimaryComponentTick.bTickEvenWhenPaused)) + { + // Our character movement isn't handling our updates, lets do it ourself. + UpdateTracking(DeltaTime); + } + }*/ + + // Process the gripped actors + TickGrip(DeltaTime); +} + +bool UGripMotionControllerComponent::GetGripWorldTransform(TArray& GripScripts, float DeltaTime, FTransform & WorldTransform, const FTransform &ParentTransform, FBPActorGripInformation &Grip, AActor * actor, UPrimitiveComponent * root, bool bRootHasInterface, bool bActorHasInterface, bool bIsForTeleport, bool &bForceADrop) +{ + SCOPE_CYCLE_COUNTER(STAT_GetGripTransform); + + bool bHasValidTransform = true; + + if (GripScripts.Num()) + { + bool bGetDefaultTransform = true; + + // Get grip script world transform overrides (if there are any) + for (UVRGripScriptBase* Script: GripScripts) + { + if (Script && Script->IsScriptActive() && Script->GetWorldTransformOverrideType() == EGSTransformOverrideType::OverridesWorldTransform) + { + // One of the grip scripts overrides the default transform + bGetDefaultTransform = false; + break; + } + } + + // If none of the scripts override the base transform + if (bGetDefaultTransform && DefaultGripScript) + { + bHasValidTransform = DefaultGripScript->CallCorrect_GetWorldTransform(this, DeltaTime, WorldTransform, ParentTransform, Grip, actor, root, bRootHasInterface, bActorHasInterface, bIsForTeleport); + bForceADrop = DefaultGripScript->Wants_ToForceDrop(); + } + + // Get grip script world transform modifiers (if there are any) + for (UVRGripScriptBase* Script : GripScripts) + { + if (Script && Script->IsScriptActive() && Script->GetWorldTransformOverrideType() != EGSTransformOverrideType::None) + { + bHasValidTransform = Script->CallCorrect_GetWorldTransform(this, DeltaTime, WorldTransform, ParentTransform, Grip, actor, root, bRootHasInterface, bActorHasInterface, bIsForTeleport); + bForceADrop = Script->Wants_ToForceDrop(); + + // Early out, one of the scripts is telling us that the transform isn't valid, something went wrong or the grip is flagged for drop + if (!bHasValidTransform || bForceADrop) + break; + } + } + } + else + { + if (DefaultGripScript) + { + bHasValidTransform = DefaultGripScript->CallCorrect_GetWorldTransform(this, DeltaTime, WorldTransform, ParentTransform, Grip, actor, root, bRootHasInterface, bActorHasInterface, bIsForTeleport); + bForceADrop = DefaultGripScript->Wants_ToForceDrop(); + } + } + + HandleGlobalLerpToHand(Grip, WorldTransform, DeltaTime); + + if (bHasValidTransform && !WorldTransform.IsValid()) + { + UE_LOG(LogVRMotionController, Warning, TEXT("Something went wrong, GetGripWorldTransform tried to return NAN!.")); + bHasValidTransform = false; + } + + return bHasValidTransform; +} + +void UGripMotionControllerComponent::TickGrip(float DeltaTime) +{ + SCOPE_CYCLE_COUNTER(STAT_TickGrip); + + // Debug test that we aren't floating physics handles + if (PhysicsGrips.Num() > (GrippedObjects.Num() + LocallyGrippedObjects.Num())) + { + CleanUpBadPhysicsHandles(); + UE_LOG(LogVRMotionController, Warning, TEXT("Something went wrong, there were too many physics handles for how many grips exist! Cleaned up bad handles.")); + } + //check(PhysicsGrips.Num() <= (GrippedObjects.Num() + LocallyGrippedObjects.Num())); + + FTransform ParentTransform = GetPivotTransform(); + + // Check for floating server sided client auth grips and handle them if we need too + if(!IsServer()) + CheckTransactionBuffer(); + + bool bOriginalPostTeleport = bIsPostTeleport; + + // Split into separate functions so that I didn't have to combine arrays since I have some removal going on + HandleGripArray(GrippedObjects, ParentTransform, DeltaTime, true); + HandleGripArray(LocallyGrippedObjects, ParentTransform, DeltaTime); + + // Empty out the teleport flag, checking original state just in case the player changed it while processing bps + if (bOriginalPostTeleport) + { + if ((GrippedObjects.Num() || LocallyGrippedObjects.Num())) + { + OnTeleportedGrips.Broadcast(); + } + + bIsPostTeleport = false; + } + + // Save out the component velocity from this and last frame + + FVector newVelocitySample = ((bSampleVelocityInWorldSpace ? GetComponentLocation() : GetRelativeLocation()) - LastRelativePosition.GetTranslation()) / DeltaTime; + + switch (VelocityCalculationType) + { + case EVRVelocityType::VRLOCITY_Default: + { + ComponentVelocity = newVelocitySample; + }break; + case EVRVelocityType::VRLOCITY_RunningAverage: + { + UVRExpansionFunctionLibrary::LowPassFilter_RollingAverage(ComponentVelocity, newVelocitySample, ComponentVelocity, VelocitySamples); + }break; + case EVRVelocityType::VRLOCITY_SamplePeak: + { + if (PeakFilter.VelocitySamples != VelocitySamples) + PeakFilter.VelocitySamples = VelocitySamples; + UVRExpansionFunctionLibrary::UpdatePeakLowPassFilter(PeakFilter, newVelocitySample); + }break; + } + + // #TODO: + // Relative angular velocity too? + // Maybe add some running averaging here to make it work across frames? + // Or Valves 30 frame high point average buffer + LastRelativePosition = bSampleVelocityInWorldSpace ? this->GetComponentTransform() : this->GetRelativeTransform(); +} + +FVector UGripMotionControllerComponent::GetComponentVelocity() const +{ + if(VelocityCalculationType == EVRVelocityType::VRLOCITY_SamplePeak) + { + return PeakFilter.GetPeak(); + } + + return Super::GetComponentVelocity(); +} + +// TEMP: #TODO: Remove +void UGripMotionControllerComponent::CalculateGripVelocity(FBPActorGripInformation& GripToFill, UPrimitiveComponent* ComponentToSample, float DeltaTime) +{ + if (!bHasAuthority && !IsServer()) + { + return; + } + + FTransform CurTrans = ComponentToSample->GetComponentTransform(); + + GripToFill.LinVel = (CurTrans.GetLocation() - GripToFill.LastVelWorldTrans.GetLocation()) / DeltaTime; + GripToFill.RotVel = FVector::RadiansToDegrees(((CurTrans.GetRotation().ToRotationVector() - GripToFill.LastVelWorldTrans.GetRotation().ToRotationVector()))) / DeltaTime; + + GripToFill.LastVelWorldTrans = CurTrans; +} + +void UGripMotionControllerComponent::HandleGripArray(TArray &GrippedObjectsArray, const FTransform & ParentTransform, float DeltaTime, bool bReplicatedArray) +{ + if (GrippedObjectsArray.Num()) + { + FTransform WorldTransform; + + for (int i = GrippedObjectsArray.Num() - 1; i >= 0; --i) + { + if (!HasGripMovementAuthority(GrippedObjectsArray[i])) + continue; + + FBPActorGripInformation * Grip = &GrippedObjectsArray[i]; + + if (!Grip) // Shouldn't be possible, but why not play it safe + continue; + + // Double checking here for a failed rep due to out of order replication from a spawned actor + if (!Grip->ValueCache.bWasInitiallyRepped && !HasGripAuthority(*Grip) && !HandleGripReplication(*Grip)) + continue; // If we didn't successfully handle the replication (out of order) then continue on. + + if (Grip->IsValid()) + { + // Continue if the grip is paused + if (Grip->bIsPaused) + continue; + + if (Grip->GripCollisionType == EGripCollisionType::EventsOnly) + continue; // Earliest safe spot to continue at, we needed to check if the object is pending kill or invalid first + + UPrimitiveComponent *root = NULL; + AActor *actor = NULL; + + // Getting the correct variables depending on the grip target type + switch (Grip->GripTargetType) + { + case EGripTargetType::ActorGrip: + //case EGripTargetType::InteractibleActorGrip: + { + actor = Grip->GetGrippedActor(); + if(actor) + root = Cast(actor->GetRootComponent()); + }break; + + case EGripTargetType::ComponentGrip: + //case EGripTargetType::InteractibleComponentGrip : + { + root = Grip->GetGrippedComponent(); + if(root) + actor = root->GetOwner(); + }break; + + default:break; + } + + // Last check to make sure the variables are valid + if (!root || !actor || !IsValid(root) || !IsValid(actor)) + continue; + + // Keep checking for pending kill on gripped objects, and ptr removals, but don't run grip logic when seamless + // traveling, to avoid physx scene issues. + if (GetWorld()->IsInSeamlessTravel()) + { + continue; + } + + // Check if either implements the interface + bool bRootHasInterface = false; + bool bActorHasInterface = false; + + if (root->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + bRootHasInterface = true; + } + else if (actor->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + // Actor grip interface is checked after component + bActorHasInterface = true; + } + + if (Grip->GripCollisionType == EGripCollisionType::CustomGrip) + { + // Don't perform logic on the movement for this object, just pass in the GripTick() event with the controller difference instead + if(bRootHasInterface) + IVRGripInterface::Execute_TickGrip(root, this, *Grip, DeltaTime); + else if(bActorHasInterface) + IVRGripInterface::Execute_TickGrip(actor, this, *Grip, DeltaTime); + + // TEMP 5.4 (or fixed) + CalculateGripVelocity(*Grip, root, DeltaTime); + continue; + } + + bool bRescalePhysicsGrips = false; + + TArray GripScripts; + + if (bRootHasInterface) + { + IVRGripInterface::Execute_GetGripScripts(root, GripScripts); + } + else if (bActorHasInterface) + { + IVRGripInterface::Execute_GetGripScripts(actor, GripScripts); + } + + + bool bForceADrop = false; + + // Get the world transform for this grip after handling secondary grips and interaction differences + bool bHasValidWorldTransform = GetGripWorldTransform(GripScripts, DeltaTime, WorldTransform, ParentTransform, *Grip, actor, root, bRootHasInterface, bActorHasInterface, false, bForceADrop); + + // If a script or behavior is telling us to skip this and continue on (IE: it dropped the grip) + if (bForceADrop) + { + if (HasGripAuthority(*Grip)) + { + if (bRootHasInterface) + DropGrip_Implementation(*Grip, IVRGripInterface::Execute_SimulateOnDrop(root)); + else if (bActorHasInterface) + DropGrip_Implementation(*Grip, IVRGripInterface::Execute_SimulateOnDrop(actor)); + else + DropGrip_Implementation(*Grip, true); + } + + continue; + } + else if (!bHasValidWorldTransform) + { + continue; + } + + if (Grip->GrippedBoneName == NAME_None && !root->GetComponentTransform().GetScale3D().Equals(WorldTransform.GetScale3D())) + bRescalePhysicsGrips = true; + + // If we just teleported, skip this update and just teleport forward + if (bIsPostTeleport) + { + + bool bSkipTeleport = false; + for (UVRGripScriptBase* Script : GripScripts) + { + if (Script && Script->IsScriptActive() && Script->Wants_DenyTeleport(this)) + { + bSkipTeleport = true; + break; + } + } + + + if (!bSkipTeleport) + { + TeleportMoveGrip_Impl(*Grip, true, true, WorldTransform); + continue; + } + } + else + { + //Grip->LastWorldTransform = WorldTransform; + } + + // Auto drop based on distance from expected point + // Not perfect, should be done post physics or in next frame prior to changing controller location + // However I don't want to recalculate world transform + // Maybe add a grip variable of "expected loc" and use that to check next frame, but for now this will do. + if ((bRootHasInterface || bActorHasInterface) && + ( + (Grip->GripCollisionType != EGripCollisionType::AttachmentGrip) && + (Grip->GripCollisionType != EGripCollisionType::PhysicsOnly) && + (Grip->GripCollisionType != EGripCollisionType::SweepWithPhysics)) && + ((Grip->GripCollisionType != EGripCollisionType::InteractiveHybridCollisionWithSweep) || ((Grip->GripCollisionType == EGripCollisionType::InteractiveHybridCollisionWithSweep) && Grip->bColliding)) + ) + { + + // After initial teleportation the constraint local pose can be not updated yet, so lets delay a frame to let it update + // Otherwise may cause unintended auto drops + if (Grip->bSkipNextConstraintLengthCheck) + { + Grip->bSkipNextConstraintLengthCheck = false; + } + else + { + float BreakDistance = 0.0f; + if (bRootHasInterface) + { + BreakDistance = IVRGripInterface::Execute_GripBreakDistance(root); + } + else if (bActorHasInterface) + { + // Actor grip interface is checked after component + BreakDistance = IVRGripInterface::Execute_GripBreakDistance(actor); + } + + FVector CheckDistance; + if (!GetPhysicsJointLength(*Grip, root, CheckDistance)) + { + CheckDistance = (WorldTransform.GetLocation() - root->GetComponentLocation()); + } + + // Set grip distance now for people to use + Grip->GripDistance = CheckDistance.Size(); + + if (BreakDistance > 0.0f) + { + if (Grip->GripDistance >= BreakDistance) + { + bool bIgnoreDrop = false; + for (UVRGripScriptBase* Script : GripScripts) + { + if (Script && Script->IsScriptActive() && Script->Wants_DenyAutoDrop()) + { + bIgnoreDrop = true; + break; + } + } + + if (bIgnoreDrop) + { + // Script canceled this out + } + else if (OnGripOutOfRange.IsBound()) + { + uint8 GripID = Grip->GripID; + OnGripOutOfRange.Broadcast(*Grip, Grip->GripDistance); + + // Check if we still have the grip or not + FBPActorGripInformation GripInfo; + EBPVRResultSwitch Result; + GetGripByID(GripInfo, GripID, Result); + if (Result == EBPVRResultSwitch::OnFailed) + { + // Don't bother moving it, it is dropped now + continue; + } + } + else if(HasGripAuthority(*Grip)) + { + if(bRootHasInterface) + DropGrip_Implementation(*Grip, IVRGripInterface::Execute_SimulateOnDrop(root)); + else + DropGrip_Implementation(*Grip, IVRGripInterface::Execute_SimulateOnDrop(actor)); + + // Don't bother moving it, it is dropped now + continue; + } + } + } + } + } + + // Start handling the grip types and their functions + switch (Grip->GripCollisionType) + { + case EGripCollisionType::InteractiveCollisionWithPhysics: + case EGripCollisionType::LockedConstraint: + { + UpdatePhysicsHandleTransform(*Grip, WorldTransform); + + if (bRescalePhysicsGrips) + root->SetWorldScale3D(WorldTransform.GetScale3D()); + + + // Sweep current collision state, only used for client side late update removal + if ( + (bHasAuthority && !this->bDisableLowLatencyUpdate && + ((Grip->GripLateUpdateSetting == EGripLateUpdateSettings::NotWhenColliding) || + (Grip->GripLateUpdateSetting == EGripLateUpdateSettings::NotWhenCollidingOrDoubleGripping))) + ) + { + //TArray Hits; + FComponentQueryParams Params(NAME_None, this->GetOwner()); + //Params.bTraceAsyncScene = root->bCheckAsyncSceneOnMove; + Params.AddIgnoredActor(actor); + Params.AddIgnoredActors(root->MoveIgnoreActors); + + actor->ForEachAttachedActors([&Params](AActor* Actor) + { + Params.AddIgnoredActor(Actor); + return true; + }); + + TArray Hits; + + // Switched over to component sweep because it picks up on pivot offsets without me manually calculating it + if ( + GetWorld()->ComponentSweepMulti(Hits, root, root->GetComponentLocation(), WorldTransform.GetLocation(), WorldTransform.GetRotation(), Params) + ) + { + + // Check if the two components are ignoring collisions with each other + UCollisionIgnoreSubsystem* CollisionIgnoreSubsystem = GetWorld()->GetSubsystem(); + + if (CollisionIgnoreSubsystem->HasCollisionIgnorePairs()) + { + // Pre-set this so it falls back to false if none of these hits are valid + Grip->bColliding = false; + + for (const FHitResult& Hit : Hits) + { + if (Hit.bBlockingHit && !CollisionIgnoreSubsystem->AreComponentsIgnoringCollisions(root, Hit.Component.Get())) + { + Grip->bColliding = true; + break; + } + } + } + else + { + if (FHitResult::GetFirstBlockingHit(Hits) != nullptr) + { + Grip->bColliding = true; + } + } + } + else + { + Grip->bColliding = false; + } + } + + }break; + + case EGripCollisionType::InteractiveCollisionWithSweep: + { + FVector OriginalPosition(root->GetComponentLocation()); + FVector NewPosition(WorldTransform.GetTranslation()); + + if (!Grip->bIsLocked) + root->ComponentVelocity = (NewPosition - OriginalPosition) / DeltaTime; + + if (Grip->bIsLocked) + WorldTransform.SetRotation(Grip->LastLockedRotation); + + FHitResult OutHit; + // Need to use without teleport so that the physics velocity is updated for when the actor is released to throw + if (bProjectNonSimulatingGrips && !Grip->bIsLocked && Grip->bSetLastWorldTransform) + { + FScopedMovementUpdate ScopedMovementUpdate(root, EScopedUpdate::DeferredUpdates); + FTransform baseTrans = this->GetAttachParent()->GetComponentTransform(); + root->SetWorldTransform(Grip->LastWorldTransform * baseTrans, false, nullptr, ETeleportType::None); + root->SetWorldTransform(WorldTransform, true, &OutHit); + } + else + { + root->SetWorldTransform(WorldTransform, true, &OutHit); + } + + if (OutHit.bBlockingHit) + { + Grip->bColliding = true; + + if (!Grip->bIsLocked) + { + Grip->bIsLocked = true; + Grip->LastLockedRotation = root->GetComponentQuat(); + } + } + else + { + Grip->bColliding = false; + + if (Grip->bIsLocked) + Grip->bIsLocked = false; + } + }break; + + case EGripCollisionType::InteractiveHybridCollisionWithPhysics: + { + UpdatePhysicsHandleTransform(*Grip, WorldTransform); + + if (bRescalePhysicsGrips) + root->SetWorldScale3D(WorldTransform.GetScale3D()); + + // Always Sweep current collision state with this, used for constraint strength + //TArray Hits; + FComponentQueryParams Params(NAME_None, this->GetOwner()); + //Params.bTraceAsyncScene = root->bCheckAsyncSceneOnMove; + Params.AddIgnoredActor(actor); + Params.AddIgnoredActors(root->MoveIgnoreActors); + + actor->ForEachAttachedActors([&Params](AActor* Actor) + { + Params.AddIgnoredActor(Actor); + return true; + }); + + TArray Hits; + // Checking both current and next position for overlap using this grip type + // Switched over to component sweep because it picks up on pivot offsets without me manually calculating it + if (Grip->bLockHybridGrip) + { + if (!Grip->bColliding) + { + SetGripConstraintStiffnessAndDamping(Grip, false); + } + + Grip->bColliding = true; + } + else if (GetWorld()->ComponentSweepMulti(Hits, root, root->GetComponentLocation(), WorldTransform.GetLocation(), WorldTransform.GetRotation(), Params) && FHitResult::GetFirstBlockingHit(Hits) != nullptr) + { + // Assume true by default, will revert if checking ignored below + Grip->bColliding = true; + + // Check if the two components are ignoring collisions with each other + UCollisionIgnoreSubsystem* CollisionIgnoreSubsystem = GetWorld()->GetSubsystem(); + + if (CollisionIgnoreSubsystem->HasCollisionIgnorePairs()) + { + + bool bOriginalColliding = Grip->bColliding; + // Pre-set this so it falls back to false if none of these hits are valid + Grip->bColliding = false; + + for (const FHitResult& Hit : Hits) + { + if (Hit.bBlockingHit && !CollisionIgnoreSubsystem->AreComponentsIgnoringCollisions(root, Hit.Component.Get())) + { + if (!bOriginalColliding) + { + SetGripConstraintStiffnessAndDamping(Grip, false); + } + Grip->bColliding = true; + break; + } + } + + if (!Grip->bColliding) + { + if (bOriginalColliding) + { + SetGripConstraintStiffnessAndDamping(Grip, true); + } + } + + + } + else + { + if (!Grip->bColliding) + { + SetGripConstraintStiffnessAndDamping(Grip, false); + } + //Grip->bColliding = true; + } + } + else + { + if (Grip->bColliding) + { + SetGripConstraintStiffnessAndDamping(Grip, true); + } + + Grip->bColliding = false; + } + + }break; + + case EGripCollisionType::InteractiveHybridCollisionWithSweep: + { + + // Make sure that there is no collision on course before turning off collision and snapping to controller + FBPActorPhysicsHandleInformation * GripHandle = GetPhysicsGrip(*Grip); + + TArray Hits; + FComponentQueryParams Params(NAME_None, this->GetOwner()); + //Params.bTraceAsyncScene = root->bCheckAsyncSceneOnMove; + Params.AddIgnoredActor(actor); + Params.AddIgnoredActors(root->MoveIgnoreActors); + + actor->ForEachAttachedActors([&Params](AActor* Actor) + { + Params.AddIgnoredActor(Actor); + return true; + }); + + FTransform BaseTransform = root->GetComponentTransform(); + + if (bProjectNonSimulatingGrips && !Grip->bColliding && Grip->bSetLastWorldTransform) + { + FTransform baseTrans = this->GetAttachParent()->GetComponentTransform(); + BaseTransform = Grip->LastWorldTransform * baseTrans; + } + + bool bWasColliding = Grip->bColliding; + bool bLerpCollisions = false; + bool bLerpRotationOnly = false; + bool bDistanceBasedInterpolation = false; + float LerpSpeed = 0.0f; + const UVRGlobalSettings* VRSettings = GetDefault(); + + if (VRSettings) + { + bLerpCollisions = VRSettings->bLerpHybridWithSweepGrips; + LerpSpeed = VRSettings->HybridWithSweepLerpDuration; + bLerpRotationOnly = VRSettings->bOnlyLerpHybridRotation; + bDistanceBasedInterpolation = VRSettings->bHybridWithSweepUseDistanceBasedLerp; + } + + if (Grip->bLockHybridGrip) + { + Grip->bColliding = true; + } + // Check our target rotation + else if (GetWorld()->ComponentSweepMulti(Hits, root, BaseTransform.GetLocation(), WorldTransform.GetLocation(), WorldTransform.GetRotation(), Params) && FHitResult::GetFirstBlockingHit(Hits) != nullptr) + { + // Assume true by default, will revert if checking ignored below + Grip->bColliding = true; + + // Check if the two components are ignoring collisions with each other + UCollisionIgnoreSubsystem* CollisionIgnoreSubsystem = GetWorld()->GetSubsystem(); + if (CollisionIgnoreSubsystem->HasCollisionIgnorePairs()) + { + // Pre-set this so it falls back to false if none of these hits are valid + Grip->bColliding = false; + + for (const FHitResult& Hit : Hits) + { + if (Hit.bBlockingHit && !CollisionIgnoreSubsystem->AreComponentsIgnoringCollisions(root, Hit.Component.Get())) + { + Grip->bColliding = true; + break; + } + } + + // We need to also check the other rotation here as a fallback + if (bLerpCollisions && !Grip->bColliding) + { + if (bLerpCollisions && GetWorld()->ComponentSweepMulti(Hits, root, BaseTransform.GetLocation(), WorldTransform.GetLocation(), root->GetComponentRotation(), Params)) + { + for (const FHitResult& Hit : Hits) + { + if (Hit.bBlockingHit && !CollisionIgnoreSubsystem->AreComponentsIgnoringCollisions(root, Hit.Component.Get())) + { + Grip->bColliding = true; + break; + } + } + } + } + } + } + // Check the other rotation + else if (bLerpCollisions && GetWorld()->ComponentSweepMulti(Hits, root, BaseTransform.GetLocation(), WorldTransform.GetLocation(), root->GetComponentRotation(), Params) && FHitResult::GetFirstBlockingHit(Hits) != nullptr) + { + // Assume true by default, will revert if checking ignored below + Grip->bColliding = true; + + // Check if the two components are ignoring collisions with each other + UCollisionIgnoreSubsystem* CollisionIgnoreSubsystem = GetWorld()->GetSubsystem(); + + if (CollisionIgnoreSubsystem->HasCollisionIgnorePairs()) + { + // Pre-set this so it falls back to false if none of these hits are valid + Grip->bColliding = false; + + for (const FHitResult& Hit : Hits) + { + if (Hit.bBlockingHit && !CollisionIgnoreSubsystem->AreComponentsIgnoringCollisions(root, Hit.Component.Get())) + { + Grip->bColliding = true; + break; + } + } + } + } + else + { + Grip->bColliding = false; + } + + if (!Grip->bColliding) + { + if (GripHandle && !GripHandle->bIsPaused) + { + PausePhysicsHandle(GripHandle); + //DestroyPhysicsHandle(*Grip); + + switch (Grip->GripTargetType) + { + case EGripTargetType::ComponentGrip: + { + root->SetSimulatePhysics(false); + }break; + case EGripTargetType::ActorGrip: + { + root->SetSimulatePhysics(false); + //actor->DisableComponentsSimulatePhysics(); + } break; + } + } + + if (bLerpCollisions && !Grip->bIsLerping) + { + if (bWasColliding && !Grip->bIsLerping) + { + // Store relative transform and base movements off of lerping out of it to the target transform + + // Re-use this transform as it will let us not add additional variables + Grip->OnGripTransform = root->GetComponentTransform().GetRelativeTransform(this->GetPivotTransform()); + Grip->CurrentLerpTime = 1.0f; + Grip->LerpSpeed = (1.f / LerpSpeed); + + if (bDistanceBasedInterpolation) + { + // Just multiplying to make the values easier + Grip->LerpSpeed *= 10.0f; + Grip->CurrentLerpTime = LerpSpeed; + } + } + + if (Grip->CurrentLerpTime > 0.0f) + { + FTransform NB = (Grip->OnGripTransform * this->GetPivotTransform()); + float Alpha = 0.0f; + + if (bDistanceBasedInterpolation) + { + if (Grip->LerpSpeed <= 0.f) + { + Alpha = 1.0f; + Grip->CurrentLerpTime = 0.0f; + } + else + { + Grip->CurrentLerpTime = FMath::Clamp(Grip->CurrentLerpTime - DeltaTime, 0.0f, 1.0f); + Alpha = FMath::Clamp(DeltaTime * Grip->LerpSpeed, 0.f, 1.f); + } + + Alpha = FMath::Clamp(DeltaTime * Grip->LerpSpeed, 0.f, 1.f); + } + else + { + Grip->CurrentLerpTime -= DeltaTime * Grip->LerpSpeed; + float OrigAlpha = FMath::Clamp(1.0f - Grip->CurrentLerpTime, 0.f, 1.0f); + Alpha = OrigAlpha; + } + + FTransform NA = WorldTransform; + NA.NormalizeRotation(); + NB.NormalizeRotation(); + + if (!bLerpRotationOnly) + { + WorldTransform.Blend(NB, NA, Alpha); + } + else + { + WorldTransform.SetRotation(FQuat::Slerp(NB.GetRotation(), NA.GetRotation(), Alpha)); + } + + if (bDistanceBasedInterpolation) + { + if(NA.Equals(WorldTransform, 0.01f)) + { + Grip->CurrentLerpTime = 0.0f; + } + else + { + // Save out current distance back to the originating transform + Grip->OnGripTransform = WorldTransform.GetRelativeTransform(this->GetPivotTransform()); + } + } + } + } + + if (bProjectNonSimulatingGrips && Grip->bSetLastWorldTransform) + { + FScopedMovementUpdate ScopedMovementUpdate(root, EScopedUpdate::DeferredUpdates); + FTransform baseTrans = this->GetAttachParent()->GetComponentTransform(); + root->SetWorldTransform(Grip->LastWorldTransform * baseTrans, false, nullptr, ETeleportType::None); + root->SetWorldTransform(WorldTransform, false);// , &OutHit); + } + else + { + root->SetWorldTransform(WorldTransform, false);// , &OutHit); + } + + if (GripHandle) + { + UpdatePhysicsHandleTransform(*Grip, WorldTransform); + } + + } + else if (Grip->bColliding) + { + if (!GripHandle) + { + SetUpPhysicsHandle(*Grip, &GripScripts); + } + else if (GripHandle->bIsPaused) + { + UnPausePhysicsHandle(*Grip, GripHandle); + } + + if (GripHandle) + { + UpdatePhysicsHandleTransform(*Grip, WorldTransform); + if (bRescalePhysicsGrips) + root->SetWorldScale3D(WorldTransform.GetScale3D()); + } + } + else + { + // Shouldn't be a grip handle if not server when server side moving + if (GripHandle) + { + UpdatePhysicsHandleTransform(*Grip, WorldTransform); + if (bRescalePhysicsGrips) + root->SetWorldScale3D(WorldTransform.GetScale3D()); + } + } + + }break; + + case EGripCollisionType::SweepWithPhysics: + { + // Ensure physics simulation is off in case something sneaked it on + if (root->IsSimulatingPhysics()) + { + root->SetSimulatePhysics(false); + } + + FVector OriginalPosition(root->GetComponentLocation()); + FRotator OriginalOrientation(root->GetComponentRotation()); + + FVector NewPosition(WorldTransform.GetTranslation()); + FRotator NewOrientation(WorldTransform.GetRotation()); + + root->ComponentVelocity = (NewPosition - OriginalPosition) / DeltaTime; + + // Now sweep collision separately so we can get hits but not have the location altered + if (bUseWithoutTracking || NewPosition != OriginalPosition || NewOrientation != OriginalOrientation) + { + FVector move = NewPosition - OriginalPosition; + + // ComponentSweepMulti does nothing if moving < UE_KINDA_SMALL_NUMBER in distance, so it's important to not try to sweep distances smaller than that. + const float MinMovementDistSq = (FMath::Square(4.f*UE_KINDA_SMALL_NUMBER)); + + if (bUseWithoutTracking || move.SizeSquared() > MinMovementDistSq || NewOrientation != OriginalOrientation) + { + if (CheckComponentWithSweep(root, move, OriginalOrientation, false)) + { + Grip->bColliding = true; + } + else + { + Grip->bColliding = false; + } + + TArray PrimChildren; + root->GetChildrenComponents(true, PrimChildren); + for (USceneComponent * Prim : PrimChildren) + { + if (UPrimitiveComponent * primComp = Cast(Prim)) + { + CheckComponentWithSweep(primComp, move, primComp->GetComponentRotation(), false); + } + } + } + } + + if (bProjectNonSimulatingGrips && Grip->bSetLastWorldTransform) + { + FScopedMovementUpdate ScopedMovementUpdate(root, EScopedUpdate::DeferredUpdates); + FTransform baseTrans = this->GetAttachParent()->GetComponentTransform(); + root->SetWorldTransform(Grip->LastWorldTransform * baseTrans, false, nullptr, ETeleportType::None); + // Move the actor, we are not offsetting by the hit result anyway + root->SetWorldTransform(WorldTransform, false); + } + else + { + // Move the actor, we are not offsetting by the hit result anyway + root->SetWorldTransform(WorldTransform, false); + } + + }break; + + case EGripCollisionType::PhysicsOnly: + { + // Ensure physics simulation is off in case something sneaked it on + if (root->IsSimulatingPhysics()) + { + root->SetSimulatePhysics(false); + } + + if (bProjectNonSimulatingGrips && Grip->bSetLastWorldTransform) + { + FScopedMovementUpdate ScopedMovementUpdate(root, EScopedUpdate::DeferredUpdates); + FTransform baseTrans = this->GetAttachParent()->GetComponentTransform(); + root->SetWorldTransform(Grip->LastWorldTransform * baseTrans, false, nullptr, ETeleportType::None); + // Move the actor, we are not offsetting by the hit result anyway + root->SetWorldTransform(WorldTransform, false); + } + else + { + // Move the actor, we are not offsetting by the hit result anyway + root->SetWorldTransform(WorldTransform, false); + } + }break; + + case EGripCollisionType::AttachmentGrip: + { + FTransform RelativeTrans = WorldTransform.GetRelativeTransform(ParentTransform); + + if (!root->GetAttachParent() || root->IsSimulatingPhysics()) + { + UE_LOG(LogVRMotionController, Warning, TEXT("Attachment Grip was missing attach parent - Attempting to Re-attach")); + + if (HasGripMovementAuthority(*Grip) || IsServer()) + { + root->SetSimulatePhysics(false); + if (root->AttachToComponent(IsValid(CustomPivotComponent) ? CustomPivotComponent.Get() : this, FAttachmentTransformRules::KeepWorldTransform)) + { + UE_LOG(LogVRMotionController, Warning, TEXT("Re-attached")); + if (!root->GetRelativeTransform().Equals(RelativeTrans)) + { + root->SetRelativeTransform(RelativeTrans); + } + } + } + } + else + { + if (!root->GetRelativeTransform().Equals(RelativeTrans)) + { + root->SetRelativeTransform(RelativeTrans); + } + } + + }break; + + case EGripCollisionType::ManipulationGrip: + case EGripCollisionType::ManipulationGripWithWristTwist: + { + UpdatePhysicsHandleTransform(*Grip, WorldTransform); + if (bRescalePhysicsGrips) + root->SetWorldScale3D(WorldTransform.GetScale3D()); + + }break; + + default: + {}break; + } + + // TEMP 5.4 (or fixed) + CalculateGripVelocity(*Grip, root, DeltaTime); // Technically for physical grips it would be post physics thre + + // We only do this if specifically requested, it has a slight perf hit and isn't normally needed for non Custom Grip types + if (bAlwaysSendTickGrip) + { + // All non custom grips tick after translation, this is still pre physics so interactive grips location will be wrong, but others will be correct + if (bRootHasInterface) + { + IVRGripInterface::Execute_TickGrip(root, this, *Grip, DeltaTime); + } + + if (bActorHasInterface) + { + IVRGripInterface::Execute_TickGrip(actor, this, *Grip, DeltaTime); + } + } + } + else + { + // Object has been destroyed without notification to plugin or is pending kill + if (!Grip->bIsPendingKill) + { + CleanUpBadGrip(GrippedObjectsArray, i, bReplicatedArray); + } + } + } + } +} + + +void UGripMotionControllerComponent::CleanUpBadGrip(TArray &GrippedObjectsArray, int GripIndex, bool bReplicatedArray) +{ + // Object has been destroyed without notification to plugin + if (!DestroyPhysicsHandle(GrippedObjectsArray[GripIndex])) + { + // Clean up tailing physics handles with null objects + for (int g = PhysicsGrips.Num() - 1; g >= 0; --g) + { + if (!PhysicsGrips[g].HandledObject || PhysicsGrips[g].HandledObject == GrippedObjectsArray[GripIndex].GrippedObject || !IsValid(PhysicsGrips[g].HandledObject)) + { + // Need to delete it from the physics thread + DestroyPhysicsHandle(&PhysicsGrips[g]); + PhysicsGrips.RemoveAt(g); + } + } + } + + if (IsServer() || HasGripAuthority(GrippedObjectsArray[GripIndex])) + { + DropGrip_Implementation(GrippedObjectsArray[GripIndex], false); + UE_LOG(LogVRMotionController, Warning, TEXT("Gripped object was null or destroying, auto dropping it")); + } + else + { + GrippedObjectsArray[GripIndex].bIsPendingKill = true; + GrippedObjectsArray[GripIndex].bIsPaused = true; + } +} + +void UGripMotionControllerComponent::CleanUpBadPhysicsHandles() +{ + // Clean up tailing physics handles with null objects + for (int g = PhysicsGrips.Num() - 1; g >= 0; --g) + { + FBPActorGripInformation * GripInfo = LocallyGrippedObjects.FindByKey(PhysicsGrips[g].GripID); + if(!GripInfo) + GrippedObjects.FindByKey(PhysicsGrips[g].GripID); + + if (!GripInfo) + { + // Need to delete it from the physics thread + DestroyPhysicsHandle(&PhysicsGrips[g]); + PhysicsGrips.RemoveAt(g); + } + } +} + +bool UGripMotionControllerComponent::UpdatePhysicsHandle(uint8 GripID, bool bFullyRecreate) +{ + FBPActorGripInformation* GripInfo = GrippedObjects.FindByKey(GripID); + if (!GripInfo) + GripInfo = LocallyGrippedObjects.FindByKey(GripID); + + if (!GripInfo) + return false; + + return UpdatePhysicsHandle(*GripInfo, bFullyRecreate); +} + +bool UGripMotionControllerComponent::UpdatePhysicsHandle(const FBPActorGripInformation& GripInfo, bool bFullyRecreate) +{ + int HandleIndex = 0; + FBPActorPhysicsHandleInformation* HandleInfo = GetPhysicsGrip(GripInfo); + + // Don't update if the handle doesn't exist or is currently paused + if (!HandleInfo || HandleInfo->bIsPaused || !HandleInfo->bInitiallySetup) + return false; + + if (bFullyRecreate || !HandleInfo->HandleData2.IsValid() || HandleInfo->bSkipResettingCom) + { + return SetUpPhysicsHandle(GripInfo); + } + + // Not fully recreating, we just re-set important variables + UPrimitiveComponent* root = GripInfo.GetGrippedComponent(); + AActor* pActor = GripInfo.GetGrippedActor(); + + if (!root && pActor) + root = Cast(pActor->GetRootComponent()); + + if (!root) + return false; + + FBodyInstance* rBodyInstance = root->GetBodyInstance(GripInfo.GrippedBoneName); + if (!rBodyInstance || !rBodyInstance->IsValidBodyInstance() || !FPhysicsInterface::IsValid(rBodyInstance->ActorHandle)) + { + return false; + } + + check(rBodyInstance->BodySetup->GetCollisionTraceFlag() != CTF_UseComplexAsSimple); + + FPhysicsCommand::ExecuteWrite(rBodyInstance->ActorHandle, [&](const FPhysicsActorHandle& Actor) + { + if (HandleInfo) + { + if (HandleInfo->KinActorData2 && FPhysicsInterface::IsValid(HandleInfo->KinActorData2)) + { + // Make sure that the constraint particles are correct, the body instance may have changed + Chaos::FConstraintBase* ConstraintHandle = HandleInfo->HandleData2.Constraint; + if (ConstraintHandle) + { + ((Chaos::FJointConstraint*)ConstraintHandle)->SetParticleProxies({ HandleInfo->KinActorData2, Actor }); + } + + // Ensure center of mass is still correct + if (HandleInfo->bSetCOM && !HandleInfo->bSkipResettingCom) + { + FTransform localCom = FPhysicsInterface::GetComTransformLocal_AssumesLocked(Actor); + //localCom.SetLocation(Loc); + localCom.SetLocation(HandleInfo->COMPosition.GetTranslation());//Loc); + FPhysicsInterface::SetComLocalPose_AssumesLocked(Actor, localCom); + } + } + } + }); + + return true; +//#endif + + //return false; +} + +bool UGripMotionControllerComponent::PausePhysicsHandle(FBPActorPhysicsHandleInformation* HandleInfo) +{ + if (!HandleInfo) + return false; + + HandleInfo->bIsPaused = true; + HandleInfo->bInitiallySetup = false; + FPhysicsInterface::ReleaseConstraint(HandleInfo->HandleData2); + return true; +} + +bool UGripMotionControllerComponent::UnPausePhysicsHandle(FBPActorGripInformation& GripInfo, FBPActorPhysicsHandleInformation* HandleInfo) +{ + if (!HandleInfo) + return false; + + HandleInfo->bIsPaused = false; + SetUpPhysicsHandle(GripInfo); + + return true; +} + +bool UGripMotionControllerComponent::DestroyPhysicsHandle(FBPActorPhysicsHandleInformation* HandleInfo) +{ + if (!HandleInfo) + return false; + + FPhysicsInterface::ReleaseConstraint(HandleInfo->HandleData2); + + if (!HandleInfo->bSkipDeletingKinematicActor) + { + if (FPhysicsInterface::IsValid(HandleInfo->KinActorData2)) + { + FPhysicsActorHandle ActorHandle = HandleInfo->KinActorData2; + FPhysicsCommand::ExecuteWrite(ActorHandle, [&](const FPhysicsActorHandle& Actor) + { + FPhysicsInterface::ReleaseActor(HandleInfo->KinActorData2, FPhysicsInterface::GetCurrentScene(HandleInfo->KinActorData2)); + }); + } + } + + return true; +} + +bool UGripMotionControllerComponent::DestroyPhysicsHandle(const FBPActorGripInformation &Grip, bool bSkipUnregistering) +{ + FBPActorPhysicsHandleInformation * HandleInfo = GetPhysicsGrip(Grip); + + if (!HandleInfo) + { + return true; + } + + UPrimitiveComponent *root = Grip.GetGrippedComponent(); + AActor * pActor = Grip.GetGrippedActor(); + + if (!root && pActor) + root = Cast(pActor->GetRootComponent()); + + if (root) + { + if (FBodyInstance * rBodyInstance = root->GetBodyInstance(Grip.GrippedBoneName)) + { + // #TODO: Should this be done on drop instead? + // Remove event registration + if (!bSkipUnregistering) + { + if (rBodyInstance->OnRecalculatedMassProperties().IsBoundToObject(this)) + { + rBodyInstance->OnRecalculatedMassProperties().RemoveAll(this); + } + } + + if (HandleInfo->bSetCOM) + { + // Reset center of mass to zero + // Get our original values + FVector vel = rBodyInstance->GetUnrealWorldVelocity(); + FVector aVel = rBodyInstance->GetUnrealWorldAngularVelocityInRadians(); + FVector originalCOM = rBodyInstance->GetCOMPosition(); + + if (rBodyInstance->IsValidBodyInstance() && rBodyInstance->BodySetup.IsValid()) + { + rBodyInstance->UpdateMassProperties(); + } + + if (rBodyInstance->IsInstanceSimulatingPhysics()) + { + // Offset the linear velocity by the new COM position and set it + vel += FVector::CrossProduct(aVel, rBodyInstance->GetCOMPosition() - originalCOM); + rBodyInstance->SetLinearVelocity(vel, false); + } + } + } + } + + DestroyPhysicsHandle(HandleInfo); + + int index; + if (GetPhysicsGripIndex(Grip, index)) + PhysicsGrips.RemoveAt(index); + + return true; +} + +void UGripMotionControllerComponent::OnGripMassUpdated(FBodyInstance* GripBodyInstance) +{ + TArray GripArray; + this->GetAllGrips(GripArray); + FBPActorGripInformation NewGrip; + + for (int i = 0; i < GripArray.Num(); i++) + { + NewGrip = GripArray[i]; + + UPrimitiveComponent *root = NewGrip.GetGrippedComponent(); + AActor * pActor = NewGrip.GetGrippedActor(); + + if (!root && pActor) + { + if (!IsValid(pActor)) + continue; + + root = Cast(pActor->GetRootComponent()); + } + + if (!root || root != GripBodyInstance->OwnerComponent) + continue; + + if (IsValid(root)) + { + UpdatePhysicsHandle(NewGrip, false); + } + break; + } +} + +bool UGripMotionControllerComponent::SetUpPhysicsHandle(const FBPActorGripInformation &NewGrip, TArray * GripScripts) +{ + UPrimitiveComponent *root = NewGrip.GetGrippedComponent(); + AActor * pActor = NewGrip.GetGrippedActor(); + + if(!root && pActor) + root = Cast(pActor->GetRootComponent()); + + if (!root) + return false; + + FBPActorPhysicsHandleInformation* HandleInfo = GetPhysicsGrip(NewGrip); + if (HandleInfo == nullptr) + { + HandleInfo = CreatePhysicsGrip(NewGrip); + } + + // If currently paused lets skip this step + if (HandleInfo->bIsPaused) + { + return false; + } + + HandleInfo->bSetCOM = false; // Zero this out in case it is a re-init + HandleInfo->bSkipDeletingKinematicActor = (bConstrainToPivot && !NewGrip.bIsLerping); + + // Check for grip scripts if we weren't passed in any + TArray LocalGripScripts; + if (GripScripts == nullptr) + { + if (root && root->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + if (IVRGripInterface::Execute_GetGripScripts(root, LocalGripScripts)) + { + GripScripts = &LocalGripScripts; + } + } + else if (pActor && pActor->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + if (IVRGripInterface::Execute_GetGripScripts(pActor, LocalGripScripts)) + { + GripScripts = &LocalGripScripts; + } + } + } + + // Needs to be simulating in order to run physics + if (!NewGrip.AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings || !NewGrip.AdvancedGripSettings.PhysicsSettings.bSkipSettingSimulating) + { + root->SetSimulatePhysics(true); + } + + // Get the PxRigidDynamic that we want to grab. + FBodyInstance* rBodyInstance = root->GetBodyInstance(NewGrip.GrippedBoneName); + Chaos::FPhysicsObject* PhysicsActor = root->GetPhysicsObjectByName(NewGrip.GrippedBoneName); + + bool bUseActorHandle = true; + if (!rBodyInstance || !rBodyInstance->IsValidBodyInstance() || !FPhysicsInterface::IsValid(rBodyInstance->ActorHandle) || !rBodyInstance->BodySetup.IsValid()) + { + if (PhysicsActor) + { + bUseActorHandle = false; + } + else + { + return false; + } + } + + if (rBodyInstance && bUseActorHandle) + { + check(rBodyInstance->BodySetup->GetCollisionTraceFlag() != CTF_UseComplexAsSimple); + + if (!HandleInfo->bSkipResettingCom && !FPhysicsInterface::IsValid(HandleInfo->KinActorData2) && !rBodyInstance->OnRecalculatedMassProperties().IsBoundToObject(this)) + { + // Reset the mass properties, this avoids an issue with some weird replication issues + // We only do this on initial grip + rBodyInstance->UpdateMassProperties(); + + } + } + + /*if (NewGrip.GrippedBoneName != NAME_None) + { + rBodyInstance->SetInstanceSimulatePhysics(true); + }*/ + + FTransform RootBoneRotation = FTransform::Identity; + if (NewGrip.GrippedBoneName != NAME_None) + { + // Skip root bone rotation + } + else + { + // I actually don't need any of this code anymore or the HandleInfo->RootBoneRotation + // However I would have to expect people to pass in the bone transform without it. + // For now I am keeping it to keep it backwards compatible as it will adjust for root bone rotation automatically then + if (USkeletalMeshComponent* skele = Cast(root)) + { + int32 RootBodyIndex = INDEX_NONE; + if (const UPhysicsAsset* PhysicsAsset = skele->GetPhysicsAsset()) + { + for (int32 i = 0; i < skele->GetNumBones(); i++) + { + if (PhysicsAsset->FindBodyIndex(skele->GetBoneName(i)) != INDEX_NONE) + { + RootBodyIndex = i; + break; + } + } + } + + if (RootBodyIndex != INDEX_NONE) + { + RootBoneRotation = FTransform(skele->GetBoneTransform(RootBodyIndex, FTransform::Identity)); + RootBoneRotation.SetScale3D(FVector(1.f)); + RootBoneRotation.NormalizeRotation(); + HandleInfo->RootBoneRotation = RootBoneRotation; + } + } + } + + // They forgot to make a single chaos::FPhysicsBody version of the write lock.... + bool bExecutedPhys = FPhysicsCommand::ExecuteWrite(PhysicsActor, PhysicsActor, [&](/*const FPhysicsActorHandle& Actor*/Chaos::FPhysicsObject* PhysActor, Chaos::FPhysicsObject* PhysActorNULL) + { + const FPhysicsActorHandle& Actor = bUseActorHandle ? rBodyInstance->GetPhysicsActorHandle() : nullptr; + Chaos::FWritePhysicsObjectInterface_External Interface = FPhysicsObjectExternalInterface::GetWrite_AssumesLocked(); + FChaosScene* PhysScene = PhysicsObjectPhysicsCoreInterface::GetScene({ &PhysActor, 1 }); + FTransform PhysActorTransform = Interface.GetTransform(PhysActor); + + if (!PhysScene) + { + return; + } + + FTransform KinPose; + FTransform trans = Interface.GetTransform(PhysActor);//FPhysicsInterface::GetGlobalPose_AssumesLocked(Actor); + + EPhysicsGripCOMType COMType = NewGrip.AdvancedGripSettings.PhysicsSettings.PhysicsGripLocationSettings; + + if (!NewGrip.AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings || COMType == EPhysicsGripCOMType::COM_Default) + { + if (NewGrip.GripCollisionType == EGripCollisionType::ManipulationGrip || NewGrip.GripCollisionType == EGripCollisionType::ManipulationGripWithWristTwist) + { + COMType = EPhysicsGripCOMType::COM_GripAtControllerLoc; + } + else + { + COMType = EPhysicsGripCOMType::COM_SetAndGripAt; + } + } + + // For geometry collections we can't set COM + if (!bUseActorHandle) + { + if (COMType == EPhysicsGripCOMType::COM_SetAndGripAt) + { + COMType = EPhysicsGripCOMType::COM_GripAtControllerLoc; + } + } + + if (bUseActorHandle && COMType == EPhysicsGripCOMType::COM_SetAndGripAt) + { + // Update the center of mass + FTransform ForwardTrans = (RootBoneRotation * NewGrip.RelativeTransform); + ForwardTrans.NormalizeRotation(); + FVector Loc = (FTransform(ForwardTrans.ToInverseMatrixWithScale())).GetLocation(); + Loc *= root->GetComponentScale(); + + FTransform localCom = FPhysicsInterface::GetComTransformLocal_AssumesLocked(Actor);//Interface.GetWorldCoM(PhysActor); + localCom.SetLocation(Loc); + FPhysicsInterface::SetComLocalPose_AssumesLocked(Actor, localCom); + + FVector ComLoc = FPhysicsInterface::GetComTransform_AssumesLocked(Actor).GetLocation(); // Interface.GetWorldCoM(PhysActor); + trans.SetLocation(ComLoc); + HandleInfo->COMPosition = FTransform(PhysActorTransform.InverseTransformPosition(ComLoc)); + HandleInfo->bSetCOM = true; + } + else if (COMType == EPhysicsGripCOMType::COM_GripAtControllerLoc) + { + FTransform ObjectTransform = PhysActorTransform; + ObjectTransform.SetScale3D(root->GetComponentScale()); + + FVector ControllerLoc = (FTransform(NewGrip.RelativeTransform.ToInverseMatrixWithScale()) * ObjectTransform).GetLocation(); + trans.SetLocation(ControllerLoc); + HandleInfo->COMPosition = FTransform(PhysActorTransform.InverseTransformPosition(ControllerLoc)); + } + else if (COMType != EPhysicsGripCOMType::COM_AtPivot) + { + FVector ComLoc = Interface.GetWorldCoM(PhysActor);// FPhysicsInterface::GetComTransform_AssumesLocked(Actor).GetLocation(); + trans.SetLocation(ComLoc); + HandleInfo->COMPosition = FTransform(PhysActorTransform.InverseTransformPosition(ComLoc)); + } + + KinPose = trans; + bool bRecreatingConstraint = false; + + + // If using twist only, lets rotate the kinematic actor to face the controller X+ + if (NewGrip.GripCollisionType == EGripCollisionType::ManipulationGripWithWristTwist) + { + FTransform PivTrans = GetPivotTransform(); + + FQuat DeltaQuat = (PivTrans.GetRotation().Inverse() * KinPose.GetRotation()).Inverse(); + + // This moves the kinematic actor to face the pivot components X+ direction + KinPose.SetRotation(KinPose.GetRotation() * DeltaQuat); + HandleInfo->COMPosition.SetRotation(HandleInfo->COMPosition.GetRotation()* DeltaQuat); + } + + if (GripScripts) + { + bool bResetCom = false; + + // Inject any alterations that the grip scripts want to make + for (UVRGripScriptBase* Script : *GripScripts) + { + if (Script && Script->IsScriptActive() && Script->InjectPrePhysicsHandle()) + { + Script->HandlePrePhysicsHandle(this, NewGrip, HandleInfo, KinPose); + bResetCom = true; + } + } + + if (bUseActorHandle && HandleInfo->bSetCOM && bResetCom) + { + FTransform localCom = FPhysicsInterface::GetComTransformLocal_AssumesLocked(Actor); + localCom.SetLocation(HandleInfo->COMPosition.GetTranslation());//Loc); + + FPhysicsInterface::SetComLocalPose_AssumesLocked(Actor, localCom); + } + } + + if (!NewGrip.bIsLerping && bConstrainToPivot && IsValid(CustomPivotComponent)) + { + if (UPrimitiveComponent* PivotPrim = Cast(CustomPivotComponent)) + { + if (FBodyInstance* Bodyinst = PivotPrim->GetBodyInstance(CustomPivotComponentSocketName)) + { + HandleInfo->KinActorData2 = Bodyinst->GetPhysicsActorHandle(); + } + } + } + + if (!FPhysicsInterface::IsValid(HandleInfo->KinActorData2)) + { + // Create kinematic actor we are going to create joint with. This will be moved around with calls to SetLocation/SetRotation. + + FActorCreationParams ActorParams; + ActorParams.InitialTM = KinPose; + ActorParams.DebugName = nullptr; + ActorParams.bEnableGravity = false; + ActorParams.bQueryOnly = false;// true; // True or false? + ActorParams.bStatic = false; + ActorParams.Scene = PhysScene;//FPhysicsInterface::GetCurrentScene(Actor); + FPhysicsInterface::CreateActor(ActorParams, HandleInfo->KinActorData2); + + if (FPhysicsInterface::IsValid(HandleInfo->KinActorData2)) + { + FPhysicsInterface::SetMass_AssumesLocked(HandleInfo->KinActorData2, 1.0f); + FPhysicsInterface::SetMassSpaceInertiaTensor_AssumesLocked(HandleInfo->KinActorData2, FVector(1.f)); + FPhysicsInterface::SetIsKinematic_AssumesLocked(HandleInfo->KinActorData2, true); + FPhysicsInterface::SetMaxDepenetrationVelocity_AssumesLocked(HandleInfo->KinActorData2, MAX_FLT); + //FPhysicsInterface::SetActorUserData_AssumesLocked(HandleInfo->KinActorData2, NULL); + } + + using namespace Chaos; + // Missing from physx, not sure how it is working for them currently. + //TArray ActorHandles; + HandleInfo->KinActorData2->GetGameThreadAPI().SetGeometry(MakeImplicitObjectPtr>(TVector(0.f), 1000.f)); + HandleInfo->KinActorData2->GetGameThreadAPI().SetObjectState(EObjectStateType::Kinematic); + FPhysicsInterface::AddActorToSolver(HandleInfo->KinActorData2, ActorParams.Scene->GetSolver()); + //ActorHandles.Add(HandleInfo->KinActorData2); + //ActorParams.Scene->AddActorsToScene_AssumesLocked(ActorHandles); + } + + // If we don't already have a handle - make one now. + if (!HandleInfo->HandleData2.IsValid()) + { + // If this is true we will totally ignore the COM type, either we are gripping unstable or the com was set to our controller, we never accept + // Grip at COM + if (!NewGrip.bIsLerping && bConstrainToPivot) + { + FTransform TargetTrans(FTransform(NewGrip.RelativeTransform.ToMatrixNoScale().Inverse()) * HandleInfo->RootBoneRotation.Inverse()); + HandleInfo->HandleData2 = FPhysicsInterface::CreateConstraint(HandleInfo->KinActorData2->GetPhysicsObject(), PhysActor, FTransform::Identity, TargetTrans); + } + else + { + HandleInfo->HandleData2 = FPhysicsInterface::CreateConstraint(HandleInfo->KinActorData2->GetPhysicsObject(), PhysActor, FTransform::Identity, KinPose.GetRelativeTransform(PhysActorTransform)); + } + } + else + { + bRecreatingConstraint = true; + + /* + FTransform newTrans = HandleInfo->COMPosition * (HandleInfo->RootBoneRotation * HandleInfo->LastPhysicsTransform); + */ + + // There isn't a direct set for the particles, so keep it as a recreation instead. + FPhysicsInterface::ReleaseConstraint(HandleInfo->HandleData2); + + if (!NewGrip.bIsLerping && bConstrainToPivot) + { + FTransform TargetTrans(NewGrip.RelativeTransform.ToMatrixNoScale().Inverse()); + HandleInfo->HandleData2 = FPhysicsInterface::CreateConstraint(HandleInfo->KinActorData2->GetPhysicsObject(), PhysActor, FTransform::Identity, TargetTrans); + } + else + { + HandleInfo->HandleData2 = FPhysicsInterface::CreateConstraint(HandleInfo->KinActorData2->GetPhysicsObject(), PhysActor, FTransform::Identity, KinPose.GetRelativeTransform(PhysActorTransform)); + } + + } + + if (HandleInfo->HandleData2.IsValid()) + { + FPhysicsInterface::SetBreakForces_AssumesLocked(HandleInfo->HandleData2, MAX_FLT, MAX_FLT); + + + if (NewGrip.GripCollisionType == EGripCollisionType::LockedConstraint) + { + FPhysicsInterface::SetLinearMotionLimitType_AssumesLocked(HandleInfo->HandleData2, PhysicsInterfaceTypes::ELimitAxis::X, ELinearConstraintMotion::LCM_Locked); + FPhysicsInterface::SetLinearMotionLimitType_AssumesLocked(HandleInfo->HandleData2, PhysicsInterfaceTypes::ELimitAxis::Y, ELinearConstraintMotion::LCM_Locked); + FPhysicsInterface::SetLinearMotionLimitType_AssumesLocked(HandleInfo->HandleData2, PhysicsInterfaceTypes::ELimitAxis::Z, ELinearConstraintMotion::LCM_Locked); + FPhysicsInterface::SetAngularMotionLimitType_AssumesLocked(HandleInfo->HandleData2, PhysicsInterfaceTypes::ELimitAxis::Twist, EAngularConstraintMotion::ACM_Locked); + FPhysicsInterface::SetAngularMotionLimitType_AssumesLocked(HandleInfo->HandleData2, PhysicsInterfaceTypes::ELimitAxis::Swing1, EAngularConstraintMotion::ACM_Locked); + FPhysicsInterface::SetAngularMotionLimitType_AssumesLocked(HandleInfo->HandleData2, PhysicsInterfaceTypes::ELimitAxis::Swing2, EAngularConstraintMotion::ACM_Locked); + FPhysicsInterface::SetProjectionEnabled_AssumesLocked(HandleInfo->HandleData2, true, 0.01f, 0.01f); + } + else + { + FPhysicsInterface::SetLinearMotionLimitType_AssumesLocked(HandleInfo->HandleData2, PhysicsInterfaceTypes::ELimitAxis::X, ELinearConstraintMotion::LCM_Free); + FPhysicsInterface::SetLinearMotionLimitType_AssumesLocked(HandleInfo->HandleData2, PhysicsInterfaceTypes::ELimitAxis::Y, ELinearConstraintMotion::LCM_Free); + FPhysicsInterface::SetLinearMotionLimitType_AssumesLocked(HandleInfo->HandleData2, PhysicsInterfaceTypes::ELimitAxis::Z, ELinearConstraintMotion::LCM_Free); + FPhysicsInterface::SetAngularMotionLimitType_AssumesLocked(HandleInfo->HandleData2, PhysicsInterfaceTypes::ELimitAxis::Twist, EAngularConstraintMotion::ACM_Free); + FPhysicsInterface::SetAngularMotionLimitType_AssumesLocked(HandleInfo->HandleData2, PhysicsInterfaceTypes::ELimitAxis::Swing1, EAngularConstraintMotion::ACM_Free); + FPhysicsInterface::SetAngularMotionLimitType_AssumesLocked(HandleInfo->HandleData2, PhysicsInterfaceTypes::ELimitAxis::Swing2, EAngularConstraintMotion::ACM_Free); + FPhysicsInterface::SetProjectionEnabled_AssumesLocked(HandleInfo->HandleData2, false); + } + + FPhysicsInterface::SetDrivePosition(HandleInfo->HandleData2, FVector::ZeroVector); + + bool bUseForceDrive = (NewGrip.AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings && NewGrip.AdvancedGripSettings.PhysicsSettings.PhysicsConstraintType == EPhysicsGripConstraintType::ForceConstraint); + + float Stiffness = NewGrip.Stiffness; + float Damping = NewGrip.Damping; + float MaxForce; + float AngularStiffness; + float AngularDamping; + float AngularMaxForce; + + const UVRGlobalSettings& VRSettings = *GetDefault(); + + if (NewGrip.AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings && NewGrip.AdvancedGripSettings.PhysicsSettings.bUseCustomAngularValues) + { + AngularStiffness = NewGrip.AdvancedGripSettings.PhysicsSettings.AngularStiffness; + AngularDamping = NewGrip.AdvancedGripSettings.PhysicsSettings.AngularDamping; + } + else + { + AngularStiffness = Stiffness * ANGULAR_STIFFNESS_MULTIPLIER; // Default multiplier + AngularDamping = Damping * ANGULAR_DAMPING_MULTIPLIER; // Default multiplier + + if (!VRSettings.bUseChaosTranslationScalers) + { + AngularStiffness *= ANGULAR_STIFFNESS_MULTIPLIER_CHAOS; + AngularDamping *= ANGULAR_DAMPING_MULTIPLIER_CHAOS; + } + } + + if (VRSettings.bUseChaosTranslationScalers) + { + Stiffness *= VRSettings.LinearDriveStiffnessScale; + Damping *= VRSettings.LinearDriveDampingScale; + AngularStiffness *= VRSettings.AngularDriveStiffnessScale; + AngularDamping *= VRSettings.AngularDriveDampingScale; + } + else + { + auto CVarLinearDriveStiffnessScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.LinearDriveStiffnessScale")); + auto CVarLinearDriveDampingScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.LinaearDriveDampingScale")); + auto CVarAngularDriveStiffnessScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.AngularDriveStiffnessScale")); + auto CVarAngularDriveDampingScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.AngularDriveDampingScale")); + + Stiffness *= CVarLinearDriveStiffnessScale->GetFloat(); + Damping *= CVarLinearDriveDampingScale->GetFloat(); + AngularStiffness *= CVarAngularDriveStiffnessScale->GetFloat(); + AngularDamping *= CVarAngularDriveDampingScale->GetFloat(); + } + + AngularMaxForce = (float)FMath::Clamp((double)AngularStiffness * (double)NewGrip.AdvancedGripSettings.PhysicsSettings.AngularMaxForceCoefficient, 0, (double)MAX_FLT); + MaxForce = (float)FMath::Clamp((double)Stiffness * (double)NewGrip.AdvancedGripSettings.PhysicsSettings.LinearMaxForceCoefficient, 0, (double)MAX_FLT); + + // Different settings for manip grip + if (NewGrip.GripCollisionType == EGripCollisionType::ManipulationGrip || NewGrip.GripCollisionType == EGripCollisionType::ManipulationGripWithWristTwist) + { + if (!bRecreatingConstraint) + { + FConstraintDrive NewLinDrive; + NewLinDrive.bEnablePositionDrive = true; + NewLinDrive.bEnableVelocityDrive = true; + NewLinDrive.Damping = Damping; + NewLinDrive.Stiffness = Stiffness; + NewLinDrive.MaxForce = MaxForce; + + //HandleInfo->LinConstraint.bEnablePositionDrive = true; + HandleInfo->LinConstraint.XDrive = NewLinDrive; + HandleInfo->LinConstraint.YDrive = NewLinDrive; + HandleInfo->LinConstraint.ZDrive = NewLinDrive; + } + + + if (NewGrip.GripCollisionType == EGripCollisionType::ManipulationGripWithWristTwist) + { + if (!bRecreatingConstraint) + { + FConstraintDrive NewAngDrive; + NewAngDrive.bEnablePositionDrive = true; + NewAngDrive.bEnableVelocityDrive = true; + NewAngDrive.Damping = AngularDamping; + NewAngDrive.Stiffness = AngularStiffness; + NewAngDrive.MaxForce = AngularMaxForce; + //NewAngDrive.MaxForce = MAX_FLT; + + HandleInfo->AngConstraint.AngularDriveMode = EAngularDriveMode::TwistAndSwing; + //AngParams.AngularDriveMode = EAngularDriveMode::SLERP; + HandleInfo->AngConstraint.TwistDrive = NewAngDrive; + } + } + + if (GripScripts) + { + // Inject any alterations that the grip scripts want to make + for (UVRGripScriptBase* Script : *GripScripts) + { + if (Script && Script->IsScriptActive() && Script->InjectPostPhysicsHandle()) + { + Script->HandlePostPhysicsHandle(this, HandleInfo); + } + } + } + + FPhysicsInterface::UpdateLinearDrive_AssumesLocked(HandleInfo->HandleData2, HandleInfo->LinConstraint); + FPhysicsInterface::UpdateAngularDrive_AssumesLocked(HandleInfo->HandleData2, HandleInfo->AngConstraint); + } + else + { + if (NewGrip.GripCollisionType == EGripCollisionType::InteractiveHybridCollisionWithPhysics) + { + // Do not effect damping, just increase stiffness so that it is stronger + // Default multiplier + Stiffness *= HYBRID_PHYSICS_GRIP_MULTIPLIER; + AngularStiffness *= HYBRID_PHYSICS_GRIP_MULTIPLIER; + AngularMaxForce = (float)FMath::Clamp((double)AngularStiffness * (double)NewGrip.AdvancedGripSettings.PhysicsSettings.AngularMaxForceCoefficient, 0, (double)MAX_FLT); + MaxForce = (float)FMath::Clamp((double)Stiffness * (double)NewGrip.AdvancedGripSettings.PhysicsSettings.LinearMaxForceCoefficient, 0, (double)MAX_FLT); + } + + if (!bRecreatingConstraint) + { + if (NewGrip.GripCollisionType != EGripCollisionType::LockedConstraint) + { + FConstraintDrive NewLinDrive; + NewLinDrive.bEnablePositionDrive = true; + NewLinDrive.bEnableVelocityDrive = true; + NewLinDrive.Damping = Damping; + NewLinDrive.Stiffness = Stiffness; + NewLinDrive.MaxForce = MaxForce; + //NewLinDrive.MaxForce = MAX_FLT; + + FConstraintDrive NewAngDrive; + NewAngDrive.bEnablePositionDrive = true; + NewAngDrive.bEnableVelocityDrive = true; + NewAngDrive.Damping = AngularDamping; + NewAngDrive.Stiffness = AngularStiffness; + NewAngDrive.MaxForce = AngularMaxForce; + //NewAngDrive.MaxForce = MAX_FLT; + + //HandleInfo->LinConstraint.bEnablePositionDrive = true; + HandleInfo->LinConstraint.XDrive.bEnablePositionDrive = true; + HandleInfo->LinConstraint.YDrive.bEnablePositionDrive = true; + HandleInfo->LinConstraint.ZDrive.bEnablePositionDrive = true; + + HandleInfo->LinConstraint.XDrive = NewLinDrive; + HandleInfo->LinConstraint.YDrive = NewLinDrive; + HandleInfo->LinConstraint.ZDrive = NewLinDrive; + + HandleInfo->AngConstraint.AngularDriveMode = EAngularDriveMode::SLERP; + HandleInfo->AngConstraint.SlerpDrive = NewAngDrive; + } + } + + if (GripScripts) + { + // Inject any alterations that the grip scripts want to make + for (UVRGripScriptBase* Script : *GripScripts) + { + if (Script && Script->IsScriptActive() && Script->InjectPostPhysicsHandle()) + { + Script->HandlePostPhysicsHandle(this, HandleInfo); + } + } + } + + FPhysicsInterface::UpdateLinearDrive_AssumesLocked(HandleInfo->HandleData2, HandleInfo->LinConstraint); + FPhysicsInterface::UpdateAngularDrive_AssumesLocked(HandleInfo->HandleData2, HandleInfo->AngConstraint); + } + + + // This is a temp workaround until epic fixes the drive creation to allow force constraints + // I wanted to use the new interface and not directly set the drive so that it is ready to delete this section + // When its fixed + if (bUseForceDrive && HandleInfo->HandleData2.IsValid() && HandleInfo->HandleData2.Constraint) + { + if (HandleInfo->HandleData2.IsValid() && HandleInfo->HandleData2.Constraint->IsType(Chaos::EConstraintType::JointConstraintType)) + { + if (Chaos::FJointConstraint* Constraint = static_cast(HandleInfo->HandleData2.Constraint)) + { + Constraint->SetLinearDriveForceMode(Chaos::EJointForceMode::Force); + Constraint->SetAngularDriveForceMode(Chaos::EJointForceMode::Force); + } + } + } + } + }); + + if (!bExecutedPhys) + { + return false; + } + + HandleInfo->bInitiallySetup = true; + + // Bind to further updates in order to keep it alive + if (bUseActorHandle && !rBodyInstance->OnRecalculatedMassProperties().IsBoundToObject(this)) + { + rBodyInstance->OnRecalculatedMassProperties().AddUObject(this, &UGripMotionControllerComponent::OnGripMassUpdated); + } + + return true; +} + +bool UGripMotionControllerComponent::SetGripConstraintStiffnessAndDamping(const FBPActorGripInformation* Grip, bool bUseHybridMultiplier) +{ + if (!Grip) + return false; + + FBPActorPhysicsHandleInformation* HandleInfo = GetPhysicsGrip(*Grip); + + if (HandleInfo) + { + if (HandleInfo->HandleData2.IsValid()) + { + FPhysicsInterface::ExecuteOnUnbrokenConstraintReadWrite(HandleInfo->HandleData2, [&](const FPhysicsConstraintHandle& InUnbrokenConstraint) + { + bool bUseForceDrive = (Grip->AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings && Grip->AdvancedGripSettings.PhysicsSettings.PhysicsConstraintType == EPhysicsGripConstraintType::ForceConstraint); + + float Stiffness = Grip->Stiffness; + float Damping = Grip->Damping; + float MaxForce; + float AngularStiffness; + float AngularDamping; + float AngularMaxForce; + + const UVRGlobalSettings& VRSettings = *GetDefault(); + + if (Grip->AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings && Grip->AdvancedGripSettings.PhysicsSettings.bUseCustomAngularValues) + { + AngularStiffness = Grip->AdvancedGripSettings.PhysicsSettings.AngularStiffness; + AngularDamping = Grip->AdvancedGripSettings.PhysicsSettings.AngularDamping; + } + else + { + AngularStiffness = Stiffness * ANGULAR_STIFFNESS_MULTIPLIER; // Default multiplier + AngularDamping = Damping * ANGULAR_DAMPING_MULTIPLIER; // Default multiplier + + if (!VRSettings.bUseChaosTranslationScalers) + { + AngularStiffness *= ANGULAR_STIFFNESS_MULTIPLIER_CHAOS; + AngularDamping *= ANGULAR_DAMPING_MULTIPLIER_CHAOS; + } + } + + if (VRSettings.bUseChaosTranslationScalers) + { + Stiffness *= VRSettings.LinearDriveStiffnessScale; + Damping *= VRSettings.LinearDriveDampingScale; + AngularStiffness *= VRSettings.AngularDriveStiffnessScale; + AngularDamping *= VRSettings.AngularDriveDampingScale; + } + else + { + auto CVarLinearDriveStiffnessScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.LinearDriveStiffnessScale")); + auto CVarLinearDriveDampingScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.LinaearDriveDampingScale")); + auto CVarAngularDriveStiffnessScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.AngularDriveStiffnessScale")); + auto CVarAngularDriveDampingScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.AngularDriveDampingScale")); + + Stiffness *= CVarLinearDriveStiffnessScale->GetFloat(); + Damping *= CVarLinearDriveDampingScale->GetFloat(); + AngularStiffness *= CVarAngularDriveStiffnessScale->GetFloat(); + AngularDamping *= CVarAngularDriveDampingScale->GetFloat(); + } + + AngularMaxForce = (float)FMath::Clamp((double)AngularStiffness * (double)Grip->AdvancedGripSettings.PhysicsSettings.AngularMaxForceCoefficient, 0, (double)MAX_FLT); + MaxForce = (float)FMath::Clamp((double)Stiffness * (double)Grip->AdvancedGripSettings.PhysicsSettings.LinearMaxForceCoefficient, 0, (double)MAX_FLT); + + + // Different settings for manip grip + if (Grip->GripCollisionType == EGripCollisionType::ManipulationGrip || Grip->GripCollisionType == EGripCollisionType::ManipulationGripWithWristTwist) + { + HandleInfo->LinConstraint.XDrive.Damping = Damping; + HandleInfo->LinConstraint.XDrive.Stiffness = Stiffness; + HandleInfo->LinConstraint.XDrive.MaxForce = MaxForce; + HandleInfo->LinConstraint.YDrive.Damping = Damping; + HandleInfo->LinConstraint.YDrive.Stiffness = Stiffness; + HandleInfo->LinConstraint.YDrive.MaxForce = MaxForce; + HandleInfo->LinConstraint.ZDrive.Damping = Damping; + HandleInfo->LinConstraint.ZDrive.Stiffness = Stiffness; + HandleInfo->LinConstraint.ZDrive.MaxForce = MaxForce; + + FPhysicsInterface::UpdateLinearDrive_AssumesLocked(HandleInfo->HandleData2, HandleInfo->LinConstraint); + if (bUseForceDrive && HandleInfo->HandleData2.IsValid() && HandleInfo->HandleData2.Constraint) + { + if (HandleInfo->HandleData2.IsValid() && HandleInfo->HandleData2.Constraint->IsType(Chaos::EConstraintType::JointConstraintType)) + { + if (Chaos::FJointConstraint* Constraint = static_cast(HandleInfo->HandleData2.Constraint)) + { + Constraint->SetLinearDriveForceMode(Chaos::EJointForceMode::Force); + Constraint->SetAngularDriveForceMode(Chaos::EJointForceMode::Force); + } + } + } + + if (Grip->GripCollisionType == EGripCollisionType::ManipulationGripWithWristTwist) + { + HandleInfo->AngConstraint.TwistDrive.Damping = AngularDamping; + HandleInfo->AngConstraint.TwistDrive.Stiffness = AngularStiffness; + HandleInfo->AngConstraint.TwistDrive.MaxForce = AngularMaxForce; + + FPhysicsInterface::UpdateAngularDrive_AssumesLocked(HandleInfo->HandleData2, HandleInfo->AngConstraint); + } + + FPhysicsInterface::SetDrivePosition(HandleInfo->HandleData2, FVector::ZeroVector); + FPhysicsInterface::SetDriveOrientation(HandleInfo->HandleData2, FQuat::Identity); + } + else + { + if (Grip->GripCollisionType == EGripCollisionType::InteractiveHybridCollisionWithPhysics) + { + // Do not effect damping, just increase stiffness so that it is stronger + // Default multiplier + Stiffness *= HYBRID_PHYSICS_GRIP_MULTIPLIER; + AngularStiffness *= HYBRID_PHYSICS_GRIP_MULTIPLIER; + + AngularMaxForce = (float)FMath::Clamp((double)AngularStiffness * (double)Grip->AdvancedGripSettings.PhysicsSettings.AngularMaxForceCoefficient, 0, (double)MAX_FLT); + MaxForce = (float)FMath::Clamp((double)Stiffness * (double)Grip->AdvancedGripSettings.PhysicsSettings.LinearMaxForceCoefficient, 0, (double)MAX_FLT); + } + + HandleInfo->LinConstraint.XDrive.Damping = Damping; + HandleInfo->LinConstraint.XDrive.Stiffness = Stiffness; + HandleInfo->LinConstraint.XDrive.MaxForce = MaxForce; + HandleInfo->LinConstraint.YDrive.Damping = Damping; + HandleInfo->LinConstraint.YDrive.Stiffness = Stiffness; + HandleInfo->LinConstraint.YDrive.MaxForce = MaxForce; + HandleInfo->LinConstraint.ZDrive.Damping = Damping; + HandleInfo->LinConstraint.ZDrive.Stiffness = Stiffness; + HandleInfo->LinConstraint.ZDrive.MaxForce = MaxForce; + + FPhysicsInterface::UpdateLinearDrive_AssumesLocked(HandleInfo->HandleData2, HandleInfo->LinConstraint); + if (bUseForceDrive && HandleInfo->HandleData2.IsValid() && HandleInfo->HandleData2.Constraint) + { + if (HandleInfo->HandleData2.IsValid() && HandleInfo->HandleData2.Constraint->IsType(Chaos::EConstraintType::JointConstraintType)) + { + if (Chaos::FJointConstraint* Constraint = static_cast(HandleInfo->HandleData2.Constraint)) + { + Constraint->SetLinearDriveForceMode(Chaos::EJointForceMode::Force); + } + } + } + + + HandleInfo->AngConstraint.SlerpDrive.Damping = AngularDamping; + HandleInfo->AngConstraint.SlerpDrive.Stiffness = AngularStiffness; + HandleInfo->AngConstraint.SlerpDrive.MaxForce = AngularMaxForce; + FPhysicsInterface::UpdateAngularDrive_AssumesLocked(HandleInfo->HandleData2, HandleInfo->AngConstraint); + if (bUseForceDrive && HandleInfo->HandleData2.IsValid() && HandleInfo->HandleData2.Constraint) + { + if (HandleInfo->HandleData2.IsValid() && HandleInfo->HandleData2.Constraint->IsType(Chaos::EConstraintType::JointConstraintType)) + { + if (Chaos::FJointConstraint* Constraint = static_cast(HandleInfo->HandleData2.Constraint)) + { + Constraint->SetAngularDriveForceMode(Chaos::EJointForceMode::Force); + } + } + } + } + + }); + + } + return true; + } + + return false; +} + +bool UGripMotionControllerComponent::GetPhysicsJointLength(const FBPActorGripInformation &GrippedActor, UPrimitiveComponent * rootComp, FVector & LocOut) +{ + if (!GrippedActor.GrippedObject) + return false; + + FBPActorPhysicsHandleInformation * HandleInfo = GetPhysicsGrip(GrippedActor); + + if (!HandleInfo || !FPhysicsInterface::IsValid(HandleInfo->KinActorData2)) + return false; + + if (!HandleInfo->HandleData2.IsValid()) + return false; + + // Not using com with skipping mass check as the COM can change on us + // Also skipping it on skip resetting com as we aren't gripped to the COM then + bool bUseComLoc = + ( + !HandleInfo->bSkipResettingCom && + (HandleInfo->bSetCOM || + (GrippedActor.AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings && GrippedActor.AdvancedGripSettings.PhysicsSettings.PhysicsGripLocationSettings == EPhysicsGripCOMType::COM_GripAt)) + ); + + // This is supposed to be the difference between the actor and the kinactor / constraint base + FTransform tran3 = FTransform::Identity; + + FBodyInstance* rBodyInstance = rootComp->GetBodyInstance(GrippedActor.GrippedBoneName); + + if (bUseComLoc && rBodyInstance && rBodyInstance->IsValidBodyInstance()) + { + tran3 = FTransform(rBodyInstance->GetCOMPosition()); + } + else + { + FTransform rr; + tran3 = FPhysicsInterface::GetLocalPose(HandleInfo->HandleData2, EConstraintFrame::Frame2); + + if (!rBodyInstance || !rBodyInstance->IsValidBodyInstance()) + { + rr = rootComp->GetComponentTransform(); + // Physx location throws out scale, this is where the problem was + rr.SetScale3D(FVector(1, 1, 1)); + } + else + rr = rBodyInstance->GetUnrealWorldTransform(); + + // Make the local pose global + tran3 = tran3 * rr; + } + + // Get the global pose for the kin actor + FTransform kinPose = FTransform::Identity; + FPhysicsCommand::ExecuteRead(HandleInfo->KinActorData2, [&](const FPhysicsActorHandle & Actor) + { + kinPose = FPhysicsInterface::GetGlobalPose_AssumesLocked(Actor); + }); + + // Return the difference + LocOut = FTransform::SubtractTranslations(kinPose, tran3); + + return true; +} + +void UGripMotionControllerComponent::UpdatePhysicsHandleTransform(const FBPActorGripInformation &GrippedActor, const FTransform& NewTransform) +{ + if (!GrippedActor.GrippedObject || (bConstrainToPivot && !GrippedActor.bIsLerping) || IsTravelingOrNullWorld()) + return; + + if (!NewTransform.IsValid()) + { + UE_LOG(LogVRMotionController, Warning, TEXT("Something went wrong, UpdatePhysicsHandeTransforms target transform contained NAN!.")); + return; + } + + FBPActorPhysicsHandleInformation * HandleInfo = GetPhysicsGrip(GrippedActor); + + if (!HandleInfo || !FPhysicsInterface::IsValid(HandleInfo->KinActorData2))// || !HandleInfo->HandleData2.IsValid()) + return; + + // Don't call moveKinematic if it hasn't changed - that will stop bodies from going to sleep. + if (!HandleInfo->LastPhysicsTransform.EqualsNoScale(NewTransform)) + { + HandleInfo->LastPhysicsTransform = NewTransform; + HandleInfo->LastPhysicsTransform.SetScale3D(FVector(1.0f)); + FPhysicsActorHandle ActorHandle = HandleInfo->KinActorData2; + FTransform newTrans = HandleInfo->COMPosition * (HandleInfo->RootBoneRotation * HandleInfo->LastPhysicsTransform); + FPhysicsCommand::ExecuteWrite(ActorHandle, [&](const FPhysicsActorHandle & Actor) + { + FPhysicsInterface::SetKinematicTarget_AssumesLocked(Actor, newTrans); + }); + } + + // Debug draw for COM movement with physics grips +#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) + if (GripMotionControllerCvars::DrawDebugGripCOM) + { + UPrimitiveComponent* me = Cast(GrippedActor.GripTargetType == EGripTargetType::ActorGrip ? GrippedActor.GetGrippedActor()->GetRootComponent() : GrippedActor.GetGrippedComponent()); + FVector curCOMPosition = me->GetBodyInstance(GrippedActor.GrippedBoneName)->GetCOMPosition(); + DrawDebugSphere(GetWorld(), curCOMPosition, 4, 32, FColor::Red, false); + FTransform TargetTransform = (HandleInfo->COMPosition * (HandleInfo->RootBoneRotation * HandleInfo->LastPhysicsTransform)); + DrawDebugSphere(GetWorld(), TargetTransform.GetLocation(), 4, 32, FColor::Cyan, false); + DrawDebugLine(GetWorld(), TargetTransform.GetTranslation(), TargetTransform.GetTranslation() + (TargetTransform.GetRotation().GetForwardVector() * 20.f), FColor::Red); + DrawDebugLine(GetWorld(), TargetTransform.GetTranslation(), TargetTransform.GetTranslation() + (TargetTransform.GetRotation().GetRightVector() * 20.f), FColor::Green); + DrawDebugLine(GetWorld(), TargetTransform.GetTranslation(), TargetTransform.GetTranslation() + (TargetTransform.GetRotation().GetUpVector() * 20.f), FColor::Blue); + } +#endif + +} + +static void PullBackHitComp(FHitResult& Hit, const FVector& Start, const FVector& End, const float Dist) +{ + const float DesiredTimeBack = FMath::Clamp(0.1f, 0.1f / Dist, 1.f / Dist) + 0.001f; + Hit.Time = FMath::Clamp(Hit.Time - DesiredTimeBack, 0.f, 1.f); +} + +bool UGripMotionControllerComponent::CheckComponentWithSweep(UPrimitiveComponent * ComponentToCheck, FVector Move, FRotator newOrientation, bool bSkipSimulatingComponents/*, bool &bHadBlockingHitOut*/) +{ + TArray Hits; + // WARNING: HitResult is only partially initialized in some paths. All data is valid only if bFilledHitResult is true. + FHitResult BlockingHit(NoInit); + BlockingHit.bBlockingHit = false; + BlockingHit.Time = 1.f; + bool bFilledHitResult = false; + bool bMoved = false; + bool bIncludesOverlapsAtEnd = false; + bool bRotationOnly = false; + + UPrimitiveComponent *root = ComponentToCheck; + + if (!root || !root->IsQueryCollisionEnabled()) + return false; + + FVector start(root->GetComponentLocation()); + + const bool bCollisionEnabled = root->IsQueryCollisionEnabled(); + + if (bCollisionEnabled) + { +#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) + if (!root->IsRegistered()) + { + UE_LOG(LogVRMotionController, Warning, TEXT("MovedComponent %s not initialized in grip motion controller"), *root->GetFullName()); + } +#endif + + UWorld* const MyWorld = GetWorld(); + FComponentQueryParams Params(TEXT("sweep_params"), root->GetOwner()); + + FCollisionResponseParams ResponseParam; + root->InitSweepCollisionParams(Params, ResponseParam); + + FVector end = start + Move; + bool const bHadBlockingHit = MyWorld->ComponentSweepMulti(Hits, root, start, end, newOrientation.Quaternion(), Params); + + if (Hits.Num() > 0) + { + const float DeltaSize = FVector::Dist(start, end); + for (int32 HitIdx = 0; HitIdx < Hits.Num(); HitIdx++) + { + PullBackHitComp(Hits[HitIdx], start, end, DeltaSize); + } + } + + if (bHadBlockingHit) + { + int32 BlockingHitIndex = INDEX_NONE; + float BlockingHitNormalDotDelta = UE_BIG_NUMBER; + for (int32 HitIdx = 0; HitIdx < Hits.Num(); HitIdx++) + { + const FHitResult& TestHit = Hits[HitIdx]; + + // Ignore the owning actor to the motion controller + if (TestHit.GetActor() == this->GetOwner() || (bSkipSimulatingComponents && TestHit.Component->IsSimulatingPhysics())) + { + if (Hits.Num() == 1) + { + //bHadBlockingHitOut = false; + return false; + } + else + continue; + } + + if (TestHit.bBlockingHit && TestHit.IsValidBlockingHit()) + { + if (TestHit.Time == 0.f) + { + // We may have multiple initial hits, and want to choose the one with the normal most opposed to our movement. + const float NormalDotDelta = (TestHit.ImpactNormal | Move); + if (NormalDotDelta < BlockingHitNormalDotDelta) + { + BlockingHitNormalDotDelta = NormalDotDelta; + BlockingHitIndex = HitIdx; + } + } + else if (BlockingHitIndex == INDEX_NONE) + { + // First non-overlapping blocking hit should be used, if an overlapping hit was not. + // This should be the only non-overlapping blocking hit, and last in the results. + BlockingHitIndex = HitIdx; + break; + } + //} + } + } + + // Update blocking hit, if there was a valid one. + if (BlockingHitIndex >= 0) + { + BlockingHit = Hits[BlockingHitIndex]; + bFilledHitResult = true; + } + } + } + + // Handle blocking hit notifications. Avoid if pending kill (which could happen after overlaps). + if (BlockingHit.bBlockingHit && IsValid(root)) + { + check(bFilledHitResult); + if (root->IsDeferringMovementUpdates()) + { + FScopedMovementUpdate* ScopedUpdate = root->GetCurrentScopedMovement(); + ScopedUpdate->AppendBlockingHitAfterMove(BlockingHit); + } + else + { + + if(root->GetOwner()) + root->DispatchBlockingHit(*root->GetOwner(), BlockingHit); + } + + return true; + } + + return false; +} + +bool UGripMotionControllerComponent::HasTrackingParameters() +{ + return /*bOffsetByHMD ||*/ bScaleTracking || bLeashToHMD || bLimitMinHeight || bLimitMaxHeight || (AttachChar && !AttachChar->bRetainRoomscale); +} + +void UGripMotionControllerComponent::ApplyTrackingParameters(FVector& OriginalPosition, bool bIsInGameThread, bool bApplyZeroing) +{ + if (bScaleTracking) + { + OriginalPosition *= TrackingScaler; + } + + if (bLimitMinHeight) + { + OriginalPosition.Z = FMath::Max(OriginalPosition.Z, MinimumHeight); + } + + if (bLimitMaxHeight) + { + OriginalPosition.Z = FMath::Min(OriginalPosition.Z, MaximumHeight); + } + + if (bApplyZeroing && (/*bOffsetByHMD ||*/ bLeashToHMD || (AttachChar && !AttachChar->bRetainRoomscale))) + { + if (bIsInGameThread) + { + if (IsLocallyControlled() && GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowedForWorld(*GetWorld())) + { + FQuat curRot; + FVector curLoc; + if (GEngine->XRSystem->GetCurrentPose(IXRTrackingSystem::HMDDeviceId, curRot, curLoc)) + { + + if (IsValid(AttachChar) && AttachChar->VRReplicatedCamera) + { + AttachChar->VRReplicatedCamera->ApplyTrackingParameters(curLoc, true); + } + + //curLoc.Z = 0; + LastLocationForLateUpdate = curLoc; + + if (IsValid(AttachChar) && !AttachChar->bRetainRoomscale) + { + FRotator StoredCameraRotOffset = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(curRot.Rotator()); + LastLocationForLateUpdate += StoredCameraRotOffset.RotateVector(FVector(AttachChar->VRRootReference->VRCapsuleOffset.X, AttachChar->VRRootReference->VRCapsuleOffset.Y, 0.0f)); + } + } + } + else + { + if (IsValid(AttachChar) && AttachChar->VRReplicatedCamera) + { + // Sample camera location instead + LastLocationForLateUpdate = AttachChar->VRReplicatedCamera->GetRelativeLocation(); + + if (!AttachChar->bRetainRoomscale && IsLocallyControlled()) + { + FRotator StoredCameraRotOffset = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(AttachChar->VRReplicatedCamera->GetRelativeRotation()); + LastLocationForLateUpdate += StoredCameraRotOffset.RotateVector(FVector(AttachChar->VRRootReference->VRCapsuleOffset.X, AttachChar->VRRootReference->VRCapsuleOffset.Y, 0.0f)); + } + } + } + } + + // #TODO: This is technically unsafe, need to use a seperate value like the transforms for the render thread + // If I ever delete the simple char then this setup can just go away anyway though + // It has a data race condition right now though + FVector CorrectLastLocation = bIsInGameThread ? LastLocationForLateUpdate : LateUpdateParams.GripRenderThreadLastLocationForLateUpdate; + + if (bLeashToHMD) + { + FVector DifferenceVec = OriginalPosition - CorrectLastLocation; + + if (DifferenceVec.SizeSquared() > FMath::Square(LeashRange)) + { + OriginalPosition = CorrectLastLocation + (DifferenceVec.GetSafeNormal() * LeashRange); + } + } + + if (/*bOffsetByHMD ||*/ (AttachChar && !AttachChar->bRetainRoomscale)) + { + OriginalPosition -= FVector(CorrectLastLocation.X, CorrectLastLocation.Y, 0.0f); + } + } +} + +void UGripMotionControllerComponent::OnModularFeatureUnregistered(const FName& Type, class IModularFeature* ModularFeature) +{ + FScopeLock Lock(&PolledMotionControllerMutex); + + if (ModularFeature == PolledMotionController_GameThread) + { + PolledMotionController_GameThread = nullptr; + } + if (ModularFeature == PolledMotionController_RenderThread) + { + PolledMotionController_RenderThread = nullptr; + } +} + + +//============================================================================= +bool UGripMotionControllerComponent::GripPollControllerState(FVector& Position, FRotator& Orientation, float WorldToMetersScale) +{ + if (IsInGameThread()) + { + bool OutbProvidedLinearVelocity; + bool OutbProvidedAngularVelocity; + bool OutbProvidedLinearAcceleration; + FVector OutLinearVelocity; + FVector OutAngularVelocityAsAxisAndLength; + FVector OutLinearAcceleration; + return GripPollControllerState_GameThread(Position, Orientation, OutbProvidedLinearVelocity, OutLinearVelocity, OutbProvidedAngularVelocity, OutAngularVelocityAsAxisAndLength, OutbProvidedLinearAcceleration, OutLinearAcceleration, WorldToMetersScale); + } + else + { + return GripPollControllerState_RenderThread(Position, Orientation, WorldToMetersScale); + } +} + +bool UGripMotionControllerComponent::GripPollControllerState_GameThread(FVector& Position, FRotator& Orientation, bool& OutbProvidedLinearVelocity, FVector& OutLinearVelocity, bool& OutbProvidedAngularVelocity, FVector& OutAngularVelocityAsAxisAndLength, bool& OutbProvidedLinearAcceleration, FVector& OutLinearAcceleration, float WorldToMetersScale) +{ + // Not calling PollControllerState from the parent because its private....... + + bool bIsInGameThread = true; + + if (bHasAuthority) + { + { + FScopeLock Lock(&PolledMotionControllerMutex); + PolledMotionController_GameThread = nullptr; + bPolledHMD_GameThread = false; + } + + // #NOTE: This was adding in 4.20, I presume to allow for HMDs as tracking sources for mixed reality. + // Skipping all of my special logic here for now + if (MotionSource == IMotionController::HMDSourceId || MotionSource == IMotionController::HeadSourceId) + { + IXRTrackingSystem* TrackingSys = GEngine->XRSystem.Get(); + if (TrackingSys) + { + FQuat OrientationQuat; + if (TrackingSys->GetCurrentPose(IXRTrackingSystem::HMDDeviceId, OrientationQuat, Position)) + { + Orientation = OrientationQuat.Rotator(); + { + FScopeLock Lock(&PolledMotionControllerMutex); + bPolledHMD_GameThread = true; // We only want a render thread update from the hmd if we polled it on the game thread. + } + return true; + } + } + } + else + { + //GripUEMotionController::FScopeLockOptional LockOptional; + TArray MotionControllers; + MotionControllers = IModularFeatures::Get().GetModularFeatureImplementations(IMotionController::GetModularFeatureName()); + for (auto MotionController : MotionControllers) + { + if (MotionController == nullptr) + { + continue; + } + + if (bIsInGameThread) + { + EControllerHand HandType; + GetHandType(HandType); + FName GripSource = (HandType == EControllerHand::Left) ? FName("LeftGrip") : FName("RightGrip"); + + CurrentTrackingStatus = MotionController->GetControllerTrackingStatus(PlayerIndex, MotionSource); + if (!bIgnoreTrackingStatus && CurrentTrackingStatus == ETrackingStatus::NotTracked) + continue; + } + + if (MotionController->GetControllerOrientationAndPosition(PlayerIndex, MotionSource, Orientation, Position, OutbProvidedLinearVelocity, OutLinearVelocity, OutbProvidedAngularVelocity, OutAngularVelocityAsAxisAndLength, OutbProvidedLinearAcceleration, OutLinearAcceleration, WorldToMetersScale)) + { + /*#if PLATFORM_PS4 + // Moving this in here to work around a PSVR module bug + if (bIsInGameThread) + { + CurrentTrackingStatus = MotionController->GetControllerTrackingStatus(PlayerIndex, MotionSource); + if (CurrentTrackingStatus == ETrackingStatus::NotTracked) + continue; + } + #endif*/ + + if (HasTrackingParameters()) + { + ApplyTrackingParameters(Position, bIsInGameThread); + } + + if (bOffsetByControllerProfile) + { + FTransform FinalControllerTransform(Orientation, Position); + if (bIsInGameThread) + { + FinalControllerTransform = CurrentControllerProfileTransform * FinalControllerTransform; + } + else + { + FinalControllerTransform = LateUpdateParams.GripRenderThreadProfileTransform * FinalControllerTransform; + } + + Orientation = FinalControllerTransform.Rotator(); + Position = FinalControllerTransform.GetTranslation(); + } + + InUseMotionController = MotionController; + OnMotionControllerUpdated(); + InUseMotionController = nullptr; + + { + FScopeLock Lock(&PolledMotionControllerMutex); + PolledMotionController_GameThread = MotionController; // We only want a render thread update from the motion controller we polled on the game thread. + } + return true; + } + + /*#if PLATFORM_PS4 + else if (bIsInGameThread) + { + CurrentTrackingStatus = MotionController->GetControllerTrackingStatus(PlayerIndex, MotionSource); + } + #endif*/ + } + } + } + return false; +} + +bool UGripMotionControllerComponent::GripPollControllerState_RenderThread(FVector& Position, FRotator& Orientation, float WorldToMetersScale) +{ + check(IsInRenderingThread()); + bool bIsInGameThread = false; + + if (PolledMotionController_RenderThread) + { + EControllerHand HandType; + GetHandType(HandType); + FName GripSource = (HandType == EControllerHand::Left) ? FName("LeftGrip") : FName("RightGrip"); + + CurrentTrackingStatus = PolledMotionController_RenderThread->GetControllerTrackingStatus(PlayerIndex, GripSource); + if (PolledMotionController_RenderThread->GetControllerOrientationAndPosition(PlayerIndex, MotionSource, Orientation, Position, WorldToMetersScale)) + { + if (HasTrackingParameters()) + { + ApplyTrackingParameters(Position, bIsInGameThread); + } + + if (bOffsetByControllerProfile) + { + FTransform FinalControllerTransform(Orientation, Position); + if (bIsInGameThread) + { + FinalControllerTransform = CurrentControllerProfileTransform * FinalControllerTransform; + } + else + { + FinalControllerTransform = LateUpdateParams.GripRenderThreadProfileTransform * FinalControllerTransform; + } + + Orientation = FinalControllerTransform.Rotator(); + Position = FinalControllerTransform.GetTranslation(); + } + return true; + } + } + + if (bPolledHMD_RenderThread) + { + IXRTrackingSystem* TrackingSys = GEngine->XRSystem.Get(); + if (TrackingSys) + { + FQuat OrientationQuat; + if (TrackingSys->GetCurrentPose(IXRTrackingSystem::HMDDeviceId, OrientationQuat, Position)) + { + Orientation = OrientationQuat.Rotator(); + return true; + } + } + } + + return false; +} + +//============================================================================= +UGripMotionControllerComponent::FGripViewExtension::FGripViewExtension(const FAutoRegister& AutoRegister, UGripMotionControllerComponent* InMotionControllerComponent) + : FSceneViewExtensionBase(AutoRegister) + , MotionControllerComponent(InMotionControllerComponent) +{ + FSceneViewExtensionIsActiveFunctor IsActiveFunc; + IsActiveFunc.IsActiveFunction = [this](const ISceneViewExtension* SceneViewExtension, const FSceneViewExtensionContext& Context) + { + check(IsInGameThread()); + + static const auto CVarEnableMotionControllerLateUpdate = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("vr.EnableMotionControllerLateUpdate")); + return MotionControllerComponent && !MotionControllerComponent->bDisableLowLatencyUpdate && MotionControllerComponent->bTracked && CVarEnableMotionControllerLateUpdate->GetValueOnGameThread(); + }; + + IsActiveThisFrameFunctions.Add(IsActiveFunc); +} + + +void UGripMotionControllerComponent::FGripViewExtension::PreRenderViewFamily_RenderThread(FRDGBuilder& GraphBuilder, FSceneViewFamily& InViewFamily) +{ + FTransform OldTransform; + FTransform NewTransform; + + { + FScopeLock ScopeLock(&CritSect); + + if (!MotionControllerComponent) + return; + + { + FScopeLock Lock(&MotionControllerComponent->PolledMotionControllerMutex); + MotionControllerComponent->PolledMotionController_RenderThread = MotionControllerComponent->PolledMotionController_GameThread; + } + + // Find a view that is associated with this player. + float WorldToMetersScale = -1.0f; + for (const FSceneView* SceneView : InViewFamily.Views) + { + if (SceneView && SceneView->PlayerIndex == MotionControllerComponent->PlayerIndex) + { + WorldToMetersScale = SceneView->WorldToMetersScale; + break; + } + } + + // If there are no views associated with this player use view 0. + if (WorldToMetersScale < 0.0f) + { + check(InViewFamily.Views.Num() > 0); + WorldToMetersScale = InViewFamily.Views[0]->WorldToMetersScale; + } + + // Poll state for the most recent controller transform + FVector Position = MotionControllerComponent->LateUpdateParams.GripRenderThreadRelativeTransform.GetTranslation(); + FRotator Orientation = MotionControllerComponent->LateUpdateParams.GripRenderThreadRelativeTransform.GetRotation().Rotator(); + + if (!MotionControllerComponent->GripPollControllerState_RenderThread(Position, Orientation, WorldToMetersScale)) + { + return; + } + + if (MotionControllerComponent->LateUpdateParams.bRenderSmoothHandTracking) + { + FTransform CalcedTransform = FTransform(Orientation, Position, MotionControllerComponent->LateUpdateParams.GripRenderThreadComponentScale); + + if (MotionControllerComponent->LateUpdateParams.bRenderSmoothWithEuroLowPassFunction) + { + CalcedTransform = MotionControllerComponent->LateUpdateParams.RenderEuroSmoothingParams.RunFilterSmoothing(CalcedTransform, MotionControllerComponent->LateUpdateParams.RenderLastDeltaTime); + //SetRelativeTransform(RenderEuroSmoothingParams.RunFilterSmoothing(CalcedTransform, RenderLastDeltaTime)); + } + else + { + if (MotionControllerComponent->LateUpdateParams.RenderSmoothingSpeed <= 0.f || MotionControllerComponent->LateUpdateParams.RenderLastSmoothRelativeTransform.Equals(FTransform::Identity)) + { + //SetRelativeTransform(CalcedTransform); + } + else + { + const float Alpha = FMath::Clamp(MotionControllerComponent->LateUpdateParams.RenderLastDeltaTime * MotionControllerComponent->LateUpdateParams.RenderSmoothingSpeed, 0.f, 1.f); + MotionControllerComponent->LateUpdateParams.RenderLastSmoothRelativeTransform.Blend(MotionControllerComponent->LateUpdateParams.RenderLastSmoothRelativeTransform, CalcedTransform, Alpha); + CalcedTransform = MotionControllerComponent->LateUpdateParams.RenderLastSmoothRelativeTransform; + //SetRelativeTransform(LastSmoothRelativeTransform); + } + } + + // Set smoothed properties + NewTransform = CalcedTransform; + } + else + { + NewTransform = FTransform(Orientation, Position, MotionControllerComponent->LateUpdateParams.GripRenderThreadComponentScale); + } + + OldTransform = MotionControllerComponent->LateUpdateParams.GripRenderThreadRelativeTransform; + //NewTransform = FTransform(Orientation, Position, MotionControllerComponent->GripRenderThreadComponentScale); + MotionControllerComponent->LateUpdateParams.GripRenderThreadRelativeTransform = NewTransform; + } // Release lock on motion controller component + + // Tell the late update manager to apply the offset to the scene components + LateUpdate.Apply_RenderThread(InViewFamily.Scene, OldTransform, NewTransform); + // #TODO: UE5 is missing this pull + //LateUpdate.Apply_RenderThread(InViewFamily.Scene, InViewFamily.bLateLatchingEnabled ? InViewFamily.FrameNumber : -1, OldTransform, NewTransform); +} + +/*void UGripMotionControllerComponent::FGripViewExtension::LateLatchingViewFamily_RenderThread(FRHICommandListImmediate& RHICmdList, FSceneViewFamily& InViewFamily) +{ + SCOPED_NAMED_EVENT(UMotionControllerComponent_Latch, FColor::Orange); + if (!MotionControllerComponent) + { + return; + } + + FTransform OldTransform; + FTransform NewTransform; + { + FScopeLock ScopeLock(&CritSect); + if (!MotionControllerComponent) + { + return; + } + + // Find a view that is associated with this player. + float WorldToMetersScale = -1.0f; + for (const FSceneView* SceneView : InViewFamily.Views) + { + if (SceneView && SceneView->PlayerIndex == MotionControllerComponent->PlayerIndex) + { + WorldToMetersScale = SceneView->WorldToMetersScale; + break; + } + } + // If there are no views associated with this player use view 0. + if (WorldToMetersScale < 0.0f) + { + check(InViewFamily.Views.Num() > 0); + WorldToMetersScale = InViewFamily.Views[0]->WorldToMetersScale; + } + + // Poll state for the most recent controller transform + FVector Position; + FRotator Orientation; + + if (!MotionControllerComponent->GripPollControllerState(Position, Orientation, WorldToMetersScale)) + { + return; + } + + OldTransform = MotionControllerComponent->GripRenderThreadRelativeTransform; + NewTransform = FTransform(Orientation, Position, MotionControllerComponent->GripRenderThreadComponentScale); + MotionControllerComponent->GripRenderThreadRelativeTransform = NewTransform; + + } // Release the lock on the MotionControllerComponent + + // Tell the late update manager to apply the offset to the scene components + LateUpdate.Apply_RenderThread(InViewFamily.Scene, InViewFamily.FrameNumber, OldTransform, NewTransform); +}*/ + +bool UGripMotionControllerComponent::K2_GetFirstActiveGrip(FBPActorGripInformation& FirstActiveGrip) +{ + FBPActorGripInformation* FirstGrip = GetFirstActiveGrip(); + + if (FirstGrip) + { + FirstActiveGrip = *FirstGrip; + return true; + } + + return false; +} + +FBPActorGripInformation* UGripMotionControllerComponent::GetFirstActiveGrip() +{ + for (FBPActorGripInformation& Grip : GrippedObjects) + { + if (Grip.IsValid() && !Grip.bIsPaused) + { + return &Grip; + } + } + + for (FBPActorGripInformation& LocalGrip : LocallyGrippedObjects) + { + if (LocalGrip.IsValid() && !LocalGrip.bIsPaused) + { + return &LocalGrip; + } + } + + return nullptr; +} + +void UGripMotionControllerComponent::GetAllGrips(TArray &GripArray) +{ + GripArray.Append(GrippedObjects); + GripArray.Append(LocallyGrippedObjects); +} + +void UGripMotionControllerComponent::GetGrippedObjects(TArray &GrippedObjectsArray) +{ + for (int i = 0; i < GrippedObjects.Num(); ++i) + { + if (GrippedObjects[i].GrippedObject) + GrippedObjectsArray.Add(GrippedObjects[i].GrippedObject); + } + + for (int i = 0; i < LocallyGrippedObjects.Num(); ++i) + { + if (LocallyGrippedObjects[i].GrippedObject) + GrippedObjectsArray.Add(LocallyGrippedObjects[i].GrippedObject); + } + +} + +void UGripMotionControllerComponent::GetGrippedActors(TArray &GrippedObjectsArray) +{ + for (int i = 0; i < GrippedObjects.Num(); ++i) + { + if(GrippedObjects[i].GetGrippedActor()) + GrippedObjectsArray.Add(GrippedObjects[i].GetGrippedActor()); + } + + for (int i = 0; i < LocallyGrippedObjects.Num(); ++i) + { + if (LocallyGrippedObjects[i].GetGrippedActor()) + GrippedObjectsArray.Add(LocallyGrippedObjects[i].GetGrippedActor()); + } + +} + +void UGripMotionControllerComponent::GetGrippedComponents(TArray &GrippedComponentsArray) +{ + for (int i = 0; i < GrippedObjects.Num(); ++i) + { + if (GrippedObjects[i].GetGrippedComponent()) + GrippedComponentsArray.Add(GrippedObjects[i].GetGrippedComponent()); + } + + for (int i = 0; i < LocallyGrippedObjects.Num(); ++i) + { + if (LocallyGrippedObjects[i].GetGrippedComponent()) + GrippedComponentsArray.Add(LocallyGrippedObjects[i].GetGrippedComponent()); + } +} + +// Locally gripped functions +void UGripMotionControllerComponent::Client_NotifyInvalidLocalGrip_Implementation(UObject * LocallyGrippedObject, uint8 GripID, bool bWasAGripConflict) +{ + if (GripID != INVALID_VRGRIP_ID) + { + if (FBPActorGripInformation* GripInfo = GetGripPtrByID(GripID)) + { + DropObjectByInterface(nullptr, GripID); + + if (LocallyGrippedObject && bWasAGripConflict) + { + OnClientAuthGripConflict.Broadcast(LocallyGrippedObject, ClientAuthConflictResolutionMethod); + } + + return; + } + } + + FBPActorGripInformation FoundGrip; + EBPVRResultSwitch Result; + + GetGripByObject(FoundGrip, LocallyGrippedObject, Result); + + if (Result == EBPVRResultSwitch::OnFailed) + return; + + // Drop it, server told us that it was a bad grip + DropObjectByInterface(nullptr, FoundGrip.GripID); + + if (LocallyGrippedObject && bWasAGripConflict) + { + OnClientAuthGripConflict.Broadcast(LocallyGrippedObject, ClientAuthConflictResolutionMethod); + } +} + +bool UGripMotionControllerComponent::Server_NotifyHandledTransaction_Validate(uint8 GripID) +{ + return true; +} + +void UGripMotionControllerComponent::Server_NotifyHandledTransaction_Implementation(uint8 GripID) +{ + for (int i = LocalTransactionBuffer.Num() - 1; i >= 0; i--) + { + if(LocalTransactionBuffer[i].GripID == GripID) + LocalTransactionBuffer.RemoveAt(i); + } + +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, LocalTransactionBuffer, this); +#endif +} + +bool UGripMotionControllerComponent::Server_NotifyLocalGripAddedOrChanged_Validate(const FBPActorGripInformation & newGrip) +{ + return true; +} + +void UGripMotionControllerComponent::Server_NotifyLocalGripAddedOrChanged_Implementation(const FBPActorGripInformation & newGrip) +{ + DIRTY_LOCALLY_GRIPPED_OBJECTS(); + + if (!newGrip.GrippedObject || newGrip.GripMovementReplicationSetting != EGripMovementReplicationSettings::ClientSide_Authoritive) + { + Client_NotifyInvalidLocalGrip(newGrip.GrippedObject, newGrip.GripID); + return; + } + + if (!LocallyGrippedObjects.Contains(newGrip)) + { + + bool bImplementsInterface = newGrip.GrippedObject->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass()); + + TArray HoldingControllers; + bool bIsHeld = false; + if (bImplementsInterface) + { + IVRGripInterface::Execute_IsHeld(newGrip.GrippedObject, HoldingControllers, bIsHeld); + + if (bIsHeld && ClientAuthConflictResolutionMethod != EVRClientAuthConflictResolutionMode::VRGRIP_CONFLICT_None) + { + // Its held and doesn't allow more than one grip at a time + if (!IVRGripInterface::Execute_AllowsMultipleGrips(newGrip.GrippedObject)) + { + // Lets see if a different owner is holding it, if so, deny this request + for (FBPGripPair& GripPair : HoldingControllers) + { + if (!GripPair.HoldingController || GripPair.GripID == INVALID_VRGRIP_ID) + { + continue; + } + + // If the controllers have different owners (if its the same then consider them as locally transacting and let it go) + if (GripPair.HoldingController->GetOwner()->GetNetOwner() != this->GetOwner()->GetNetOwner()) + { + switch (ClientAuthConflictResolutionMethod) + { + case EVRClientAuthConflictResolutionMode::VRGRIP_CONFLICT_First: + { + // Deny the grip, another connection already came and gripped it + Client_NotifyInvalidLocalGrip(newGrip.GrippedObject, newGrip.GripID, true); + + OnClientAuthGripConflict.Broadcast(newGrip.GrippedObject, ClientAuthConflictResolutionMethod); + return; + }break; + case EVRClientAuthConflictResolutionMode::VRGRIP_CONFLICT_Last: + { + // Deny the old grip, another connection came and gripped it + GripPair.HoldingController->DropObjectByInterface(newGrip.GrippedObject, GripPair.GripID); + GripPair.HoldingController->Client_NotifyInvalidLocalGrip(newGrip.GrippedObject, GripPair.GripID, true); + OnClientAuthGripConflict.Broadcast(newGrip.GrippedObject, ClientAuthConflictResolutionMethod); + }break; + case EVRClientAuthConflictResolutionMode::VRGRIP_CONFLICT_DropAll: + { + // Deny both grips + Client_NotifyInvalidLocalGrip(newGrip.GrippedObject, newGrip.GripID, true); + GripPair.HoldingController->DropObjectByInterface(newGrip.GrippedObject, GripPair.GripID); + GripPair.HoldingController->Client_NotifyInvalidLocalGrip(newGrip.GrippedObject, GripPair.GripID, true); + OnClientAuthGripConflict.Broadcast(newGrip.GrippedObject, ClientAuthConflictResolutionMethod); + return; + }break; + case EVRClientAuthConflictResolutionMode::VRGRIP_CONFLICT_None: + default: + { + OnClientAuthGripConflict.Broadcast(newGrip.GrippedObject, ClientAuthConflictResolutionMethod); + }break; + + } + } + } + } + } + } + + + UPrimitiveComponent* PrimComp = nullptr; + AActor* pActor = nullptr; + + PrimComp = newGrip.GetGrippedComponent(); + pActor = newGrip.GetGrippedActor(); + + if (!PrimComp && pActor) + { + PrimComp = Cast(pActor->GetRootComponent()); + } + else if (!pActor && PrimComp) + { + pActor = PrimComp->GetOwner(); + } + + if (!PrimComp || !pActor) + { + Client_NotifyInvalidLocalGrip(newGrip.GrippedObject, newGrip.GripID); + return; + } + + bool bHadOriginalSettings = false; + bool bOriginalGravity = false; + bool bOriginalReplication = false; + + if (bImplementsInterface) + { + //if (IVRGripInterface::Execute_DenyGripping(root)) + // return false; // Interface is saying not to grip it right now + if (bIsHeld) + { + // If we are held by multiple controllers then lets copy our original values from the first one + if (HoldingControllers.Num() > 0 && HoldingControllers[0].HoldingController != nullptr) + { + FBPActorGripInformation* gripInfo = HoldingControllers[0].HoldingController->GetGripPtrByID(HoldingControllers[0].GripID); + + if (gripInfo != nullptr) + { + bHadOriginalSettings = true; + bOriginalGravity = gripInfo->bOriginalGravity; + bOriginalReplication = gripInfo->bOriginalReplicatesMovement; + } + } + } + } + + int32 NewIndex = LocallyGrippedObjects.Add(newGrip); + DIRTY_LOCALLY_GRIPPED_OBJECTS(); + + if (NewIndex != INDEX_NONE && LocallyGrippedObjects.Num() > 0) + { + if (bHadOriginalSettings) + { + LocallyGrippedObjects[NewIndex].bOriginalReplicatesMovement = bOriginalReplication; + LocallyGrippedObjects[NewIndex].bOriginalGravity = bOriginalGravity; + } + else + { + LocallyGrippedObjects[NewIndex].bOriginalReplicatesMovement = pActor->IsReplicatingMovement(); + LocallyGrippedObjects[NewIndex].bOriginalGravity = PrimComp->IsGravityEnabled(); + } + + HandleGripReplication(LocallyGrippedObjects[NewIndex]); + } + + // Initialize the differences, clients will do this themselves on the rep back, this sets up the cache + //HandleGripReplication(LocallyGrippedObjects[LocallyGrippedObjects.Num() - 1]); + } + else + { + int32 IndexFound = INDEX_NONE; + if (LocallyGrippedObjects.Find(newGrip, IndexFound) && IndexFound != INDEX_NONE) + { + FBPActorGripInformation OriginalGrip = LocallyGrippedObjects[IndexFound]; + LocallyGrippedObjects[IndexFound].RepCopy(newGrip); + HandleGripReplication(LocallyGrippedObjects[IndexFound], &OriginalGrip); + } + } + + // Server has to call this themselves + //OnRep_LocallyGrippedObjects(); +} + + +bool UGripMotionControllerComponent::Server_NotifyLocalGripRemoved_Validate(uint8 GripID, const FTransform_NetQuantize &TransformAtDrop, FVector_NetQuantize100 OptAngularVelocity, FVector_NetQuantize100 OptLinearVelocity) +{ + return true; +} + +void UGripMotionControllerComponent::Server_NotifyLocalGripRemoved_Implementation(uint8 GripID, const FTransform_NetQuantize &TransformAtDrop, FVector_NetQuantize100 OptAngularVelocity, FVector_NetQuantize100 OptLinearVelocity) +{ + DIRTY_LOCALLY_GRIPPED_OBJECTS(); + + FBPActorGripInformation FoundGrip; + EBPVRResultSwitch Result; + GetGripByID(FoundGrip, GripID, Result); + + if (Result == EBPVRResultSwitch::OnFailed) + return; + + if (FoundGrip.GripCollisionType != EGripCollisionType::EventsOnly) + { + switch (FoundGrip.GripTargetType) + { + case EGripTargetType::ActorGrip: + { + if (AActor* DroppingActor = FoundGrip.GetGrippedActor()) + { + if (IsValid(DroppingActor) && TransformAtDrop.IsValid()) + { + DroppingActor->SetActorTransform(TransformAtDrop, false, nullptr, ETeleportType::None); + } + } + }break; + case EGripTargetType::ComponentGrip: + { + if (UPrimitiveComponent* DroppingComp = FoundGrip.GetGrippedComponent()) + { + if (IsValid(DroppingComp) && TransformAtDrop.IsValid()) + { + DroppingComp->SetWorldTransform(TransformAtDrop, false, nullptr, ETeleportType::None); + } + } + }break; + default:break; + } + } + + if (!DropObjectByInterface_Implementation(nullptr, FoundGrip.GripID, OptAngularVelocity, OptLinearVelocity, true)) + { + DropGrip_Implementation(FoundGrip, false, OptAngularVelocity, OptLinearVelocity,true); + } +} + + +bool UGripMotionControllerComponent::Server_NotifySecondaryAttachmentChanged_Validate( + uint8 GripID, + const FBPSecondaryGripInfo& SecondaryGripInfo) +{ + return true; +} + +void UGripMotionControllerComponent::Server_NotifySecondaryAttachmentChanged_Implementation( + uint8 GripID, + const FBPSecondaryGripInfo& SecondaryGripInfo) +{ + DIRTY_LOCALLY_GRIPPED_OBJECTS(); + + FBPActorGripInformation * GripInfo = LocallyGrippedObjects.FindByKey(GripID); + if (GripInfo != nullptr) + { + FBPActorGripInformation OriginalGrip = *GripInfo; + + // I override the = operator now so that it won't set the lerp components + GripInfo->SecondaryGripInfo.RepCopy(SecondaryGripInfo); + + // Initialize the differences, clients will do this themselves on the rep back + HandleGripReplication(*GripInfo, &OriginalGrip); + } + +} + +bool UGripMotionControllerComponent::Server_NotifySecondaryAttachmentChanged_Retain_Validate( + uint8 GripID, + const FBPSecondaryGripInfo& SecondaryGripInfo, const FTransform_NetQuantize & NewRelativeTransform) +{ + return true; +} + +void UGripMotionControllerComponent::Server_NotifySecondaryAttachmentChanged_Retain_Implementation( + uint8 GripID, + const FBPSecondaryGripInfo& SecondaryGripInfo, const FTransform_NetQuantize & NewRelativeTransform) +{ + DIRTY_LOCALLY_GRIPPED_OBJECTS(); + + FBPActorGripInformation * GripInfo = LocallyGrippedObjects.FindByKey(GripID); + if (GripInfo != nullptr) + { + FBPActorGripInformation OriginalGrip = *GripInfo; + + // I override the = operator now so that it won't set the lerp components + GripInfo->SecondaryGripInfo.RepCopy(SecondaryGripInfo); + GripInfo->RelativeTransform = NewRelativeTransform; + + // Initialize the differences, clients will do this themselves on the rep back + HandleGripReplication(*GripInfo, &OriginalGrip); + } + +} +void UGripMotionControllerComponent::GetControllerDeviceID(FXRDeviceId & DeviceID, EBPVRResultSwitch &Result, bool bCheckOpenVROnly) +{ + EControllerHand ControllerHandIndex; + if (!IMotionController::GetHandEnumForSourceName(MotionSource, ControllerHandIndex)) + { + Result = EBPVRResultSwitch::OnFailed; + return; + } + + TArray XRAssetSystems = IModularFeatures::Get().GetModularFeatureImplementations(IXRSystemAssets::GetModularFeatureName()); + for (IXRSystemAssets* AssetSys : XRAssetSystems) + { + if (bCheckOpenVROnly && !AssetSys->GetSystemName().IsEqual(FName(TEXT("SteamVR")))) + continue; + + const int32 XRID = AssetSys->GetDeviceId(ControllerHandIndex); + + if (XRID != INDEX_NONE) + { + DeviceID = FXRDeviceId(AssetSys, XRID); + Result = EBPVRResultSwitch::OnSucceeded; + return; + } + } + + DeviceID = FXRDeviceId(); + Result = EBPVRResultSwitch::OnFailed; + return; +} + + +/* +* +* Custom late update manager implementation +* +*/ + +FExpandedLateUpdateManager::FExpandedLateUpdateManager() + : LateUpdateGameWriteIndex(0) + , LateUpdateRenderReadIndex(0) +{ +} + +void FExpandedLateUpdateManager::Setup(const FTransform& ParentToWorld, UGripMotionControllerComponent* Component, bool bSkipLateUpdate) +{ + if (!Component) + return; + + check(IsInGameThread()); + + + UpdateStates[LateUpdateGameWriteIndex].Primitives.Reset(); + UpdateStates[LateUpdateGameWriteIndex].ParentToWorld = ParentToWorld; + + //Add additional late updates registered to this controller that aren't children and aren't gripped + //This array is editable in blueprint and can be used for things like arms or the like. + for (UPrimitiveComponent* primComp : Component->AdditionalLateUpdateComponents) + { + if (primComp) + GatherLateUpdatePrimitives(primComp); + } + + ProcessGripArrayLateUpdatePrimitives(Component, Component->LocallyGrippedObjects); + ProcessGripArrayLateUpdatePrimitives(Component, Component->GrippedObjects); + + GatherLateUpdatePrimitives(Component); + //GatherLateUpdatePrimitives(Component); + + UpdateStates[LateUpdateGameWriteIndex].bSkip = bSkipLateUpdate; + ++UpdateStates[LateUpdateGameWriteIndex].TrackingNumber; + + int32 NextFrameRenderReadIndex = LateUpdateGameWriteIndex; + LateUpdateGameWriteIndex = 1 - LateUpdateGameWriteIndex; + + ENQUEUE_RENDER_COMMAND(UpdateLateUpdateRenderReadIndexCommand)( + [NextFrameRenderReadIndex, this](FRHICommandListImmediate& RHICmdList) + { + LateUpdateRenderReadIndex = NextFrameRenderReadIndex; + }); + +} + +//void FExpandedLateUpdateManager::Apply_RenderThread(FSceneInterface* Scene, const int32 FrameNumber, const FTransform& OldRelativeTransform, const FTransform& NewRelativeTransform) +void FExpandedLateUpdateManager::Apply_RenderThread(FSceneInterface* Scene, const FTransform& OldRelativeTransform, const FTransform& NewRelativeTransform) +{ + FRHICommandListBase& RHICmdList = FRHICommandListImmediate::Get(); + + check(IsInRenderingThread()); + + if (!UpdateStates[LateUpdateRenderReadIndex].Primitives.Num() || UpdateStates[LateUpdateRenderReadIndex].bSkip) + { + return; + } + + const FTransform OldCameraTransform = OldRelativeTransform * UpdateStates[LateUpdateRenderReadIndex].ParentToWorld; + const FTransform NewCameraTransform = NewRelativeTransform * UpdateStates[LateUpdateRenderReadIndex].ParentToWorld; + const FMatrix LateUpdateTransform = (OldCameraTransform.Inverse() * NewCameraTransform).ToMatrixWithScale(); + + bool bIndicesHaveChanged = false; + + /* + // Under HMD late-latching senario, Apply_RenderThread will be called twice in same frame under PreRenderViewFamily_RenderThread and + // LateLatchingViewFamily_RenderThread. We don't want to apply PrimitivePair.Value = -1 directly on UpdateStates[LateUpdateRenderReadIndex].Primitives + // because the modification will affect second Apply_RenderThread's logic under LateLatchingViewFamily_RenderThread. + // Since the list is very small(only affect stuff attaching to the controller), we just make a local copy PrimitivesLocal. + TMap PrimitivesLocal = UpdateStates[LateUpdateRenderReadIndex].Primitives; + for (auto& PrimitivePair : PrimitivesLocal)*/ + for (auto& PrimitivePair : UpdateStates[LateUpdateRenderReadIndex].Primitives) + { + if (PrimitivePair.Value == -1) + continue; + + FPrimitiveSceneInfo* RetrievedSceneInfo = Scene->GetPrimitiveSceneInfo(PrimitivePair.Value); + FPrimitiveSceneInfo* CachedSceneInfo = PrimitivePair.Key; + + // If the retrieved scene info is different than our cached scene info then the scene has changed in the meantime + // and we need to search through the entire scene to make sure it still exists. + if (CachedSceneInfo != RetrievedSceneInfo) + { + bIndicesHaveChanged = true; + break; // No need to continue here, as we are going to brute force the scene primitives below anyway. + } + else if (CachedSceneInfo->Proxy) + { + CachedSceneInfo->Proxy->ApplyLateUpdateTransform(RHICmdList, LateUpdateTransform); + PrimitivePair.Value = -1; // Set the cached index to -1 to indicate that this primitive was already processed + /*if (FrameNumber >= 0) + { + CachedSceneInfo->Proxy->SetPatchingFrameNumber(FrameNumber); + }*/ + } + } + + // Indices have changed, so we need to scan the entire scene for primitives that might still exist + if (bIndicesHaveChanged) + { + int32 Index = 0; + FPrimitiveSceneInfo* RetrievedSceneInfo = Scene->GetPrimitiveSceneInfo(Index++); + while (RetrievedSceneInfo) + { + /*int32* PrimitiveIndex = PrimitivesLocal.Find(RetrievedSceneInfo); + if (RetrievedSceneInfo->Proxy && PrimitiveIndex != nullptr && *PrimitiveIndex >= 0)*/ + if (RetrievedSceneInfo->Proxy && UpdateStates[LateUpdateRenderReadIndex].Primitives.Contains(RetrievedSceneInfo) && UpdateStates[LateUpdateRenderReadIndex].Primitives[RetrievedSceneInfo] >= 0) + { + RetrievedSceneInfo->Proxy->ApplyLateUpdateTransform(RHICmdList, LateUpdateTransform); + /*if (FrameNumber >= 0) + { + RetrievedSceneInfo->Proxy->SetPatchingFrameNumber(FrameNumber); + }*/ + } + RetrievedSceneInfo = Scene->GetPrimitiveSceneInfo(Index++); + } + } +} + +void FExpandedLateUpdateManager::CacheSceneInfo(USceneComponent* Component) +{ + ensureMsgf(!Component->IsUsingAbsoluteLocation() && !Component->IsUsingAbsoluteRotation(), TEXT("SceneComponents that use absolute location or rotation are not supported by the LateUpdateManager")); + // If a scene proxy is present, cache it + UPrimitiveComponent* PrimitiveComponent = dynamic_cast(Component); + if (PrimitiveComponent && PrimitiveComponent->SceneProxy) + { + FPrimitiveSceneInfo* PrimitiveSceneInfo = PrimitiveComponent->SceneProxy->GetPrimitiveSceneInfo(); + if (PrimitiveSceneInfo && PrimitiveSceneInfo->IsIndexValid()) + { + UpdateStates[LateUpdateGameWriteIndex].Primitives.Emplace(PrimitiveSceneInfo, PrimitiveSceneInfo->GetIndex()); + } + } +} + +void FExpandedLateUpdateManager::GatherLateUpdatePrimitives(USceneComponent* ParentComponent) +{ + CacheSceneInfo(ParentComponent); + TArray DirectComponents; + + // Std late updates + ParentComponent->GetChildrenComponents(true, DirectComponents); + for (USceneComponent* Component : DirectComponents) + { + if (Component != nullptr) + { + CacheSceneInfo(Component); + } + } +} + +void FExpandedLateUpdateManager::ProcessGripArrayLateUpdatePrimitives(UGripMotionControllerComponent * MotionControllerComponent, TArray & GripArray) +{ + for (FBPActorGripInformation actor : GripArray) + { + // Skip actors that are colliding if turning off late updates during collision. + // Also skip turning off late updates for SweepWithPhysics, as it should always be locked to the hand + if (!actor.GrippedObject || actor.GripCollisionType == EGripCollisionType::EventsOnly) + continue; + + // Handle late updates even with attachment, we need to add it to a skip list for the primary gatherer to process + if (actor.GripCollisionType == EGripCollisionType::AttachmentGrip) + { + continue; + } + + // Don't allow late updates with server sided movement, there is no point + if (actor.GripMovementReplicationSetting == EGripMovementReplicationSettings::ForceServerSideMovement && !MotionControllerComponent->IsServer()) + continue; + + // Don't late update paused grips + if (actor.bIsPaused) + continue; + + switch (actor.GripLateUpdateSetting) + { + case EGripLateUpdateSettings::LateUpdatesAlwaysOff: + { + continue; + }break; + case EGripLateUpdateSettings::NotWhenColliding: + { + if (actor.bColliding && actor.GripCollisionType != EGripCollisionType::SweepWithPhysics && + actor.GripCollisionType != EGripCollisionType::PhysicsOnly) + continue; + }break; + case EGripLateUpdateSettings::NotWhenDoubleGripping: + { + if (actor.SecondaryGripInfo.bHasSecondaryAttachment) + continue; + }break; + case EGripLateUpdateSettings::NotWhenCollidingOrDoubleGripping: + { + if ( + (actor.bColliding && actor.GripCollisionType != EGripCollisionType::SweepWithPhysics && actor.GripCollisionType != EGripCollisionType::PhysicsOnly) || + (actor.SecondaryGripInfo.bHasSecondaryAttachment) + ) + { + continue; + } + }break; + case EGripLateUpdateSettings::LateUpdatesAlwaysOn: + default: + {}break; + } + + // Don't run late updates if we have a grip script that denies it + if (actor.GrippedObject->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + TArray GripScripts; + if (IVRGripInterface::Execute_GetGripScripts(actor.GrippedObject, GripScripts)) + { + bool bContinueOn = false; + for (UVRGripScriptBase* Script : GripScripts) + { + if (Script && Script->IsScriptActive() && Script->Wants_DenyLateUpdates()) + { + bContinueOn = true; + break; + } + } + + if (bContinueOn) + continue; + } + } + + // Get late update primitives + switch (actor.GripTargetType) + { + case EGripTargetType::ActorGrip: + //case EGripTargetType::InteractibleActorGrip: + { + AActor * pActor = actor.GetGrippedActor(); + if (pActor) + { + if (USceneComponent * rootComponent = pActor->GetRootComponent()) + { + GatherLateUpdatePrimitives(rootComponent); + } + } + + }break; + + case EGripTargetType::ComponentGrip: + //case EGripTargetType::InteractibleComponentGrip: + { + UPrimitiveComponent * cPrimComp = actor.GetGrippedComponent(); + if (cPrimComp) + { + GatherLateUpdatePrimitives(cPrimComp); + } + }break; + } + } +} + +void UGripMotionControllerComponent::GetHandType(EControllerHand& Hand) +{ + if (!IMotionController::GetHandEnumForSourceName(MotionSource, Hand)) + { + // Check if the palm motion source extension is being used + // I assume eventually epic will handle this case + if (MotionSource.Compare(FName(TEXT("RightPalm"))) == 0) + { + Hand = EControllerHand::Right; + } + // Could skip this and default to left now but would rather check + else if (MotionSource.Compare(FName(TEXT("LeftPalm"))) == 0) + { + Hand = EControllerHand::Left; + } + else + { + Hand = EControllerHand::Left; + } + } +} + +void UGripMotionControllerComponent::SetCustomPivotComponent(USceneComponent * NewCustomPivotComponent, FName PivotSocketName) +{ + CustomPivotComponent = NewCustomPivotComponent; + CustomPivotComponentSocketName = PivotSocketName; +} + +FTransform UGripMotionControllerComponent::GetPivotTransform_BP() +{ + return GetPivotTransform(); +} + +FVector UGripMotionControllerComponent::GetPivotLocation_BP() +{ + return GetPivotLocation(); +} + +FTransform UGripMotionControllerComponent::ConvertToControllerRelativeTransform(const FTransform & InTransform) +{ + return InTransform.GetRelativeTransform(!bSkipPivotTransformAdjustment && IsValid(CustomPivotComponent) ? CustomPivotComponent->GetSocketTransform(CustomPivotComponentSocketName) : this->GetComponentTransform()); +} + +FTransform UGripMotionControllerComponent::ConvertToGripRelativeTransform(const FTransform& GrippedActorTransform, const FTransform & InTransform) +{ + return InTransform.GetRelativeTransform(GrippedActorTransform); +} + +bool UGripMotionControllerComponent::GetIsObjectHeld(const UObject * ObjectToCheck) +{ + if (!ObjectToCheck) + return false; + + return (GrippedObjects.FindByKey(ObjectToCheck) || LocallyGrippedObjects.FindByKey(ObjectToCheck)); +} + +bool UGripMotionControllerComponent::GetIsHeld(const AActor * ActorToCheck) +{ + if (!ActorToCheck) + return false; + + return (GrippedObjects.FindByKey(ActorToCheck) || LocallyGrippedObjects.FindByKey(ActorToCheck)); +} + +bool UGripMotionControllerComponent::GetIsComponentHeld(const UPrimitiveComponent * ComponentToCheck) +{ + if (!ComponentToCheck) + return false; + + return (GrippedObjects.FindByKey(ComponentToCheck) || LocallyGrippedObjects.FindByKey(ComponentToCheck)); + + //return false; +} + +bool UGripMotionControllerComponent::GetIsSecondaryAttachment(const USceneComponent * ComponentToCheck, FBPActorGripInformation & Grip) +{ + if (!ComponentToCheck) + return false; + + for (int i = 0; i < GrippedObjects.Num(); ++i) + { + if (GrippedObjects[i].SecondaryGripInfo.bHasSecondaryAttachment && GrippedObjects[i].SecondaryGripInfo.SecondaryAttachment == ComponentToCheck) + { + Grip = GrippedObjects[i]; + return true; + } + } + + for (int i = 0; i < LocallyGrippedObjects.Num(); ++i) + { + if (LocallyGrippedObjects[i].SecondaryGripInfo.bHasSecondaryAttachment && LocallyGrippedObjects[i].SecondaryGripInfo.SecondaryAttachment == ComponentToCheck) + { + Grip = LocallyGrippedObjects[i]; + return true; + } + } + + return false; +} + +bool UGripMotionControllerComponent::HasGrippedObjects() +{ + return GrippedObjects.Num() > 0 || LocallyGrippedObjects.Num() > 0; +} + +bool UGripMotionControllerComponent::SetUpPhysicsHandle_BP(const FBPActorGripInformation &Grip) +{ + return SetUpPhysicsHandle(Grip); +} + +bool UGripMotionControllerComponent::DestroyPhysicsHandle_BP(const FBPActorGripInformation &Grip) +{ + return DestroyPhysicsHandle(Grip); +} + +bool UGripMotionControllerComponent::UpdatePhysicsHandle_BP(const FBPActorGripInformation& Grip, bool bFullyRecreate) +{ + return UpdatePhysicsHandle(Grip.GripID, bFullyRecreate); +} + +bool UGripMotionControllerComponent::GetPhysicsHandleSettings(const FBPActorGripInformation& Grip, FBPAdvancedPhysicsHandleSettings& PhysicsHandleSettingsOut) +{ + FBPActorPhysicsHandleInformation * HandleInfo = GetPhysicsGrip(Grip); + + if (!HandleInfo) + return false; + + PhysicsHandleSettingsOut.FillFrom(HandleInfo); + return true; +} + +bool UGripMotionControllerComponent::SetPhysicsHandleSettings(const FBPActorGripInformation& Grip, const FBPAdvancedPhysicsHandleSettings& PhysicsHandleSettingsIn) +{ + FBPActorPhysicsHandleInformation* HandleInfo = GetPhysicsGrip(Grip); + + if (!HandleInfo) + return false; + + PhysicsHandleSettingsIn.FillTo(HandleInfo); + return UpdatePhysicsHandle(Grip, true); +} + + +void UGripMotionControllerComponent::UpdatePhysicsHandleTransform_BP(const FBPActorGripInformation &GrippedActor, const FTransform& NewTransform) +{ + return UpdatePhysicsHandleTransform(GrippedActor, NewTransform); +} + +bool UGripMotionControllerComponent::GetGripDistance_BP(FBPActorGripInformation &Grip, FVector ExpectedLocation, float & CurrentDistance) +{ + if (!Grip.GrippedObject) + return false; + + UPrimitiveComponent * RootComp = nullptr; + + if (Grip.GripTargetType == EGripTargetType::ActorGrip) + { + RootComp = Cast(Grip.GetGrippedActor()->GetRootComponent()); + } + else + RootComp = Grip.GetGrippedComponent(); + + if (!RootComp) + return false; + + FVector CheckDistance; + if (!GetPhysicsJointLength(Grip, RootComp, CheckDistance)) + { + CheckDistance = (ExpectedLocation - RootComp->GetComponentLocation()); + } + // Set grip distance now for people to use + CurrentDistance = CheckDistance.Size(); + return true; +} + +bool UGripMotionControllerComponent::GripControllerIsTracked() const +{ + return IsTracked(); +} + +bool UGripMotionControllerComponent::HasAuthority() const +{ + return bHasAuthority; +} + +void UGripMotionControllerComponent::CheckTransactionBuffer() +{ + if (LocalTransactionBuffer.Num()) + { + for (int i = LocalTransactionBuffer.Num() - 1; i >= 0; --i) + { + if (LocalTransactionBuffer[i].ValueCache.bWasInitiallyRepped && LocalTransactionBuffer[i].GripID != LocalTransactionBuffer[i].ValueCache.CachedGripID) + { + // There appears to be a bug with TArray replication where if you replace an index with another value of that + // Index, it doesn't fully re-init the object, this is a workaround to re-zero non replicated variables + // when that happens. + LocalTransactionBuffer[i].ClearNonReppingItems(); + } + + if (!LocalTransactionBuffer[i].ValueCache.bWasInitiallyRepped && LocalTransactionBuffer[i].GrippedObject->IsValidLowLevelFast()) + { + LocalTransactionBuffer[i].ValueCache.bWasInitiallyRepped = true; + LocalTransactionBuffer[i].ValueCache.CachedGripID = LocalTransactionBuffer[i].GripID; + + int32 Index = LocallyGrippedObjects.Add(LocalTransactionBuffer[i]); + DIRTY_LOCALLY_GRIPPED_OBJECTS(); + + if (Index != INDEX_NONE) + { + NotifyGrip(LocallyGrippedObjects[Index]); + } + + Server_NotifyHandledTransaction(LocalTransactionBuffer[i].GripID); + } + } + } +} + +///////////////////////////////////////////////// +//- Push networking getter / setter functions +///////////////////////////////////////////////// + +void UGripMotionControllerComponent::SetSmoothReplicatedMotion(bool bNewSmoothReplicatedMotion) +{ + bSmoothReplicatedMotion = bNewSmoothReplicatedMotion; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, bSmoothReplicatedMotion, this); +#endif +} + +void UGripMotionControllerComponent::SetReplicateWithoutTracking(bool bNewReplicateWithoutTracking) +{ + bReplicateWithoutTracking = bNewReplicateWithoutTracking; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, bReplicateWithoutTracking, this); +#endif +} + +void UGripMotionControllerComponent::SetControllerNetUpdateRate(float NewControllerNetUpdateRate) +{ + ControllerNetUpdateRate = NewControllerNetUpdateRate; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, ControllerNetUpdateRate, this); +#endif +} + +void UGripMotionControllerComponent::DIRTY_GRIPPED_OBJECTS() +{ +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, GrippedObjects, this); +#endif +} + +void UGripMotionControllerComponent::DIRTY_LOCALLY_GRIPPED_OBJECTS() +{ +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, LocallyGrippedObjects, this); +#endif +} + +///////////////////////////////////////////////// +//- End Push networking getter / setter functions +///////////////////////////////////////////////// \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_Default.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_Default.cpp new file mode 100644 index 0000000..96f36c8 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_Default.cpp @@ -0,0 +1,233 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#include "GripScripts/GS_Default.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GS_Default) + +#include "VRGripInterface.h" +#include "Components/PrimitiveComponent.h" +#include "GameFramework/Actor.h" +#include "GameFramework/WorldSettings.h" +#include "GripMotionControllerComponent.h" + +UGS_Default::UGS_Default(const FObjectInitializer& ObjectInitializer) : + Super(ObjectInitializer) +{ + bIsActive = true; + WorldTransformOverrideType = EGSTransformOverrideType::OverridesWorldTransform; +} + +void UGS_Default::GetAnyScaling(FVector& Scaler, FBPActorGripInformation& Grip, FVector& frontLoc, FVector& frontLocOrig, ESecondaryGripType SecondaryType, FTransform& SecondaryTransform) +{ + if (Grip.SecondaryGripInfo.GripLerpState != EGripLerpState::EndLerp) + { + //float Scaler = 1.0f; + if (SecondaryType == ESecondaryGripType::SG_FreeWithScaling_Retain || SecondaryType == ESecondaryGripType::SG_SlotOnlyWithScaling_Retain || SecondaryType == ESecondaryGripType::SG_ScalingOnly) + { + /*Grip.SecondaryScaler*/ Scaler = FVector(frontLoc.Size() / frontLocOrig.Size()); + //bRescalePhysicsGrips = true; // This is for the physics grips + } + } +} + +void UGS_Default::ApplySmoothingAndLerp(FBPActorGripInformation& Grip, FVector& frontLoc, FVector& frontLocOrig, float DeltaTime) +{ + if (Grip.SecondaryGripInfo.GripLerpState == EGripLerpState::StartLerp) // Lerp into the new grip to smooth the transition + { + /*if (Grip.AdvancedGripSettings.SecondaryGripSettings.SecondaryGripScaler_DEPRECATED < 1.0f) + { + FVector SmoothedValue = Grip.AdvancedGripSettings.SecondaryGripSettings.SecondarySmoothing.RunFilterSmoothing(frontLoc, DeltaTime); + + frontLoc = FMath::Lerp(SmoothedValue, frontLoc, Grip.AdvancedGripSettings.SecondaryGripSettings.SecondaryGripScaler_DEPRECATED); + }*/ + + frontLocOrig = FMath::Lerp(frontLocOrig, frontLoc, FMath::Clamp(Grip.SecondaryGripInfo.curLerp / Grip.SecondaryGripInfo.LerpToRate, 0.0f, 1.0f)); + } + /*else if (Grip.SecondaryGripInfo.GripLerpState == EGripLerpState::ConstantLerp_DEPRECATED) // If there is a frame by frame lerp + { + FVector SmoothedValue = Grip.AdvancedGripSettings.SecondaryGripSettings.SecondarySmoothing.RunFilterSmoothing(frontLoc, DeltaTime); + + frontLoc = FMath::Lerp(SmoothedValue, frontLoc, Grip.AdvancedGripSettings.SecondaryGripSettings.SecondaryGripScaler_DEPRECATED); + }*/ +} + +bool UGS_Default::GetWorldTransform_Implementation +( + UGripMotionControllerComponent* GrippingController, + float DeltaTime, FTransform& WorldTransform, + const FTransform& ParentTransform, + FBPActorGripInformation& Grip, + AActor* actor, + UPrimitiveComponent* root, + bool bRootHasInterface, + bool bActorHasInterface, + bool bIsForTeleport +) +{ + if (!GrippingController) + return false; + + // Just simple transform setting + WorldTransform = Grip.RelativeTransform * Grip.AdditionTransform * ParentTransform; + + // Check the grip lerp state, this it ouside of the secondary attach check below because it can change the result of it + if ((Grip.SecondaryGripInfo.bHasSecondaryAttachment && Grip.SecondaryGripInfo.SecondaryAttachment) || Grip.SecondaryGripInfo.GripLerpState == EGripLerpState::EndLerp) + { + switch (Grip.SecondaryGripInfo.GripLerpState) + { + case EGripLerpState::StartLerp: + case EGripLerpState::EndLerp: + { + if (Grip.SecondaryGripInfo.curLerp > 0.01f) + Grip.SecondaryGripInfo.curLerp -= DeltaTime; + else + { + /*if (Grip.SecondaryGripInfo.bHasSecondaryAttachment && + Grip.AdvancedGripSettings.SecondaryGripSettings.bUseSecondaryGripSettings && + Grip.AdvancedGripSettings.SecondaryGripSettings.SecondaryGripScaler_DEPRECATED < 1.0f) + { + Grip.SecondaryGripInfo.GripLerpState = EGripLerpState::ConstantLerp_DEPRECATED; + } + else*/ + Grip.SecondaryGripInfo.GripLerpState = EGripLerpState::NotLerping; + } + + }break; + //case EGripLerpState::ConstantLerp_DEPRECATED: + case EGripLerpState::NotLerping: + default:break; + } + } + + // Handle the interp and multi grip situations, re-checking the grip situation here as it may have changed in the switch above. + if ((Grip.SecondaryGripInfo.bHasSecondaryAttachment && Grip.SecondaryGripInfo.SecondaryAttachment) || Grip.SecondaryGripInfo.GripLerpState == EGripLerpState::EndLerp) + { + FTransform SecondaryTransform = Grip.RelativeTransform * ParentTransform; + + // Checking secondary grip type for the scaling setting + ESecondaryGripType SecondaryType = ESecondaryGripType::SG_None; + + if (bRootHasInterface) + SecondaryType = IVRGripInterface::Execute_SecondaryGripType(root); + else if (bActorHasInterface) + SecondaryType = IVRGripInterface::Execute_SecondaryGripType(actor); + + // If the grip is a custom one, skip all of this logic we won't be changing anything + if (SecondaryType != ESecondaryGripType::SG_Custom) + { + // Variables needed for multi grip transform + FVector BasePoint = ParentTransform.GetLocation(); // Get our pivot point + const FTransform PivotToWorld = FTransform(FQuat::Identity, BasePoint); + const FTransform WorldToPivot = FTransform(FQuat::Identity, -BasePoint); + + FVector frontLocOrig; + FVector frontLoc; + + // Ending lerp out of a multi grip + if (Grip.SecondaryGripInfo.GripLerpState == EGripLerpState::EndLerp) + { + frontLocOrig = (/*WorldTransform*/SecondaryTransform.TransformPosition(Grip.SecondaryGripInfo.SecondaryRelativeTransform.GetLocation())) - BasePoint; + frontLoc = Grip.SecondaryGripInfo.LastRelativeLocation; + + frontLocOrig = FMath::Lerp(frontLoc, frontLocOrig, FMath::Clamp(Grip.SecondaryGripInfo.curLerp / Grip.SecondaryGripInfo.LerpToRate, 0.0f, 1.0f)); + } + else // Is in a multi grip, might be lerping into it as well. + { + //FVector curLocation; // Current location of the secondary grip + + // Calculates the correct secondary attachment location and sets frontLoc to it + CalculateSecondaryLocation(frontLoc, BasePoint, Grip, GrippingController); + + frontLocOrig = (/*WorldTransform*/SecondaryTransform.TransformPosition(Grip.SecondaryGripInfo.SecondaryRelativeTransform.GetLocation())) - BasePoint; + + // Apply any smoothing settings and lerping in / constant lerping + ApplySmoothingAndLerp(Grip, frontLoc, frontLocOrig, DeltaTime); + + Grip.SecondaryGripInfo.LastRelativeLocation = frontLoc; + } + + // Get any scaling addition from a scaling secondary grip type + FVector Scaler = FVector(1.0f); + if (SecondaryType == ESecondaryGripType::SG_FreeWithScaling_Retain || SecondaryType == ESecondaryGripType::SG_SlotOnlyWithScaling_Retain || SecondaryType == ESecondaryGripType::SG_ScalingOnly) + { + GetAnyScaling(Scaler, Grip, frontLoc, frontLocOrig, SecondaryType, SecondaryTransform); + } + + Grip.SecondaryGripInfo.SecondaryGripDistance = FVector::Dist(frontLocOrig, frontLoc); + + /*if (Grip.AdvancedGripSettings.SecondaryGripSettings.bUseSecondaryGripSettings && Grip.AdvancedGripSettings.SecondaryGripSettings.bUseSecondaryGripDistanceInfluence_DEPRECATED) + { + float rotScaler = 1.0f - FMath::Clamp((Grip.SecondaryGripInfo.SecondaryGripDistance - Grip.AdvancedGripSettings.SecondaryGripSettings.GripInfluenceDeadZone_DEPRECATED) / FMath::Max(Grip.AdvancedGripSettings.SecondaryGripSettings.GripInfluenceDistanceToZero_DEPRECATED, 1.0f), 0.0f, 1.0f); + frontLoc = FMath::Lerp(frontLocOrig, frontLoc, rotScaler); + }*/ + + // Skip rot val for scaling only + if (SecondaryType != ESecondaryGripType::SG_ScalingOnly) + { + // Get the rotation difference from the initial second grip + FQuat rotVal = FQuat::FindBetweenVectors(frontLocOrig, frontLoc); + + // Rebase the world transform to the pivot point, add the rotation, remove the pivot point rebase + WorldTransform = WorldTransform * WorldToPivot * FTransform(rotVal, FVector::ZeroVector, Scaler) * PivotToWorld; + } + else + { + // Rebase the world transform to the pivot point, add the scaler, remove the pivot point rebase + WorldTransform = WorldTransform * WorldToPivot * FTransform(FQuat::Identity, FVector::ZeroVector, Scaler) * PivotToWorld; + } + } + } + return true; +} + +void UGS_Default::CalculateSecondaryLocation(FVector& frontLoc, const FVector& BasePoint, FBPActorGripInformation& Grip, UGripMotionControllerComponent* GrippingController) +{ + bool bPulledControllerLoc = false; + if (UGripMotionControllerComponent* OtherController = Cast(Grip.SecondaryGripInfo.SecondaryAttachment)) + { + bool bPulledCurrentTransform = false; + + if (IsValid(OtherController->CustomPivotComponent)) + { + FTransform SecondaryTrans = FTransform::Identity; + SecondaryTrans = OtherController->GetPivotTransform(); + bPulledControllerLoc = true; + frontLoc = SecondaryTrans.GetLocation() - BasePoint; + } + } + + if (!bPulledControllerLoc) + { + frontLoc = Grip.SecondaryGripInfo.SecondaryAttachment->GetComponentLocation() - BasePoint; + } +} + +void UGS_ExtendedDefault::GetAnyScaling(FVector& Scaler, FBPActorGripInformation& Grip, FVector& frontLoc, FVector& frontLocOrig, ESecondaryGripType SecondaryType, FTransform& SecondaryTransform) +{ + if (Grip.SecondaryGripInfo.GripLerpState != EGripLerpState::EndLerp) + { + + //float Scaler = 1.0f; + if (SecondaryType == ESecondaryGripType::SG_FreeWithScaling_Retain || SecondaryType == ESecondaryGripType::SG_SlotOnlyWithScaling_Retain || SecondaryType == ESecondaryGripType::SG_ScalingOnly) + { + /*Grip.SecondaryScaler*/ Scaler = FVector(frontLoc.Size() / frontLocOrig.Size()); + //bRescalePhysicsGrips = true; // This is for the physics grips + + if (bLimitGripScaling) + { + // Get the total scale after modification + // #TODO: convert back to singular float version? Can get Min() & Max() to convert the float to a range...think about it + FVector WorldScale = /*WorldTransform*/SecondaryTransform.GetScale3D(); + FVector CombinedScale = WorldScale * Scaler; + + // Clamp to the minimum and maximum values + CombinedScale.X = FMath::Clamp(CombinedScale.X, MinimumGripScaling.X, MaximumGripScaling.X); + CombinedScale.Y = FMath::Clamp(CombinedScale.Y, MinimumGripScaling.Y, MaximumGripScaling.Y); + CombinedScale.Z = FMath::Clamp(CombinedScale.Z, MinimumGripScaling.Z, MaximumGripScaling.Z); + + // Recreate in scaler form so that the transform chain below works as normal + Scaler = CombinedScale / WorldScale; + } + //Scaler = Grip.SecondaryScaler; + } + } +} diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_GunTools.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_GunTools.cpp new file mode 100644 index 0000000..21f2762 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_GunTools.cpp @@ -0,0 +1,604 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#include "GripScripts/GS_GunTools.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GS_GunTools) + +#include "VRGripInterface.h" +#include "GripMotionControllerComponent.h" +#include "VRExpansionFunctionLibrary.h" +#include "IXRTrackingSystem.h" +#include "VRGlobalSettings.h" +#include "VRBaseCharacter.h" +#include "VRCharacter.h" +#include "VRRootComponent.h" +#include "Components/PrimitiveComponent.h" +#include "GameFramework/Actor.h" +//#include "Camera/CameraComponent.h" +#include "ReplicatedVRCameraComponent.h" +#include "DrawDebugHelpers.h" + +UGS_GunTools::UGS_GunTools(const FObjectInitializer& ObjectInitializer) : + Super(ObjectInitializer) +{ + bIsActive = true; + WorldTransformOverrideType = EGSTransformOverrideType::OverridesWorldTransform; + PivotOffset = FVector::ZeroVector; + VirtualStockComponent = nullptr; + MountWorldTransform = FTransform::Identity; + //StockSnapOffset = FVector(0.f, 0.f, 0.f); + bIsMounted = false; + + + bHasRecoil = false; + bApplyRecoilAsPhysicalForce = false; + MaxRecoilTranslation = FVector::ZeroVector; + MaxRecoilRotation = FVector::ZeroVector; + MaxRecoilScale = FVector(1.f); + bHasActiveRecoil = false; + DecayRate = 20.f; + LerpRate = 30.f; + + BackEndRecoilStorage = FTransform::Identity; + + bUseGlobalVirtualStockSettings = true; + + bUseHighQualityRemoteSimulation = false; + + bInjectPrePhysicsHandle = true; + //bInjectPostPhysicsHandle = true; + WeaponRootOrientationComponent = NAME_None; + OrientationComponentRelativeFacing = FTransform::Identity; + StoredRootOffset = FQuat::Identity; +} + +void UGS_GunTools::OnBeginPlay_Implementation(UObject* CallingOwner) +{ + // Grip base has no super of this + + if (WeaponRootOrientationComponent.IsValid()) + { + if (AActor * Owner = GetOwner()) + { + FName CurrentCompName = NAME_None; + for (UActorComponent* ChildComp : Owner->GetComponents()) + { + CurrentCompName = ChildComp->GetFName(); + if (CurrentCompName == NAME_None) + continue; + + if (CurrentCompName == WeaponRootOrientationComponent) + { + if (USceneComponent * SceneComp = Cast(ChildComp)) + { + OrientationComponentRelativeFacing = SceneComp->GetRelativeTransform(); + } + + break; + } + } + } + } +} + +void UGS_GunTools::HandlePrePhysicsHandle(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation &GripInfo, FBPActorPhysicsHandleInformation* HandleInfo, FTransform& KinPose) +{ + if (!bIsActive) + return; + + if (WeaponRootOrientationComponent != NAME_None) + { + StoredRootOffset = HandleInfo->RootBoneRotation.GetRotation().Inverse() * OrientationComponentRelativeFacing.GetRotation(); + + // Alter to rotate to x+ if we have an orientation component + FQuat DeltaQuat = OrientationComponentRelativeFacing.GetRotation(); + + KinPose.SetRotation(KinPose.GetRotation() * StoredRootOffset); + HandleInfo->COMPosition.SetRotation(HandleInfo->COMPosition.GetRotation() * StoredRootOffset); + } + else + { + StoredRootOffset = FQuat::Identity; + } + + if (GripInfo.bIsSlotGrip && !PivotOffset.IsZero()) + { + KinPose.SetLocation(KinPose.TransformPosition(PivotOffset)); + HandleInfo->COMPosition.SetLocation(HandleInfo->COMPosition.TransformPosition(PivotOffset)); + } +} + +/*void UGS_GunTools::HandlePostPhysicsHandle(UGripMotionControllerComponent* GrippingController, FBPActorPhysicsHandleInformation* HandleInfo) +{ +}*/ + +bool UGS_GunTools::GetWorldTransform_Implementation +( + UGripMotionControllerComponent* GrippingController, + float DeltaTime, FTransform & WorldTransform, + const FTransform &ParentTransform, + FBPActorGripInformation &Grip, + AActor * actor, + UPrimitiveComponent * root, + bool bRootHasInterface, + bool bActorHasInterface, + bool bIsForTeleport +) +{ + if (!GrippingController) + return false; + + bool bSkipHighQualityOperations = !bUseHighQualityRemoteSimulation && !GrippingController->HasAuthority(); + + /*if (!GunViewExtension.IsValid() && GEngine) + { + GunViewExtension = FSceneViewExtensions::NewExtension(GrippingController); + }*/ + + // Just simple transform setting + if (bHasRecoil && bHasActiveRecoil) + { + BackEndRecoilStorage.Blend(BackEndRecoilStorage, BackEndRecoilTarget, FMath::Clamp(LerpRate * DeltaTime, 0.f, 1.f)); + BackEndRecoilTarget.Blend(BackEndRecoilTarget, FTransform::Identity, FMath::Clamp(DecayRate * DeltaTime, 0.f, 1.f)); + bHasActiveRecoil = !BackEndRecoilTarget.Equals(FTransform::Identity); + + if (!bHasActiveRecoil) + { + BackEndRecoilStorage.SetIdentity(); + BackEndRecoilTarget.SetIdentity(); + } + } + + if (bHasActiveRecoil) + { + // Using a matrix to avoid FTransform inverse math issues + FTransform relTransform(Grip.RelativeTransform.ToInverseMatrixWithScale()); + + // Eventually may want to adjust the pivot of the recoil rotation by the PivotOffset vector... + FVector Pivot = relTransform.GetLocation() + PivotOffset; + const FTransform PivotToWorld = FTransform(FQuat::Identity, Pivot); + const FTransform WorldToPivot = FTransform(FQuat::Identity, -Pivot); + + WorldTransform = WorldToPivot * BackEndRecoilStorage * PivotToWorld * Grip.RelativeTransform * Grip.AdditionTransform * ParentTransform; + } + else + WorldTransform = Grip.RelativeTransform * Grip.AdditionTransform * ParentTransform; + + // Check the grip lerp state, this it ouside of the secondary attach check below because it can change the result of it + if (Grip.SecondaryGripInfo.bHasSecondaryAttachment && Grip.SecondaryGripInfo.SecondaryAttachment) + { + if (!bSkipHighQualityOperations && bUseVirtualStock) + { + if (IsValid(VirtualStockComponent)) + { + FRotator PureYaw = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(VirtualStockComponent->GetComponentRotation()); + MountWorldTransform = FTransform(PureYaw.Quaternion(), VirtualStockComponent->GetComponentLocation() + PureYaw.RotateVector(VirtualStockSettings.StockSnapOffset)); + } + /*else if (GrippingController->bHasAuthority && GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowedForWorld(*GetWorld())) + { + FQuat curRot = FQuat::Identity; + FVector curLoc = FVector::ZeroVector; + + if (GEngine->XRSystem->GetCurrentPose(IXRTrackingSystem::HMDDeviceId, curRot, curLoc)) + { + // Translate hmd offset by the gripping controllers parent component, this should be in the same space + FRotator PureYaw = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(curRot.Rotator()); + + if (AVRCharacter* OwningCharacter = Cast(GrippingController->GetOwner())) + { + if (!OwningCharacter->bRetainRoomscale) + { + curLoc.X = 0.0f; + curLoc.Y = 0.0f; + curLoc += PureYaw.RotateVector(FVector(-OwningCharacter->VRRootReference->VRCapsuleOffset.X, -OwningCharacter->VRRootReference->VRCapsuleOffset.Y, -OwningCharacter->VRRootReference->GetScaledCapsuleHalfHeight())); + } + } + + MountWorldTransform = FTransform(PureYaw.Quaternion(), curLoc + PureYaw.RotateVector(VirtualStockSettings.StockSnapOffset)) * GrippingController->GetAttachParent()->GetComponentTransform(); + } + }*/ + else if(IsValid(CameraComponent)) + { + FRotator PureYaw = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(CameraComponent->GetComponentRotation()); + MountWorldTransform = FTransform(PureYaw.Quaternion(), CameraComponent->GetComponentLocation() + PureYaw.RotateVector(VirtualStockSettings.StockSnapOffset)); + } + + float StockSnapDistance = FMath::Square(VirtualStockSettings.StockSnapDistance); + float DistSquared = FVector::DistSquared(ParentTransform.GetTranslation(), MountWorldTransform.GetTranslation()); + + if (!VirtualStockSettings.bUseDistanceBasedStockSnapping || (DistSquared <= StockSnapDistance)) + { + + float StockSnapLerpThresh = FMath::Square(VirtualStockSettings.StockSnapLerpThreshold); + + if (StockSnapLerpThresh > 0.0f) + VirtualStockSettings.StockLerpValue = 1.0f - FMath::Clamp((DistSquared - (StockSnapDistance - StockSnapLerpThresh)) / StockSnapLerpThresh, 0.0f, 1.0f); + else + VirtualStockSettings.StockLerpValue = 1.0f; // Just skip lerping logic + + if (!bIsMounted) + { + VirtualStockSettings.StockHandSmoothing.ResetSmoothingFilter(); + + // Mount up + bIsMounted = true; + OnVirtualStockModeChanged.Broadcast(bIsMounted); + } + + // Adjust the mount location to follow the Z of the primary hand + if (VirtualStockSettings.bAdjustZOfStockToPrimaryHand) + { + FVector WorldTransVec = MountWorldTransform.GetTranslation(); + + if (WorldTransVec.Z >= ParentTransform.GetTranslation().Z) + { + WorldTransVec.Z = ParentTransform.GetTranslation().Z; + MountWorldTransform.SetLocation(WorldTransVec); + } + } + +#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) + if (VirtualStockSettings.bDebugDrawVirtualStock) + { + DrawDebugLine(GetWorld(), ParentTransform.GetTranslation(), MountWorldTransform.GetTranslation(), FColor::Red); + DrawDebugLine(GetWorld(), Grip.SecondaryGripInfo.SecondaryAttachment->GetComponentLocation(), MountWorldTransform.GetTranslation(), FColor::Green); + DrawDebugSphere(GetWorld(), MountWorldTransform.GetTranslation(), 10.f, 32, FColor::White); + } +#endif + } + else + { + if (bIsMounted) + { + bIsMounted = false; + VirtualStockSettings.StockLerpValue = 0.0f; + OnVirtualStockModeChanged.Broadcast(bIsMounted); + } + } + } + } + else + { + if (bIsMounted) + { + bIsMounted = false; + VirtualStockSettings.StockLerpValue = 0.0f; + OnVirtualStockModeChanged.Broadcast(bIsMounted); + } + } + + // Check the grip lerp state, this it ouside of the secondary attach check below because it can change the result of it + if ((Grip.SecondaryGripInfo.bHasSecondaryAttachment && Grip.SecondaryGripInfo.SecondaryAttachment) || Grip.SecondaryGripInfo.GripLerpState == EGripLerpState::EndLerp) + { + switch (Grip.SecondaryGripInfo.GripLerpState) + { + case EGripLerpState::StartLerp: + case EGripLerpState::EndLerp: + { + if (Grip.SecondaryGripInfo.curLerp > 0.01f) + Grip.SecondaryGripInfo.curLerp -= DeltaTime; + else + { + Grip.SecondaryGripInfo.GripLerpState = EGripLerpState::NotLerping; + } + + }break; + //case EGripLerpState::ConstantLerp_DEPRECATED: + case EGripLerpState::NotLerping: + default:break; + } + } + + // Handle the interp and multi grip situations, re-checking the grip situation here as it may have changed in the switch above. + if ((Grip.SecondaryGripInfo.bHasSecondaryAttachment && Grip.SecondaryGripInfo.SecondaryAttachment) || Grip.SecondaryGripInfo.GripLerpState == EGripLerpState::EndLerp) + { + FTransform NewWorldTransform = WorldTransform; + FTransform SecondaryTransform = Grip.RelativeTransform * ParentTransform; + + // Checking secondary grip type for the scaling setting + ESecondaryGripType SecondaryType = ESecondaryGripType::SG_None; + + if (bRootHasInterface) + SecondaryType = IVRGripInterface::Execute_SecondaryGripType(root); + else if (bActorHasInterface) + SecondaryType = IVRGripInterface::Execute_SecondaryGripType(actor); + + // If the grip is a custom one, skip all of this logic we won't be changing anything + if (SecondaryType != ESecondaryGripType::SG_Custom) + { + // Variables needed for multi grip transform + FVector BasePoint = ParentTransform.GetLocation(); + FVector Pivot = ParentTransform.GetLocation(); + + if (Grip.bIsSlotGrip) + { + if (FBPActorPhysicsHandleInformation * PhysHandle = GrippingController->GetPhysicsGrip(Grip)) + { + Pivot = SecondaryTransform.TransformPositionNoScale(SecondaryTransform.InverseTransformPositionNoScale(Pivot) + (StoredRootOffset * PhysHandle->RootBoneRotation.GetRotation()).RotateVector(PivotOffset)); + } + else + { + Pivot = SecondaryTransform.TransformPositionNoScale(SecondaryTransform.InverseTransformPositionNoScale(Pivot) + OrientationComponentRelativeFacing.GetRotation().RotateVector(PivotOffset)); + } + } + + // Debug draw for COM movement with physics grips +#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) + static const auto CVarDrawCOMDebugSpheresAccess = IConsoleManager::Get().FindConsoleVariable(TEXT("vr.DrawDebugCenterOfMassForGrips")); + if (CVarDrawCOMDebugSpheresAccess->GetInt() > 0) + { + DrawDebugSphere(GetWorld(), Pivot, 5, 32, FColor::Orange, false); + } +#endif + + const FTransform PivotToWorld = FTransform(FQuat::Identity, Pivot);//BasePoint); + const FTransform WorldToPivot = FTransform(FQuat::Identity, -Pivot);//-BasePoint); + + FVector frontLocOrig; + FVector frontLoc; + + // Ending lerp out of a multi grip + if (Grip.SecondaryGripInfo.GripLerpState == EGripLerpState::EndLerp) + { + WorldTransform.Blend(WorldTransform, RelativeTransOnSecondaryRelease* GrippingController->GetPivotTransform(), FMath::Clamp(Grip.SecondaryGripInfo.curLerp / Grip.SecondaryGripInfo.LerpToRate, 0.0f, 1.0f)); + return true; + } + else // Is in a multi grip, might be lerping into it as well. + { + //FVector curLocation; // Current location of the secondary grip + + // Calculates the correct secondary attachment location and sets frontLoc to it + CalculateSecondaryLocation(frontLoc, BasePoint, Grip, GrippingController); + + frontLocOrig = (/*WorldTransform*/SecondaryTransform.TransformPosition(Grip.SecondaryGripInfo.SecondaryRelativeTransform.GetLocation())) - BasePoint; + + // Apply any smoothing settings and lerping in / constant lerping + GunTools_ApplySmoothingAndLerp(Grip, frontLoc, frontLocOrig, DeltaTime, bSkipHighQualityOperations); + + Grip.SecondaryGripInfo.LastRelativeLocation = frontLoc; + } + + // Get any scaling addition from a scaling secondary grip type + FVector Scaler = FVector(1.0f); + GetAnyScaling(Scaler, Grip, frontLoc, frontLocOrig, SecondaryType, SecondaryTransform); + + Grip.SecondaryGripInfo.SecondaryGripDistance = FVector::Dist(frontLocOrig, frontLoc); + + if (!bSkipHighQualityOperations && AdvSecondarySettings.bUseAdvancedSecondarySettings && AdvSecondarySettings.bUseSecondaryGripDistanceInfluence) + { + float rotScaler = 1.0f - FMath::Clamp((Grip.SecondaryGripInfo.SecondaryGripDistance - AdvSecondarySettings.GripInfluenceDeadZone) / FMath::Max(AdvSecondarySettings.GripInfluenceDistanceToZero, 1.0f), 0.0f, 1.0f); + frontLoc = FMath::Lerp(frontLocOrig, frontLoc, rotScaler); + } + + // Skip rot val for scaling only + if (SecondaryType != ESecondaryGripType::SG_ScalingOnly) + { + // Get shoulder mount addition rotation + if (!bSkipHighQualityOperations && bUseVirtualStock && bIsMounted) + { + // Get the rotation difference from the initial second grip + FQuat rotVal = FQuat::FindBetweenVectors(GrippingController->GetPivotLocation() - MountWorldTransform.GetTranslation(), (frontLoc + BasePoint) - MountWorldTransform.GetTranslation()); + FQuat MountAdditionRotation = FQuat::FindBetweenVectors(frontLocOrig, GrippingController->GetPivotLocation() - MountWorldTransform.GetTranslation()); + + if (VirtualStockSettings.StockLerpValue < 1.0f) + { + // Rebase the world transform to the pivot point, add the rotation, remove the pivot point rebase + FTransform NA = FTransform(rotVal * MountAdditionRotation, FVector::ZeroVector, Scaler); + FTransform NB = FTransform(FQuat::FindBetweenVectors(frontLocOrig, frontLoc), FVector::ZeroVector, Scaler); + NA.NormalizeRotation(); + NB.NormalizeRotation(); + + // Quaternion interpolation + NA.Blend(NB, NA, VirtualStockSettings.StockLerpValue); + + NewWorldTransform = WorldTransform * WorldToPivot * NA * PivotToWorld; + } + else + { + // Rebase the world transform to the pivot point, add the rotation, remove the pivot point rebase + NewWorldTransform = WorldTransform * WorldToPivot * MountAdditionRotation * FTransform(rotVal, FVector::ZeroVector, Scaler) * PivotToWorld; + } + } + else + { + // Get the rotation difference from the initial second grip + FQuat rotVal = FQuat::FindBetweenVectors(frontLocOrig, frontLoc); + + // Rebase the world transform to the pivot point, add the rotation, remove the pivot point rebase + NewWorldTransform = WorldTransform * WorldToPivot * FTransform(rotVal, FVector::ZeroVector, Scaler) * PivotToWorld; + } + } + else + { + + // Get shoulder mount addition rotation + if (!bSkipHighQualityOperations && bUseVirtualStock && bIsMounted) + { + FQuat MountAdditionRotation = FQuat::FindBetweenVectors(frontLocOrig, GrippingController->GetPivotLocation() - MountWorldTransform.GetTranslation()); + + // If it is exactly 1.0f then lets skip all of the extra logic and just set it + if (VirtualStockSettings.StockLerpValue < 1.0f) + { + FTransform NA = FTransform(MountAdditionRotation, FVector::ZeroVector, Scaler); + FTransform NB = FTransform(FQuat::Identity, FVector::ZeroVector, Scaler); + NA.NormalizeRotation(); + NB.NormalizeRotation(); + + // Quaternion interpolation + NA.Blend(NB, NA, VirtualStockSettings.StockLerpValue); + NewWorldTransform = WorldTransform * WorldToPivot * NA * PivotToWorld; + } + else + { + // Rebase the world transform to the pivot point, add the scaler, remove the pivot point rebase + NewWorldTransform = WorldTransform * WorldToPivot * MountAdditionRotation * FTransform(FQuat::Identity, FVector::ZeroVector, Scaler) * PivotToWorld; + } + } + else + { + // Rebase the world transform to the pivot point, add the scaler, remove the pivot point rebase + NewWorldTransform = WorldTransform * WorldToPivot * FTransform(FQuat::Identity, FVector::ZeroVector, Scaler) * PivotToWorld; + } + } + } + + if (Grip.SecondaryGripInfo.GripLerpState == EGripLerpState::StartLerp) + { + WorldTransform.Blend(NewWorldTransform, WorldTransform, FMath::Clamp(Grip.SecondaryGripInfo.curLerp / Grip.SecondaryGripInfo.LerpToRate, 0.0f, 1.0f)); + } + else + { + WorldTransform = NewWorldTransform; + } + + if (bIsMounted && VirtualStockSettings.bSmoothStockHand) + { + if (GrippingController->GetAttachParent()) + { + FTransform ParentTrans = GrippingController->GetAttachParent()->GetComponentTransform(); + FTransform ParentRel = WorldTransform * ParentTrans.Inverse(); + ParentRel.Blend(ParentRel, VirtualStockSettings.StockHandSmoothing.RunFilterSmoothing(ParentRel, DeltaTime), VirtualStockSettings.SmoothingValueForStock); + WorldTransform = ParentRel * ParentTrans; + } + } + + if (Grip.SecondaryGripInfo.bHasSecondaryAttachment) + { + RelativeTransOnSecondaryRelease = WorldTransform.GetRelativeTransform(GrippingController->GetPivotTransform()); + } + } + + return true; +} + +void UGS_GunTools::OnGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) +{ + + if (bUseGlobalVirtualStockSettings) + { + if (GrippingController->IsLocallyControlled()) + { + FBPVirtualStockSettings VirtualSettings; + UVRGlobalSettings::GetVirtualStockGlobalSettings(VirtualSettings); + VirtualStockSettings.CopyFrom(VirtualSettings); + } + } + + // Super doesn't do anything on grip + + // Reset smoothing filters + if (AdvSecondarySettings.bUseConstantGripScaler) + { + if (AdvSecondarySettings.bUseGlobalSmoothingSettings) + { + const UVRGlobalSettings& VRSettings = *GetDefault(); + AdvSecondarySettings.SecondarySmoothing.CutoffSlope = VRSettings.OneEuroCutoffSlope; + AdvSecondarySettings.SecondarySmoothing.DeltaCutoff = VRSettings.OneEuroDeltaCutoff; + AdvSecondarySettings.SecondarySmoothing.MinCutoff = VRSettings.OneEuroMinCutoff; + } + + AdvSecondarySettings.SecondarySmoothing.ResetSmoothingFilter(); + } + + if (bUseVirtualStock) + { + ResetStockVariables(); + } + + GetVirtualStockTarget(GrippingController); +} + +void UGS_GunTools::GetVirtualStockTarget(UGripMotionControllerComponent * GrippingController) +{ + if (GrippingController && (GrippingController->HasAuthority() || bUseHighQualityRemoteSimulation)) + { + if (AVRBaseCharacter * vrOwner = Cast(GrippingController->GetOwner())) + { + if (vrOwner->VRReplicatedCamera) + { + CameraComponent = vrOwner->VRReplicatedCamera; + return; + } + } + else + { + TArray children = GrippingController->GetOwner()->GetRootComponent()->GetAttachChildren(); + + for (int i = 0; i < children.Num(); i++) + { + if (children[i]->IsA(UCameraComponent::StaticClass())) + { + CameraComponent = children[i]; + return; + } + } + } + + CameraComponent = nullptr; + } +} + +void UGS_GunTools::OnSecondaryGrip_Implementation(UGripMotionControllerComponent * Controller, USceneComponent * SecondaryGripComponent, const FBPActorGripInformation & GripInformation) +{ + // Super doesn't do anything on Secondary grip + + // Reset smoothing filters + if (AdvSecondarySettings.bUseConstantGripScaler) + { + if (AdvSecondarySettings.bUseGlobalSmoothingSettings) + { + const UVRGlobalSettings& VRSettings = *GetDefault(); + AdvSecondarySettings.SecondarySmoothing.CutoffSlope = VRSettings.OneEuroCutoffSlope; + AdvSecondarySettings.SecondarySmoothing.DeltaCutoff = VRSettings.OneEuroDeltaCutoff; + AdvSecondarySettings.SecondarySmoothing.MinCutoff = VRSettings.OneEuroMinCutoff; + } + + AdvSecondarySettings.SecondarySmoothing.ResetSmoothingFilter(); + } + + if (bUseVirtualStock) + ResetStockVariables(); +} + +void UGS_GunTools::ResetRecoil() +{ + BackEndRecoilStorage = FTransform::Identity; + BackEndRecoilTarget = FTransform::Identity; +} + +void UGS_GunTools::AddRecoilInstance(const FTransform & RecoilAddition, FVector Optional_Location) +{ + if (!bHasRecoil) + return; + + if (bApplyRecoilAsPhysicalForce) + { + if (FBodyInstance * BodyInst = GetParentBodyInstance()) + { + BodyInst->AddImpulseAtPosition(RecoilAddition.GetLocation(), Optional_Location); + } + } + else + { + BackEndRecoilTarget += RecoilAddition; + + FVector CurVec = BackEndRecoilTarget.GetTranslation(); + CurVec.X = FMath::Clamp(CurVec.X, -FMath::Abs(MaxRecoilTranslation.X), FMath::Abs(MaxRecoilTranslation.X)); + CurVec.Y = FMath::Clamp(CurVec.Y, -FMath::Abs(MaxRecoilTranslation.Y), FMath::Abs(MaxRecoilTranslation.Y)); + CurVec.Z = FMath::Clamp(CurVec.Z, -FMath::Abs(MaxRecoilTranslation.Z), FMath::Abs(MaxRecoilTranslation.Z)); + BackEndRecoilTarget.SetTranslation(CurVec); + + FVector CurScale = BackEndRecoilTarget.GetScale3D(); + CurScale.X = FMath::Clamp(CurScale.X, -FMath::Abs(MaxRecoilScale.X), FMath::Abs(MaxRecoilScale.X)); + CurScale.Y = FMath::Clamp(CurScale.Y, -FMath::Abs(MaxRecoilScale.Y), FMath::Abs(MaxRecoilScale.Y)); + CurScale.Z = FMath::Clamp(CurScale.Z, -FMath::Abs(MaxRecoilScale.Z), FMath::Abs(MaxRecoilScale.Z)); + BackEndRecoilTarget.SetScale3D(CurScale); + + FRotator curRot = BackEndRecoilTarget.Rotator(); + curRot.Pitch = FMath::Clamp(curRot.Pitch, -FMath::Abs(MaxRecoilRotation.Y), FMath::Abs(MaxRecoilRotation.Y)); + curRot.Yaw = FMath::Clamp(curRot.Yaw, -FMath::Abs(MaxRecoilRotation.Z), FMath::Abs(MaxRecoilRotation.Z)); + curRot.Roll = FMath::Clamp(curRot.Roll, -FMath::Abs(MaxRecoilRotation.X), FMath::Abs(MaxRecoilRotation.X)); + BackEndRecoilTarget.SetRotation(curRot.Quaternion()); + + bHasActiveRecoil = !BackEndRecoilTarget.Equals(FTransform::Identity); + } +} diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_InteractibleSettings.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_InteractibleSettings.cpp new file mode 100644 index 0000000..3560b6e --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_InteractibleSettings.cpp @@ -0,0 +1,136 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#include "GripScripts/GS_InteractibleSettings.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GS_InteractibleSettings) + +#include "Components/PrimitiveComponent.h" +#include "GripMotionControllerComponent.h" +#include "GameFramework/Actor.h" + +UGS_InteractibleSettings::UGS_InteractibleSettings(const FObjectInitializer& ObjectInitializer) : + Super(ObjectInitializer) +{ + bIsActive = true; + WorldTransformOverrideType = EGSTransformOverrideType::OverridesWorldTransform; +} + +void UGS_InteractibleSettings::OnBeginPlay_Implementation(UObject * CallingOwner) +{ + if (InteractionSettings.bGetInitialPositionsOnBeginPlay) + { + FTransform parentTrans = GetParentTransform(!InteractionSettings.bLimitsInLocalSpace); + + InteractionSettings.InitialAngularTranslation = parentTrans.Rotator(); + InteractionSettings.InitialLinearTranslation = parentTrans.GetTranslation(); + } +} +void UGS_InteractibleSettings::OnGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) +{ + if (InteractionSettings.bIgnoreHandRotation && !InteractionSettings.bHasValidBaseTransform) + { + RemoveRelativeRotation(GrippingController, GripInformation); + } + +} + +void UGS_InteractibleSettings::OnGripRelease_Implementation(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed) +{ + InteractionSettings.bHasValidBaseTransform = false; +} + +void UGS_InteractibleSettings::RemoveRelativeRotation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) +{ + InteractionSettings.BaseTransform = GripInformation.RelativeTransform; + + // Reconstitute the controller transform relative to the object, then remove the rotation and set it back to relative to controller + // This could likely be done easier by just removing rotation that the object doesn't possess but for now this will do. + FTransform compTrans = this->GetParentTransform(true, GripInformation.GrippedBoneName); + + InteractionSettings.BaseTransform = FTransform(InteractionSettings.BaseTransform.ToInverseMatrixWithScale()) * compTrans; // Reconstitute transform + InteractionSettings.BaseTransform.SetScale3D(GrippingController->GetPivotTransform().GetScale3D()); + InteractionSettings.BaseTransform.SetRotation(FQuat::Identity); // Remove rotation + + InteractionSettings.BaseTransform = compTrans.GetRelativeTransform(InteractionSettings.BaseTransform); // Set back to relative + InteractionSettings.bHasValidBaseTransform = true; +} + +bool UGS_InteractibleSettings::GetWorldTransform_Implementation +( + UGripMotionControllerComponent* GrippingController, + float DeltaTime, FTransform & WorldTransform, + const FTransform &ParentTransform, + FBPActorGripInformation &Grip, + AActor * actor, + UPrimitiveComponent * root, + bool bRootHasInterface, + bool bActorHasInterface, + bool bIsForTeleport +) +{ + if (!root) + return false; + + FTransform LocalTransform; + + if (InteractionSettings.bIgnoreHandRotation) + { + if (!InteractionSettings.bHasValidBaseTransform) + { + // Removes the rotation portion of the relative grip transform + RemoveRelativeRotation(GrippingController, Grip); + } + + FTransform RotationalessTransform = ParentTransform; + RotationalessTransform.SetRotation(FQuat::Identity); + + WorldTransform = InteractionSettings.BaseTransform * Grip.AdditionTransform * RotationalessTransform; + } + else + WorldTransform = Grip.RelativeTransform * Grip.AdditionTransform * ParentTransform; + + + if (InteractionSettings.bLimitsInLocalSpace) + { + if (USceneComponent * parent = root->GetAttachParent()) + LocalTransform = parent->GetComponentTransform(); + else + LocalTransform = FTransform::Identity; + + WorldTransform = WorldTransform.GetRelativeTransform(LocalTransform); + } + + FVector componentLoc = WorldTransform.GetLocation(); + + // Translation settings + if (InteractionSettings.bLimitX) + componentLoc.X = FMath::Clamp(componentLoc.X, InteractionSettings.InitialLinearTranslation.X + InteractionSettings.MinLinearTranslation.X, InteractionSettings.InitialLinearTranslation.X + InteractionSettings.MaxLinearTranslation.X); + + if (InteractionSettings.bLimitY) + componentLoc.Y = FMath::Clamp(componentLoc.Y, InteractionSettings.InitialLinearTranslation.Y + InteractionSettings.MinLinearTranslation.Y, InteractionSettings.InitialLinearTranslation.Y + InteractionSettings.MaxLinearTranslation.Y); + + if (InteractionSettings.bLimitZ) + componentLoc.Z = FMath::Clamp(componentLoc.Z, InteractionSettings.InitialLinearTranslation.Z + InteractionSettings.MinLinearTranslation.Z, InteractionSettings.InitialLinearTranslation.Z + InteractionSettings.MaxLinearTranslation.Z); + + WorldTransform.SetLocation(componentLoc); + + FRotator componentRot = WorldTransform.GetRotation().Rotator(); + + // Rotation Settings + if (InteractionSettings.bLimitPitch) + componentRot.Pitch = FMath::Clamp(componentRot.Pitch, InteractionSettings.InitialAngularTranslation.Pitch + InteractionSettings.MinAngularTranslation.Pitch, InteractionSettings.InitialAngularTranslation.Pitch + InteractionSettings.MaxAngularTranslation.Pitch); + + if (InteractionSettings.bLimitYaw) + componentRot.Yaw = FMath::Clamp(componentRot.Yaw, InteractionSettings.InitialAngularTranslation.Yaw + InteractionSettings.MinAngularTranslation.Yaw, InteractionSettings.InitialAngularTranslation.Yaw + InteractionSettings.MaxAngularTranslation.Yaw); + + if (InteractionSettings.bLimitRoll) + componentRot.Roll = FMath::Clamp(componentRot.Roll, InteractionSettings.InitialAngularTranslation.Roll + InteractionSettings.MinAngularTranslation.Roll, InteractionSettings.InitialAngularTranslation.Roll + InteractionSettings.MaxAngularTranslation.Roll); + + WorldTransform.SetRotation(componentRot.Quaternion()); + + if (InteractionSettings.bLimitsInLocalSpace) + { + WorldTransform = WorldTransform * LocalTransform; + } + + return true; +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_LerpToHand.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_LerpToHand.cpp new file mode 100644 index 0000000..6555498 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_LerpToHand.cpp @@ -0,0 +1,193 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "GripScripts/GS_LerpToHand.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GS_LerpToHand) + +#include "GripMotionControllerComponent.h" +#include "VRGlobalSettings.h" +#include "Components/PrimitiveComponent.h" +#include "GameFramework/Actor.h" +#include "Math/DualQuat.h" + +UGS_LerpToHand::UGS_LerpToHand(const FObjectInitializer& ObjectInitializer) : + Super(ObjectInitializer) +{ + bIsActive = false; + bDenyAutoDrop = true; // Always deny auto dropping while this script is active + WorldTransformOverrideType = EGSTransformOverrideType::ModifiesWorldTransform; + + LerpInterpolationMode = EVRLerpInterpolationMode::QuatInterp; + LerpDuration = 1.f; + LerpSpeed = 0.0f; + CurrentLerpTime = 0.0f; + OnGripTransform = FTransform::Identity; + bUseCurve = false; + MinDistanceForLerp = 0.0f; + MinSpeedForLerp = 0.f; + MaxSpeedForLerp = 0.f; + TargetGrip = INVALID_VRGRIP_ID; +} + +//void UGS_InteractibleSettings::BeginPlay_Implementation() {} +void UGS_LerpToHand::OnGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) +{ + const UVRGlobalSettings& VRSettings = *GetDefault(); + + // Removed this, let per object scripts overide + // Dont run if the global lerping is enabled + /*if (VRSettings.bUseGlobalLerpToHand) + { + bIsActive = false; + return; + }*/ + + TargetGrip = GripInformation.GripID; + + OnGripTransform = GetParentTransform(true, GripInformation.GrippedBoneName); + UObject* ParentObj = this->GetParent(); + + FTransform TargetTransform = GripInformation.RelativeTransform * GrippingController->GetPivotTransform(); + float Distance = FVector::Dist(OnGripTransform.GetLocation(), TargetTransform.GetLocation()); + if (MinDistanceForLerp > 0.0f && Distance < MinDistanceForLerp) + { + // Don't init + OnLerpToHandFinished.Broadcast(); + return; + } + else + { + float LerpScaler = 1.0f; + float DistanceToSpeed = Distance / LerpDuration; + if (DistanceToSpeed < MinSpeedForLerp) + { + LerpScaler = MinSpeedForLerp / DistanceToSpeed; + } + else if (MaxSpeedForLerp > 0.f && DistanceToSpeed > MaxSpeedForLerp) + { + LerpScaler = MaxSpeedForLerp / DistanceToSpeed; + } + else + { + LerpScaler = 1.0f; + } + + // Get the modified lerp speed + LerpSpeed = ((1.f / LerpDuration) * LerpScaler); + + OnLerpToHandBegin.Broadcast(); + + if (FBPActorGripInformation* GripInfo = GrippingController->GetGripPtrByID(GripInformation.GripID)) + { + GripInfo->bIsLerping = true; + } + } + + + + bIsActive = true; + CurrentLerpTime = 0.0f; +} + +void UGS_LerpToHand::OnGripRelease_Implementation(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed) +{ + if(GripInformation.GripID == TargetGrip) + { + TargetGrip = INVALID_VRGRIP_ID; + bIsActive = false; + } +} + +bool UGS_LerpToHand::GetWorldTransform_Implementation +( + UGripMotionControllerComponent* GrippingController, + float DeltaTime, FTransform & WorldTransform, + const FTransform &ParentTransform, + FBPActorGripInformation &Grip, + AActor * actor, + UPrimitiveComponent * root, + bool bRootHasInterface, + bool bActorHasInterface, + bool bIsForTeleport +) +{ + if (!root) + return false; + + if (LerpDuration <= 0.f || !Grip.bIsLerping) + { + Grip.bIsLerping = false; + GrippingController->OnLerpToHandFinished.Broadcast(Grip); + bIsActive = false; + } + + FTransform NA = OnGripTransform;//root->GetComponentTransform(); + + float Alpha = 0.0f; + + CurrentLerpTime += DeltaTime * LerpSpeed; + float OrigAlpha = FMath::Clamp(CurrentLerpTime, 0.f, 1.0f); + Alpha = OrigAlpha; + + if (bUseCurve) + { + if (FRichCurve * richCurve = OptionalCurveToFollow.GetRichCurve()) + { + /*if (CurrentLerpTime > richCurve->GetLastKey().Time) + { + // Stop lerping + OnLerpToHandFinished.Broadcast(); + CurrentLerpTime = 0.0f; + bIsActive = false; + return true; + } + else*/ + { + Alpha = FMath::Clamp(richCurve->Eval(Alpha), 0.f, 1.f); + //CurrentLerpTime += DeltaTime; + } + } + } + + FTransform NB = WorldTransform; + NA.NormalizeRotation(); + NB.NormalizeRotation(); + + // Quaternion interpolation + if (LerpInterpolationMode == EVRLerpInterpolationMode::QuatInterp) + { + WorldTransform.Blend(NA, NB, Alpha); + } + + // Euler Angle interpolation + else if (LerpInterpolationMode == EVRLerpInterpolationMode::EulerInterp) + { + WorldTransform.SetTranslation(FMath::Lerp(NA.GetTranslation(), NB.GetTranslation(), Alpha)); + WorldTransform.SetScale3D(FMath::Lerp(NA.GetScale3D(), NB.GetScale3D(), Alpha)); + + FRotator A = NA.Rotator(); + FRotator B = NB.Rotator(); + WorldTransform.SetRotation(FQuat(A + (Alpha * (B - A)))); + } + // Dual quaternion interpolation + else + { + if ((NB.GetRotation() | NA.GetRotation()) < 0.0f) + { + NB.SetRotation(NB.GetRotation()*-1.0f); + } + WorldTransform = (FDualQuat(NA)*(1 - Alpha) + FDualQuat(NB)*Alpha).Normalized().AsFTransform(FMath::Lerp(NA.GetScale3D(), NB.GetScale3D(), Alpha)); + } + + // Turn it off if we need to + if (OrigAlpha == 1.0f) + { + OnLerpToHandFinished.Broadcast(); + Grip.bIsLerping = false; + GrippingController->OnLerpToHandFinished.Broadcast(Grip); + CurrentLerpTime = 0.0f; + bIsActive = false; + } + + return true; +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_Melee.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_Melee.cpp new file mode 100644 index 0000000..f0d848f --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_Melee.cpp @@ -0,0 +1,1017 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#include "GripScripts/GS_Melee.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GS_Melee) + +#include "VRGripInterface.h" +#include "GameFramework/WorldSettings.h" +#include "PhysicalMaterials/PhysicalMaterial.h" +#include "PhysicsEngine/PhysicsConstraintActor.h" +#include "PhysicsEngine/PhysicsConstraintComponent.h" +#include "VRExpansionFunctionLibrary.h" +#include "GripMotionControllerComponent.h" +#include "VRGlobalSettings.h" +#include "DrawDebugHelpers.h" +#include "Components/PrimitiveComponent.h" +#include "GameFramework/Actor.h" +#include "GripMotionControllerComponent.h" + +UGS_Melee::UGS_Melee(const FObjectInitializer& ObjectInitializer) : + Super(ObjectInitializer) +{ + bIsActive = true; + WorldTransformOverrideType = EGSTransformOverrideType::ModifiesWorldTransform; + bDenyLateUpdates = true; + + + bInjectPrePhysicsHandle = true; + bInjectPostPhysicsHandle = true; + WeaponRootOrientationComponent = NAME_None; + OrientationComponentRelativeFacing = FTransform::Identity; + + bAutoSetPrimaryAndSecondaryHands = true; + PrimaryHandSelectionType = EVRMeleePrimaryHandType::VRPHAND_Rear; + bHasValidPrimaryHand = false; + + //RollingVelocityAverage = FVector::ZeroVector; + bIsLodged = false; + + //bCanEverTick = true; + bCheckLodge = false; + bIsHeld = false; + bCanEverTick = false; + bAlwaysTickPenetration = false; + bUsePrimaryHandSettingsWithOneHand = false; + COMType = EVRMeleeComType::VRPMELEECOM_BetweenHands; + bOnlyPenetrateWithTwoHands = false; +} + +void UGS_Melee::SetIsLodged(bool IsLodged, UPrimitiveComponent* LodgeComponent) +{ + bIsLodged = IsLodged; + LodgedComponent = LodgeComponent; +} + +void UGS_Melee::UpdateDualHandInfo() +{ + TArray HoldingControllers; + + bool bIsHeldOther; + IVRGripInterface::Execute_IsHeld(GetParent(), HoldingControllers, bIsHeldOther); + + float PHand = 0.0f; + float SHand = 0.0f; + bHasValidPrimaryHand = false; + + FBPActorGripInformation* FrontHandGrip = nullptr; + FBPActorGripInformation* RearHandGrip = nullptr; + + SecondaryHand = FBPGripPair(); + PrimaryHand = FBPGripPair(); + + int NumControllers = HoldingControllers.Num(); + + for (FBPGripPair& Grip : HoldingControllers) + { + if (NumControllers > 1) + { + if (!Grip.IsValid()) + continue; + + FBPActorGripInformation* GripInfo = Grip.HoldingController->GetGripPtrByID(Grip.GripID); + if (GripInfo) + { + float GripDistanceOnPrimaryAxis = 0.f; + FTransform relTransform(GripInfo->RelativeTransform.ToInverseMatrixWithScale()); + relTransform = relTransform.GetRelativeTransform(OrientationComponentRelativeFacing); + + // This is the Forward vector projected transform + // The most negative one of these is the rearmost hand + FVector localLoc = relTransform.GetTranslation(); + + switch (PrimaryHandSelectionType) + { + case EVRMeleePrimaryHandType::VRPHAND_Slotted: + { + if (GripInfo->bIsSlotGrip) + { + PrimaryHand = Grip; + bHasValidPrimaryHand = true; + } + else + { + if (!PrimaryHand.IsValid()) + { + PrimaryHand = Grip; + } + + SecondaryHand = Grip; + } + }break; + case EVRMeleePrimaryHandType::VRPHAND_Front: + case EVRMeleePrimaryHandType::VRPHAND_Rear: + { + + if (((PrimaryHandSelectionType == EVRMeleePrimaryHandType::VRPHAND_Rear) ? localLoc.X < PHand : localLoc.X > PHand) || !PrimaryHand.HoldingController) + { + PrimaryHand = Grip; + PHand = localLoc.X; + bHasValidPrimaryHand = true; + } + + if ((((PrimaryHandSelectionType == EVRMeleePrimaryHandType::VRPHAND_Rear) ? localLoc.X > SHand : localLoc.X < SHand) || !SecondaryHand.HoldingController || SecondaryHand.HoldingController == PrimaryHand.HoldingController)) + { + SecondaryHand = Grip; + SHand = localLoc.X; + } + + }break; + default:break; + } + } + } + else + { + PrimaryHand = Grip; + SecondaryHand = FBPGripPair(); + } + } + + + if (PrimaryHand.IsValid() && (COMType == EVRMeleeComType::VRPMELEECOM_BetweenHands || COMType == EVRMeleeComType::VRPMELEECOM_PrimaryHand)) + { + FBPActorGripInformation* GripInfo = PrimaryHand.HoldingController->GetGripPtrByID(PrimaryHand.GripID); + + if (SecondaryHand.IsValid()) + { + FBPActorGripInformation* GripInfoS = SecondaryHand.HoldingController->GetGripPtrByID(SecondaryHand.GripID); + + if (GripInfo && GripInfoS) + { + FVector Primary = GripInfo->RelativeTransform.InverseTransformPositionNoScale(FVector::ZeroVector); + FVector Secondary = GripInfoS->RelativeTransform.InverseTransformPositionNoScale(FVector::ZeroVector); + + FVector Final = (COMType == EVRMeleeComType::VRPMELEECOM_PrimaryHand) ? Primary : ((Primary + Secondary) / 2.f); + ObjectRelativeGripCenter.SetLocation(Final); + } + } + else + { + if (GripInfo) + { + + if (GripInfo->SecondaryGripInfo.bHasSecondaryAttachment) + { + FVector gripLoc = GripInfo->RelativeTransform.InverseTransformPositionNoScale(FVector::ZeroVector); + FVector secGripLoc = GripInfo->SecondaryGripInfo.SecondaryRelativeTransform.GetLocation(); + FVector finalloc = (COMType == EVRMeleeComType::VRPMELEECOM_PrimaryHand) ? gripLoc : (gripLoc + secGripLoc) / 2.f; + FVector finalScaled = finalloc * GripInfo->RelativeTransform.GetScale3D(); + + FTransform ownerTrans = GetOwner()->GetActorTransform(); + + //DrawDebugSphere(GetWorld(), ownerTrans.TransformPosition(finalScaled), 4.0f, 32, FColor::Orange, true); + + + ObjectRelativeGripCenter.SetLocation(finalScaled); + PrimaryHand.HoldingController->ReCreateGrip(*GripInfo); + } + else + { + ObjectRelativeGripCenter = FTransform::Identity; + } + } + } + } +} + +void UGS_Melee::UpdateHandPositionAndRotation(FBPGripPair HandPair, FTransform HandWorldTransform, FVector& LocDifference, float& RotDifference, bool bUpdateLocation, bool bUpdateRotation) +{ + LocDifference = FVector::ZeroVector; + + if (HandPair.IsValid()) + { + FBPActorGripInformation* GripInfo = HandPair.HoldingController->GetGripPtrByID(HandPair.GripID); + + if (GripInfo) + { + // Make hand relative to object transform + FTransform RelativeTrans = GripInfo->RelativeTransform.Inverse(); + FVector OriginalLoc = RelativeTrans.GetLocation(); + FQuat OriginalRot = RelativeTrans.GetRotation(); + + // Get our current parent transform + FTransform ParentTransform = GetParentTransform(); + + FQuat orientationRot = OrientationComponentRelativeFacing.GetRotation(); + + if (bUpdateLocation) + { + FVector currentRelVec = orientationRot.RotateVector(ParentTransform.InverseTransformPosition(HandWorldTransform.GetLocation())); + FVector currentLoc = orientationRot.RotateVector(RelativeTrans.GetLocation()); + currentLoc.X = currentRelVec.X; + RelativeTrans.SetLocation(orientationRot.UnrotateVector(currentLoc)); + } + + if (bUpdateRotation) + { + FRotator currentRelRot = (orientationRot * (ParentTransform.GetRotation().Inverse() * HandWorldTransform.GetRotation())).Rotator(); + FRotator currentRot = (orientationRot * RelativeTrans.GetRotation()).Rotator(); + currentRot.Roll = currentRelRot.Roll; + RelativeTrans.SetRotation(orientationRot.Inverse() * currentRot.Quaternion()); + } + + GripInfo->RelativeTransform = RelativeTrans.Inverse(); + HandPair.HoldingController->UpdatePhysicsHandle(*GripInfo, true); + HandPair.HoldingController->NotifyGripTransformChanged(*GripInfo); + + LocDifference = RelativeTrans.GetLocation() - OriginalLoc; + RotDifference = RelativeTrans.GetRotation().Rotator().Roll - OriginalRot.Rotator().Roll; + + // Instead of recreating, can directly set local pose here + + + FBPGripPair SecHand = SecondaryHand; + UpdateDualHandInfo(); + + if (SecondaryHand.IsValid() && !(SecHand == SecondaryHand)) + { + + GripInfo = SecondaryHand.HoldingController->GetGripPtrByID(SecondaryHand.GripID); + GripInfo->AdvancedGripSettings.PhysicsSettings.PhysicsGripLocationSettings = EPhysicsGripCOMType::COM_GripAtControllerLoc; + + FBPActorPhysicsHandleInformation* HandleInfo = SecondaryHand.HoldingController->GetPhysicsGrip(SecondaryHand.GripID); + if (HandleInfo) + { + SecondaryHandPhysicsSettings.FillTo(HandleInfo); + SecondaryHand.HoldingController->UpdatePhysicsHandle(SecondaryHand.GripID, true); + } + + GripInfo = PrimaryHand.HoldingController->GetGripPtrByID(PrimaryHand.GripID); + + switch (COMType) + { + case EVRMeleeComType::VRPMELEECOM_Normal: + case EVRMeleeComType::VRPMELEECOM_BetweenHands: + { + GripInfo->AdvancedGripSettings.PhysicsSettings.PhysicsGripLocationSettings = EPhysicsGripCOMType::COM_GripAtControllerLoc; + }break; + + case EVRMeleeComType::VRPMELEECOM_PrimaryHand: + { + GripInfo->AdvancedGripSettings.PhysicsSettings.PhysicsGripLocationSettings = EPhysicsGripCOMType::COM_SetAndGripAt; + } + } + + HandleInfo = PrimaryHand.HoldingController->GetPhysicsGrip(PrimaryHand.GripID); + if (HandleInfo) + { + if (bHasValidPrimaryHand) + { + PrimaryHandPhysicsSettings.FillTo(HandleInfo); + } + else + { + SecondaryHandPhysicsSettings.FillTo(HandleInfo); + } + PrimaryHand.HoldingController->UpdatePhysicsHandle(PrimaryHand.GripID, true); + } + } + + if (COMType != EVRMeleeComType::VRPMELEECOM_Normal) + SetComBetweenHands(HandPair.HoldingController, HandPair.HoldingController->GetPhysicsGrip(HandPair.GripID)); + } + } +} + +void UGS_Melee::UpdateHandPosition(FBPGripPair HandPair, FVector HandWorldPosition, FVector& LocDifference) +{ + LocDifference = FVector::ZeroVector; + + if (HandPair.IsValid()) + { + FBPActorGripInformation* GripInfo = HandPair.HoldingController->GetGripPtrByID(HandPair.GripID); + + if (GripInfo) + { + // Make hand relative to object transform + FTransform RelativeTrans = GripInfo->RelativeTransform.Inverse(); + FVector OriginalLoc = RelativeTrans.GetLocation(); + + // Get our current parent transform + FTransform ParentTransform = GetParentTransform(); + + FQuat orientationRot = OrientationComponentRelativeFacing.GetRotation(); + FVector currentRelVec = orientationRot.RotateVector(ParentTransform.InverseTransformPosition(HandWorldPosition)); + //currentRelVec = OrientationComponentRelativeFacing.GetRotation().UnrotateVector(currentRelVec); + + FVector currentLoc = orientationRot.RotateVector(RelativeTrans.GetLocation()); + currentLoc.X = currentRelVec.X; + + RelativeTrans.SetLocation(orientationRot.UnrotateVector(currentLoc)); + GripInfo->RelativeTransform = RelativeTrans.Inverse(); + HandPair.HoldingController->UpdatePhysicsHandle(*GripInfo, true); + HandPair.HoldingController->NotifyGripTransformChanged(*GripInfo); + + LocDifference = RelativeTrans.GetLocation() - OriginalLoc; + + // Instead of recreating, can directly set local pose here + + + FBPGripPair SecHand = SecondaryHand; + UpdateDualHandInfo(); + + if (SecondaryHand.IsValid() && !(SecHand == SecondaryHand)) + { + + GripInfo = SecondaryHand.HoldingController->GetGripPtrByID(SecondaryHand.GripID); + GripInfo->AdvancedGripSettings.PhysicsSettings.PhysicsGripLocationSettings = EPhysicsGripCOMType::COM_GripAtControllerLoc; + + FBPActorPhysicsHandleInformation* HandleInfo = SecondaryHand.HoldingController->GetPhysicsGrip(SecondaryHand.GripID); + if (HandleInfo) + { + SecondaryHandPhysicsSettings.FillTo(HandleInfo); + SecondaryHand.HoldingController->UpdatePhysicsHandle(SecondaryHand.GripID, true); + } + + GripInfo = PrimaryHand.HoldingController->GetGripPtrByID(PrimaryHand.GripID); + + switch (COMType) + { + case EVRMeleeComType::VRPMELEECOM_Normal: + case EVRMeleeComType::VRPMELEECOM_BetweenHands: + { + GripInfo->AdvancedGripSettings.PhysicsSettings.PhysicsGripLocationSettings = EPhysicsGripCOMType::COM_GripAtControllerLoc; + }break; + + case EVRMeleeComType::VRPMELEECOM_PrimaryHand: + { + GripInfo->AdvancedGripSettings.PhysicsSettings.PhysicsGripLocationSettings = EPhysicsGripCOMType::COM_SetAndGripAt; + } + } + + HandleInfo = PrimaryHand.HoldingController->GetPhysicsGrip(PrimaryHand.GripID); + if (HandleInfo) + { + if (bHasValidPrimaryHand) + { + PrimaryHandPhysicsSettings.FillTo(HandleInfo); + } + else + { + SecondaryHandPhysicsSettings.FillTo(HandleInfo); + } + PrimaryHand.HoldingController->UpdatePhysicsHandle(PrimaryHand.GripID, true); + } + } + + if (COMType != EVRMeleeComType::VRPMELEECOM_Normal) + SetComBetweenHands(HandPair.HoldingController, HandPair.HoldingController->GetPhysicsGrip(HandPair.GripID)); + } + } +} + +void UGS_Melee::SetPrimaryAndSecondaryHands(FBPGripPair& PrimaryGrip, FBPGripPair& SecondaryGrip) +{ + PrimaryHand = PrimaryGrip; + SecondaryHand = SecondaryGrip; +} + +void UGS_Melee::OnSecondaryGrip_Implementation(UGripMotionControllerComponent* Controller, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) +{ + if (!bIsActive) + return; + + UpdateDualHandInfo(); +} + +void UGS_Melee::OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) +{ + if (!bIsActive) + return; + + // Not storing an id, we should only be doing this once +// GetOwner()->OnActorHit.AddDynamic(this, &UGS_Melee::OnActorHit); + + // This lets us change the grip settings prior to actually starting the grip off + //SetTickEnabled(true); + //bCheckLodge = true; + bIsHeld = true; + + //if (GrippingController->HasGripAuthority(GripInformation)) + { + UpdateDualHandInfo(); + + // If we have multiple hands then alter the grip settings here for what we have already, the other will wait until post event + if (SecondaryHand.IsValid()) + { + FBPActorGripInformation * GripInfo = SecondaryHand.HoldingController->GetGripPtrByID(SecondaryHand.GripID); + GripInfo->AdvancedGripSettings.PhysicsSettings.PhysicsGripLocationSettings = EPhysicsGripCOMType::COM_GripAtControllerLoc; + + FBPActorPhysicsHandleInformation* HandleInfo = SecondaryHand.HoldingController->GetPhysicsGrip(SecondaryHand.GripID); + if (HandleInfo) + { + SecondaryHandPhysicsSettings.FillTo(HandleInfo); + SecondaryHand.HoldingController->UpdatePhysicsHandle(SecondaryHand.GripID, true); + } + + GripInfo = PrimaryHand.HoldingController->GetGripPtrByID(PrimaryHand.GripID); + + switch (COMType) + { + case EVRMeleeComType::VRPMELEECOM_Normal: + case EVRMeleeComType::VRPMELEECOM_BetweenHands: + { + GripInfo->AdvancedGripSettings.PhysicsSettings.PhysicsGripLocationSettings = EPhysicsGripCOMType::COM_GripAtControllerLoc; + }break; + + case EVRMeleeComType::VRPMELEECOM_PrimaryHand: + { + GripInfo->AdvancedGripSettings.PhysicsSettings.PhysicsGripLocationSettings = EPhysicsGripCOMType::COM_SetAndGripAt; + } + } + + HandleInfo = PrimaryHand.HoldingController->GetPhysicsGrip(PrimaryHand.GripID); + if (HandleInfo) + { + if (bHasValidPrimaryHand) + { + PrimaryHandPhysicsSettings.FillTo(HandleInfo); + } + else + { + SecondaryHandPhysicsSettings.FillTo(HandleInfo); + } + PrimaryHand.HoldingController->UpdatePhysicsHandle(PrimaryHand.GripID, true); + } + } + } +} + +void UGS_Melee::OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) +{ + + if (!bIsActive) + return; + + // Refresh our IsHeld var + TArray HoldingControllers; + IVRGripInterface::Execute_IsHeld(GetParent(), HoldingControllers, bIsHeld); + + if (SecondaryHand.IsValid() && SecondaryHand.HoldingController == ReleasingController && SecondaryHand.GripID == GripInformation.GripID) + { + SecondaryHand = FBPGripPair(); + } + else if (PrimaryHand.IsValid() && PrimaryHand.HoldingController == ReleasingController && PrimaryHand.GripID == GripInformation.GripID) + { + if (SecondaryHand.IsValid()) + { + PrimaryHand = SecondaryHand; + SecondaryHand = FBPGripPair(); + } + else + { + PrimaryHand = FBPGripPair(); + } + } + + if (COMType != EVRMeleeComType::VRPMELEECOM_Normal) + { + if (UPrimitiveComponent* PrimComp = Cast(GetParentSceneComp())) + { + if (FBodyInstance* rBodyInstance = PrimComp->GetBodyInstance()) + { + if (rBodyInstance->IsValidBodyInstance() && rBodyInstance->BodySetup.IsValid()) + { + + // If bound we need to cancel out + bool bWasBound = false; + if (PrimaryHand.IsValid()) + { + if (rBodyInstance->OnRecalculatedMassProperties().IsBoundToObject(PrimaryHand.HoldingController)) + { + rBodyInstance->OnRecalculatedMassProperties().RemoveAll(this); + bWasBound = true; + } + } + + rBodyInstance->UpdateMassProperties(); + + // Restore binding + if (bWasBound) + { + rBodyInstance->OnRecalculatedMassProperties().AddUObject(PrimaryHand.HoldingController, &UGripMotionControllerComponent::OnGripMassUpdated); + } + } + } + } + } + + if (PrimaryHand.IsValid()) + { + + FBPActorPhysicsHandleInformation* HandleInfo = PrimaryHand.HoldingController->GetPhysicsGrip(PrimaryHand.GripID); + if (HandleInfo) + { + FBPActorGripInformation * GripInfo = PrimaryHand.HoldingController->GetGripPtrByID(PrimaryHand.GripID); + + // Reset custom COM changes + if (!SecondaryHand.IsValid()) + { + HandleInfo->bSkipResettingCom = false; + UpdateDualHandInfo(); + } + + if (GripInfo) + { + //Reset defaults here still!!! + HandleInfo->LinConstraint.XDrive.bEnablePositionDrive = true; + HandleInfo->LinConstraint.XDrive.bEnableVelocityDrive = true; + HandleInfo->LinConstraint.XDrive.Stiffness = GripInfo->Stiffness; + HandleInfo->LinConstraint.XDrive.Damping = GripInfo->Damping; + + HandleInfo->LinConstraint.YDrive = HandleInfo->LinConstraint.XDrive; + HandleInfo->LinConstraint.ZDrive = HandleInfo->LinConstraint.XDrive; + + HandleInfo->AngConstraint.SwingDrive.bEnablePositionDrive = false; + HandleInfo->AngConstraint.SwingDrive.bEnableVelocityDrive = false; + HandleInfo->AngConstraint.TwistDrive.bEnablePositionDrive = false; + HandleInfo->AngConstraint.TwistDrive.bEnableVelocityDrive = false; + HandleInfo->AngConstraint.AngularDriveMode = EAngularDriveMode::SLERP; + HandleInfo->AngConstraint.SlerpDrive.bEnablePositionDrive = true; + HandleInfo->AngConstraint.SlerpDrive.bEnableVelocityDrive = true; + + if (GripInfo->AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings && GripInfo->AdvancedGripSettings.PhysicsSettings.bUseCustomAngularValues) + { + HandleInfo->AngConstraint.SlerpDrive.Damping = GripInfo->AdvancedGripSettings.PhysicsSettings.AngularDamping; + HandleInfo->AngConstraint.SlerpDrive.Stiffness = GripInfo->AdvancedGripSettings.PhysicsSettings.AngularStiffness; + } + else + { + HandleInfo->AngConstraint.SlerpDrive.Damping = GripInfo->Damping * 1.4f; + HandleInfo->AngConstraint.SlerpDrive.Stiffness = GripInfo->Stiffness * 1.5f; + } + + FBPAdvGripSettings AdvSettings = IVRGripInterface::Execute_AdvancedGripSettings(GripInfo->GrippedObject); + GripInfo->AdvancedGripSettings.PhysicsSettings.PhysicsGripLocationSettings = AdvSettings.PhysicsSettings.PhysicsGripLocationSettings; + + PrimaryHand.HoldingController->UpdatePhysicsHandle(PrimaryHand.GripID, true); + } + } + } + +} + +void UGS_Melee::OnBeginPlay_Implementation(UObject * CallingOwner) +{ + // Grip base has no super of this + + if (AActor * Owner = GetOwner()) + { + FName CurrentCompName = NAME_None; + bool bSearchRootComp = WeaponRootOrientationComponent.IsValid(); + int RemainingCount = PenetrationNotifierComponents.Num(); + for (UActorComponent* ChildComp : Owner->GetComponents()) + { + CurrentCompName = ChildComp->GetFName(); + if (CurrentCompName == NAME_None) + continue; + + if (bSearchRootComp && CurrentCompName == WeaponRootOrientationComponent) + { + bSearchRootComp = false; + if (USceneComponent * SceneComp = Cast(ChildComp)) + { + OrientationComponentRelativeFacing = SceneComp->GetRelativeTransform(); + } + } + + if (FBPLodgeComponentInfo * Found = PenetrationNotifierComponents.FindByKey(CurrentCompName)) + { + if (UPrimitiveComponent * PrimComp = Cast(ChildComp)) + { + Found->TargetComponent = TObjectPtr(PrimComp); + //PrimComp->OnComponentHit.AddDynamic(this, &UGS_Melee::OnLodgeHitCallback); + } + + // Decrement even if it failed the cast, they just had it wrong. + RemainingCount--; + } + + if (!bSearchRootComp && RemainingCount < 1) + { + break; + } + } + + // If we found at least one penetration object + if (RemainingCount < PenetrationNotifierComponents.Num()) + { + Owner->OnActorHit.AddDynamic(this, &UGS_Melee::OnLodgeHitCallback); + bCheckLodge = true; + } + } +} + +void UGS_Melee::OnEndPlay_Implementation(const EEndPlayReason::Type EndPlayReason) +{ + if (AActor * Owner = GetOwner()) + { + Owner->OnActorHit.RemoveDynamic(this, &UGS_Melee::OnLodgeHitCallback); + } +} + +void UGS_Melee::OnLodgeHitCallback(AActor* SelfActor, AActor* OtherActor, FVector NormalImpulse, const FHitResult& Hit) +{ + if (!Hit.GetComponent()) + return; + + if (!bCheckLodge || !bIsActive || bIsLodged || OtherActor == SelfActor) + { + if (bAlwaysTickPenetration || bIsHeld) + { + OnMeleeInvalidHit.Broadcast(OtherActor, Hit.GetComponent(), NormalImpulse, Hit); + } + return; + } + + // Escape out if we are not held and are not set to always tick penetration + if (!bAlwaysTickPenetration && !bIsHeld) + return; + + TArray AllowedPenetrationSurfaceTypes; + + if (OverrideMeleeSurfaceSettings.Num() > 0) + { + // Use our local copy + AllowedPenetrationSurfaceTypes = OverrideMeleeSurfaceSettings; + } + else + { + // Use the global settings + UVRGlobalSettings::GetMeleeSurfaceGlobalSettings(AllowedPenetrationSurfaceTypes); + } + + FBPHitSurfaceProperties HitSurfaceProperties; + if (Hit.PhysMaterial.IsValid()) + { + HitSurfaceProperties.SurfaceType = Hit.PhysMaterial->SurfaceType; + } + + if (AllowedPenetrationSurfaceTypes.Num()) + { + // Reject bad surface types + if (!Hit.PhysMaterial.IsValid()) + { + OnMeleeInvalidHit.Broadcast(OtherActor, Hit.GetComponent(), NormalImpulse, Hit); + return; + } + + EPhysicalSurface PhysSurfaceType = Hit.PhysMaterial->SurfaceType; + int32 IndexOfSurface = AllowedPenetrationSurfaceTypes.IndexOfByPredicate([&PhysSurfaceType](const FBPHitSurfaceProperties& Entry) { return Entry.SurfaceType == PhysSurfaceType; }); + + if (IndexOfSurface != INDEX_NONE) + { + HitSurfaceProperties = AllowedPenetrationSurfaceTypes[IndexOfSurface]; + } + else + { + // Surface is not part of our default list, don't allow penetration + HitSurfaceProperties.bSurfaceAllowsPenetration = false; + // Not a valid surface type to throw an event + //return; + } + } + + /*if (UPrimitiveComponent * root = Cast(SelfActor->GetRootComponent())) + { + if (FBodyInstance * rBodyInstance = root->GetBodyInstance()) + { + //float mass =rBodyInstance->GetBodyMass(); + //ImpulseVelocity = (NormalImpulse / rBodyInstance->GetBodyMass()).SizeSquared(); + RollingVelocityAverage += FVector::CrossProduct(RollingAngVelocityAverage, Hit.ImpactPoint - (rBodyInstance->GetCOMPosition())); + } + }*/ + +// FVector FrameToFrameVelocity = RollingVelocityAverage; + + // If we hit, then regardless of penetration, end the velocity history and reset +// RollingVelocityAverage = FVector::ZeroVector; +// RollingAngVelocityAverage = FVector::ZeroVector; + + bool bHadFirstHit = false; + FBPLodgeComponentInfo FirstHitComp; + + float HitNormalImpulse = NormalImpulse.SizeSquared(); + + for(FBPLodgeComponentInfo &LodgeData : PenetrationNotifierComponents) + { + if (!IsValid(LodgeData.TargetComponent)) + continue; + + FBox LodgeLocalBox = LodgeData.TargetComponent->CalcLocalBounds().GetBox(); + FVector LocalHit = LodgeData.TargetComponent->GetComponentTransform().InverseTransformPosition(Hit.ImpactPoint); + //FBox LodgeBox = LodgeData.TargetComponent->Bounds.GetBox(); + if (IsValid(LodgeData.TargetComponent) && LodgeLocalBox.IsInsideOrOn(LocalHit))//LodgeBox.IsInsideOrOn(Hit.ImpactPoint)) + { + FVector ForwardVec = LodgeData.TargetComponent->GetForwardVector(); + + // Using swept objects hit normal as we are looking for a facing from ourselves + float DotValue = FMath::Abs(FVector::DotProduct(Hit.Normal, ForwardVec)); + float Velocity = NormalImpulse.ProjectOnToNormal(ForwardVec).SizeSquared();//FrameToFrameVelocity.ProjectOnToNormal(ForwardVec); + // Check if the velocity was strong enough along our axis to count as a lodge event + // Also that our facing was in the relatively correct direction + + if (HitSurfaceProperties.bSurfaceAllowsPenetration && (!bOnlyPenetrateWithTwoHands || SecondaryHand.IsValid())) + { + if (LodgeData.ZoneType != EVRMeleeZoneType::VRPMELLE_ZONETYPE_Hit && DotValue >= (1.0f - LodgeData.AcceptableForwardProductRange) && (Velocity * HitSurfaceProperties.StabVelocityScaler) >= FMath::Square(LodgeData.PenetrationVelocity)) + { + OnShouldLodgeInObject.Broadcast(LodgeData, OtherActor, Hit.GetComponent(), Hit.GetComponent()->GetCollisionObjectType(), HitSurfaceProperties, NormalImpulse, Hit); + return; + //break; + } + } + + float HitImpulse = LodgeData.bIgnoreForwardVectorForHitImpulse ? HitNormalImpulse : Velocity; + + if (!bHadFirstHit && LodgeData.ZoneType > EVRMeleeZoneType::VRPMELLE_ZONETYPE_Stab && DotValue >= (1.0f - LodgeData.AcceptableForwardProductRangeForHits) && HitImpulse >= FMath::Square(LodgeData.MinimumHitVelocity)) + { + bHadFirstHit = true; + FirstHitComp = LodgeData; + } + } + } + + if (bHadFirstHit) + { + OnMeleeHit.Broadcast(FirstHitComp, OtherActor, Hit.GetComponent(), Hit.GetComponent()->GetCollisionObjectType(), HitSurfaceProperties, NormalImpulse, Hit); + } + else + { + OnMeleeInvalidHit.Broadcast(OtherActor, Hit.GetComponent(), NormalImpulse, Hit); + } +} + + +void UGS_Melee::HandlePrePhysicsHandle(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation &GripInfo, FBPActorPhysicsHandleInformation * HandleInfo, FTransform & KinPose) +{ + if (!bIsActive) + return; + + if (WeaponRootOrientationComponent != NAME_None) + { + // Alter to rotate to x+ if we have an orientation component + FQuat DeltaQuat = OrientationComponentRelativeFacing.GetRotation(); + + // This moves the kinematic actor to face its X+ in the direction designated + KinPose.SetRotation(KinPose.GetRotation() * (HandleInfo->RootBoneRotation.GetRotation().Inverse() * DeltaQuat)); + HandleInfo->COMPosition.SetRotation(HandleInfo->COMPosition.GetRotation() * (HandleInfo->RootBoneRotation.GetRotation().Inverse() * DeltaQuat)); + } +} + +void UGS_Melee::HandlePostPhysicsHandle(UGripMotionControllerComponent* GrippingController, FBPActorPhysicsHandleInformation * HandleInfo) +{ + if (!bIsActive) + return; + + if (SecondaryHand.IsValid() )// && GrippingController == PrimaryHand.HoldingController) + { + if (GrippingController == SecondaryHand.HoldingController && HandleInfo->GripID == SecondaryHand.GripID) + { + SecondaryHandPhysicsSettings.FillTo(HandleInfo); + } + else if (GrippingController == PrimaryHand.HoldingController && HandleInfo->GripID == PrimaryHand.GripID) + { + if (bHasValidPrimaryHand) + { + PrimaryHandPhysicsSettings.FillTo(HandleInfo); + } + else + { + SecondaryHandPhysicsSettings.FillTo(HandleInfo); + } + } + + if (COMType != EVRMeleeComType::VRPMELEECOM_Normal) + SetComBetweenHands(GrippingController, HandleInfo); + } + else + { + if (bUsePrimaryHandSettingsWithOneHand) + { + PrimaryHandPhysicsSettings.FillTo(HandleInfo); + } + + if (COMType != EVRMeleeComType::VRPMELEECOM_Normal) + SetComBetweenHands(GrippingController, HandleInfo); + } +} + +void UGS_Melee::SetComBetweenHands(UGripMotionControllerComponent* GrippingController, FBPActorPhysicsHandleInformation * HandleInfo) +{ + + if (!GrippingController || !HandleInfo) + return; + + if (COMType != EVRMeleeComType::VRPMELEECOM_Normal && SecondaryHand.IsValid()) + { + //if (PrimaryHand.HoldingController == GrippingController) + { + if (UPrimitiveComponent * PrimComp = Cast(GetParentSceneComp())) + { + if (FBodyInstance * rBodyInstance = PrimComp->GetBodyInstance()) + { + FPhysicsCommand::ExecuteWrite(rBodyInstance->ActorHandle, [&](const FPhysicsActorHandle& Actor) + { + FTransform localCom = FPhysicsInterface::GetComTransformLocal_AssumesLocked(Actor); + localCom.SetLocation((HandleInfo->RootBoneRotation * ObjectRelativeGripCenter).GetLocation()); + FPhysicsInterface::SetComLocalPose_AssumesLocked(Actor, localCom); + + }); + } + } + } + + HandleInfo->bSetCOM = true; // Should i remove this? + HandleInfo->bSkipResettingCom = true; + } + else + { + HandleInfo->bSkipResettingCom = false; + } +} + +/*void UGS_Melee::Tick(float DeltaTime) +{ + AActor* myOwner = GetOwner(); + + if (UPrimitiveComponent * root = Cast(myOwner->GetRootComponent())) + { + FBodyInstance* rBodyInstance = root->GetBodyInstance(); + if (rBodyInstance && rBodyInstance->IsValidBodyInstance()) + { + RollingVelocityAverage = rBodyInstance->GetUnrealWorldVelocity(); + RollingAngVelocityAverage = rBodyInstance->GetUnrealWorldAngularVelocityInRadians(); + } + } +}*/ + +bool UGS_Melee::Wants_DenyTeleport_Implementation(UGripMotionControllerComponent* Controller) +{ + /*if (PrimaryHand.IsValid() && Controller != PrimaryHand.HoldingController) + { + return true; + }*/ + + return false; +} + +bool UGS_Melee::GetWorldTransform_Implementation +( + UGripMotionControllerComponent* GrippingController, + float DeltaTime, FTransform & WorldTransform, + const FTransform &ParentTransform, + FBPActorGripInformation &Grip, + AActor * actor, + UPrimitiveComponent * root, + bool bRootHasInterface, + bool bActorHasInterface, + bool bIsForTeleport +) +{ + if (!GrippingController) + return false; + + // Just simple transform setting + WorldTransform = Grip.RelativeTransform * Grip.AdditionTransform * ParentTransform; + if (Grip.SecondaryGripInfo.bHasSecondaryAttachment) + { + WorldTransform.SetLocation((GrippingController->GetPivotLocation() + Grip.SecondaryGripInfo.SecondaryAttachment->GetComponentLocation()) / 2.f); + } + + // Check the grip lerp state, this it ouside of the secondary attach check below because it can change the result of it + if ((Grip.SecondaryGripInfo.bHasSecondaryAttachment && Grip.SecondaryGripInfo.SecondaryAttachment) || Grip.SecondaryGripInfo.GripLerpState == EGripLerpState::EndLerp) + { + switch (Grip.SecondaryGripInfo.GripLerpState) + { + case EGripLerpState::StartLerp: + case EGripLerpState::EndLerp: + { + if (Grip.SecondaryGripInfo.curLerp > 0.01f) + Grip.SecondaryGripInfo.curLerp -= DeltaTime; + else + { + /*if (Grip.SecondaryGripInfo.bHasSecondaryAttachment && + Grip.AdvancedGripSettings.SecondaryGripSettings.bUseSecondaryGripSettings && + Grip.AdvancedGripSettings.SecondaryGripSettings.SecondaryGripScaler_DEPRECATED < 1.0f) + { + Grip.SecondaryGripInfo.GripLerpState = EGripLerpState::ConstantLerp_DEPRECATED; + } + else*/ + Grip.SecondaryGripInfo.GripLerpState = EGripLerpState::NotLerping; + } + + }break; + //case EGripLerpState::ConstantLerp_DEPRECATED: + case EGripLerpState::NotLerping: + default:break; + } + } + + // Handle the interp and multi grip situations, re-checking the grip situation here as it may have changed in the switch above. + if ((Grip.SecondaryGripInfo.bHasSecondaryAttachment && Grip.SecondaryGripInfo.SecondaryAttachment) || Grip.SecondaryGripInfo.GripLerpState == EGripLerpState::EndLerp) + { + FTransform SecondaryTransform = Grip.RelativeTransform * ParentTransform; + + // Checking secondary grip type for the scaling setting + ESecondaryGripType SecondaryType = ESecondaryGripType::SG_None; + + if (bRootHasInterface) + SecondaryType = IVRGripInterface::Execute_SecondaryGripType(root); + else if (bActorHasInterface) + SecondaryType = IVRGripInterface::Execute_SecondaryGripType(actor); + + // If the grip is a custom one, skip all of this logic we won't be changing anything + if (SecondaryType != ESecondaryGripType::SG_Custom) + { + // Variables needed for multi grip transform + FVector BasePoint = ParentTransform.GetLocation(); // Get our pivot point + const FTransform PivotToWorld = FTransform(FQuat::Identity, BasePoint); + const FTransform WorldToPivot = FTransform(FQuat::Identity, -BasePoint); + + FVector frontLocOrig; + FVector frontLoc; + + // Ending lerp out of a multi grip + if (Grip.SecondaryGripInfo.GripLerpState == EGripLerpState::EndLerp) + { + frontLocOrig = (/*WorldTransform*/SecondaryTransform.TransformPosition(Grip.SecondaryGripInfo.SecondaryRelativeTransform.GetLocation())) - BasePoint; + frontLoc = Grip.SecondaryGripInfo.LastRelativeLocation; + + frontLocOrig = FMath::Lerp(frontLoc, frontLocOrig, FMath::Clamp(Grip.SecondaryGripInfo.curLerp / Grip.SecondaryGripInfo.LerpToRate, 0.0f, 1.0f)); + } + else // Is in a multi grip, might be lerping into it as well. + { + //FVector curLocation; // Current location of the secondary grip + + // Calculates the correct secondary attachment location and sets frontLoc to it + CalculateSecondaryLocation(frontLoc, BasePoint, Grip, GrippingController); + + frontLocOrig = (/*WorldTransform*/SecondaryTransform.TransformPosition(Grip.SecondaryGripInfo.SecondaryRelativeTransform.GetLocation())) - BasePoint; + + // Apply any smoothing settings and lerping in / constant lerping + ApplySmoothingAndLerp(Grip, frontLoc, frontLocOrig, DeltaTime); + + Grip.SecondaryGripInfo.LastRelativeLocation = frontLoc; + } + + // Get any scaling addition from a scaling secondary grip type + FVector Scaler = FVector(1.0f); + if (SecondaryType == ESecondaryGripType::SG_FreeWithScaling_Retain || SecondaryType == ESecondaryGripType::SG_SlotOnlyWithScaling_Retain || SecondaryType == ESecondaryGripType::SG_ScalingOnly) + { + GetAnyScaling(Scaler, Grip, frontLoc, frontLocOrig, SecondaryType, SecondaryTransform); + } + + Grip.SecondaryGripInfo.SecondaryGripDistance = FVector::Dist(frontLocOrig, frontLoc); + + /*if (Grip.AdvancedGripSettings.SecondaryGripSettings.bUseSecondaryGripSettings && Grip.AdvancedGripSettings.SecondaryGripSettings.bUseSecondaryGripDistanceInfluence_DEPRECATED) + { + float rotScaler = 1.0f - FMath::Clamp((Grip.SecondaryGripInfo.SecondaryGripDistance - Grip.AdvancedGripSettings.SecondaryGripSettings.GripInfluenceDeadZone_DEPRECATED) / FMath::Max(Grip.AdvancedGripSettings.SecondaryGripSettings.GripInfluenceDistanceToZero_DEPRECATED, 1.0f), 0.0f, 1.0f); + frontLoc = FMath::Lerp(frontLocOrig, frontLoc, rotScaler); + }*/ + + // Skip rot val for scaling only + if (SecondaryType != ESecondaryGripType::SG_ScalingOnly) + { + // Get the rotation difference from the initial second grip + FQuat rotVal = FQuat::FindBetweenVectors(frontLocOrig, frontLoc); + + // Rebase the world transform to the pivot point, add the rotation, remove the pivot point rebase + WorldTransform = WorldTransform * WorldToPivot * FTransform(rotVal, FVector::ZeroVector, Scaler) * PivotToWorld; + } + else + { + // Rebase the world transform to the pivot point, add the scaler, remove the pivot point rebase + WorldTransform = WorldTransform * WorldToPivot * FTransform(FQuat::Identity, FVector::ZeroVector, Scaler) * PivotToWorld; + } + } + + + // Fixup X rotation to keep it aligned with the primary hand. + //WorldTransform = Grip.RelativeTransform * Grip.AdditionTransform * ParentTransform; + + // Get primary hand relative position + FTransform InverseTrans(Grip.RelativeTransform.ToInverseMatrixWithScale()); + + // Get the original location of the hand + FVector origLocation = InverseTrans.GetLocation(); + + FVector orientedvector = FVector::VectorPlaneProject(origLocation, -OrientationComponentRelativeFacing.GetRotation().GetForwardVector()); + FVector newLocation = FVector::VectorPlaneProject(WorldTransform.InverseTransformPosition(GrippingController->GetPivotLocation()), OrientationComponentRelativeFacing.GetRotation().GetForwardVector()); + + FQuat DeltaQuat = FQuat::FindBetweenVectors(orientedvector, newLocation); + + WorldTransform.SetRotation(DeltaQuat * WorldTransform.GetRotation()); + } + + return true; +} diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_Physics.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_Physics.cpp new file mode 100644 index 0000000..c954563 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/GS_Physics.cpp @@ -0,0 +1,111 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#include "GripScripts/GS_Physics.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GS_Physics) + +#include "VRGripInterface.h" +#include "Components/PrimitiveComponent.h" +#include "GameFramework/Actor.h" +#include "GripMotionControllerComponent.h" + +UGS_Physics::UGS_Physics(const FObjectInitializer& ObjectInitializer) : + Super(ObjectInitializer) +{ + bIsActive = true; + WorldTransformOverrideType = EGSTransformOverrideType::None; + + bDenyLateUpdates = true; + + bInjectPrePhysicsHandle = false; + bInjectPostPhysicsHandle = true; + + bCanEverTick = false; + + SingleHandPhysicsSettings.TwistSettings.MaxForceCoefficient = 1.f; + SingleHandPhysicsSettings.SwingSettings = SingleHandPhysicsSettings.TwistSettings; + SingleHandPhysicsSettings.SlerpSettings = SingleHandPhysicsSettings.TwistSettings; + + SingleHandPhysicsSettings.XAxisSettings.MaxForceCoefficient = 1.f; + SingleHandPhysicsSettings.YAxisSettings = SingleHandPhysicsSettings.XAxisSettings; + SingleHandPhysicsSettings.ZAxisSettings = SingleHandPhysicsSettings.XAxisSettings; + +} + +void UGS_Physics::UpdateDualHandInfo(UGripMotionControllerComponent* GrippingController, bool bReCreate) +{ + TArray HoldingControllers; + bool bIsHeld; + IVRGripInterface::Execute_IsHeld(GetParent(), HoldingControllers, bIsHeld); + + int NumControllers = HoldingControllers.Num(); + + for (FBPGripPair& Grip : HoldingControllers) + { + if (NumControllers > 1) + { + FBPActorPhysicsHandleInformation* HandleInfo = Grip.HoldingController->GetPhysicsGrip(Grip.GripID); + if (HandleInfo) + { + MultiHandPhysicsSettings.FillTo(HandleInfo); + + if(bReCreate && Grip.HoldingController != GrippingController) + Grip.HoldingController->UpdatePhysicsHandle(Grip.GripID, true); + } + } + else + { + FBPActorPhysicsHandleInformation* HandleInfo = Grip.HoldingController->GetPhysicsGrip(Grip.GripID); + if (HandleInfo) + { + SingleHandPhysicsSettings.FillTo(HandleInfo); + + if(bReCreate) + Grip.HoldingController->UpdatePhysicsHandle(Grip.GripID, true); + } + } + } +} + + +void UGS_Physics::OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) +{ + if (!bIsActive) + return; + + UpdateDualHandInfo(GrippingController, true); +} + +void UGS_Physics::OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) +{ + + if (!bIsActive) + return; + + UpdateDualHandInfo(nullptr, true); +} + +// Should I be orienting it to the controller for these types of grips? +/*void UGS_Physics::HandlePrePhysicsHandle(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation &GripInfo, FBPActorPhysicsHandleInformation * HandleInfo, FTransform & KinPose) +{ + if (!bIsActive) + return; + + if (WeaponRootOrientationComponent != NAME_None) + { + // Alter to rotate to x+ if we have an orientation component + FQuat DeltaQuat = OrientationComponentRelativeFacing.GetRotation(); + + // This moves the kinematic actor to face its X+ in the direction designated + KinPose.SetRotation(KinPose.GetRotation() * (HandleInfo->RootBoneRotation.GetRotation().Inverse() * DeltaQuat)); + HandleInfo->COMPosition.SetRotation(HandleInfo->COMPosition.GetRotation() * (HandleInfo->RootBoneRotation.GetRotation().Inverse() * DeltaQuat)); + } +}*/ + +void UGS_Physics::HandlePostPhysicsHandle(UGripMotionControllerComponent* GrippingController, FBPActorPhysicsHandleInformation * HandleInfo) +{ + if (!bIsActive) + return; + + + UpdateDualHandInfo(GrippingController, false); +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/VRGripScriptBase.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/VRGripScriptBase.cpp new file mode 100644 index 0000000..2b91220 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/GripScripts/VRGripScriptBase.cpp @@ -0,0 +1,486 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#include "GripScripts/VRGripScriptBase.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRGripScriptBase) + +#include "GripMotionControllerComponent.h" +#include "VRGripInterface.h" +#include "Engine/BlueprintGeneratedClass.h" +#include "Components/PrimitiveComponent.h" +#include "GameFramework/Actor.h" +#include "Net/UnrealNetwork.h" +#include "Net/Core/PushModel/PushModel.h" +#include "Engine/NetDriver.h" + +#if UE_WITH_IRIS +#include "Iris/ReplicationSystem/ReplicationFragmentUtil.h" +#endif // UE_WITH_IRIS + + +UVRGripScriptBase::UVRGripScriptBase(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ +// PrimaryComponentTick.bCanEverTick = false; +// PrimaryComponentTick.bStartWithTickEnabled = false; +// PrimaryComponentTick.TickGroup = ETickingGroup::TG_PrePhysics; + WorldTransformOverrideType = EGSTransformOverrideType::None; + bDenyAutoDrop = false; + bDenyLateUpdates = false; + bForceDrop = false; + bIsActive = false; + + bCanEverTick = false; + bAllowTicking = false; +} + +void UVRGripScriptBase::OnEndPlay_Implementation(const EEndPlayReason::Type EndPlayReason) {}; +void UVRGripScriptBase::OnBeginPlay_Implementation(UObject * CallingOwner) {}; + +bool UVRGripScriptBase::GetWorldTransform_Implementation(UGripMotionControllerComponent* GrippingController, float DeltaTime, FTransform & WorldTransform, const FTransform &ParentTransform, FBPActorGripInformation &Grip, AActor * actor, UPrimitiveComponent * root, bool bRootHasInterface, bool bActorHasInterface, bool bIsForTeleport) { return true; } +void UVRGripScriptBase::OnGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) {} +void UVRGripScriptBase::OnGripRelease_Implementation(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed) {} +void UVRGripScriptBase::OnSecondaryGrip_Implementation(UGripMotionControllerComponent * Controller, USceneComponent * SecondaryGripComponent, const FBPActorGripInformation & GripInformation) {} +void UVRGripScriptBase::OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent * Controller, USceneComponent * ReleasingSecondaryGripComponent, const FBPActorGripInformation & GripInformation) {} + + +EGSTransformOverrideType UVRGripScriptBase::GetWorldTransformOverrideType() { return WorldTransformOverrideType; } +bool UVRGripScriptBase::IsScriptActive() { return bIsActive; } +//bool UVRGripScriptBase::Wants_DenyAutoDrop() { return bDenyAutoDrop; } +//bool UVRGripScriptBase::Wants_DenyLateUpdates() { return bDenyLateUpdates; } +//bool UVRGripScriptBase::Wants_ToForceDrop() { return bForceDrop; } +bool UVRGripScriptBase::Wants_DenyTeleport_Implementation(UGripMotionControllerComponent * Controller) { return false; } +void UVRGripScriptBase::HandlePrePhysicsHandle(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation &GripInfo, FBPActorPhysicsHandleInformation * HandleInfo, FTransform & KinPose) {} +void UVRGripScriptBase::HandlePostPhysicsHandle(UGripMotionControllerComponent* GrippingController, FBPActorPhysicsHandleInformation * HandleInfo) {} + +UVRGripScriptBase* UVRGripScriptBase::GetGripScriptByClass(UObject* WorldContextObject, TSubclassOf GripScriptClass, EBPVRResultSwitch& Result) +{ + if (WorldContextObject->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + TArray GripScripts; + if (IVRGripInterface::Execute_GetGripScripts(WorldContextObject, GripScripts)) + { + for (UVRGripScriptBase* Script : GripScripts) + { + if (Script && Script->IsA(GripScriptClass)) + { + Result = EBPVRResultSwitch::OnSucceeded; + return Script; + } + } + } + } + + Result = EBPVRResultSwitch::OnFailed; + return nullptr; +} + +#if UE_WITH_IRIS +void UVRGripScriptBase::RegisterReplicationFragments(UE::Net::FFragmentRegistrationContext& Context, UE::Net::EFragmentRegistrationFlags RegistrationFlags) +{ + using namespace UE::Net; + + Super::RegisterReplicationFragments(Context, RegistrationFlags); + + // Build descriptors and allocate PropertyReplicationFragments for this object + FReplicationFragmentUtil::CreateAndRegisterFragmentsForObject(this, Context, RegistrationFlags); +} +#endif // UE_WITH_IRIS + +void UVRGripScriptBase::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + // Uobject has no replicated props + //Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // Replicate here if required + UBlueprintGeneratedClass* BPClass = Cast(GetClass()); + if (BPClass != NULL) + { + BPClass->GetLifetimeBlueprintReplicationList(OutLifetimeProps); + } + + FDoRepLifetimeParams SharedParams; + SharedParams.bIsPushBased = true; + + DOREPLIFETIME_WITH_PARAMS(UVRGripScriptBase, bReplicates, SharedParams); +} + +void UVRGripScriptBase::SetIsReplicated(bool bShouldReplicate) +{ + if (GetIsReplicated() != bShouldReplicate) + { + bReplicates = bShouldReplicate; + + FBoolProperty* BoolProperty = CastField(this->GetClass()->FindPropertyByName("bReplicates")); + MARK_PROPERTY_DIRTY(this, BoolProperty); + //MARK_PROPERTY_DIRTY_FROM_NAME(UVRGripScriptBase, bReplicates, this); + + // Remove us from the subobject replication list if we need to be + if (AActor* OwningActor = Cast(GetParent())) + { + if (OwningActor->IsUsingRegisteredSubObjectList()) + { + if (bReplicates) + { + if (!OwningActor->IsReplicatedSubObjectRegistered(this)) + { + OwningActor->AddReplicatedSubObject(this); + } + } + else if(OwningActor->IsReplicatedSubObjectRegistered(this)) + { + OwningActor->RemoveReplicatedSubObject(this); + } + } + } + else if (UActorComponent* OwningComp = Cast(GetParent())) + { + if (bReplicates) + { + if (!OwningComp->IsReplicatedSubObjectRegistered(this)) + { + OwningComp->AddReplicatedSubObject(this); + } + } + else if (OwningComp->IsReplicatedSubObjectRegistered(this)) + { + OwningComp->RemoveReplicatedSubObject(this); + } + } + } +} + +void UVRGripScriptBase::Tick(float DeltaTime) +{ + // Do nothing by default +} + +bool UVRGripScriptBase::IsTickable() const +{ + return bAllowTicking; +} + +UWorld* UVRGripScriptBase::GetTickableGameObjectWorld() const +{ + return GetWorld(); +} + +bool UVRGripScriptBase::IsTickableInEditor() const +{ + return false; +} + +bool UVRGripScriptBase::IsTickableWhenPaused() const +{ + return false; +} + +ETickableTickType UVRGripScriptBase::GetTickableTickType() const +{ + if(IsTemplate(RF_ClassDefaultObject)) + return ETickableTickType::Never; + + return bCanEverTick ? ETickableTickType::Conditional : ETickableTickType::Never; +} + +TStatId UVRGripScriptBase::GetStatId() const +{ + RETURN_QUICK_DECLARE_CYCLE_STAT(UVRGripScriptBase, STATGROUP_Tickables); +} + +void UVRGripScriptBase::SetTickEnabled(bool bTickEnabled) +{ + bAllowTicking = bTickEnabled; +} + + +// Not currently compiling in editor builds....not entirely sure why... +/* +void UVRGripScriptBase::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) +{ + + // In the grippables pre replication to pass it on +#ifndef WITH_EDITOR + // Run pre-replication for any grip scripts + if (GripLogicScripts.Num()) + { + if (UNetDriver* NetDriver = GetNetDriver()) + { + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script && IsValid(Script)) + { + Script->PreReplication(*((IRepChangedPropertyTracker *)NetDriver->FindOrCreateRepChangedPropertyTracker(Script).Get())); + } + } + } + } +#endif + + UBlueprintGeneratedClass* BPClass = Cast(GetClass()); + if (BPClass != NULL) + { + BPClass->InstancePreReplication(this, ChangedPropertyTracker); + } +}*/ + +bool UVRGripScriptBase::CallRemoteFunction(UFunction * Function, void * Parms, FOutParmRec * OutParms, FFrame * Stack) +{ + bool bProcessed = false; + + if (AActor* MyOwner = GetOwner()) + { + FWorldContext* const Context = GEngine->GetWorldContextFromWorld(GetWorld()); + if (Context != nullptr) + { + for (FNamedNetDriver& Driver : Context->ActiveNetDrivers) + { + if (Driver.NetDriver != nullptr && Driver.NetDriver->ShouldReplicateFunction(MyOwner, Function)) + { + Driver.NetDriver->ProcessRemoteFunction(MyOwner, Function, Parms, OutParms, Stack, this); + + bProcessed = true; + } + } + } + } + + return bProcessed; +} + +int32 UVRGripScriptBase::GetFunctionCallspace(UFunction * Function, FFrame * Stack) +{ + AActor* Owner = GetOwner(); + + if (HasAnyFlags(RF_ClassDefaultObject) || !IsSupportedForNetworking() || !Owner) + { + // This handles absorbing authority/cosmetic + return GEngine->GetGlobalFunctionCallspace(Function, this, Stack); + } + + // Owner is certified valid now + return Owner->GetFunctionCallspace(Function, Stack); +} + +FTransform UVRGripScriptBase::GetGripTransform(const FBPActorGripInformation &Grip, const FTransform & ParentTransform) +{ + return Grip.RelativeTransform * Grip.AdditionTransform * ParentTransform; +} + +USceneComponent * UVRGripScriptBase::GetParentSceneComp() +{ + UObject* ParentObj = this->GetParent(); + + if (USceneComponent * PrimParent = Cast(ParentObj)) + { + return PrimParent; + } + else if (AActor * ParentActor = Cast(ParentObj)) + { + return ParentActor->GetRootComponent(); + } + + return nullptr; +} + +FTransform UVRGripScriptBase::GetParentTransform(bool bGetWorldTransform, FName BoneName) +{ + UObject* ParentObj = this->GetParent(); + + if (USceneComponent* PrimParent = Cast(ParentObj)) + { + if (BoneName != NAME_None) + { + return PrimParent->GetSocketTransform(BoneName); + } + else + { + return PrimParent->GetComponentTransform(); + } + } + else if (AActor* ParentActor = Cast(ParentObj)) + { + return ParentActor->GetActorTransform(); + } + + return FTransform::Identity; +} + +FBodyInstance * UVRGripScriptBase::GetParentBodyInstance(FName OptionalBoneName) +{ + UObject * ParentObj = this->GetParent(); + + if (UPrimitiveComponent * PrimParent = Cast(ParentObj)) + { + return PrimParent->GetBodyInstance(OptionalBoneName); + } + else if (AActor * ParentActor = Cast(ParentObj)) + { + if (UPrimitiveComponent * Prim = Cast(ParentActor->GetRootComponent())) + { + return Prim->GetBodyInstance(OptionalBoneName); + } + } + + return nullptr; +} + +UObject * UVRGripScriptBase::GetParent() +{ + return this->GetOuter(); +} + +AActor * UVRGripScriptBase::GetOwner() +{ + UObject * myOuter = this->GetOuter(); + + if (!myOuter) + return nullptr; + + if (AActor * ActorOwner = Cast(myOuter)) + { + return ActorOwner; + } + else if (UActorComponent * ComponentOwner = Cast(myOuter)) + { + return ComponentOwner->GetOwner(); + } + + return nullptr; +} + +bool UVRGripScriptBase::HasAuthority() +{ + if (AActor * MyOwner = GetOwner()) + { + return MyOwner->GetLocalRole() == ROLE_Authority; + } + + return false; +} + +bool UVRGripScriptBase::IsServer() +{ + if (AActor * MyOwner = GetOwner()) + { + return MyOwner->GetNetMode() < ENetMode::NM_Client; + } + + return false; +} + +UWorld* UVRGripScriptBase::GetWorld() const +{ + if (IsTemplate()) + return nullptr; + + if (GIsEditor && !GIsPlayInEditorWorld) + { + return nullptr; + } + else if (UObject * Outer = GetOuter()) + { + return Outer->GetWorld(); + } + + return nullptr; +} + +void UVRGripScriptBase::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + // Remove us from the subobject replication list if we need to be + if (AActor* OwningActor = Cast(GetParent())) + { + if (OwningActor->IsUsingRegisteredSubObjectList()) + { + OwningActor->RemoveReplicatedSubObject(this); + } + } + else if (UActorComponent* OwningComp = Cast(GetParent())) + { + if (OwningComp->IsUsingRegisteredSubObjectList()) + { + OwningComp->RemoveReplicatedSubObject(this); + } + } + + OnEndPlay(EndPlayReason); +} + +void UVRGripScriptBase::BeginDestroy() +{ + Super::BeginDestroy(); + + if (bReplicates) + { + // Remove us from the subobject replication list if we need to be + if (AActor* OwningActor = Cast(GetParent())) + { + if (OwningActor->IsUsingRegisteredSubObjectList()) + { + OwningActor->RemoveReplicatedSubObject(this); + } + } + else if (UActorComponent* OwningComp = Cast(GetParent())) + { + if (OwningComp->IsUsingRegisteredSubObjectList()) + { + OwningComp->RemoveReplicatedSubObject(this); + } + } + } +} + +void UVRGripScriptBase::BeginPlay(UObject * CallingOwner) +{ + if (bAlreadyNotifiedPlay) + return; + + if (bReplicates) + { + // Register us to the subobject replication list if we need to be + if (AActor* OwningActor = Cast(CallingOwner)) + { + if (OwningActor->IsUsingRegisteredSubObjectList()) + { + OwningActor->AddReplicatedSubObject(this, ReplicationCondition); + } + } + else if (UActorComponent* OwningComp = Cast(CallingOwner)) + { + if (OwningComp->IsUsingRegisteredSubObjectList()) + { + OwningComp->AddReplicatedSubObject(this, ReplicationCondition); + } + } + } + + bAlreadyNotifiedPlay = true; + + // Notify the subscripts about begin play + OnBeginPlay(CallingOwner); +} + +void UVRGripScriptBase::PostInitProperties() +{ + Super::PostInitProperties(); + + if (bReplicates) + { + //Called in game, when World exist . BeginPlay will not be called in editor + if (GetWorld()) + { + if (AActor* Owner = GetOwner()) + { + if (Owner->IsActorInitialized()) + { + BeginPlay(GetParent()); + } + } + } + } +} + +void UVRGripScriptBaseBP::Tick(float DeltaTime) +{ + ReceiveTick(DeltaTime); +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableActor.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableActor.cpp new file mode 100644 index 0000000..57d69df --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableActor.cpp @@ -0,0 +1,930 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Grippables/GrippableActor.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GrippableActor) + +#include "TimerManager.h" +#include "Net/UnrealNetwork.h" +#include "PhysicsReplication.h" +#include "GameFramework/PlayerController.h" +#include "GameFramework/PlayerState.h" +#include "GripMotionControllerComponent.h" +#include "VRExpansionFunctionLibrary.h" +#include "Misc/BucketUpdateSubsystem.h" +#include "GripScripts/VRGripScriptBase.h" +#include "DrawDebugHelpers.h" + +#include "Physics/Experimental/PhysScene_Chaos.h" +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + + //============================================================================= +AGrippableActor::AGrippableActor(const FObjectInitializer& ObjectInitializer) + : Super() +{ + VRGripInterfaceSettings.bDenyGripping = false; + VRGripInterfaceSettings.OnTeleportBehavior = EGripInterfaceTeleportBehavior::TeleportAllComponents; + VRGripInterfaceSettings.bSimulateOnDrop = true; + VRGripInterfaceSettings.SlotDefaultGripType = EGripCollisionType::InteractiveCollisionWithPhysics; + VRGripInterfaceSettings.FreeDefaultGripType = EGripCollisionType::InteractiveCollisionWithPhysics; + VRGripInterfaceSettings.SecondaryGripType = ESecondaryGripType::SG_None; + VRGripInterfaceSettings.MovementReplicationType = EGripMovementReplicationSettings::ForceClientSideMovement; + VRGripInterfaceSettings.LateUpdateSetting = EGripLateUpdateSettings::NotWhenCollidingOrDoubleGripping; + VRGripInterfaceSettings.ConstraintStiffness = 1500.0f; + VRGripInterfaceSettings.ConstraintDamping = 200.0f; + VRGripInterfaceSettings.ConstraintBreakDistance = 100.0f; + VRGripInterfaceSettings.SecondarySlotRange = 20.0f; + VRGripInterfaceSettings.PrimarySlotRange = 20.0f; + + VRGripInterfaceSettings.bIsHeld = false; + + // Default replication on for multiplayer + //this->bNetLoadOnClient = false; + SetReplicatingMovement(true); + bReplicates = true; + + bRepGripSettingsAndGameplayTags = true; + bAllowIgnoringAttachOnOwner = true; + bReplicateGripScripts = false; + + // #TODO we can register them maybe in the future + // Don't use the replicated list, use our custom replication instead + bReplicateUsingRegisteredSubObjectList = false; + + // Setting a minimum of every 3rd frame (VR 90fps) for replication consideration + // Otherwise we will get some massive slow downs if the replication is allowed to hit the 2 per second minimum default + MinNetUpdateFrequency = 30.0f; +} + +void AGrippableActor::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableActor, bReplicateGripScripts, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableActor, bRepGripSettingsAndGameplayTags, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableActor, bAllowIgnoringAttachOnOwner, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableActor, ClientAuthReplicationData, PushModelParams); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableActor, GripLogicScripts, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableActor, VRGripInterfaceSettings, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableActor, GameplayTags, PushModelParamsWithCondition); + + DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, AttachmentReplication); + + FDoRepLifetimeParams AttachmentReplicationParams{ COND_Custom, REPNOTIFY_Always, /*bIsPushBased=*/true }; + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableActor, AttachmentWeldReplication, AttachmentReplicationParams); +} + +void AGrippableActor::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) +{ + // Don't replicate if set to not do it + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AGrippableActor, VRGripInterfaceSettings, bRepGripSettingsAndGameplayTags); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AGrippableActor, GameplayTags, bRepGripSettingsAndGameplayTags); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AGrippableActor, GripLogicScripts, bReplicateGripScripts); + + //Super::PreReplication(ChangedPropertyTracker); + +#if WITH_PUSH_MODEL + const AActor* const OldAttachParent = AttachmentWeldReplication.AttachParent; + const UActorComponent* const OldAttachComponent = AttachmentWeldReplication.AttachComponent; +#endif + + // Attachment replication gets filled in by GatherCurrentMovement(), but in the case of a detached root we need to trigger remote detachment. + AttachmentWeldReplication.AttachParent = nullptr; + AttachmentWeldReplication.AttachComponent = nullptr; + + GatherCurrentMovement(); + + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AActor, ReplicatedMovement, IsReplicatingMovement()); + + // Don't need to replicate AttachmentReplication if the root component replicates, because it already handles it. + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AGrippableActor, AttachmentWeldReplication, RootComponent && !RootComponent->GetIsReplicated()); + + // Don't need to replicate AttachmentReplication if the root component replicates, because it already handles it. + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AActor, AttachmentReplication, false);// RootComponent && !RootComponent->GetIsReplicated()); + + +#if WITH_PUSH_MODEL + if (UNLIKELY(OldAttachParent != AttachmentWeldReplication.AttachParent || OldAttachComponent != AttachmentWeldReplication.AttachComponent)) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, AttachmentWeldReplication, this); + } +#endif + + /*PRAGMA_DISABLE_DEPRECATION_WARNINGS + UBlueprintGeneratedClass* BPClass = Cast(GetClass()); + if (BPClass != nullptr) + { + BPClass->InstancePreReplication(this, ChangedPropertyTracker); + } + PRAGMA_ENABLE_DEPRECATION_WARNINGS*/ +} + +void AGrippableActor::GatherCurrentMovement() +{ + if (IsReplicatingMovement() || (RootComponent && RootComponent->GetAttachParent())) + { + bool bWasAttachmentModified = false; + bool bWasRepMovementModified = false; + + AActor* OldAttachParent = AttachmentWeldReplication.AttachParent; + USceneComponent* OldAttachComponent = AttachmentWeldReplication.AttachComponent; + + AttachmentWeldReplication.AttachParent = nullptr; + AttachmentWeldReplication.AttachComponent = nullptr; + + FRepMovement& RepMovement = GetReplicatedMovement_Mutable(); + + UPrimitiveComponent* RootPrimComp = Cast(GetRootComponent()); + if (RootPrimComp && RootPrimComp->IsSimulatingPhysics()) + { +#if UE_WITH_IRIS + const bool bPrevRepPhysics = GetReplicatedMovement_Mutable().bRepPhysics; +#endif // UE_WITH_IRIS + + bool bFoundInCache = false; + + UWorld* World = GetWorld(); + int ServerFrame = 0; + if (FPhysScene_Chaos* Scene = static_cast(World->GetPhysicsScene())) + { + if (const FRigidBodyState* FoundState = Scene->GetStateFromReplicationCache(RootPrimComp, ServerFrame)) + { + RepMovement.FillFrom(*FoundState, this, Scene->ReplicationCache.ServerFrame); + bFoundInCache = true; + } + } + + if (!bFoundInCache) + { + // fallback to GT data + FRigidBodyState RBState; + RootPrimComp->GetRigidBodyState(RBState); + RepMovement.FillFrom(RBState, this, 0); + } + + // Don't replicate movement if we're welded to another parent actor. + // Their replication will affect our position indirectly since we are attached. + RepMovement.bRepPhysics = !RootPrimComp->IsWelded(); + + if (!RepMovement.bRepPhysics) + { + if (RootComponent->GetAttachParent() != nullptr) + { + // Networking for attachments assumes the RootComponent of the AttachParent actor. + // If that's not the case, we can't update this, as the client wouldn't be able to resolve the Component and would detach as a result. + AttachmentWeldReplication.AttachParent = RootComponent->GetAttachParent()->GetAttachmentRootActor(); + if (AttachmentWeldReplication.AttachParent != nullptr) + { + AttachmentWeldReplication.LocationOffset = RootComponent->GetRelativeLocation(); + AttachmentWeldReplication.RotationOffset = RootComponent->GetRelativeRotation(); + AttachmentWeldReplication.RelativeScale3D = RootComponent->GetRelativeScale3D(); + AttachmentWeldReplication.AttachComponent = RootComponent->GetAttachParent(); + AttachmentWeldReplication.AttachSocket = RootComponent->GetAttachSocketName(); + AttachmentWeldReplication.bIsWelded = RootPrimComp ? RootPrimComp->IsWelded() : false; + + // Technically, the values might have stayed the same, but we'll just assume they've changed. + bWasAttachmentModified = true; + } + } + } + + // Technically, the values might have stayed the same, but we'll just assume they've changed. + bWasRepMovementModified = true; + +#if UE_WITH_IRIS + // If RepPhysics has changed value then notify the ReplicationSystem + if (bPrevRepPhysics != GetReplicatedMovement_Mutable().bRepPhysics) + { + UpdateReplicatePhysicsCondition(); + } +#endif // UE_WITH_IRIS + } + else if (RootComponent != nullptr) + { + // If we are attached, don't replicate absolute position, use AttachmentReplication instead. + if (RootComponent->GetAttachParent() != nullptr) + { + // Networking for attachments assumes the RootComponent of the AttachParent actor. + // If that's not the case, we can't update this, as the client wouldn't be able to resolve the Component and would detach as a result. + AttachmentWeldReplication.AttachParent = RootComponent->GetAttachParentActor(); + if (AttachmentWeldReplication.AttachParent != nullptr) + { + AttachmentWeldReplication.LocationOffset = RootComponent->GetRelativeLocation(); + AttachmentWeldReplication.RotationOffset = RootComponent->GetRelativeRotation(); + AttachmentWeldReplication.RelativeScale3D = RootComponent->GetRelativeScale3D(); + AttachmentWeldReplication.AttachComponent = RootComponent->GetAttachParent(); + AttachmentWeldReplication.AttachSocket = RootComponent->GetAttachSocketName(); + AttachmentWeldReplication.bIsWelded = RootPrimComp ? RootPrimComp->IsWelded() : false; + + // Technically, the values might have stayed the same, but we'll just assume they've changed. + bWasAttachmentModified = true; + } + } + else + { + RepMovement.Location = FRepMovement::RebaseOntoZeroOrigin(RootComponent->GetComponentLocation(), this); + RepMovement.Rotation = RootComponent->GetComponentRotation(); + RepMovement.LinearVelocity = GetVelocity(); + RepMovement.AngularVelocity = FVector::ZeroVector; + + // Technically, the values might have stayed the same, but we'll just assume they've changed. + bWasRepMovementModified = true; + } + + bWasRepMovementModified = (bWasRepMovementModified || RepMovement.bRepPhysics); + RepMovement.bRepPhysics = false; + } + +#if WITH_PUSH_MODEL + if (bWasRepMovementModified) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AActor, ReplicatedMovement, this); + } + + if (bWasAttachmentModified || + OldAttachParent != AttachmentWeldReplication.AttachParent || + OldAttachComponent != AttachmentWeldReplication.AttachComponent) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, AttachmentWeldReplication, this); + } +#endif + } +} + +bool AGrippableActor::ShouldWeSkipAttachmentReplication(bool bConsiderHeld) const +{ + if ((bConsiderHeld && !VRGripInterfaceSettings.bWasHeld) || GetNetMode() < ENetMode::NM_Client) + return false; + + if (VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive || + VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep) + { + // First return if we are locally held (owner may not have replicated yet) + for (const FBPGripPair& Grip : VRGripInterfaceSettings.HoldingControllers) + { + if (IsValid(Grip.HoldingController) && Grip.HoldingController->IsLocallyControlled()) + { + return true; + } + } + + // then return if we have a local net owner + return HasLocalNetOwner(); + } + else + return false; +} + +void AGrippableActor::OnRep_AttachmentReplication() +{ + if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) + //if (bAllowIgnoringAttachOnOwner && ShouldWeSkipAttachmentReplication()) + { + return; + } + + if (AttachmentWeldReplication.AttachParent) + { + if (RootComponent) + { + USceneComponent* AttachParentComponent = (AttachmentWeldReplication.AttachComponent ? ToRawPtr(AttachmentWeldReplication.AttachComponent) : AttachmentWeldReplication.AttachParent->GetRootComponent()); + + if (AttachParentComponent) + { + RootComponent->SetRelativeLocation_Direct(AttachmentWeldReplication.LocationOffset); + RootComponent->SetRelativeRotation_Direct(AttachmentWeldReplication.RotationOffset); + RootComponent->SetRelativeScale3D_Direct(AttachmentWeldReplication.RelativeScale3D); + + // If we're already attached to the correct Parent and Socket, then the update must be position only. + // AttachToComponent would early out in this case. + // Note, we ignore the special case for simulated bodies in AttachToComponent as AttachmentReplication shouldn't get updated + // if the body is simulated (see AActor::GatherMovement). + const bool bAlreadyAttached = (AttachParentComponent == RootComponent->GetAttachParent() && AttachmentWeldReplication.AttachSocket == RootComponent->GetAttachSocketName() && AttachParentComponent->GetAttachChildren().Contains(RootComponent)); + if (bAlreadyAttached) + { + // Note, this doesn't match AttachToComponent, but we're assuming it's safe to skip physics (see comment above). + RootComponent->UpdateComponentToWorld(EUpdateTransformFlags::SkipPhysicsUpdate, ETeleportType::None); + } + else + { + FAttachmentTransformRules attachRules = FAttachmentTransformRules::KeepRelativeTransform; + attachRules.bWeldSimulatedBodies = AttachmentWeldReplication.bIsWelded; + RootComponent->AttachToComponent(AttachParentComponent, attachRules, AttachmentWeldReplication.AttachSocket); + } + } + } + } + else + { + DetachFromActor(FDetachmentTransformRules::KeepWorldTransform); + + // Handle the case where an object was both detached and moved on the server in the same frame. + // Calling this extraneously does not hurt but will properly fire events if the movement state changed while attached. + // This is needed because client side movement is ignored when attached + if (IsReplicatingMovement()) + { + OnRep_ReplicatedMovement(); + } + } +} + +bool AGrippableActor::ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) +{ + bool WroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags); + + if (bReplicateGripScripts && !IsUsingRegisteredSubObjectList()) + { + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script && IsValid(Script)) + { + WroteSomething |= Channel->ReplicateSubobject(Script, *Bunch, *RepFlags); + } + } + } + + return WroteSomething; +} + +//============================================================================= +AGrippableActor::~AGrippableActor() +{ +} + +void AGrippableActor::BeginPlay() +{ + // Call the base class + Super::BeginPlay(); + + // Call all grip scripts begin play events so they can perform any needed logic + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script) + { + Script->BeginPlay(this); + } + } +} + + +void AGrippableActor::SetDenyGripping(bool bDenyGripping) +{ + VRGripInterfaceSettings.bDenyGripping = bDenyGripping; +} + +void AGrippableActor::SetGripPriority(int NewGripPriority) +{ + VRGripInterfaceSettings.AdvancedGripSettings.GripPriority = NewGripPriority; +} + +void AGrippableActor::TickGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation, float DeltaTime) {} +void AGrippableActor::OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) {} +void AGrippableActor::OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) { } +void AGrippableActor::OnChildGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) {} +void AGrippableActor::OnChildGripRelease_Implementation(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed) {} +void AGrippableActor::OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripAdded.Broadcast(GripOwningController, GripInformation); } +void AGrippableActor::OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripRemoved.Broadcast(GripOwningController, GripInformation); } +void AGrippableActor::OnUsed_Implementation() {} +void AGrippableActor::OnEndUsed_Implementation() {} +void AGrippableActor::OnSecondaryUsed_Implementation() {} +void AGrippableActor::OnEndSecondaryUsed_Implementation() {} +void AGrippableActor::OnInput_Implementation(FKey Key, EInputEvent KeyEvent) {} +bool AGrippableActor::RequestsSocketing_Implementation(USceneComponent *& ParentToSocketTo, FName & OptionalSocketName, FTransform_NetQuantize & RelativeTransform) { return false; } + +bool AGrippableActor::DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator) +{ + return VRGripInterfaceSettings.bDenyGripping; +} + + +EGripInterfaceTeleportBehavior AGrippableActor::TeleportBehavior_Implementation() +{ + return VRGripInterfaceSettings.OnTeleportBehavior; +} + +bool AGrippableActor::SimulateOnDrop_Implementation() +{ + return VRGripInterfaceSettings.bSimulateOnDrop; +} + +EGripCollisionType AGrippableActor::GetPrimaryGripType_Implementation(bool bIsSlot) +{ + return bIsSlot ? VRGripInterfaceSettings.SlotDefaultGripType : VRGripInterfaceSettings.FreeDefaultGripType; +} + +ESecondaryGripType AGrippableActor::SecondaryGripType_Implementation() +{ + return VRGripInterfaceSettings.SecondaryGripType; +} + +EGripMovementReplicationSettings AGrippableActor::GripMovementReplicationType_Implementation() +{ + return VRGripInterfaceSettings.MovementReplicationType; +} + +EGripLateUpdateSettings AGrippableActor::GripLateUpdateSetting_Implementation() +{ + return VRGripInterfaceSettings.LateUpdateSetting; +} + +void AGrippableActor::GetGripStiffnessAndDamping_Implementation(float &GripStiffnessOut, float &GripDampingOut) +{ + GripStiffnessOut = VRGripInterfaceSettings.ConstraintStiffness; + GripDampingOut = VRGripInterfaceSettings.ConstraintDamping; +} + +FBPAdvGripSettings AGrippableActor::AdvancedGripSettings_Implementation() +{ + return VRGripInterfaceSettings.AdvancedGripSettings; +} + +float AGrippableActor::GripBreakDistance_Implementation() +{ + return VRGripInterfaceSettings.ConstraintBreakDistance; +} + +void AGrippableActor::ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool & bHadSlotInRange, FTransform & SlotWorldTransform, FName & SlotName, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ + if (OverridePrefix.IsNone()) + bSecondarySlot ? OverridePrefix = "VRGripS" : OverridePrefix = "VRGripP"; + + UVRExpansionFunctionLibrary::GetGripSlotInRangeByTypeName(OverridePrefix, this, WorldLocation, bSecondarySlot ? VRGripInterfaceSettings.SecondarySlotRange : VRGripInterfaceSettings.PrimarySlotRange, bHadSlotInRange, SlotWorldTransform, SlotName, CallingController); +} + +bool AGrippableActor::AllowsMultipleGrips_Implementation() +{ + return VRGripInterfaceSettings.bAllowMultipleGrips; +} + +void AGrippableActor::IsHeld_Implementation(TArray & HoldingControllers, bool & bIsHeld) +{ + HoldingControllers = VRGripInterfaceSettings.HoldingControllers; + bIsHeld = VRGripInterfaceSettings.bIsHeld; +} + +bool AGrippableActor::AddToClientReplicationBucket() +{ + if (ShouldWeSkipAttachmentReplication(false)) + { + // The subsystem automatically removes entries with the same function signature so its safe to just always add here + GetWorld()->GetSubsystem()->AddObjectToBucket(ClientAuthReplicationData.UpdateRate, this, FName(TEXT("PollReplicationEvent"))); + ClientAuthReplicationData.bIsCurrentlyClientAuth = true; + + if (UWorld * World = GetWorld()) + ClientAuthReplicationData.TimeAtInitialThrow = World->GetTimeSeconds(); + + return true; + } + + return false; +} + +bool AGrippableActor::RemoveFromClientReplicationBucket() +{ + if (ClientAuthReplicationData.bIsCurrentlyClientAuth) + { + GetWorld()->GetSubsystem()->RemoveObjectFromBucketByFunctionName(this, FName(TEXT("PollReplicationEvent"))); + CeaseReplicationBlocking(); + return true; + } + + return false; +} + +void AGrippableActor::Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed) +{ + if (bGripped) + { + OnGripped.Broadcast(Controller, GripInformation); + } + else + { + OnDropped.Broadcast(Controller, GripInformation, bWasSocketed); + } +} + +void AGrippableActor::SetHeld_Implementation(UGripMotionControllerComponent * HoldingController, uint8 GripID, bool bIsHeld) +{ + if (bIsHeld) + { + VRGripInterfaceSettings.HoldingControllers.AddUnique(FBPGripPair(HoldingController, GripID)); + RemoveFromClientReplicationBucket(); + + VRGripInterfaceSettings.bWasHeld = true; + VRGripInterfaceSettings.bIsHeld = VRGripInterfaceSettings.HoldingControllers.Num() > 0; + } + else + { + VRGripInterfaceSettings.HoldingControllers.Remove(FBPGripPair(HoldingController, GripID)); + VRGripInterfaceSettings.bIsHeld = VRGripInterfaceSettings.HoldingControllers.Num() > 0; + + if (ClientAuthReplicationData.bUseClientAuthThrowing && !VRGripInterfaceSettings.bIsHeld) + { + bool bWasLocallyOwned = HoldingController ? HoldingController->IsLocallyControlled() : false; + if (bWasLocallyOwned && ShouldWeSkipAttachmentReplication(false)) + { + if (UPrimitiveComponent* PrimComp = Cast(GetRootComponent())) + { + if (PrimComp->IsSimulatingPhysics()) + { + AddToClientReplicationBucket(); + } + } + } + } + } +} + +bool AGrippableActor::GetGripScripts_Implementation(TArray & ArrayReference) +{ + ArrayReference = GripLogicScripts; + return GripLogicScripts.Num() > 0; +} + +/*FBPInteractionSettings AGrippableActor::GetInteractionSettings_Implementation() +{ + return VRGripInterfaceSettings.InteractionSettings; +}*/ + +bool AGrippableActor::PollReplicationEvent() +{ + if (!ClientAuthReplicationData.bIsCurrentlyClientAuth || !this->HasLocalNetOwner() || VRGripInterfaceSettings.bIsHeld) + return false; // Tell the bucket subsystem to remove us from consideration + + UWorld* OurWorld = GetWorld(); + if (!OurWorld) + return false; // Tell the bucket subsystem to remove us from consideration + + bool bRemoveBlocking = false; + + if ((OurWorld->GetTimeSeconds() - ClientAuthReplicationData.TimeAtInitialThrow) > 10.0f) + { + // Lets time out sending, its been 10 seconds since we threw the object and its likely that it is conflicting with some server + // Authed movement that is forcing it to keep momentum. + //return false; // Tell the bucket subsystem to remove us from consideration + bRemoveBlocking = true; + } + + // Store current transform for resting check + FTransform CurTransform = this->GetActorTransform(); + + if (!bRemoveBlocking) + { + if (!CurTransform.GetRotation().Equals(ClientAuthReplicationData.LastActorTransform.GetRotation()) || !CurTransform.GetLocation().Equals(ClientAuthReplicationData.LastActorTransform.GetLocation())) + { + ClientAuthReplicationData.LastActorTransform = CurTransform; + + if (UPrimitiveComponent * PrimComp = Cast(RootComponent)) + { + // Need to clamp to a max time since start, to handle cases with conflicting collisions + if (PrimComp->IsSimulatingPhysics() && ShouldWeSkipAttachmentReplication(false)) + { + FRepMovementVR ClientAuthMovementRep; + if (ClientAuthMovementRep.GatherActorsMovement(this)) + { + Server_GetClientAuthReplication(ClientAuthMovementRep); + + if (PrimComp->RigidBodyIsAwake()) + { + return true; + } + } + } + } + else + { + bRemoveBlocking = true; + //return false; // Tell the bucket subsystem to remove us from consideration + } + } + //else + // { + // Difference is too small, lets end sending location + //ClientAuthReplicationData.LastActorTransform = FTransform::Identity; + // } + } + + bool TimedBlockingRelease = false; + + AActor* TopOwner = GetOwner(); + if (TopOwner != nullptr) + { + AActor* tempOwner = TopOwner->GetOwner(); + + // I have an owner so search that for the top owner + while (tempOwner) + { + TopOwner = tempOwner; + tempOwner = TopOwner->GetOwner(); + } + + if (APlayerController * PlayerController = Cast(TopOwner)) + { + if (APlayerState * PlayerState = PlayerController->PlayerState) + { + if (ClientAuthReplicationData.ResetReplicationHandle.IsValid()) + { + OurWorld->GetTimerManager().ClearTimer(ClientAuthReplicationData.ResetReplicationHandle); + } + + // Lets clamp the ping to a min / max value just in case + float clampedPing = FMath::Clamp(PlayerState->ExactPing * 0.001f, 0.0f, 1000.0f); + OurWorld->GetTimerManager().SetTimer(ClientAuthReplicationData.ResetReplicationHandle, this, &AGrippableActor::CeaseReplicationBlocking, clampedPing, false); + TimedBlockingRelease = true; + } + } + } + + if (!TimedBlockingRelease) + { + CeaseReplicationBlocking(); + } + + // Tell server to kill us + Server_EndClientAuthReplication(); + return false; // Tell the bucket subsystem to remove us from consideration +} + +void AGrippableActor::CeaseReplicationBlocking() +{ + if (ClientAuthReplicationData.bIsCurrentlyClientAuth) + ClientAuthReplicationData.bIsCurrentlyClientAuth = false; + + ClientAuthReplicationData.LastActorTransform = FTransform::Identity; + + if (ClientAuthReplicationData.ResetReplicationHandle.IsValid()) + { + if (UWorld * OurWorld = GetWorld()) + { + OurWorld->GetTimerManager().ClearTimer(ClientAuthReplicationData.ResetReplicationHandle); + } + } +} + +void AGrippableActor::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + + RemoveFromClientReplicationBucket(); + + // Call all grip scripts begin play events so they can perform any needed logic + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script) + { + Script->EndPlay(EndPlayReason); + } + } + + Super::EndPlay(EndPlayReason); +} + +bool AGrippableActor::Server_EndClientAuthReplication_Validate() +{ + return true; +} + +void AGrippableActor::Server_EndClientAuthReplication_Implementation() +{ + if (UWorld* World = GetWorld()) + { + if (FPhysScene* PhysScene = World->GetPhysicsScene()) + { + if (IPhysicsReplication* PhysicsReplication = PhysScene->GetPhysicsReplication()) + { + if (UPrimitiveComponent* RootPrim = Cast(GetRootComponent())) + { + PhysicsReplication->RemoveReplicatedTarget(RootPrim); + } + } + } + } +} + +bool AGrippableActor::Server_GetClientAuthReplication_Validate(const FRepMovementVR & newMovement) +{ + return true; +} + +void AGrippableActor::Server_GetClientAuthReplication_Implementation(const FRepMovementVR & newMovement) +{ + if (!VRGripInterfaceSettings.bIsHeld) + { + if (!newMovement.Location.ContainsNaN() && !newMovement.Rotation.ContainsNaN()) + { + FRepMovement& MovementRep = GetReplicatedMovement_Mutable(); + newMovement.CopyTo(MovementRep); + OnRep_ReplicatedMovement(); + } + } +} + +void AGrippableActor::OnRep_ReplicateMovement() +{ + if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) + //if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) + { + return; + } + + if (RootComponent) + { + const FRepAttachment ReplicationAttachment = GetAttachmentReplication(); + if (!ReplicationAttachment.AttachParent) + { + const FRepMovement& RepMove = GetReplicatedMovement(); + + // This "fix" corrects the simulation state not replicating over correctly + // If you turn off movement replication, simulate an object, turn movement replication back on and un-simulate, it never knows the difference + // This change ensures that it is checking against the current state + if (RootComponent->IsSimulatingPhysics() != RepMove.bRepPhysics)//SavedbRepPhysics != ReplicatedMovement.bRepPhysics) + { + // Turn on/off physics sim to match server. + SyncReplicatedPhysicsSimulation(); + + // It doesn't really hurt to run it here, the super can call it again but it will fail out as they already match + } + } + } + + Super::OnRep_ReplicateMovement(); +} + +void AGrippableActor::OnRep_ReplicatedMovement() +{ + if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) + //if (ClientAuthReplicationData.bIsCurrentlyClientAuth && ShouldWeSkipAttachmentReplication(false)) + { + return; + } + + Super::OnRep_ReplicatedMovement(); +} + +void AGrippableActor::PostNetReceivePhysicState() +{ + if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) + //if ((ClientAuthReplicationData.bIsCurrentlyClientAuth || VRGripInterfaceSettings.bIsHeld) && bAllowIgnoringAttachOnOwner && ShouldWeSkipAttachmentReplication(false)) + { + return; + } + + Super::PostNetReceivePhysicState(); +} +// This isn't called very many places but it does come up +void AGrippableActor::MarkComponentsAsGarbage(bool bModify) +{ + Super::MarkComponentsAsGarbage(bModify); + + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject *SubObject = GripLogicScripts[i]) + { + SubObject->MarkAsGarbage(); + } + } + + GripLogicScripts.Empty(); +} + +/** Called right before being marked for destruction due to network replication */ +// Clean up our objects so that they aren't sitting around for GC +void AGrippableActor::PreDestroyFromReplication() +{ + Super::PreDestroyFromReplication(); + + // Destroy any sub-objects we created + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject *SubObject = GripLogicScripts[i]) + { + OnSubobjectDestroyFromReplication(SubObject); //-V595 + SubObject->PreDestroyFromReplication(); + SubObject->MarkAsGarbage(); + } + } + + for (UActorComponent * ActorComp : GetComponents()) + { + // Pending kill components should have already had this called as they were network spawned and are being killed + if (ActorComp && IsValid(ActorComp) && ActorComp->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + ActorComp->PreDestroyFromReplication(); + } + + GripLogicScripts.Empty(); +} + +// On Destroy clean up our objects +void AGrippableActor::BeginDestroy() +{ + Super::BeginDestroy(); + + for (int32 i = 0; i < GripLogicScripts.Num(); i++) + { + if (UObject *SubObject = GripLogicScripts[i]) + { + SubObject->MarkAsGarbage(); + } + } + + GripLogicScripts.Empty(); +} + +void AGrippableActor::GetSubobjectsWithStableNamesForNetworking(TArray& ObjList) +{ + Super::GetSubobjectsWithStableNamesForNetworking(ObjList); + + if (bReplicateGripScripts) + { + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject* SubObject = GripLogicScripts[i]) + { + ObjList.Add(SubObject); + } + } + } +} + +///////////////////////////////////////////////// +//- Push networking getter / setter functions +///////////////////////////////////////////////// + +void AGrippableActor::SetReplicateGripScripts(bool bNewReplicateGripScripts) +{ + bReplicateGripScripts = bNewReplicateGripScripts; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, bReplicateGripScripts, this); +#endif +} + +TArray>& AGrippableActor::GetGripLogicScripts() +{ +#if WITH_PUSH_MODEL + if (bReplicateGripScripts) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, GripLogicScripts, this); + } +#endif + + return GripLogicScripts; +} + +void AGrippableActor::SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags) +{ + bRepGripSettingsAndGameplayTags = bNewRepGripSettingsAndGameplayTags; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, bRepGripSettingsAndGameplayTags, this); +#endif +} + +void AGrippableActor::SetAllowIgnoringAttachOnOwner(bool bNewAllowIgnoringAttachOnOwner) +{ + bAllowIgnoringAttachOnOwner = bNewAllowIgnoringAttachOnOwner; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, bAllowIgnoringAttachOnOwner, this); +#endif +} + +FVRClientAuthReplicationData& AGrippableActor::GetClientAuthReplicationData(FVRClientAuthReplicationData& ClientAuthData) +{ +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, ClientAuthReplicationData, this); +#endif + return ClientAuthReplicationData; +} + +FBPInterfaceProperties& AGrippableActor::GetVRGripInterfaceSettings(bool bMarkDirty) +{ +#if WITH_PUSH_MODEL + if (bMarkDirty && bRepGripSettingsAndGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, VRGripInterfaceSettings, this); + } +#endif + + return VRGripInterfaceSettings; +} + +FGameplayTagContainer& AGrippableActor::GetGameplayTags() +{ +#if WITH_PUSH_MODEL + if (bRepGripSettingsAndGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, GameplayTags, this); + } +#endif + + return GameplayTags; +} + +///////////////////////////////////////////////// +//- End Push networking getter / setter functions +///////////////////////////////////////////////// \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableBoxComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableBoxComponent.cpp new file mode 100644 index 0000000..ec8f05d --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableBoxComponent.cpp @@ -0,0 +1,402 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Grippables/GrippableBoxComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GrippableBoxComponent) + +#include "GripMotionControllerComponent.h" +#include "VRExpansionFunctionLibrary.h" +#include "GripScripts/VRGripScriptBase.h" +#include "Net/UnrealNetwork.h" + +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + +//============================================================================= +UGrippableBoxComponent::~UGrippableBoxComponent() +{ +} + + //============================================================================= +UGrippableBoxComponent::UGrippableBoxComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + VRGripInterfaceSettings.bDenyGripping = false; + VRGripInterfaceSettings.OnTeleportBehavior = EGripInterfaceTeleportBehavior::DropOnTeleport; + VRGripInterfaceSettings.bSimulateOnDrop = true; + VRGripInterfaceSettings.SlotDefaultGripType = EGripCollisionType::ManipulationGrip; + VRGripInterfaceSettings.FreeDefaultGripType = EGripCollisionType::ManipulationGrip; + VRGripInterfaceSettings.SecondaryGripType = ESecondaryGripType::SG_None; + VRGripInterfaceSettings.MovementReplicationType = EGripMovementReplicationSettings::ForceClientSideMovement; + VRGripInterfaceSettings.LateUpdateSetting = EGripLateUpdateSettings::LateUpdatesAlwaysOff; + VRGripInterfaceSettings.ConstraintStiffness = 1500.0f; + VRGripInterfaceSettings.ConstraintDamping = 200.0f; + VRGripInterfaceSettings.ConstraintBreakDistance = 100.0f; + VRGripInterfaceSettings.SecondarySlotRange = 20.0f; + VRGripInterfaceSettings.PrimarySlotRange = 20.0f; + VRGripInterfaceSettings.bIsHeld = false; + + bReplicateMovement = false; + //this->bReplicates = true; + + bRepGripSettingsAndGameplayTags = true; + bReplicateGripScripts = false; + + // #TODO we can register them maybe in the future + // Don't use the replicated list, use our custom replication instead + bReplicateUsingRegisteredSubObjectList = false; +} + +void UGrippableBoxComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableBoxComponent, bReplicateGripScripts, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableBoxComponent, bRepGripSettingsAndGameplayTags, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableBoxComponent, bReplicateMovement, PushModelParams); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableBoxComponent, GripLogicScripts, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableBoxComponent, VRGripInterfaceSettings, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableBoxComponent, GameplayTags, PushModelParamsWithCondition); +} + +void UGrippableBoxComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) +{ + Super::PreReplication(ChangedPropertyTracker); + + // Don't replicate if set to not do it + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UGrippableBoxComponent, VRGripInterfaceSettings, bRepGripSettingsAndGameplayTags); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UGrippableBoxComponent, GameplayTags, bRepGripSettingsAndGameplayTags); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UGrippableBoxComponent, GripLogicScripts, bReplicateGripScripts); + + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeLocation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeRotation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeScale3D, bReplicateMovement); +} + +bool UGrippableBoxComponent::ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) +{ + bool WroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags); + + if (bReplicateGripScripts && !IsUsingRegisteredSubObjectList()) + { + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script && IsValid(Script)) + { + WroteSomething |= Channel->ReplicateSubobject(Script, *Bunch, *RepFlags); + } + } + } + + return WroteSomething; +} + + +void UGrippableBoxComponent::BeginPlay() +{ + // Call the base class + Super::BeginPlay(); + + // Call all grip scripts begin play events so they can perform any needed logic + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script) + { + Script->BeginPlay(this); + } + } + + bOriginalReplicatesMovement = bReplicateMovement; +} + +void UGrippableBoxComponent::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + // Call the base class + Super::EndPlay(EndPlayReason); + + // Call all grip scripts begin play events so they can perform any needed logic + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script) + { + Script->EndPlay(EndPlayReason); + } + } +} + +void UGrippableBoxComponent::SetDenyGripping(bool bDenyGripping) +{ + VRGripInterfaceSettings.bDenyGripping = bDenyGripping; +} + +void UGrippableBoxComponent::SetGripPriority(int NewGripPriority) +{ + VRGripInterfaceSettings.AdvancedGripSettings.GripPriority = NewGripPriority; +} + +void UGrippableBoxComponent::TickGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation, float DeltaTime) {} +void UGrippableBoxComponent::OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) { } +void UGrippableBoxComponent::OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) { } +void UGrippableBoxComponent::OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) {} +void UGrippableBoxComponent::OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) {} +void UGrippableBoxComponent::OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripAdded.Broadcast(GripOwningController, GripInformation); } +void UGrippableBoxComponent::OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripRemoved.Broadcast(GripOwningController, GripInformation); } +void UGrippableBoxComponent::OnUsed_Implementation() {} +void UGrippableBoxComponent::OnEndUsed_Implementation() {} +void UGrippableBoxComponent::OnSecondaryUsed_Implementation() {} +void UGrippableBoxComponent::OnEndSecondaryUsed_Implementation() {} +void UGrippableBoxComponent::OnInput_Implementation(FKey Key, EInputEvent KeyEvent) {} +bool UGrippableBoxComponent::RequestsSocketing_Implementation(USceneComponent *& ParentToSocketTo, FName & OptionalSocketName, FTransform_NetQuantize & RelativeTransform) { return false; } + +bool UGrippableBoxComponent::DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator) +{ + return VRGripInterfaceSettings.bDenyGripping; +} + +EGripInterfaceTeleportBehavior UGrippableBoxComponent::TeleportBehavior_Implementation() +{ + return VRGripInterfaceSettings.OnTeleportBehavior; +} + +bool UGrippableBoxComponent::SimulateOnDrop_Implementation() +{ + return VRGripInterfaceSettings.bSimulateOnDrop; +} + +EGripCollisionType UGrippableBoxComponent::GetPrimaryGripType_Implementation(bool bIsSlot) +{ + return bIsSlot ? VRGripInterfaceSettings.SlotDefaultGripType : VRGripInterfaceSettings.FreeDefaultGripType; +} + +ESecondaryGripType UGrippableBoxComponent::SecondaryGripType_Implementation() +{ + return VRGripInterfaceSettings.SecondaryGripType; +} + +EGripMovementReplicationSettings UGrippableBoxComponent::GripMovementReplicationType_Implementation() +{ + return VRGripInterfaceSettings.MovementReplicationType; +} + +EGripLateUpdateSettings UGrippableBoxComponent::GripLateUpdateSetting_Implementation() +{ + return VRGripInterfaceSettings.LateUpdateSetting; +} + +void UGrippableBoxComponent::GetGripStiffnessAndDamping_Implementation(float &GripStiffnessOut, float &GripDampingOut) +{ + GripStiffnessOut = VRGripInterfaceSettings.ConstraintStiffness; + GripDampingOut = VRGripInterfaceSettings.ConstraintDamping; +} + +FBPAdvGripSettings UGrippableBoxComponent::AdvancedGripSettings_Implementation() +{ + return VRGripInterfaceSettings.AdvancedGripSettings; +} + +float UGrippableBoxComponent::GripBreakDistance_Implementation() +{ + return VRGripInterfaceSettings.ConstraintBreakDistance; +} + +void UGrippableBoxComponent::ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool & bHadSlotInRange, FTransform & SlotWorldTransform, FName & SlotName, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ + if (OverridePrefix.IsNone()) + bSecondarySlot ? OverridePrefix = "VRGripS" : OverridePrefix = "VRGripP"; + + UVRExpansionFunctionLibrary::GetGripSlotInRangeByTypeName_Component(OverridePrefix, this, WorldLocation, bSecondarySlot ? VRGripInterfaceSettings.SecondarySlotRange : VRGripInterfaceSettings.PrimarySlotRange, bHadSlotInRange, SlotWorldTransform, SlotName, CallingController); +} + +bool UGrippableBoxComponent::AllowsMultipleGrips_Implementation() +{ + return VRGripInterfaceSettings.bAllowMultipleGrips; +} + +void UGrippableBoxComponent::IsHeld_Implementation(TArray & HoldingControllers, bool & bIsHeld) +{ + HoldingControllers = VRGripInterfaceSettings.HoldingControllers; + bIsHeld = VRGripInterfaceSettings.bIsHeld; +} + +void UGrippableBoxComponent::Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed) +{ + if (bGripped) + { + OnGripped.Broadcast(Controller, GripInformation); + } + else + { + OnDropped.Broadcast(Controller, GripInformation, bWasSocketed); + } +} + +void UGrippableBoxComponent::SetHeld_Implementation(UGripMotionControllerComponent * HoldingController, uint8 GripID, bool bIsHeld) +{ + if (bIsHeld) + { + if (VRGripInterfaceSettings.MovementReplicationType != EGripMovementReplicationSettings::ForceServerSideMovement) + { + if (!VRGripInterfaceSettings.bIsHeld) + bOriginalReplicatesMovement = bReplicateMovement; + bReplicateMovement = false; + } + + VRGripInterfaceSettings.bWasHeld = true; + VRGripInterfaceSettings.HoldingControllers.AddUnique(FBPGripPair(HoldingController, GripID)); + } + else + { + if (VRGripInterfaceSettings.MovementReplicationType != EGripMovementReplicationSettings::ForceServerSideMovement) + { + bReplicateMovement = bOriginalReplicatesMovement; + } + + VRGripInterfaceSettings.HoldingControllers.Remove(FBPGripPair(HoldingController, GripID)); + } + + VRGripInterfaceSettings.bIsHeld = VRGripInterfaceSettings.HoldingControllers.Num() > 0; +} + +/*FBPInteractionSettings UGrippableBoxComponent::GetInteractionSettings_Implementation() +{ + return VRGripInterfaceSettings.InteractionSettings; +}*/ + +bool UGrippableBoxComponent::GetGripScripts_Implementation(TArray & ArrayReference) +{ + ArrayReference = GripLogicScripts; + return GripLogicScripts.Num() > 0; +} + +void UGrippableBoxComponent::PreDestroyFromReplication() +{ + Super::PreDestroyFromReplication(); + + // Destroy any sub-objects we created + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject *SubObject = GripLogicScripts[i]) + { + SubObject->PreDestroyFromReplication(); + SubObject->MarkAsGarbage(); + } + } + + GripLogicScripts.Empty(); +} + +void UGrippableBoxComponent::GetSubobjectsWithStableNamesForNetworking(TArray &ObjList) +{ + if (bReplicateGripScripts) + { + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject* SubObject = GripLogicScripts[i]) + { + ObjList.Add(SubObject); + } + } + } +} + +// This one is for components to clean up +void UGrippableBoxComponent::OnComponentDestroyed(bool bDestroyingHierarchy) +{ + // Call the super at the end, after we've done what we needed to do + Super::OnComponentDestroyed(bDestroyingHierarchy); + + // Don't set these in editor preview window and the like, it causes saving issues + if (UWorld * World = GetWorld()) + { + EWorldType::Type WorldType = World->WorldType; + if (WorldType == EWorldType::Editor || WorldType == EWorldType::EditorPreview) + { + return; + } + } + + for (int32 i = 0; i < GripLogicScripts.Num(); i++) + { + if (UObject *SubObject = GripLogicScripts[i]) + { + SubObject->MarkAsGarbage(); + } + } + + GripLogicScripts.Empty(); +} + +///////////////////////////////////////////////// +//- Push networking getter / setter functions +///////////////////////////////////////////////// + +void UGrippableBoxComponent::SetReplicateGripScripts(bool bNewReplicateGripScripts) +{ + bReplicateGripScripts = bNewReplicateGripScripts; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableBoxComponent, bReplicateGripScripts, this); +#endif +} + +TArray>& UGrippableBoxComponent::GetGripLogicScripts() +{ +#if WITH_PUSH_MODEL + if (bReplicateGripScripts) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableBoxComponent, GripLogicScripts, this); + } +#endif + + return GripLogicScripts; +} + +void UGrippableBoxComponent::SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags) +{ + bRepGripSettingsAndGameplayTags = bNewRepGripSettingsAndGameplayTags; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableBoxComponent, bRepGripSettingsAndGameplayTags, this); +#endif +} + +void UGrippableBoxComponent::SetReplicateMovement(bool bNewReplicateMovement) +{ + bReplicateMovement = bNewReplicateMovement; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableBoxComponent, bReplicateMovement, this); +#endif +} + +FBPInterfaceProperties& UGrippableBoxComponent::GetVRGripInterfaceSettings(bool bMarkDirty) +{ +#if WITH_PUSH_MODEL + if (bMarkDirty && bRepGripSettingsAndGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableBoxComponent, VRGripInterfaceSettings, this); + } +#endif + + return VRGripInterfaceSettings; +} + +FGameplayTagContainer& UGrippableBoxComponent::GetGameplayTags() +{ +#if WITH_PUSH_MODEL + if (bRepGripSettingsAndGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableBoxComponent, GameplayTags, this); + } +#endif + + return GameplayTags; +} + +///////////////////////////////////////////////// +//- End Push networking getter / setter functions +///////////////////////////////////////////////// \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableCapsuleComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableCapsuleComponent.cpp new file mode 100644 index 0000000..9178cb5 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableCapsuleComponent.cpp @@ -0,0 +1,402 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Grippables/GrippableCapsuleComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GrippableCapsuleComponent) + +#include "GripMotionControllerComponent.h" +#include "VRExpansionFunctionLibrary.h" +#include "GripScripts/VRGripScriptBase.h" +#include "Net/UnrealNetwork.h" + +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + + //============================================================================= +UGrippableCapsuleComponent::UGrippableCapsuleComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + VRGripInterfaceSettings.bDenyGripping = false; + VRGripInterfaceSettings.OnTeleportBehavior = EGripInterfaceTeleportBehavior::DropOnTeleport; + VRGripInterfaceSettings.bSimulateOnDrop = true; + VRGripInterfaceSettings.SlotDefaultGripType = EGripCollisionType::ManipulationGrip; + VRGripInterfaceSettings.FreeDefaultGripType = EGripCollisionType::ManipulationGrip; + VRGripInterfaceSettings.SecondaryGripType = ESecondaryGripType::SG_None; + VRGripInterfaceSettings.MovementReplicationType = EGripMovementReplicationSettings::ForceClientSideMovement; + VRGripInterfaceSettings.LateUpdateSetting = EGripLateUpdateSettings::LateUpdatesAlwaysOff; + VRGripInterfaceSettings.ConstraintStiffness = 1500.0f; + VRGripInterfaceSettings.ConstraintDamping = 200.0f; + VRGripInterfaceSettings.ConstraintBreakDistance = 100.0f; + VRGripInterfaceSettings.SecondarySlotRange = 20.0f; + VRGripInterfaceSettings.PrimarySlotRange = 20.0f; + + VRGripInterfaceSettings.bIsHeld = false; + + bReplicateMovement = false; + //this->bReplicates = true; + + bRepGripSettingsAndGameplayTags = true; + bReplicateGripScripts = false; + + // #TODO we can register them maybe in the future + // Don't use the replicated list, use our custom replication instead + bReplicateUsingRegisteredSubObjectList = false; +} + +void UGrippableCapsuleComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableCapsuleComponent, bReplicateGripScripts, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableCapsuleComponent, bRepGripSettingsAndGameplayTags, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableCapsuleComponent, bReplicateMovement, PushModelParams); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableCapsuleComponent, GripLogicScripts, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableCapsuleComponent, VRGripInterfaceSettings, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableCapsuleComponent, GameplayTags, PushModelParamsWithCondition); +} + +void UGrippableCapsuleComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) +{ + Super::PreReplication(ChangedPropertyTracker); + + // Don't replicate if set to not do it + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UGrippableCapsuleComponent, VRGripInterfaceSettings, bRepGripSettingsAndGameplayTags); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UGrippableCapsuleComponent, GameplayTags, bRepGripSettingsAndGameplayTags); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UGrippableCapsuleComponent, GripLogicScripts, bReplicateGripScripts); + + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeLocation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeRotation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeScale3D, bReplicateMovement); +} + +bool UGrippableCapsuleComponent::ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) +{ + bool WroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags); + + if (bReplicateGripScripts && !IsUsingRegisteredSubObjectList()) + { + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script && IsValid(Script)) + { + WroteSomething |= Channel->ReplicateSubobject(Script, *Bunch, *RepFlags); + } + } + } + + return WroteSomething; +} + +//============================================================================= +UGrippableCapsuleComponent::~UGrippableCapsuleComponent() +{ +} + +void UGrippableCapsuleComponent::BeginPlay() +{ + // Call the base class + Super::BeginPlay(); + + // Call all grip scripts begin play events so they can perform any needed logic + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script) + { + Script->BeginPlay(this); + } + } + + bOriginalReplicatesMovement = bReplicateMovement; +} + +void UGrippableCapsuleComponent::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + // Call the base class + Super::EndPlay(EndPlayReason); + + // Call all grip scripts begin play events so they can perform any needed logic + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script) + { + Script->EndPlay(EndPlayReason); + } + } +} + +void UGrippableCapsuleComponent::SetDenyGripping(bool bDenyGripping) +{ + VRGripInterfaceSettings.bDenyGripping = bDenyGripping; +} + +void UGrippableCapsuleComponent::SetGripPriority(int NewGripPriority) +{ + VRGripInterfaceSettings.AdvancedGripSettings.GripPriority = NewGripPriority; +} + +void UGrippableCapsuleComponent::TickGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation, float DeltaTime) {} +void UGrippableCapsuleComponent::OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) {} +void UGrippableCapsuleComponent::OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) { } +void UGrippableCapsuleComponent::OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) {} +void UGrippableCapsuleComponent::OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) {} +void UGrippableCapsuleComponent::OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripAdded.Broadcast(GripOwningController, GripInformation); } +void UGrippableCapsuleComponent::OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripRemoved.Broadcast(GripOwningController, GripInformation); } +void UGrippableCapsuleComponent::OnUsed_Implementation() {} +void UGrippableCapsuleComponent::OnEndUsed_Implementation() {} +void UGrippableCapsuleComponent::OnSecondaryUsed_Implementation() {} +void UGrippableCapsuleComponent::OnEndSecondaryUsed_Implementation() {} +void UGrippableCapsuleComponent::OnInput_Implementation(FKey Key, EInputEvent KeyEvent) {} +bool UGrippableCapsuleComponent::RequestsSocketing_Implementation(USceneComponent *& ParentToSocketTo, FName & OptionalSocketName, FTransform_NetQuantize & RelativeTransform) { return false; } + + +bool UGrippableCapsuleComponent::DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator) +{ + return VRGripInterfaceSettings.bDenyGripping; +} + +EGripInterfaceTeleportBehavior UGrippableCapsuleComponent::TeleportBehavior_Implementation() +{ + return VRGripInterfaceSettings.OnTeleportBehavior; +} + +bool UGrippableCapsuleComponent::SimulateOnDrop_Implementation() +{ + return VRGripInterfaceSettings.bSimulateOnDrop; +} + +EGripCollisionType UGrippableCapsuleComponent::GetPrimaryGripType_Implementation(bool bIsSlot) +{ + return bIsSlot ? VRGripInterfaceSettings.SlotDefaultGripType : VRGripInterfaceSettings.FreeDefaultGripType; +} + +ESecondaryGripType UGrippableCapsuleComponent::SecondaryGripType_Implementation() +{ + return VRGripInterfaceSettings.SecondaryGripType; +} + +EGripMovementReplicationSettings UGrippableCapsuleComponent::GripMovementReplicationType_Implementation() +{ + return VRGripInterfaceSettings.MovementReplicationType; +} + +EGripLateUpdateSettings UGrippableCapsuleComponent::GripLateUpdateSetting_Implementation() +{ + return VRGripInterfaceSettings.LateUpdateSetting; +} + +void UGrippableCapsuleComponent::GetGripStiffnessAndDamping_Implementation(float &GripStiffnessOut, float &GripDampingOut) +{ + GripStiffnessOut = VRGripInterfaceSettings.ConstraintStiffness; + GripDampingOut = VRGripInterfaceSettings.ConstraintDamping; +} + +FBPAdvGripSettings UGrippableCapsuleComponent::AdvancedGripSettings_Implementation() +{ + return VRGripInterfaceSettings.AdvancedGripSettings; +} + +float UGrippableCapsuleComponent::GripBreakDistance_Implementation() +{ + return VRGripInterfaceSettings.ConstraintBreakDistance; +} + +void UGrippableCapsuleComponent::ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool & bHadSlotInRange, FTransform & SlotWorldTransform, FName & SlotName, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ + if (OverridePrefix.IsNone()) + bSecondarySlot ? OverridePrefix = "VRGripS" : OverridePrefix = "VRGripP"; + + UVRExpansionFunctionLibrary::GetGripSlotInRangeByTypeName_Component(OverridePrefix, this, WorldLocation, bSecondarySlot ? VRGripInterfaceSettings.SecondarySlotRange : VRGripInterfaceSettings.PrimarySlotRange, bHadSlotInRange, SlotWorldTransform, SlotName, CallingController); +} + +bool UGrippableCapsuleComponent::AllowsMultipleGrips_Implementation() +{ + return VRGripInterfaceSettings.bAllowMultipleGrips; +} + +void UGrippableCapsuleComponent::IsHeld_Implementation(TArray & HoldingControllers, bool & bIsHeld) +{ + HoldingControllers = VRGripInterfaceSettings.HoldingControllers; + bIsHeld = VRGripInterfaceSettings.bIsHeld; +} + +void UGrippableCapsuleComponent::Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed) +{ + if (bGripped) + { + OnGripped.Broadcast(Controller, GripInformation); + } + else + { + OnDropped.Broadcast(Controller, GripInformation, bWasSocketed); + } +} + +void UGrippableCapsuleComponent::SetHeld_Implementation(UGripMotionControllerComponent * HoldingController, uint8 GripID, bool bIsHeld) +{ + if (bIsHeld) + { + if (VRGripInterfaceSettings.MovementReplicationType != EGripMovementReplicationSettings::ForceServerSideMovement) + { + if (!VRGripInterfaceSettings.bIsHeld) + bOriginalReplicatesMovement = bReplicateMovement; + bReplicateMovement = false; + } + + VRGripInterfaceSettings.bWasHeld = true; + VRGripInterfaceSettings.HoldingControllers.AddUnique(FBPGripPair(HoldingController, GripID)); + } + else + { + if (VRGripInterfaceSettings.MovementReplicationType != EGripMovementReplicationSettings::ForceServerSideMovement) + { + bReplicateMovement = bOriginalReplicatesMovement; + } + + VRGripInterfaceSettings.HoldingControllers.Remove(FBPGripPair(HoldingController, GripID)); + } + + VRGripInterfaceSettings.bIsHeld = VRGripInterfaceSettings.HoldingControllers.Num() > 0; +} + +/*FBPInteractionSettings UGrippableCapsuleComponent::GetInteractionSettings_Implementation() +{ + return VRGripInterfaceSettings.InteractionSettings; +}*/ + +bool UGrippableCapsuleComponent::GetGripScripts_Implementation(TArray & ArrayReference) +{ + ArrayReference = GripLogicScripts; + return GripLogicScripts.Num() > 0; +} + +void UGrippableCapsuleComponent::PreDestroyFromReplication() +{ + Super::PreDestroyFromReplication(); + + // Destroy any sub-objects we created + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject *SubObject = GripLogicScripts[i]) + { + SubObject->PreDestroyFromReplication(); + SubObject->MarkAsGarbage(); + } + } + + GripLogicScripts.Empty(); +} + +void UGrippableCapsuleComponent::GetSubobjectsWithStableNamesForNetworking(TArray &ObjList) +{ + if (bReplicateGripScripts) + { + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject* SubObject = GripLogicScripts[i]) + { + ObjList.Add(SubObject); + } + } + } +} + +void UGrippableCapsuleComponent::OnComponentDestroyed(bool bDestroyingHierarchy) +{ + // Call the super at the end, after we've done what we needed to do + Super::OnComponentDestroyed(bDestroyingHierarchy); + + // Don't set these in editor preview window and the like, it causes saving issues + if (UWorld * World = GetWorld()) + { + EWorldType::Type WorldType = World->WorldType; + if (WorldType == EWorldType::Editor || WorldType == EWorldType::EditorPreview) + { + return; + } + } + + for (int32 i = 0; i < GripLogicScripts.Num(); i++) + { + if (UObject *SubObject = GripLogicScripts[i]) + { + SubObject->MarkAsGarbage(); + } + } + + GripLogicScripts.Empty(); +} + +///////////////////////////////////////////////// +//- Push networking getter / setter functions +///////////////////////////////////////////////// + +void UGrippableCapsuleComponent::SetReplicateGripScripts(bool bNewReplicateGripScripts) +{ + bReplicateGripScripts = bNewReplicateGripScripts; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableCapsuleComponent, bReplicateGripScripts, this); +#endif +} + +TArray>& UGrippableCapsuleComponent::GetGripLogicScripts() +{ +#if WITH_PUSH_MODEL + if (bReplicateGripScripts) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableCapsuleComponent, GripLogicScripts, this); + } +#endif + + return GripLogicScripts; +} + +void UGrippableCapsuleComponent::SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags) +{ + bRepGripSettingsAndGameplayTags = bNewRepGripSettingsAndGameplayTags; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableCapsuleComponent, bRepGripSettingsAndGameplayTags, this); +#endif +} + +void UGrippableCapsuleComponent::SetReplicateMovement(bool bNewReplicateMovement) +{ + bReplicateMovement = bNewReplicateMovement; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableCapsuleComponent, bReplicateMovement, this); +#endif +} + +FBPInterfaceProperties& UGrippableCapsuleComponent::GetVRGripInterfaceSettings(bool bMarkDirty) +{ +#if WITH_PUSH_MODEL + if (bMarkDirty && bRepGripSettingsAndGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableCapsuleComponent, VRGripInterfaceSettings, this); + } +#endif + + return VRGripInterfaceSettings; +} + +FGameplayTagContainer& UGrippableCapsuleComponent::GetGameplayTags() +{ +#if WITH_PUSH_MODEL + if (bRepGripSettingsAndGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableCapsuleComponent, GameplayTags, this); + } +#endif + + return GameplayTags; +} + +///////////////////////////////////////////////// +//- End Push networking getter / setter functions +///////////////////////////////////////////////// \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableCharacter.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableCharacter.cpp new file mode 100644 index 0000000..7750958 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableCharacter.cpp @@ -0,0 +1,31 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Grippables/GrippableCharacter.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GrippableCharacter) + +#include "VRGlobalSettings.h" +#include "Grippables/GrippableSkeletalMeshComponent.h" + + +AGrippableCharacter::AGrippableCharacter(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer.SetDefaultSubobjectClass(ACharacter::MeshComponentName, UVRGlobalSettings::GetDefaultGrippableCharacterMeshComponentClass())) +{ + ViewOriginationSocket = NAME_None; + GrippableMeshReference = Cast(GetMesh()); +} + +void AGrippableCharacter::GetActorEyesViewPoint(FVector& Location, FRotator& Rotation) const +{ + if (ViewOriginationSocket != NAME_None) + { + if (USkeletalMeshComponent* MyMesh = GetMesh()) + { + FTransform SocketTransform = MyMesh->GetSocketTransform(ViewOriginationSocket, RTS_World); + Location = SocketTransform.GetLocation(); + Rotation = SocketTransform.GetRotation().Rotator(); + return; + } + } + + Super::GetActorEyesViewPoint(Location, Rotation); +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableDataTypes.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableDataTypes.cpp new file mode 100644 index 0000000..c6be104 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableDataTypes.cpp @@ -0,0 +1,25 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Grippables/GrippableDataTypes.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GrippableDataTypes) + +#include "GameFramework/Actor.h" + + +bool FRepAttachmentWithWeld::NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) +{ + // Our additional weld bit is here + Ar.SerializeBits(&bIsWelded, 1); + Ar << AttachParent; + LocationOffset.NetSerialize(Ar, Map, bOutSuccess); + RelativeScale3D.NetSerialize(Ar, Map, bOutSuccess); + RotationOffset.SerializeCompressedShort(Ar); + Ar << AttachSocket; + Ar << AttachComponent; + return true; +} + +FRepAttachmentWithWeld::FRepAttachmentWithWeld() +{ + bIsWelded = false; +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippablePhysicsReplication.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippablePhysicsReplication.cpp new file mode 100644 index 0000000..b06da07 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippablePhysicsReplication.cpp @@ -0,0 +1,2123 @@ + +/*============================================================================= + PhysicsReplication.cpp: Code for keeping replicated physics objects in sync with the server based on replicated server state data. + Copy / override of this class for VR client authority +=============================================================================*/ + + +#include "Grippables/GrippablePhysicsReplication.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GrippablePhysicsReplication) + +#include "CoreMinimal.h" +#include "PhysicsEngine/BodyInstance.h" +#include "Components/PrimitiveComponent.h" +#include "Components/SkeletalMeshComponent.h" +#include "UObject/ObjectMacros.h" +#include "UObject/Interface.h" +#include "DrawDebugHelpers.h" +#include "Chaos/ChaosMarshallingManager.h" +#include "PhysicsProxy/SingleParticlePhysicsProxy.h" +#include "Chaos/PhysicsObjectInternalInterface.h" + +#include "PBDRigidsSolver.h" +#include "Chaos/PBDRigidsEvolutionGBF.h" +#include "VRGlobalSettings.h" +#include "PhysicsEngine/PhysicsSettings.h" +#include "Physics/Experimental/PhysScene_Chaos.h" +#include "Chaos/DebugDrawQueue.h" +#include "Chaos/Particles.h" +//#include "Components/SkeletalMeshComponent.h" +#include "Misc/ScopeRWLock.h" + +#include "GameFramework/PlayerController.h" +#include "GameFramework/PlayerState.h" +#include "Engine/Player.h" +//#include "PhysicsInterfaceTypesCore.h" + +// I cannot dynamic cast without RTTI so I am using a static var as a declarative in case the user removed our custom replicator +// We don't want our casts to cause issues. +namespace VRPhysicsReplicationStatics +{ + static bool bHasVRPhysicsReplication = false; +} + +// Hacky work around for them not exporting these.... +#if WITH_EDITOR +namespace PhysicsReplicationCVars +{ + int32 SkipSkeletalRepOptimization = 1; +#if !UE_BUILD_SHIPPING + //int32 LogPhysicsReplicationHardSnaps = 0; +#endif + + int32 EnableDefaultReplication = 0; + + namespace ResimulationCVars + { + bool bRuntimeCorrectionEnabled = true; + bool bRuntimeVelocityCorrection = false; + bool bRuntimeCorrectConnectedBodies = true; + float PosStabilityMultiplier = 0.5f; + float RotStabilityMultiplier = 1.0f; + float VelStabilityMultiplier = 0.5f; + float AngVelStabilityMultiplier = 0.5f; + bool bDrawDebug = false; + } + + namespace PredictiveInterpolationCVars + { + float PosCorrectionTimeBase = 0.0f; + float PosCorrectionTimeMin = 0.1f; + float PosCorrectionTimeMultiplier = 1.0f; + float RotCorrectionTimeBase = 0.0f; + float RotCorrectionTimeMin = 0.1f; + float RotCorrectionTimeMultiplier = 1.0f; + float PosInterpolationTimeMultiplier = 1.1f; + float RotInterpolationTimeMultiplier = 1.25f; + float AverageReceiveIntervalSmoothing = 3.0f; + float ExtrapolationTimeMultiplier = 3.0f; + float ExtrapolationMinTime = 0.75f; + float MinExpectedDistanceCovered = 0.5f; + float ErrorAccumulationDecreaseMultiplier = 0.5f; + float ErrorAccumulationSeconds = 3.0f; + bool bDisableErrorVelocityLimits = false; + float ErrorAccLinVelMaxLimit = 50.0f; + float ErrorAccAngVelMaxLimit = 1.5f; + float SoftSnapPosStrength = 0.5f; + float SoftSnapRotStrength = 0.5f; + bool bSoftSnapToSource = false; + float EarlyOutDistanceSqr = 1.0f; + float EarlyOutAngle = 1.5f; + bool bEarlyOutWithVelocity = true; + bool bSkipVelocityRepOnPosEarlyOut = true; + bool bPostResimWaitForUpdate = false; + bool bVelocityBased = true; + bool bPosCorrectionAsVelocity = false; + bool bDisableSoftSnap = false; + bool bAlwaysHardSnap = false; + bool bSkipReplication = false; + bool bDontClearTarget = false; + bool bDrawDebugTargets = false; + bool bDrawDebugVectors = false; + float SleepSecondsClearTarget = 15.0f; + int32 TargetTickAlignmentClampMultiplier = 1; + } + +} +#endif + +/*struct FAsyncPhysicsRepCallbackDataVR : public Chaos::FSimCallbackInput +{ + TArray Buffer; + ErrorCorrectionData ErrorCorrection; + + void Reset() + { + Buffer.Reset(); + } +};*/ + +/*class FPhysicsReplicationAsyncCallbackVR final : public Chaos::TSimCallbackObject +{ + virtual void OnPreSimulate_Internal() override + { + FPhysicsReplicationVR::ApplyAsyncDesiredStateVR(GetDeltaTime_Internal(), GetConsumerInput_Internal()); + } +};*/ + +FPhysicsReplicationVR::~FPhysicsReplicationVR() +{ + if (PhysicsReplicationAsyncVR) + { + if (auto* Solver = PhysSceneVR->GetSolver()) + { + Solver->UnregisterAndFreeSimCallbackObject_External(PhysicsReplicationAsyncVR); + } + } +} + + +void ComputeDeltasVR(const FVector& CurrentPos, const FQuat& CurrentQuat, const FVector& TargetPos, const FQuat& TargetQuat, FVector& OutLinDiff, float& OutLinDiffSize, + FVector& OutAngDiffAxis, float& OutAngDiff, float& OutAngDiffSize) +{ + OutLinDiff = TargetPos - CurrentPos; + OutLinDiffSize = OutLinDiff.Size(); + const FQuat InvCurrentQuat = CurrentQuat.Inverse(); + const FQuat DeltaQuat = InvCurrentQuat * TargetQuat; + DeltaQuat.ToAxisAndAngle(OutAngDiffAxis, OutAngDiff); + OutAngDiff = FMath::RadiansToDegrees(FMath::UnwindRadians(OutAngDiff)); + OutAngDiffSize = FMath::Abs(OutAngDiff); +} + +FPhysicsReplicationVR::FPhysicsReplicationVR(FPhysScene* PhysScene) : + FPhysicsReplication(PhysScene) +{ + PhysSceneVR = PhysScene; + AsyncInputVR = nullptr; + PhysicsReplicationAsyncVR = nullptr; + if (auto* Solver = PhysSceneVR->GetSolver()) + { + PhysicsReplicationAsyncVR = Solver->CreateAndRegisterSimCallbackObject_External(); + PhysicsReplicationAsyncVR->Setup(UPhysicsSettings::Get()->PhysicErrorCorrection); + } + + //CurAsyncDataVR = nullptr; + //AsyncCallbackServer = nullptr; + + VRPhysicsReplicationStatics::bHasVRPhysicsReplication = true; +} + +void FPhysicsReplicationVR::PrepareAsyncData_ExternalVR(const FRigidBodyErrorCorrection& ErrorCorrection) +{ + //todo move this logic into a common function? + static const auto CVarLinSet = IConsoleManager::Get().FindConsoleVariable(TEXT("p.PositionLerp")); + const float PositionLerp = CVarLinSet->GetFloat() >= 0.0f ? CVarLinSet->GetFloat() : ErrorCorrection.PositionLerp; + + static const auto CVarLinLerp = IConsoleManager::Get().FindConsoleVariable(TEXT("p.LinearVelocityCoefficient")); + const float LinearVelocityCoefficient = CVarLinLerp->GetFloat() >= 0.0f ? CVarLinLerp->GetFloat() : ErrorCorrection.LinearVelocityCoefficient; + + static const auto CVarAngSet = IConsoleManager::Get().FindConsoleVariable(TEXT("p.AngleLerp")); + const float AngleLerp = CVarAngSet->GetFloat() >= 0.0f ? CVarAngSet->GetFloat() : ErrorCorrection.AngleLerp; + + static const auto CVarAngLerp = IConsoleManager::Get().FindConsoleVariable(TEXT("p.AngularVelocityCoefficient")); + const float AngularVelocityCoefficient = CVarAngLerp->GetFloat() >= 0.0f ? CVarAngLerp->GetFloat() : ErrorCorrection.AngularVelocityCoefficient; + + AsyncInputVR = PhysicsReplicationAsyncVR->GetProducerInputData_External(); + AsyncInputVR->ErrorCorrection.PositionLerp = PositionLerp; + AsyncInputVR->ErrorCorrection.AngleLerp = AngleLerp; + AsyncInputVR->ErrorCorrection.LinearVelocityCoefficient = LinearVelocityCoefficient; + AsyncInputVR->ErrorCorrection.AngularVelocityCoefficient = AngularVelocityCoefficient; +} + +/*void FPhysicsReplicationVR::ApplyAsyncDesiredStateVR(const float DeltaSeconds, const FAsyncPhysicsRepCallbackDataVR* AsyncData) +{ + using namespace Chaos; + if (AsyncData) + { + for (const FAsyncPhysicsDesiredState& State : AsyncData->Buffer) + { + float LinearVelocityCoefficient = AsyncData->ErrorCorrection.LinearVelocityCoefficient; + float AngularVelocityCoefficient = AsyncData->ErrorCorrection.AngularVelocityCoefficient; + float PositionLerp = AsyncData->ErrorCorrection.PositionLerp; + float AngleLerp = AsyncData->ErrorCorrection.AngleLerp; + if (State.ErrorCorrection.IsSet()) + { + ErrorCorrectionData ECData = State.ErrorCorrection.GetValue(); + LinearVelocityCoefficient = ECData.LinearVelocityCoefficient; + AngularVelocityCoefficient = ECData.AngularVelocityCoefficient; + PositionLerp = ECData.PositionLerp; + AngleLerp = ECData.AngleLerp; + } + + //Proxy should exist because we are using latest and any pending deletes would have been enqueued after + Chaos::FSingleParticlePhysicsProxy* Proxy = State.Proxy; + auto* Handle = Proxy->GetPhysicsThreadAPI(); + + + if (Handle && Handle->CanTreatAsRigid()) + { + const FVector TargetPos = State.WorldTM.GetLocation(); + const FQuat TargetQuat = State.WorldTM.GetRotation(); + + // Get Current state + FRigidBodyState CurrentState; + CurrentState.Position = Handle->X(); + CurrentState.Quaternion = Handle->R(); + CurrentState.AngVel = Handle->W(); + CurrentState.LinVel = Handle->V(); + + FVector LinDiff; + float LinDiffSize; + FVector AngDiffAxis; + float AngDiff; + float AngDiffSize; + ComputeDeltasVR(CurrentState.Position, CurrentState.Quaternion, TargetPos, TargetQuat, LinDiff, LinDiffSize, AngDiffAxis, AngDiff, AngDiffSize); + + const FVector NewLinVel = FVector(State.LinearVelocity) + (LinDiff * LinearVelocityCoefficient * DeltaSeconds); + const FVector NewAngVel = FVector(State.AngularVelocity) + (AngDiffAxis * AngDiff * AngularVelocityCoefficient * DeltaSeconds); + + const FVector NewPos = FMath::Lerp(FVector(CurrentState.Position), TargetPos, PositionLerp); + const FQuat NewAng = FQuat::Slerp(CurrentState.Quaternion, TargetQuat, AngleLerp); + + Handle->SetX(NewPos); + Handle->SetR(NewAng); + Handle->SetV(NewLinVel); + Handle->SetW(FMath::DegreesToRadians(NewAngVel)); + + if (State.bShouldSleep) + { + // don't allow kinematic to sleeping transition + if (Handle->ObjectState() != EObjectStateType::Kinematic) + { + auto* Solver = Proxy->GetSolver(); + Solver->GetEvolution()->SetParticleObjectState(Proxy->GetHandle_LowLevel()->CastToRigidParticle(), EObjectStateType::Sleeping); //todo: move object state into physics thread api + } + } + } + } + } +}*/ + + +bool FPhysicsReplicationVR::IsInitialized() +{ + return VRPhysicsReplicationStatics::bHasVRPhysicsReplication; +} + + +bool FPhysicsReplicationVR::ApplyRigidBodyState(float DeltaSeconds, FBodyInstance* BI, FReplicatedPhysicsTarget& PhysicsTarget, const FRigidBodyErrorCorrection& ErrorCorrection, const float InPingSecondsOneWay, int32 LocalFrame, int32 NumPredictedFrames) +{ + + // Skip all of the custom logic if we aren't the server + if (const UWorld* World = GetOwningWorld()) + { + if (World->GetNetMode() == ENetMode::NM_Client) + { + return FPhysicsReplication::ApplyRigidBodyState(DeltaSeconds, BI, PhysicsTarget, ErrorCorrection, InPingSecondsOneWay, LocalFrame, NumPredictedFrames); + } + } + + // Call into the old ApplyRigidBodyState function for now, + return ApplyRigidBodyState(DeltaSeconds, BI, PhysicsTarget, ErrorCorrection, InPingSecondsOneWay); +} + +/*void FPhysicsReplicationVR::SetReplicatedTarget(UPrimitiveComponent* Component, FName BoneName, const FRigidBodyState& ReplicatedTarget, int32 ServerFrame) +{ + + // Skip all of the custom logic if we aren't the server + if (const UWorld* World = GetOwningWorld()) + { + if (World->GetNetMode() == ENetMode::NM_Client) + { + return FPhysicsReplication::SetReplicatedTarget(Component, BoneName, ReplicatedTarget, ServerFrame); + } + } + + static const auto CVarEnableDefaultReplication = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.EnableDefaultReplication")); + + // If networked physics prediction is enabled, enforce the new physics replication flow via SetReplicatedTarget() using PhysicsObject instead of BodyInstance from BoneName. + AActor* Owner = Component->GetOwner(); + + if (Owner && (CVarEnableDefaultReplication->GetBool() || Owner->GetPhysicsReplicationMode() != EPhysicsReplicationMode::Default)) // For now, only opt in to the PhysicsObject flow if not using Default replication or if default is allowed via CVar. + { + const ENetRole OwnerRole = Owner->GetLocalRole(); + const bool bIsSimulated = OwnerRole == ROLE_SimulatedProxy; + const bool bIsReplicatedAutonomous = OwnerRole == ROLE_AutonomousProxy && Component->bReplicatePhysicsToAutonomousProxy; + if (bIsSimulated || bIsReplicatedAutonomous) + { + Chaos::FConstPhysicsObjectHandle PhysicsObject = Component->GetPhysicsObjectByName(BoneName); + SetReplicatedTargetVR(PhysicsObject, ReplicatedTarget, ServerFrame, Owner->GetPhysicsReplicationMode()); + return; + } + } + + return FPhysicsReplication::SetReplicatedTarget(Component, BoneName, ReplicatedTarget, ServerFrame); +}*/ + +void FPhysicsReplicationVR::SetReplicatedTargetVR(Chaos::FConstPhysicsObjectHandle PhysicsObject, const FRigidBodyState& ReplicatedTarget, int32 ServerFrame, EPhysicsReplicationMode ReplicationMode) +{ + if (!PhysicsObject) + { + return; + } + + UWorld* OwningWorld = GetOwningWorld(); + if (OwningWorld == nullptr) + { + return; + } + + // TODO, Check if owning actor is ROLE_SimulatedProxy or ROLE_AutonomousProxy ? + + FReplicatedPhysicsTarget Target(PhysicsObject); + + Target.ReplicationMode = ReplicationMode; + Target.ServerFrame = ServerFrame; + Target.TargetState = ReplicatedTarget; + Target.ArrivedTimeSeconds = OwningWorld->GetTimeSeconds(); + + ensure(!Target.TargetState.Position.ContainsNaN()); + + ReplicatedTargetsQueueVR.Add(Target); +} + +void FPhysicsReplicationVR::RemoveReplicatedTarget(UPrimitiveComponent* Component) +{ + + // Skip all of the custom logic if we aren't the server + if (const UWorld* World = GetOwningWorld()) + { + if (World->GetNetMode() == ENetMode::NM_Client) + { + return FPhysicsReplication::RemoveReplicatedTarget(Component); + } + } + + if (Component == nullptr) + { + return; + } + + // Call super version to ensure its removed from the inaccessible deprecated targets list + FPhysicsReplication::RemoveReplicatedTarget(Component); + + // Remove from legacy flow + //ComponentToTargets_DEPRECATED.Remove(Component); + + // Remove from FPhysicsObject flow + Chaos::FConstPhysicsObjectHandle PhysicsObject = Component->GetPhysicsObjectByName(NAME_None); + FReplicatedPhysicsTarget Target(PhysicsObject); // This creates a new but empty target and when it tries to update the current target in the async flow it will remove it from replication since it's empty. + ReplicatedTargetsQueueVR.Add(Target); +} + +bool FPhysicsReplicationVR::ApplyRigidBodyState(float DeltaSeconds, FBodyInstance* BI, FReplicatedPhysicsTarget& PhysicsTarget, const FRigidBodyErrorCorrection& ErrorCorrection, const float PingSecondsOneWay, bool* bDidHardSnap) +{ + // Skip all of the custom logic if we aren't the server + if (const UWorld* World = GetOwningWorld()) + { + if (World->GetNetMode() == ENetMode::NM_Client) + { + return FPhysicsReplication::ApplyRigidBodyState(DeltaSeconds, BI, PhysicsTarget, ErrorCorrection, PingSecondsOneWay); + } + } + + static const auto CVarSkipPhysicsReplication = IConsoleManager::Get().FindConsoleVariable(TEXT("p.SkipPhysicsReplication")); + if (CVarSkipPhysicsReplication->GetInt()) + { + return false; + } + + if (!BI->IsInstanceSimulatingPhysics()) + { + return false; + } + + // + // NOTES: + // + // The operation of this method has changed since 4.18. + // + // When a new remote physics state is received, this method will + // be called on tick until the local state is within an adequate + // tolerance of the new state. + // + // The received state is extrapolated based on ping, by some + // adjustable amount. + // + // A correction velocity is added new state's velocity, and assigned + // to the body. The correction velocity scales with the positional + // difference, so without the interference of external forces, this + // will result in an exponentially decaying correction. + // + // Generally it is not needed and will interrupt smoothness of + // the replication, but stronger corrections can be obtained by + // adjusting position lerping. + // + // If progress is not being made towards equilibrium, due to some + // divergence in physics states between the owning and local sims, + // an error value is accumulated, representing the amount of time + // spent in an unresolvable state. + // + // Once the error value has exceeded some threshold (0.5 seconds + // by default), a hard snap to the target physics state is applied. + // + + bool bRestoredState = true; + const FRigidBodyState NewState = PhysicsTarget.TargetState; + const float NewQuatSizeSqr = NewState.Quaternion.SizeSquared(); + + // failure cases + if (!BI->IsInstanceSimulatingPhysics()) + { + UE_LOG(LogPhysics, Warning, TEXT("Physics replicating on non-simulated body. (%s)"), *BI->GetBodyDebugName()); + return bRestoredState; + } + else if (NewQuatSizeSqr < UE_KINDA_SMALL_NUMBER) + { + UE_LOG(LogPhysics, Warning, TEXT("Invalid zero quaternion set for body. (%s)"), *BI->GetBodyDebugName()); + return bRestoredState; + } + else if (FMath::Abs(NewQuatSizeSqr - 1.f) > UE_KINDA_SMALL_NUMBER) + { + UE_LOG(LogPhysics, Warning, TEXT("Quaternion (%f %f %f %f) with non-unit magnitude detected. (%s)"), + NewState.Quaternion.X, NewState.Quaternion.Y, NewState.Quaternion.Z, NewState.Quaternion.W, *BI->GetBodyDebugName()); + return bRestoredState; + } + + // Grab configuration variables from engine config or from CVars if overriding is turned on. + static const auto CVarNetPingExtrapolation = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetPingExtrapolation")); + const float NetPingExtrapolation = CVarNetPingExtrapolation->GetFloat() >= 0.0f ? CVarNetPingExtrapolation->GetFloat() : ErrorCorrection.PingExtrapolation; + + static const auto CVarNetPingLimit = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetPingLimit")); + const float NetPingLimit = CVarNetPingLimit->GetFloat() > 0.0f ? CVarNetPingLimit->GetFloat() : ErrorCorrection.PingLimit; + + static const auto CVarErrorPerLinearDifference = IConsoleManager::Get().FindConsoleVariable(TEXT("p.ErrorPerLinearDifference")); + const float ErrorPerLinearDiff = CVarErrorPerLinearDifference->GetFloat() >= 0.0f ? CVarErrorPerLinearDifference->GetFloat() : ErrorCorrection.ErrorPerLinearDifference; + + static const auto CVarErrorPerAngularDifference = IConsoleManager::Get().FindConsoleVariable(TEXT("p.ErrorPerAngularDifference")); + const float ErrorPerAngularDiff = CVarErrorPerAngularDifference->GetFloat() >= 0.0f ? CVarErrorPerAngularDifference->GetFloat() : ErrorCorrection.ErrorPerAngularDifference; + + static const auto CVarMaxRestoredStateError = IConsoleManager::Get().FindConsoleVariable(TEXT("p.MaxRestoredStateError")); + const float MaxRestoredStateError = CVarMaxRestoredStateError->GetFloat() >= 0.0f ? CVarMaxRestoredStateError->GetFloat() : ErrorCorrection.MaxRestoredStateError; + + static const auto CVarErrorAccumulation = IConsoleManager::Get().FindConsoleVariable(TEXT("p.ErrorAccumulationSeconds")); + const float ErrorAccumulationSeconds = CVarErrorAccumulation->GetFloat() >= 0.0f ? CVarErrorAccumulation->GetFloat() : ErrorCorrection.ErrorAccumulationSeconds; + + static const auto CVarErrorAccumulationDistanceSq = IConsoleManager::Get().FindConsoleVariable(TEXT("p.ErrorAccumulationDistanceSq")); + const float ErrorAccumulationDistanceSq = CVarErrorAccumulationDistanceSq->GetFloat() >= 0.0f ? CVarErrorAccumulationDistanceSq->GetFloat() : ErrorCorrection.ErrorAccumulationDistanceSq; + + static const auto CVarErrorAccumulationSimilarity = IConsoleManager::Get().FindConsoleVariable(TEXT("p.ErrorAccumulationSimilarity")); + const float ErrorAccumulationSimilarity = CVarErrorAccumulationSimilarity->GetFloat() >= 0.0f ? CVarErrorAccumulationSimilarity->GetFloat() : ErrorCorrection.ErrorAccumulationSimilarity; + + static const auto CVarLinSet = IConsoleManager::Get().FindConsoleVariable(TEXT("p.PositionLerp")); + const float PositionLerp = CVarLinSet->GetFloat() >= 0.0f ? CVarLinSet->GetFloat() : ErrorCorrection.PositionLerp; + + static const auto CVarLinLerp = IConsoleManager::Get().FindConsoleVariable(TEXT("p.LinearVelocityCoefficient")); + const float LinearVelocityCoefficient = CVarLinLerp->GetFloat() >= 0.0f ? CVarLinLerp->GetFloat() : ErrorCorrection.LinearVelocityCoefficient; + + static const auto CVarAngSet = IConsoleManager::Get().FindConsoleVariable(TEXT("p.AngleLerp")); + const float AngleLerp = CVarAngSet->GetFloat() >= 0.0f ? CVarAngSet->GetFloat() : ErrorCorrection.AngleLerp; + + static const auto CVarAngLerp = IConsoleManager::Get().FindConsoleVariable(TEXT("p.AngularVelocityCoefficient")); + const float AngularVelocityCoefficient = CVarAngLerp->GetFloat() >= 0.0f ? CVarAngLerp->GetFloat() : ErrorCorrection.AngularVelocityCoefficient; + + static const auto CVarMaxLinearHardSnapDistance = IConsoleManager::Get().FindConsoleVariable(TEXT("p.MaxLinearHardSnapDistance")); + const float MaxLinearHardSnapDistance = CVarMaxLinearHardSnapDistance->GetFloat() >= 0.f ? CVarMaxLinearHardSnapDistance->GetFloat() : ErrorCorrection.MaxLinearHardSnapDistance; + + // Get Current state + FRigidBodyState CurrentState; + BI->GetRigidBodyState(CurrentState); + + /////// EXTRAPOLATE APPROXIMATE TARGET VALUES /////// + + // Starting from the last known authoritative position, and + // extrapolate an approximation using the last known velocity + // and ping. + const float PingSeconds = FMath::Clamp(PingSecondsOneWay, 0.f, NetPingLimit); + const float ExtrapolationDeltaSeconds = PingSeconds * NetPingExtrapolation; + const FVector ExtrapolationDeltaPos = NewState.LinVel * ExtrapolationDeltaSeconds; + const FVector_NetQuantize100 TargetPos = NewState.Position + ExtrapolationDeltaPos; + float NewStateAngVel; + FVector NewStateAngVelAxis; + NewState.AngVel.FVector::ToDirectionAndLength(NewStateAngVelAxis, NewStateAngVel); + NewStateAngVel = FMath::DegreesToRadians(NewStateAngVel); + const FQuat ExtrapolationDeltaQuaternion = FQuat(NewStateAngVelAxis, NewStateAngVel * ExtrapolationDeltaSeconds); + FQuat TargetQuat = ExtrapolationDeltaQuaternion * NewState.Quaternion; + + /////// COMPUTE DIFFERENCES /////// + + FVector LinDiff; + float LinDiffSize; + FVector AngDiffAxis; + float AngDiff; + + float AngDiffSize; + + ComputeDeltasVR(CurrentState.Position, CurrentState.Quaternion, TargetPos, TargetQuat, LinDiff, LinDiffSize, AngDiffAxis, AngDiff, AngDiffSize); + + /////// ACCUMULATE ERROR IF NOT APPROACHING SOLUTION /////// + + // Store sleeping state + const bool bShouldSleep = (NewState.Flags & ERigidBodyFlags::Sleeping) != 0; + const bool bWasAwake = BI->IsInstanceAwake(); + const bool bAutoWake = false; + + const float Error = (LinDiffSize * ErrorPerLinearDiff) + (AngDiffSize * ErrorPerAngularDiff); + bRestoredState = Error < MaxRestoredStateError; + if (bRestoredState) + { + PhysicsTarget.AccumulatedErrorSeconds = 0.0f; + } + else + { + // + // The heuristic for error accumulation here is: + // 1. Did the physics tick from the previous step fail to + // move the body towards a resolved position? + // 2. Was the linear error in the same direction as the + // previous frame? + // 3. Is the linear error large enough to accumulate error? + // + // If these conditions are met, then "error" time will accumulate. + // Once error has accumulated for a certain number of seconds, + // a hard-snap to the target will be performed. + // + // TODO: Rotation while moving linearly can still mess up this + // heuristic. We need to account for it. + // + + // Project the change in position from the previous tick onto the + // linear error from the previous tick. This value roughly represents + // how much correction was performed over the previous physics tick. + const float PrevProgress = FVector::DotProduct( + FVector(CurrentState.Position) - PhysicsTarget.PrevPos, + (PhysicsTarget.PrevPosTarget - PhysicsTarget.PrevPos).GetSafeNormal()); + + // Project the current linear error onto the linear error from the + // previous tick. This value roughly represents how little the direction + // of the linear error state has changed, and how big the error is. + const float PrevSimilarity = FVector::DotProduct( + TargetPos - FVector(CurrentState.Position), + PhysicsTarget.PrevPosTarget - PhysicsTarget.PrevPos); + + // If the conditions from the heuristic outlined above are met, accumulate + // error. Otherwise, reduce it. + if (PrevProgress < ErrorAccumulationDistanceSq && + PrevSimilarity > ErrorAccumulationSimilarity) + { + PhysicsTarget.AccumulatedErrorSeconds += DeltaSeconds; + } + else + { + PhysicsTarget.AccumulatedErrorSeconds = FMath::Max(PhysicsTarget.AccumulatedErrorSeconds - DeltaSeconds, 0.0f); + } + + // Hard snap if error accumulation or linear error is big enough, and clear the error accumulator. + static const auto CVarAlwaysHardSnap = IConsoleManager::Get().FindConsoleVariable(TEXT("p.AlwaysHardSnap")); + const bool bHardSnap = + LinDiffSize > MaxLinearHardSnapDistance || + PhysicsTarget.AccumulatedErrorSeconds > ErrorAccumulationSeconds || + CVarAlwaysHardSnap->GetInt(); + + const FTransform IdealWorldTM(TargetQuat, TargetPos); + + if (bHardSnap) + { +#if !UE_BUILD_SHIPPING + if (PhysicsReplicationCVars::LogPhysicsReplicationHardSnaps && GetOwningWorld()) + { + UE_LOG(LogTemp, Warning, TEXT("Simulated HARD SNAP - \nCurrent Pos - %s, Target Pos - %s\n CurrentState.LinVel - %s, New Lin Vel - %s\nTarget Extrapolation Delta - %s, Is Replay? - %d, Is Asleep - %d, Prev Progress - %f, Prev Similarity - %f"), + *CurrentState.Position.ToString(), *TargetPos.ToString(), *CurrentState.LinVel.ToString(), *NewState.LinVel.ToString(), + *ExtrapolationDeltaPos.ToString(), GetOwningWorld()->IsPlayingReplay(), !BI->IsInstanceAwake(), PrevProgress, PrevSimilarity); + if (bDidHardSnap) + { + *bDidHardSnap = true; + } + if (LinDiffSize > MaxLinearHardSnapDistance) + { + UE_LOG(LogTemp, Warning, TEXT("Hard snap due to linear difference error")); + } + else + { + UE_LOG(LogTemp, Warning, TEXT("Hard snap due to accumulated error")) + } + } +#endif + // Too much error so just snap state here and be done with it + PhysicsTarget.AccumulatedErrorSeconds = 0.0f; + bRestoredState = true; + BI->SetBodyTransform(IdealWorldTM, ETeleportType::ResetPhysics, bAutoWake); + + // Set the new velocities + BI->SetLinearVelocity(NewState.LinVel, false, bAutoWake); + BI->SetAngularVelocityInRadians(FMath::DegreesToRadians(NewState.AngVel), false, bAutoWake); + } + else + { + // Small enough error to interpolate + if (PhysicsReplicationAsyncVR == nullptr) //sync case + { + const FVector NewLinVel = FVector(NewState.LinVel) + (LinDiff * LinearVelocityCoefficient * DeltaSeconds); + const FVector NewAngVel = FVector(NewState.AngVel) + (AngDiffAxis * AngDiff * AngularVelocityCoefficient * DeltaSeconds); + + const FVector NewPos = FMath::Lerp(FVector(CurrentState.Position), FVector(TargetPos), PositionLerp); + const FQuat NewAng = FQuat::Slerp(CurrentState.Quaternion, TargetQuat, AngleLerp); + + BI->SetBodyTransform(FTransform(NewAng, NewPos), ETeleportType::ResetPhysics); + BI->SetLinearVelocity(NewLinVel, false); + BI->SetAngularVelocityInRadians(FMath::DegreesToRadians(NewAngVel), false); + } + else + { + //If async is used, enqueue for callback + FPhysicsRepAsyncInputData AsyncInputData(nullptr); + AsyncInputData.TargetState = NewState; + AsyncInputData.TargetState.Position = IdealWorldTM.GetLocation(); + AsyncInputData.TargetState.Quaternion = IdealWorldTM.GetRotation(); + AsyncInputData.Proxy = static_cast(BI->GetPhysicsActorHandle()); + AsyncInputData.ErrorCorrection = { ErrorCorrection.LinearVelocityCoefficient, ErrorCorrection.AngularVelocityCoefficient, ErrorCorrection.PositionLerp, ErrorCorrection.AngleLerp }; + + AsyncInputData.LatencyOneWay = PingSeconds; + + + AsyncInputVR->InputData.Add(AsyncInputData); + /*FAsyncPhysicsDesiredState AsyncDesiredState; + AsyncDesiredState.WorldTM = IdealWorldTM; + AsyncDesiredState.LinearVelocity = NewState.LinVel; + AsyncDesiredState.AngularVelocity = NewState.AngVel; + AsyncDesiredState.Proxy = static_cast(BI->GetPhysicsActorHandle()); + AsyncDesiredState.ErrorCorrection = { ErrorCorrection.LinearVelocityCoefficient, ErrorCorrection.AngularVelocityCoefficient, ErrorCorrection.PositionLerp, ErrorCorrection.AngleLerp }; + AsyncDesiredState.bShouldSleep = bShouldSleep; + CurAsyncDataVR->Buffer.Add(AsyncDesiredState);*/ + } + } + + // Should we show the async part? +#if !UE_BUILD_SHIPPING + static const auto CVarNetShowCorrections = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetShowCorrections")); + if (CVarNetShowCorrections->GetInt() != 0) + { + PhysicsTarget.ErrorHistory.bAutoAdjustMinMax = false; + PhysicsTarget.ErrorHistory.MinValue = 0.0f; + PhysicsTarget.ErrorHistory.MaxValue = 1.0f; + PhysicsTarget.ErrorHistory.AddSample(PhysicsTarget.AccumulatedErrorSeconds / ErrorAccumulationSeconds); + if (UWorld* OwningWorld = GetOwningWorld()) + { + FColor Color = FColor::White; + static const auto CVarNetCorrectionLifetime = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetCorrectionLifetime")); + DrawDebugDirectionalArrow(OwningWorld, CurrentState.Position, TargetPos, 5.0f, Color, true, CVarNetCorrectionLifetime->GetFloat(), 0, 1.5f); +#if 0 + //todo: do we show this in async mode? + DrawDebugFloatHistory(*OwningWorld, PhysicsTarget.ErrorHistory, NewPos + FVector(0.0f, 0.0f, 100.0f), FVector2D(100.0f, 50.0f), FColor::White); +#endif + } + } +#endif + } + + /////// SLEEP UPDATE /////// + + if (bShouldSleep) + { + // In the async case, we apply sleep state in ApplyAsyncDesiredState + if (PhysicsReplicationAsyncVR == nullptr) + { + BI->PutInstanceToSleep(); + } + } + + PhysicsTarget.PrevPosTarget = TargetPos; + PhysicsTarget.PrevPos = FVector(CurrentState.Position); + + return bRestoredState; +} + +void FPhysicsReplicationVR::OnTick(float DeltaSeconds, TMap, FReplicatedPhysicsTarget>& ComponentsToTargets) +{ + // Skip all of the custom logic if we aren't the server + if (const UWorld* World = GetOwningWorld()) + { + if (World->GetNetMode() == ENetMode::NM_Client) + { + return FPhysicsReplication::OnTick(DeltaSeconds, ComponentsToTargets); + } + } + + using namespace Chaos; + + if (ShouldSkipPhysicsReplication()) + { + return; + } + + using namespace Chaos; + + + int32 LocalFrameOffset = 0; // LocalFrame = ServerFrame + LocalFrameOffset; + if (FPhysicsSolverBase::IsNetworkPhysicsPredictionEnabled()) + { + if (UWorld* World = GetOwningWorld()) + { + if (World->GetNetMode() == NM_Client) + { + if (APlayerController* PlayerController = World->GetFirstPlayerController()) + { + LocalFrameOffset = PlayerController->GetNetworkPhysicsTickOffset(); + } + } + } + } + + const FRigidBodyErrorCorrection& PhysicErrorCorrection = UPhysicsSettings::Get()->PhysicErrorCorrection; + if (PhysicsReplicationAsyncVR) + { + PrepareAsyncData_ExternalVR(PhysicErrorCorrection); + } + + // Get the ping between this PC & the server + const float LocalPing = 0.0f;//GetLocalPing(); + + for (auto Itr = ComponentsToTargets.CreateIterator(); Itr; ++Itr) + { + bool bRemoveItr = false; + if (UPrimitiveComponent* PrimComp = Itr.Key().Get()) + { + if (PrimComp->GetAttachParent() == nullptr) + { + if (FBodyInstance* BI = PrimComp->GetBodyInstance(Itr.Value().BoneName)) + { + FReplicatedPhysicsTarget& PhysicsTarget = Itr.Value(); + FRigidBodyState& UpdatedState = PhysicsTarget.TargetState; + bool bUpdated = false; + if (AActor* OwningActor = PrimComp->GetOwner()) + { + // Removed as this is server sided + /* + const ENetRole OwnerRole = OwningActor->GetLocalRole(); + const bool bIsSimulated = OwnerRole == ROLE_SimulatedProxy; + const bool bIsReplicatedAutonomous = OwnerRole == ROLE_AutonomousProxy && PrimComp->bReplicatePhysicsToAutonomousProxy; + if (bIsSimulated || bIsReplicatedAutonomous)*/ + + // Deleted everything here, we will always be the server, I already filtered out clients to default logic + { + // Get the ping of this thing's owner. If nobody owns it, + // then it's server authoritative. + /*const*/ float OwnerPing = 0.0f;// GetOwnerPing(OwningActor, PhysicsTarget); + + /*if (UPlayer* OwningPlayer = OwningActor->GetNetOwningPlayer()) + { + if (APlayerController* PlayerController = OwningPlayer->GetPlayerController(nullptr)) + { + if (APlayerState* PlayerState = PlayerController->PlayerState) + { + OwnerPing = PlayerState->ExactPing; + } + } + }*/ + + // Get the total ping - this approximates the time since the update was + // actually generated on the machine that is doing the authoritative sim. + // NOTE: We divide by 2 to approximate 1-way ping from 2-way ping. + const float PingSecondsOneWay = 0.0f;// (LocalPing + OwnerPing) * 0.5f * 0.001f; + + if (UpdatedState.Flags & ERigidBodyFlags::NeedsUpdate) + { + const int32 LocalFrame = PhysicsTarget.ServerFrame - LocalFrameOffset; + const bool bRestoredState = ApplyRigidBodyState(DeltaSeconds, BI, PhysicsTarget, PhysicErrorCorrection, PingSecondsOneWay, LocalFrame, 0); + + // Need to update the component to match new position. + static const auto CVarSkipSkeletalRepOptimization = IConsoleManager::Get().FindConsoleVariable(TEXT("p.SkipSkeletalRepOptimization")); + if (/*PhysicsReplicationCVars::SkipSkeletalRepOptimization*/CVarSkipSkeletalRepOptimization->GetInt() == 0 || Cast(PrimComp) == nullptr) //simulated skeletal mesh does its own polling of physics results so we don't need to call this as it'll happen at the end of the physics sim + { + PrimComp->SyncComponentToRBPhysics(); + } + if (bRestoredState) + { + bRemoveItr = true; + } + } + } + } + } + } + } + + if (bRemoveItr) + { + OnTargetRestored(Itr.Key().Get(), Itr.Value()); + Itr.RemoveCurrent(); + } + } + + // PhysicsObject replication flow + for (FReplicatedPhysicsTarget& PhysicsTarget : ReplicatedTargetsQueueVR) + { + const float PingSecondsOneWay = LocalPing * 0.5f * 0.001f; + + // Queue up the target state for async replication + FPhysicsRepAsyncInputData AsyncInputData(PhysicsTarget.PhysicsObject); + AsyncInputData.TargetState = PhysicsTarget.TargetState; + AsyncInputData.Proxy = nullptr; + + AsyncInputData.RepMode = PhysicsTarget.ReplicationMode; + AsyncInputData.ServerFrame = PhysicsTarget.ServerFrame; + AsyncInputData.FrameOffset = LocalFrameOffset; + AsyncInputData.LatencyOneWay = PingSecondsOneWay; + + AsyncInputVR->InputData.Add(AsyncInputData); + } + ReplicatedTargetsQueueVR.Reset(); + + AsyncInputVR = nullptr; +} + +FRepMovementVR::FRepMovementVR() : FRepMovement() +{ + LocationQuantizationLevel = EVectorQuantization::RoundTwoDecimals; + VelocityQuantizationLevel = EVectorQuantization::RoundTwoDecimals; + RotationQuantizationLevel = ERotatorQuantization::ShortComponents; +} + +FRepMovementVR::FRepMovementVR(FRepMovement& other) : FRepMovement() +{ + FRepMovementVR(); + + LinearVelocity = other.LinearVelocity; + AngularVelocity = other.AngularVelocity; + Location = other.Location; + Rotation = other.Rotation; + bSimulatedPhysicSleep = other.bSimulatedPhysicSleep; + bRepPhysics = other.bRepPhysics; +} + +void FRepMovementVR::CopyTo(FRepMovement& other) const +{ + other.LinearVelocity = LinearVelocity; + other.AngularVelocity = AngularVelocity; + other.Location = Location; + other.Rotation = Rotation; + other.bSimulatedPhysicSleep = bSimulatedPhysicSleep; + other.bRepPhysics = bRepPhysics; +} + +bool FRepMovementVR::NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) +{ + return FRepMovement::NetSerialize(Ar, Map, bOutSuccess); +} + +bool FRepMovementVR::GatherActorsMovement(AActor* OwningActor) +{ + //if (/*bReplicateMovement || (RootComponent && RootComponent->GetAttachParent())*/) + { + UPrimitiveComponent* RootPrimComp = Cast(OwningActor->GetRootComponent()); + if (RootPrimComp && RootPrimComp->IsSimulatingPhysics()) + { + FRigidBodyState RBState; + RootPrimComp->GetRigidBodyState(RBState); + + FillFrom(RBState, OwningActor); + // Don't replicate movement if we're welded to another parent actor. + // Their replication will affect our position indirectly since we are attached. + bRepPhysics = !RootPrimComp->IsWelded(); + } + else if (RootPrimComp != nullptr) + { + // If we are attached, don't replicate absolute position, use AttachmentReplication instead. + if (RootPrimComp->GetAttachParent() != nullptr) + { + return false; // We don't handle attachment rep + + } + else + { + Location = FRepMovement::RebaseOntoZeroOrigin(RootPrimComp->GetComponentLocation(), OwningActor); + Rotation = RootPrimComp->GetComponentRotation(); + LinearVelocity = OwningActor->GetVelocity(); + AngularVelocity = FVector::ZeroVector; + } + + bRepPhysics = false; + } + } + + /*if (const UWorld* World = GetOwningWorld()) + { + if (APlayerController* PlayerController = World->GetFirstPlayerController()) + { + if (APlayerState* PlayerState = PlayerController->PlayerState) + { + CurrentPing = PlayerState->ExactPing; + } + } + }*/ + + return true; +} + + +#pragma region FPhysicsReplicationAsync + +void FPhysicsReplicationAsyncVR::OnPhysicsObjectUnregistered_Internal(Chaos::FConstPhysicsObjectHandle PhysicsObject) +{ + ObjectToTarget.Remove(PhysicsObject); + ObjectToSettings.Remove(PhysicsObject); +} + +void FPhysicsReplicationAsyncVR::RegisterSettings(Chaos::FConstPhysicsObjectHandle PhysicsObject, FNetworkPhysicsSettingsAsync InSettings) +{ + if (PhysicsObject != nullptr) + { + FNetworkPhysicsSettingsAsync& Settings = ObjectToSettings.FindOrAdd(PhysicsObject); + Settings = InSettings; + } +} + +void FPhysicsReplicationAsyncVR::FetchObjectSettings(Chaos::FConstPhysicsObjectHandle PhysicsObject) +{ + FNetworkPhysicsSettingsAsync* CustomSettings = ObjectToSettings.Find(PhysicsObject); + SettingsCurrent = (CustomSettings != nullptr) ? *CustomSettings : SettingsDefault; +} + +void FPhysicsReplicationAsyncVR::OnPostInitialize_Internal() +{ + Chaos::FPBDRigidsSolver* RigidsSolver = static_cast(GetSolver()); + + if (ensure(RigidsSolver)) + { + // This doesn't even do anything currently, nothing gets it #TODO: CHECK BACK ON THIS + //RigidsSolver->SetPhysicsReplication(this); + } +} + +void FPhysicsReplicationAsyncVR::OnPreSimulate_Internal() +{ + if (FPhysicsReplication::ShouldSkipPhysicsReplication()) + { + return; + } + + if (const FPhysicsReplicationAsyncInput* AsyncInput = GetConsumerInput_Internal()) + { + Chaos::FPBDRigidsSolver* RigidsSolver = static_cast(GetSolver()); + check(RigidsSolver); + + // Early out if this is a resim frame + Chaos::FRewindData* RewindData = RigidsSolver->GetRewindData(); + const bool bRewindDataExist = RewindData != nullptr; + if (bRewindDataExist && RewindData->IsResim()) + { + // TODO, Handle the transition from post-resim to interpolation better (disabled by default, resim vs replication interaction is handled via FPhysicsReplicationAsync::CacheResimInteractions) + static const auto CVarPostResimWaitForUpdate = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.PostResimWaitForUpdate")); + if (CVarPostResimWaitForUpdate->GetBool() && RewindData->IsFinalResim()) + { + for (auto Itr = ObjectToTarget.CreateIterator(); Itr; ++Itr) + { + FReplicatedPhysicsTargetAsync& Target = Itr.Value(); + + // If final resim frame, mark interpolated targets as waiting for up to date data from the server. + if (Target.RepMode == EPhysicsReplicationMode::PredictiveInterpolation) + { + Target.SetWaiting(RigidsSolver->GetCurrentFrame() + Target.FrameOffset, Target.RepModeOverride); + } + } + } + + return; + } + + // Update async targets with target input + for (const FPhysicsRepAsyncInputData& Input : AsyncInput->InputData) + { + if (Input.TargetState.Flags == ERigidBodyFlags::None) + { + // Remove replication target + ObjectToTarget.Remove(Input.PhysicsObject); + continue; + } + + if (!bRewindDataExist && Input.RepMode == EPhysicsReplicationMode::Resimulation) + { + // We don't have rewind data but an actor is set to replicate using resimulation; we need to enable rewind capture. + if (ensure(Chaos::FPBDRigidsSolver::IsNetworkPhysicsPredictionEnabled())) + { + const int32 NumFrames = FMath::Max(1, Chaos::FPBDRigidsSolver::GetPhysicsHistoryCount()); + RigidsSolver->EnableRewindCapture(NumFrames, true); + } + } + + UpdateRewindDataTarget(Input); + UpdateAsyncTarget(Input, RigidsSolver); + } + + if (Chaos::FPBDRigidsSolver::IsNetworkPhysicsPredictionEnabled()) + { + CacheResimInteractions(); + } + + ApplyTargetStatesAsync(GetDeltaTime_Internal(), AsyncInput->ErrorCorrection, AsyncInput->InputData); + } +} + +void FPhysicsReplicationAsyncVR::UpdateRewindDataTarget(const FPhysicsRepAsyncInputData& Input) +{ + if (Input.PhysicsObject == nullptr) + { + return; + } + + Chaos::FPBDRigidsSolver* RigidsSolver = static_cast(GetSolver()); + if (RigidsSolver == nullptr) + { + return; + } + + Chaos::FRewindData* RewindData = RigidsSolver->GetRewindData(); + if (RewindData == nullptr) + { + return; + } + + Chaos::FReadPhysicsObjectInterface_Internal Interface = Chaos::FPhysicsObjectInternalInterface::GetRead(); + if (Chaos::FGeometryParticleHandle* Handle = Interface.GetParticle(Input.PhysicsObject)) + { + // Cache all target states inside RewindData + const int32 LocalFrame = Input.ServerFrame - Input.FrameOffset; + RewindData->SetTargetStateAtFrame(*Handle, LocalFrame, Chaos::FFrameAndPhase::EParticleHistoryPhase::PostPushData, + Input.TargetState.Position, Input.TargetState.Quaternion, + Input.TargetState.LinVel, Input.TargetState.AngVel, (Input.TargetState.Flags & ERigidBodyFlags::Sleeping)); + } +} + +void FPhysicsReplicationAsyncVR::UpdateAsyncTarget(const FPhysicsRepAsyncInputData& Input, Chaos::FPBDRigidsSolver* RigidsSolver) +{ + if (Input.PhysicsObject == nullptr) + { + return; + } + + FReplicatedPhysicsTargetAsync* Target = ObjectToTarget.Find(Input.PhysicsObject); + bool bFirstTarget = Target == nullptr; + if (bFirstTarget) + { + // First time we add a target, set previous state to current input + Target = &ObjectToTarget.Add(Input.PhysicsObject, FReplicatedPhysicsTargetAsync()); + Target->PrevPos = Input.TargetState.Position; + Target->PrevPosTarget = Input.TargetState.Position; + Target->PrevRotTarget = Input.TargetState.Quaternion; + Target->PrevLinVel = Input.TargetState.LinVel; + Target->RepModeOverride = Input.RepMode; + } + + /** Target Update Description + * @param Input = incoming state target for replication. + * + * Input comes mainly from the server but can be a faked state produced by the client for example if the client object wakes up from sleeping. + * Fake inputs should have a ServerFrame of -1 (bool bIsFake = Input.ServerFrame == -1) + * Server inputs can have ServerFrame values of either 0 or an incrementing integer value. + * If the ServerFrame is 0 it should always be 0. If it's incrementing it will always increment. + * + * @local Target = The current state target used for replication, to be updated with data from Input. + * Read about the different target properties in FReplicatedPhysicsTargetAsync + * + * IMPORTANT: + * Target.ServerFrame can be -1 if the target is newly created or if it has data from a fake input. + * + * SendInterval is calculated by taking Input.ServerFrame - Target.ServerFrame + * Note, can only be calculated if the server is sending incrementing SendIntervals and if we have received a valid input previously so we have the previous ServerFrame cached in Target. + * + * ReceiveInterval is calculated by taking RigidsSolver->GetCurrentFrame() - Target.ReceiveFrame + * Note that ReceiveInterval is only used if SendInterval is 0 + * + * Target.TickCount starts at 0 and is incremented each tick that the target is used for, TickCount is reset back to 0 each time Target is updated with new Input. + * + * NOTE: With perfect network conditions SendInterval, ReceiveInterval and Target.TickCount will be the same value. + */ + + if ((bFirstTarget || Input.ServerFrame == 0 || Input.ServerFrame > Target->ServerFrame)) + { + // Get the current physics frame + const int32 CurrentFrame = RigidsSolver->GetCurrentFrame(); + + // Cache TickCount before updating it, force to 0 if ServerFrame is -1 + const int32 PrevTickCount = (Target->ServerFrame < 0) ? 0 : Target->TickCount; + + // Cache SendInterval, only calculate if we have a valid Target->ServerFrame, else leave at 0. + const int32 SendInterval = (Target->ServerFrame <= 0) ? 0 : Input.ServerFrame - Target->ServerFrame; + + // Cache if this target was previously allowed to be altered, before this update + const bool bPrevAllowTargetAltering = Target->bAllowTargetAltering; + + // Set if the target is allowed to be altered after this update + Target->bAllowTargetAltering = !(Target->TargetState.Flags & ERigidBodyFlags::Sleeping) && !(Input.TargetState.Flags & ERigidBodyFlags::Sleeping); + + // Set Target->ReceiveInterval from either SendInterval or the number of physics ticks between receiving input states + if (SendInterval > 0) + { + Target->ReceiveInterval = SendInterval; + } + else + { + const int32 PrevReceiveFrame = Target->ReceiveFrame < 0 ? (CurrentFrame - 1) : Target->ReceiveFrame; + Target->ReceiveInterval = (CurrentFrame - PrevReceiveFrame); + } + + // Update target from input and reset properties + PRAGMA_DISABLE_DEPRECATION_WARNINGS + Target->PrevServerFrame = Target->bWaiting ? Input.ServerFrame : Target->ServerFrame; // DEPRECATED UE5.4 + Target->PrevReceiveFrame = (Target->ReceiveFrame == INDEX_NONE) ? (RigidsSolver->GetCurrentFrame() - 1) : Target->ReceiveFrame; // DEPRECATED UE5.4 + PRAGMA_ENABLE_DEPRECATION_WARNINGS + Target->ServerFrame = Input.ServerFrame; + Target->ReceiveFrame = CurrentFrame; + Target->TargetState = Input.TargetState; + Target->RepMode = Input.RepMode; + Target->FrameOffset = Input.FrameOffset; + Target->TickCount = 0; + Target->AccumulatedSleepSeconds = 0.0f; + + // Update waiting state + Target->UpdateWaiting(Input.ServerFrame); + + if (Input.RepMode == EPhysicsReplicationMode::PredictiveInterpolation) + { + +#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) + static const auto CVarDrawDebugTargets = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.DrawDebugTargets")); + if (CVarDrawDebugTargets->GetBool()) + { + const FVector Offset = FVector(0.0f, 0.0f, 50.0f); + + static const auto CVarNetCorrectionLifetime = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetCorrectionLifetime")); + Chaos::FDebugDrawQueue::GetInstance().DrawDebugBox(Input.TargetState.Position + Offset, FVector(15.0f, 15.0f, 15.0f), Input.TargetState.Quaternion, FColor::MakeRandomSeededColor(Input.ServerFrame), false, CVarNetCorrectionLifetime->GetFloat(), 0, 1.0f); + } +#endif + + // Cache the position we received this target at, Predictive Interpolation will alter the target state but use this as the source position for reconciliation. + Target->PrevPosTarget = Input.TargetState.Position; + Target->PrevRotTarget = Input.TargetState.Quaternion; + + { + /** Target Alignment Feature + * With variable network conditions state inputs from the server can arrive both later or earlier than expected. + * Target Alignment can adjust for this to make replication act on a target in the timeline that the client is currently replicating in. + * + * If SendInterval is 4 we expect TickCount to be 4. TickCount - SendInterval = 0, meaning the client and server has ticked physics the same amount between the target states. + * + * If SendInterval is 4 and TickCount is 2 we have only simulated physics for 2 ticks with the previous target while the server had simulated physics 4 ticks between previous target and new target + * TickCount - SendInterval = -2 + * To align this we need to adjust the new target by predicting backwards by 2 ticks, else the replication will start replicating towards a state that is 2 ticks further ahead than expected, making replication speed up. + * + * Same goes for vice-versa: + * If SendInterval is 4 and TickCount is 6 we have simulated physics for 6 ticks with the previous target while the server had simulated physics 4 ticks between previous target and new target + * TickCount - SendInterval = 2 + * To align this we need to adjust the new target by predicting forwards by 2 ticks, else the replication will start replicating towards a state that is 2 ticks behind than expected, making replication slow down. + * + * Note that state inputs from the server can arrive fluctuating between above examples, but over time the alignment is evened out to 0. + * If the clients latency is raised or lowered since replication started there might be a consistent offset in the TickCount which is handled by TimeDilation of client physics through APlayerController::UpdateServerAsyncPhysicsTickOffset() + */ + + // Run target alignment if we have been allowed to alter the target during the last two target updates + if (!bFirstTarget && bPrevAllowTargetAltering && Target->bAllowTargetAltering) + { + static const auto CVarTargetTickAlignmentClampMultiplier = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.TargetTickAlignmentClampMultiplier")); + const int32 AdjustedAverageReceiveInterval = FMath::CeilToInt(Target->AverageReceiveInterval) * CVarTargetTickAlignmentClampMultiplier->GetInt(); + + // Set the TickCount to the physics tick offset value from where we expected this target to arrive. + // If the client has ticked 2 times ahead from the last target and this target is 3 ticks in front of the previous target then the TickOffset should be -1 + Target->TickCount = FMath::Clamp(PrevTickCount - Target->ReceiveInterval, -AdjustedAverageReceiveInterval, AdjustedAverageReceiveInterval); + + // Apply target alignment if we aren't waiting for a newer state from the server + if (!Target->IsWaiting()) + { + FPhysicsReplicationAsyncVR::ExtrapolateTarget(*Target, Target->TickCount, GetDeltaTime_Internal()); + } + } + } + } + } + + /** Cache the latest ping time */ + LatencyOneWay = Input.LatencyOneWay; +} + + +void FPhysicsReplicationAsyncVR::CacheResimInteractions() +{ + static const auto CVarResimDisableReplicationOnInteraction = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.Resim.DisableReplicationOnInteraction")); + if (!CVarResimDisableReplicationOnInteraction->GetBool()) + { + return; + } + + Chaos::FPBDRigidsSolver* RigidsSolver = static_cast(GetSolver()); + if (RigidsSolver == nullptr) + { + return; + } + + ParticlesInResimIslands.Empty(FMath::CeilToInt(static_cast(ParticlesInResimIslands.Num()) * 0.9f)); + Chaos::Private::FPBDIslandManager& IslandManager = RigidsSolver->GetEvolution()->GetIslandManager(); + Chaos::FWritePhysicsObjectInterface_Internal Interface = Chaos::FPhysicsObjectInternalInterface::GetWrite(); + for (auto Itr = ObjectToTarget.CreateIterator(); Itr; ++Itr) + { + FReplicatedPhysicsTargetAsync& Target = Itr.Value(); + if (Target.RepMode == EPhysicsReplicationMode::Resimulation) + { + Chaos::FConstPhysicsObjectHandle& POHandle = Itr.Key(); + if (Chaos::FGeometryParticleHandle* Handle = Interface.GetParticle(POHandle)) + { + // Get a list of particles from the same island as a resim particle is in, i.e. particles interacting with a resim particle + for (const Chaos::FGeometryParticleHandle* InteractParticle : IslandManager.FindParticlesInIslands(IslandManager.FindParticleIslands(Handle))) + { + ParticlesInResimIslands.Add(InteractParticle->GetHandleIdx()); + } + } + } + } +} + +void FPhysicsReplicationAsyncVR::ApplyTargetStatesAsync(const float DeltaSeconds, const FPhysicsRepErrorCorrectionData& ErrorCorrection, const TArray& InputData) +{ + using namespace Chaos; + + // Deprecated, legacy BodyInstance flow + for (const FPhysicsRepAsyncInputData& Input : InputData) + { + if (Input.Proxy != nullptr) + { + Chaos::FSingleParticlePhysicsProxy* Proxy = Input.Proxy; + Chaos::FRigidBodyHandle_Internal* Handle = Proxy->GetPhysicsThreadAPI(); + + const FPhysicsRepErrorCorrectionData& UsedErrorCorrection = Input.ErrorCorrection.IsSet() ? Input.ErrorCorrection.GetValue() : ErrorCorrection; + DefaultReplication_DEPRECATED(Handle, Input, DeltaSeconds, UsedErrorCorrection); + } + } + + // PhysicsObject flow + Chaos::FWritePhysicsObjectInterface_Internal Interface = Chaos::FPhysicsObjectInternalInterface::GetWrite(); + for (auto Itr = ObjectToTarget.CreateIterator(); Itr; ++Itr) + { + bool bRemoveItr = true; // Remove current cached replication target unless replication logic tells us to store it for next tick + + Chaos::FConstPhysicsObjectHandle& POHandle = Itr.Key(); + if (FGeometryParticleHandle* Handle = Interface.GetParticle(POHandle)) + { + FReplicatedPhysicsTargetAsync& Target = Itr.Value(); + + + if (FPBDRigidParticleHandle* RigidHandle = Handle->CastToRigidParticle()) + { + // Cache custom settings for this object if there are any + FetchObjectSettings(POHandle); + + const EPhysicsReplicationMode RepMode = Target.IsWaiting() ? Target.RepModeOverride : Target.RepMode; + switch (RepMode) + { + case EPhysicsReplicationMode::Default: + bRemoveItr = DefaultReplication(RigidHandle, Target, DeltaSeconds); + break; + + case EPhysicsReplicationMode::PredictiveInterpolation: + bRemoveItr = PredictiveInterpolation(RigidHandle, Target, DeltaSeconds); + break; + + case EPhysicsReplicationMode::Resimulation: + bRemoveItr = ResimulationReplication(RigidHandle, Target, DeltaSeconds); + break; + } + Target.TickCount++; + } + } + + if (bRemoveItr) + { + Itr.RemoveCurrent(); + } + } +} + +//** Async function for legacy replication flow that goes partially through GT to then finishes in PT in this function. */ +void FPhysicsReplicationAsyncVR::DefaultReplication_DEPRECATED(Chaos::FRigidBodyHandle_Internal* Handle, const FPhysicsRepAsyncInputData& State, const float DeltaSeconds, const FPhysicsRepErrorCorrectionData& ErrorCorrection) +{ + if (Handle && Handle->CanTreatAsRigid()) + { + const float LinearVelocityCoefficient = ErrorCorrection.LinearVelocityCoefficient; + const float AngularVelocityCoefficient = ErrorCorrection.AngularVelocityCoefficient; + const float PositionLerp = ErrorCorrection.PositionLerp; + const float AngleLerp = ErrorCorrection.AngleLerp; + + const FVector TargetPos = State.TargetState.Position; + const FQuat TargetQuat = State.TargetState.Quaternion; + + // Get Current state + FRigidBodyState CurrentState; + CurrentState.Position = Handle->X(); + CurrentState.Quaternion = Handle->R(); + CurrentState.AngVel = Handle->W(); + CurrentState.LinVel = Handle->V(); + + FVector LinDiff; + float LinDiffSize; + FVector AngDiffAxis; + float AngDiff; + float AngDiffSize; + ComputeDeltasVR(CurrentState.Position, CurrentState.Quaternion, TargetPos, TargetQuat, LinDiff, LinDiffSize, AngDiffAxis, AngDiff, AngDiffSize); + + const FVector NewLinVel = FVector(State.TargetState.LinVel) + (LinDiff * LinearVelocityCoefficient * DeltaSeconds); + const FVector NewAngVel = FVector(State.TargetState.AngVel) + (AngDiffAxis * AngDiff * AngularVelocityCoefficient * DeltaSeconds); + + const FVector NewPos = FMath::Lerp(FVector(CurrentState.Position), TargetPos, PositionLerp); + const FQuat NewAng = FQuat::Slerp(CurrentState.Quaternion, TargetQuat, AngleLerp); + + Handle->SetX(NewPos); + Handle->SetR(NewAng); + Handle->SetV(NewLinVel); + Handle->SetW(FMath::DegreesToRadians(NewAngVel)); + + if (State.TargetState.Flags & ERigidBodyFlags::Sleeping) + { + // don't allow kinematic to sleeping transition + if (Handle->ObjectState() != Chaos::EObjectStateType::Kinematic) + { + Chaos::FPBDRigidsSolver* RigidsSolver = static_cast(GetSolver()); + if (RigidsSolver) + { + RigidsSolver->GetEvolution()->SetParticleObjectState(Handle->GetProxy()->GetHandle_LowLevel()->CastToRigidParticle(), Chaos::EObjectStateType::Sleeping); //todo: move object state into physics thread api + } + } + } + } +} + + +/** Default replication, run in simulation tick */ +bool FPhysicsReplicationAsyncVR::DefaultReplication(Chaos::FPBDRigidParticleHandle* Handle, FReplicatedPhysicsTargetAsync& Target, const float DeltaSeconds) +{ + Chaos::FPBDRigidsSolver* RigidsSolver = static_cast(GetSolver()); + if (RigidsSolver == nullptr) + { + return true; + } + + static const auto CVarResimDisableReplicationOnInteraction = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.Resim.DisableReplicationOnInteraction")); + if (CVarResimDisableReplicationOnInteraction->GetBool() && ParticlesInResimIslands.Contains(Handle->GetHandleIdx())) + { + return false; + } + + // + // NOTES: + // + // The operation of this method has changed since 4.18. + // + // When a new remote physics state is received, this method will + // be called on tick until the local state is within an adequate + // tolerance of the new state. + // + // The received state is extrapolated based on ping, by some + // adjustable amount. + // + // A correction velocity is added new state's velocity, and assigned + // to the body. The correction velocity scales with the positional + // difference, so without the interference of external forces, this + // will result in an exponentially decaying correction. + // + // Generally it is not needed and will interrupt smoothness of + // the replication, but stronger corrections can be obtained by + // adjusting position lerping. + // + // If progress is not being made towards equilibrium, due to some + // divergence in physics states between the owning and local sims, + // an error value is accumulated, representing the amount of time + // spent in an unresolvable state. + // + // Once the error value has exceeded some threshold (0.5 seconds + // by default), a hard snap to the target physics state is applied. + // + + + bool bRestoredState = true; + const FRigidBodyState NewState = Target.TargetState; + const float NewQuatSizeSqr = NewState.Quaternion.SizeSquared(); + + + const FString ObjectName +#if CHAOS_DEBUG_NAME + = Handle && Handle->DebugName() ? *Handle->DebugName() : FString(TEXT("")); +#else + = FString(TEXT("")); +#endif + + // failure cases + if (Handle == nullptr) + { + UE_LOG(LogPhysics, Warning, TEXT("Trying to replicate rigid state for non-rigid particle. (%s)"), *ObjectName); + return bRestoredState; + } + else if (NewQuatSizeSqr < UE_KINDA_SMALL_NUMBER) + { + UE_LOG(LogPhysics, Warning, TEXT("Invalid zero quaternion set for body. (%s)"), *ObjectName); + return bRestoredState; + } + else if (FMath::Abs(NewQuatSizeSqr - 1.f) > UE_KINDA_SMALL_NUMBER) + { + UE_LOG(LogPhysics, Warning, TEXT("Quaternion (%f %f %f %f) with non-unit magnitude detected. (%s)"), + NewState.Quaternion.X, NewState.Quaternion.Y, NewState.Quaternion.Z, NewState.Quaternion.W, *ObjectName); + return bRestoredState; + } + + // Grab configuration variables from engine config or from CVars if overriding is turned on. + static const auto CVarNetPingExtrapolation = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetPingExtrapolation")); + const float NetPingExtrapolation = CVarNetPingExtrapolation->GetFloat() >= 0.0f ? CVarNetPingExtrapolation->GetFloat() : ErrorCorrectionDefault.PingExtrapolation; + + static const auto CVarNetPingLimit = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetPingLimit")); + const float NetPingLimit = CVarNetPingLimit->GetFloat() > 0.0f ? CVarNetPingLimit->GetFloat() : ErrorCorrectionDefault.PingLimit; + + static const auto CVarErrorPerLinearDifference = IConsoleManager::Get().FindConsoleVariable(TEXT("p.ErrorPerLinearDifference")); + const float ErrorPerLinearDiff = CVarErrorPerLinearDifference->GetFloat() >= 0.0f ? CVarErrorPerLinearDifference->GetFloat() : ErrorCorrectionDefault.ErrorPerLinearDifference; + + static const auto CVarErrorPerAngularDifference = IConsoleManager::Get().FindConsoleVariable(TEXT("p.ErrorPerAngularDifference")); + const float ErrorPerAngularDiff = CVarErrorPerAngularDifference->GetFloat() >= 0.0f ? CVarErrorPerAngularDifference->GetFloat() : ErrorCorrectionDefault.ErrorPerAngularDifference; + + static const auto CVarMaxRestoredStateError = IConsoleManager::Get().FindConsoleVariable(TEXT("p.MaxRestoredStateError")); + const float MaxRestoredStateError = CVarMaxRestoredStateError->GetFloat() >= 0.0f ? CVarMaxRestoredStateError->GetFloat() : ErrorCorrectionDefault.MaxRestoredStateError; + + static const auto CVarErrorAccumulation = IConsoleManager::Get().FindConsoleVariable(TEXT("p.ErrorAccumulationSeconds")); + const float ErrorAccumulationSeconds = CVarErrorAccumulation->GetFloat() >= 0.0f ? CVarErrorAccumulation->GetFloat() : ErrorCorrectionDefault.ErrorAccumulationSeconds; + + static const auto CVarErrorAccumulationDistanceSq = IConsoleManager::Get().FindConsoleVariable(TEXT("p.ErrorAccumulationDistanceSq")); + const float ErrorAccumulationDistanceSq = CVarErrorAccumulationDistanceSq->GetFloat() >= 0.0f ? CVarErrorAccumulationDistanceSq->GetFloat() : ErrorCorrectionDefault.ErrorAccumulationDistanceSq; + + static const auto CVarErrorAccumulationSimilarity = IConsoleManager::Get().FindConsoleVariable(TEXT("p.ErrorAccumulationSimilarity")); + const float ErrorAccumulationSimilarity = CVarErrorAccumulationSimilarity->GetFloat() >= 0.0f ? CVarErrorAccumulationSimilarity->GetFloat() : ErrorCorrectionDefault.ErrorAccumulationSimilarity; + + static const auto CVarLinSet = IConsoleManager::Get().FindConsoleVariable(TEXT("p.PositionLerp")); + const float PositionLerp = CVarLinSet->GetFloat() >= 0.0f ? CVarLinSet->GetFloat() : ErrorCorrectionDefault.PositionLerp; + + static const auto CVarLinLerp = IConsoleManager::Get().FindConsoleVariable(TEXT("p.LinearVelocityCoefficient")); + const float LinearVelocityCoefficient = CVarLinLerp->GetFloat() >= 0.0f ? CVarLinLerp->GetFloat() : ErrorCorrectionDefault.LinearVelocityCoefficient; + + static const auto CVarAngSet = IConsoleManager::Get().FindConsoleVariable(TEXT("p.AngleLerp")); + const float AngleLerp = CVarAngSet->GetFloat() >= 0.0f ? CVarAngSet->GetFloat() : ErrorCorrectionDefault.AngleLerp; + + static const auto CVarAngLerp = IConsoleManager::Get().FindConsoleVariable(TEXT("p.AngularVelocityCoefficient")); + const float AngularVelocityCoefficient = CVarAngLerp->GetFloat() >= 0.0f ? CVarAngLerp->GetFloat() : ErrorCorrectionDefault.AngularVelocityCoefficient; + + static const auto CVarMaxLinearHardSnapDistance = IConsoleManager::Get().FindConsoleVariable(TEXT("p.MaxLinearHardSnapDistance")); + const float MaxLinearHardSnapDistance = CVarMaxLinearHardSnapDistance->GetFloat() >= 0.f ? CVarMaxLinearHardSnapDistance->GetFloat() : ErrorCorrectionDefault.MaxLinearHardSnapDistance; + + // Get Current state + FRigidBodyState CurrentState; + CurrentState.Position = Handle->GetX(); + CurrentState.Quaternion = Handle->GetR(); + CurrentState.AngVel = Handle->GetW(); + CurrentState.LinVel = Handle->GetV(); + + + // Starting from the last known authoritative position, and + // extrapolate an approximation using the last known velocity + // and ping. + const float PingSeconds = FMath::Clamp(LatencyOneWay, 0.f, NetPingLimit); + const float ExtrapolationDeltaSeconds = PingSeconds * NetPingExtrapolation; + const FVector ExtrapolationDeltaPos = NewState.LinVel * ExtrapolationDeltaSeconds; + const FVector_NetQuantize100 TargetPos = NewState.Position + ExtrapolationDeltaPos; + float NewStateAngVel; + FVector NewStateAngVelAxis; + NewState.AngVel.FVector::ToDirectionAndLength(NewStateAngVelAxis, NewStateAngVel); + NewStateAngVel = FMath::DegreesToRadians(NewStateAngVel); + const FQuat ExtrapolationDeltaQuaternion = FQuat(NewStateAngVelAxis, NewStateAngVel * ExtrapolationDeltaSeconds); + FQuat TargetQuat = ExtrapolationDeltaQuaternion * NewState.Quaternion; + + + FVector LinDiff; + float LinDiffSize; + FVector AngDiffAxis; + float AngDiff; + float AngDiffSize; + ComputeDeltasVR(CurrentState.Position, CurrentState.Quaternion, TargetPos, TargetQuat, LinDiff, LinDiffSize, AngDiffAxis, AngDiff, AngDiffSize); + + /////// ACCUMULATE ERROR IF NOT APPROACHING SOLUTION /////// + + // Store sleeping state + const bool bShouldSleep = (NewState.Flags & ERigidBodyFlags::Sleeping) != 0; + const bool bWasAwake = !Handle->Sleeping(); + const bool bAutoWake = false; + + const float Error = (LinDiffSize * ErrorPerLinearDiff) + (AngDiffSize * ErrorPerAngularDiff); + + bRestoredState = Error < MaxRestoredStateError; + if (bRestoredState) + { + Target.AccumulatedErrorSeconds = 0.0f; + } + else + { + // + // The heuristic for error accumulation here is: + + // 1. Did the physics tick from the previous step fail to + // move the body towards a resolved position? + // 2. Was the linear error in the same direction as the + // previous frame? + // 3. Is the linear error large enough to accumulate error? + // + // If these conditions are met, then "error" time will accumulate. + // Once error has accumulated for a certain number of seconds, + // a hard-snap to the target will be performed. + // + // TODO: Rotation while moving linearly can still mess up this + // heuristic. We need to account for it. + // + + // Project the change in position from the previous tick onto the + // linear error from the previous tick. This value roughly represents + // how much correction was performed over the previous physics tick. + const float PrevProgress = FVector::DotProduct( + FVector(CurrentState.Position) - Target.PrevPos, + (Target.PrevPosTarget - Target.PrevPos).GetSafeNormal()); + + // Project the current linear error onto the linear error from the + // previous tick. This value roughly represents how little the direction + // of the linear error state has changed, and how big the error is. + const float PrevSimilarity = FVector::DotProduct( + TargetPos - FVector(CurrentState.Position), + Target.PrevPosTarget - Target.PrevPos); + + // If the conditions from the heuristic outlined above are met, accumulate + // error. Otherwise, reduce it. + if (PrevProgress < ErrorAccumulationDistanceSq && + PrevSimilarity > ErrorAccumulationSimilarity) + { + Target.AccumulatedErrorSeconds += DeltaSeconds; + } + else + { + Target.AccumulatedErrorSeconds = FMath::Max(Target.AccumulatedErrorSeconds - DeltaSeconds, 0.0f); + } + + // Hard snap if error accumulation or linear error is big enough, and clear the error accumulator. + const bool bHardSnap = + LinDiffSize > MaxLinearHardSnapDistance || + Target.AccumulatedErrorSeconds > ErrorAccumulationSeconds || + CharacterMovementCVars::AlwaysHardSnap; + + if (bHardSnap) + { +#if !UE_BUILD_SHIPPING + if (PhysicsReplicationCVars::LogPhysicsReplicationHardSnaps) + { + UE_LOG(LogTemp, Warning, TEXT("Simulated HARD SNAP - \nCurrent Pos - %s, Target Pos - %s\n CurrentState.LinVel - %s, New Lin Vel - %s\nTarget Extrapolation Delta - %s, Is Asleep - %d, Prev Progress - %f, Prev Similarity - %f"), + *CurrentState.Position.ToString(), *TargetPos.ToString(), *CurrentState.LinVel.ToString(), *NewState.LinVel.ToString(), + *ExtrapolationDeltaPos.ToString(), Handle->Sleeping(), PrevProgress, PrevSimilarity); + + if (LinDiffSize > MaxLinearHardSnapDistance) + { + UE_LOG(LogTemp, Warning, TEXT("Hard snap due to linear difference error")); + } + else + { + UE_LOG(LogTemp, Warning, TEXT("Hard snap due to accumulated error")) + } + } +#endif + // Too much error so just snap state here and be done with it + Target.AccumulatedErrorSeconds = 0.0f; + bRestoredState = true; + Handle->SetX(TargetPos); + Handle->SetR(TargetQuat); + Handle->SetV(NewState.LinVel); + Handle->SetW(FMath::DegreesToRadians(NewState.AngVel)); + } + else + { + const FVector NewLinVel = FVector(Target.TargetState.LinVel) + (LinDiff * LinearVelocityCoefficient * DeltaSeconds); + const FVector NewAngVel = FVector(Target.TargetState.AngVel) + (AngDiffAxis * AngDiff * AngularVelocityCoefficient * DeltaSeconds); + + const FVector NewPos = FMath::Lerp(FVector(CurrentState.Position), TargetPos, PositionLerp); + const FQuat NewAng = FQuat::Slerp(CurrentState.Quaternion, TargetQuat, AngleLerp); + + Handle->SetX(NewPos); + Handle->SetR(NewAng); + Handle->SetV(NewLinVel); + Handle->SetW(FMath::DegreesToRadians(NewAngVel)); + } + } + + if (bShouldSleep) + { + // don't allow kinematic to sleeping transition + if (Handle->ObjectState() != Chaos::EObjectStateType::Kinematic) + { + RigidsSolver->GetEvolution()->SetParticleObjectState(Handle, Chaos::EObjectStateType::Sleeping); + } + } + + Target.PrevPosTarget = TargetPos; + Target.PrevPos = FVector(CurrentState.Position); + + return bRestoredState; +} + +/** Interpolating towards replicated states from the server while predicting local physics +* TODO, detailed description +*/ +bool FPhysicsReplicationAsyncVR::PredictiveInterpolation(Chaos::FPBDRigidParticleHandle* Handle, FReplicatedPhysicsTargetAsync& Target, const float DeltaSeconds) +{ + static const auto CVarSkipReplication = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.SkipReplication")); + if (CVarSkipReplication->GetBool()) + { + return true; + } + + if (Target.IsWaiting()) + { + return false; + } + + Chaos::FPBDRigidsSolver* RigidsSolver = static_cast(GetSolver()); + if (RigidsSolver == nullptr) + { + return true; + } + + static const auto CVarResimDisableReplicationOnInteraction = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.Resim.DisableReplicationOnInteraction")); + if (CVarResimDisableReplicationOnInteraction->GetBool() && ParticlesInResimIslands.Contains(Handle->GetHandleIdx())) + { + // If particle is in an island with a resim object, don't run replication and wait for an up to date target (after leaving the island) + Target.SetWaiting(RigidsSolver->GetCurrentFrame() + Target.FrameOffset, EPhysicsReplicationMode::Resimulation); + return false; + } + +#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) + static const auto CVarDrawDebugTargets = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.DrawDebugTargets")); + if (CVarDrawDebugTargets->GetBool()) + { + const FVector Offset = FVector(0.0f, 0.0f, 50.0f); + const FVector StartPos = Target.TargetState.Position + Offset; + const int32 SizeMultiplier = FMath::Clamp(Target.TickCount, -4, 30); + static const auto CVarNetCorrectionLifetime = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetCorrectionLifetime")); + Chaos::FDebugDrawQueue::GetInstance().DrawDebugBox(StartPos, FVector(5.0f + SizeMultiplier * 0.75f, 5.0f + SizeMultiplier * 0.75f, 5.0f + SizeMultiplier * 0.75f), Target.TargetState.Quaternion, FColor::MakeRandomSeededColor(Target.ServerFrame), false, CVarNetCorrectionLifetime->GetFloat(), 0, 1.0f); + } +#endif + + const bool bIsSleeping = Handle->IsSleeping(); + const bool bCanSimulate = Handle->IsDynamic() || bIsSleeping; + + // Accumulate sleep time or reset back to 0s if not sleeping + Target.AccumulatedSleepSeconds = bIsSleeping ? (Target.AccumulatedSleepSeconds + DeltaSeconds) : 0.0f; + + // Helper for sleep and target clearing at replication end + auto EndReplicationHelper = [RigidsSolver, Handle, bCanSimulate, bIsSleeping, DeltaSeconds](FReplicatedPhysicsTargetAsync& Target, bool bOkToClear) -> bool + { + const bool bShouldSleep = (Target.TargetState.Flags & ERigidBodyFlags::Sleeping) != 0; + const bool bReplicatingPhysics = (Target.TargetState.Flags & ERigidBodyFlags::RepPhysics) != 0; + + // --- Set Sleep State --- + if (bOkToClear && bShouldSleep && bCanSimulate) + { + RigidsSolver->GetEvolution()->SetParticleObjectState(Handle, Chaos::EObjectStateType::Sleeping); + } + + static const auto CVarSleepSecondsClearTarget = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.SleepSecondsClearTarget")); + static const auto CVarDontClearTarget = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.DontClearTarget")); + // --- Should replication stop? --- + const bool bClearTarget = + (!bCanSimulate + || (bOkToClear && bShouldSleep && Target.AccumulatedSleepSeconds >= CVarSleepSecondsClearTarget->GetFloat()) // Don't clear the target due to sleeping until the object both should sleep and is sleeping for n seconds + || (bOkToClear && !bReplicatingPhysics)) + && !CVarDontClearTarget->GetBool(); + + // --- Target Prediction --- + if (!bClearTarget && Target.bAllowTargetAltering) + { + static const auto CVarExtrapolationTimeMultiplier = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.ExtrapolationTimeMultiplier")); + static const auto CVarExtrapolationMinTime = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.ExtrapolationMinTime")); + const int32 ExtrapolationTickLimit = FMath::Max( + FMath::CeilToInt(Target.AverageReceiveInterval * CVarExtrapolationTimeMultiplier->GetFloat()), // Extrapolate time based on receive interval * multiplier + FMath::CeilToInt(CVarExtrapolationMinTime->GetFloat() / DeltaSeconds)); // At least extrapolate for N seconds + if (Target.TickCount <= ExtrapolationTickLimit) + { + FPhysicsReplicationAsyncVR::ExtrapolateTarget(Target, 1, DeltaSeconds); + } + } + + return bClearTarget; + }; + + + static const auto CVarEarlyOutWithVelocity = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.EarlyOutWithVelocity")); + static const auto CVarEarlyOutDistanceSqr = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.EarlyOutDistanceSqr")); + // If target velocity is low enough, check the distance from the current position to the source position of our target to see if it's low enough to early out of replication + const bool bXCanEarlyOut = (CVarEarlyOutWithVelocity->GetBool() || Target.TargetState.LinVel.SizeSquared() < UE_KINDA_SMALL_NUMBER) && + (Target.PrevPosTarget - Handle->GetX()).SizeSquared() < CVarEarlyOutDistanceSqr->GetFloat(); + + // Early out if we are within range of target, also apply target sleep state + if (bXCanEarlyOut) + { + // Get the rotational offset between the blended rotation target and the current rotation + const FQuat TargetRotDelta = Target.TargetState.Quaternion * Handle->GetR().Inverse(); + + // Convert to angle axis + float Angle; + FVector Axis; + TargetRotDelta.ToAxisAndAngle(Axis, Angle); + Angle = FMath::Abs(FMath::UnwindRadians(Angle)); + + static const auto CVarEarlyOutAngle = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.EarlyOutAngle")); + if (Angle < FMath::DegreesToRadians(CVarEarlyOutAngle->GetFloat())) + { + // Early Out + return EndReplicationHelper(Target, true); + } + } + + // Wake up if sleeping + if (bIsSleeping) + { + RigidsSolver->GetEvolution()->SetParticleObjectState(Handle, Chaos::EObjectStateType::Dynamic); + } + + static const auto CVarAverageReceiveIntervalSmoothing = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.AverageReceiveIntervalSmoothing")); + // Update the AverageReceiveInterval if Target.ReceiveInterval has a valid value to update from + Target.AverageReceiveInterval = Target.ReceiveInterval == 0 ? Target.AverageReceiveInterval : FMath::Lerp(Target.AverageReceiveInterval, Target.ReceiveInterval, FMath::Clamp((1.0f / (Target.ReceiveInterval * CVarAverageReceiveIntervalSmoothing->GetFloat())), 0.0f, 1.0f)); + + // CurrentState + FRigidBodyState CurrentState; + CurrentState.Position = Handle->GetX(); + CurrentState.Quaternion = Handle->GetR(); + CurrentState.LinVel = Handle->GetV(); + CurrentState.AngVel = Handle->GetW(); // Note: Current angular velocity is in Radians + + // NewState + const FVector TargetPos = FVector(Target.TargetState.Position); + const FQuat TargetRot = Target.TargetState.Quaternion; + const FVector TargetLinVel = FVector(Target.TargetState.LinVel); + const FVector TargetAngVel = FVector(Target.TargetState.AngVel); // Note: Target angular velocity is in Degrees + + /** --- Reconciliation --- + * If target velocities are low enough, check the traveled direction and distance from previous frame and compare with replicated linear velocity. + * If the object isn't moving enough along the replicated velocity it's considered stuck and needs reconciliation. + * SoftSnap is performed each tick while there is a registered error, if enough time pass HardSnap forces the object into the correct state. */ + static const auto CVarVelocityBased = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.VelocityBased")); + bool bSoftSnap = !CVarVelocityBased->GetBool(); + + static const auto CVarDisableErrorVelocityLimits = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.DisableErrorVelocityLimits")); + static const auto CVarErrorAccLinVelMaxLimit = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.ErrorAccLinVelMaxLimit")); + static const auto CVarErrorAccAngVelMaxLimit = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.ErrorAccAngVelMaxLimit")); + if (CVarDisableErrorVelocityLimits->GetBool() || + (TargetLinVel.Size() < CVarErrorAccLinVelMaxLimit->GetFloat() && TargetAngVel.Size() < CVarErrorAccAngVelMaxLimit->GetFloat())) + { + const FVector PrevDiff = CurrentState.Position - Target.PrevPos; + const float ExpectedDistance = (Target.PrevLinVel * DeltaSeconds).Size(); + const float CoveredDistance = FVector::DotProduct(PrevDiff, Target.PrevLinVel.GetSafeNormal()); + const float CoveredAplha = FMath::Clamp(CoveredDistance / ExpectedDistance, 0.0f, 1.0f); + + // If the object is moving less than X% of the expected distance, accumulate error seconds + static const auto CVarMinExpectedDistanceCovered = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.MinExpectedDistanceCovered")); + if (CoveredAplha < CVarMinExpectedDistanceCovered->GetFloat()) + { + Target.AccumulatedErrorSeconds += DeltaSeconds; + bSoftSnap = true; + } + else if (Target.AccumulatedErrorSeconds > 0.f) + { + static const auto CVarErrorAccumulationDecreaseMultiplier = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.ErrorAccumulationDecreaseMultiplier")); + const float DecreaseTime = DeltaSeconds * CVarErrorAccumulationDecreaseMultiplier->GetFloat(); + Target.AccumulatedErrorSeconds = FMath::Max(Target.AccumulatedErrorSeconds - DecreaseTime, 0.0f); + bSoftSnap = true; + } + } + else + { + Target.AccumulatedErrorSeconds = 0; + } + + static const auto CVarVelocityBasedSetting = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.VelocityBased")); + if (SettingsCurrent.PredictiveInterpolationSettings.GetDisableSoftSnap() && CVarVelocityBasedSetting->GetBool()) + { + bSoftSnap = false; + } + + static const auto CVarErrorAccumulationSeconds = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.ErrorAccumulationSeconds")); + static const auto CVarAlwaysHardSnap = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.AlwaysHardSnap")); + const bool bHardSnap = !bCanSimulate || + Target.AccumulatedErrorSeconds > CVarErrorAccumulationSeconds->GetFloat() || + CVarAlwaysHardSnap->GetBool(); + + if (bHardSnap) + { + Target.AccumulatedErrorSeconds = 0.0f; + + if (Handle->IsKinematic()) + { + // Set a FKinematicTarget to hard snap kinematic object + const Chaos::FKinematicTarget KinTarget = Chaos::FKinematicTarget::MakePositionTarget(Target.PrevPosTarget, Target.PrevRotTarget); // Uses EKinematicTargetMode::Position + RigidsSolver->GetEvolution()->SetParticleKinematicTarget(Handle, KinTarget); + } + else + { + // Set XPRQVW to hard snap dynamic object + Handle->SetX(Target.PrevPosTarget); + Handle->SetP(Target.PrevPosTarget); + Handle->SetR(Target.PrevRotTarget); + Handle->SetQ(Target.PrevRotTarget); + Handle->SetV(Target.TargetState.LinVel); + Handle->SetW(FMath::DegreesToRadians(Target.TargetState.AngVel)); + } + + // Cache data for next replication + Target.PrevLinVel = FVector(Target.TargetState.LinVel); + + // End replication and go to sleep if that's requested + return EndReplicationHelper(Target, true); + } + else // Velocity-based Replication + { + // Calculate interpolation time based on current average receive rate + const float AverageReceiveIntervalSeconds = Target.AverageReceiveInterval * DeltaSeconds; + const float InterpolationTime = AverageReceiveIntervalSeconds * SettingsCurrent.PredictiveInterpolationSettings.GetPosInterpolationTimeMultiplier(); + + // Calculate position correction time based on current Round Trip Time + const float RTT = LatencyOneWay * 2.f; + const float PosCorrectionTime = FMath::Max(SettingsCurrent.PredictiveInterpolationSettings.GetPosCorrectionTimeBase() + AverageReceiveIntervalSeconds + RTT * SettingsCurrent.PredictiveInterpolationSettings.GetPosCorrectionTimeMultiplier(), + DeltaSeconds + SettingsCurrent.PredictiveInterpolationSettings.GetPosCorrectionTimeMin()); + const float RotCorrectionTime = FMath::Max(SettingsCurrent.PredictiveInterpolationSettings.GetRotCorrectionTimeBase() + AverageReceiveIntervalSeconds + RTT * SettingsCurrent.PredictiveInterpolationSettings.GetRotCorrectionTimeMultiplier(), + DeltaSeconds + SettingsCurrent.PredictiveInterpolationSettings.GetRotCorrectionTimeMin()); + + if ((bXCanEarlyOut && SettingsCurrent.PredictiveInterpolationSettings.GetSkipVelocityRepOnPosEarlyOut()) == false) + { // --- Velocity Replication --- + + // Get PosDiff + const FVector PosDiff = TargetPos - CurrentState.Position; + + // Get LinVelDiff by adding inverted CurrentState.LinVel to TargetLinVel + const FVector LinVelDiff = -CurrentState.LinVel + TargetLinVel; + + // Calculate velocity blend amount for this tick as an alpha value + const float Alpha = FMath::Clamp(DeltaSeconds / InterpolationTime, 0.0f, 1.0f); + + FVector RepLinVel; + static const auto CVarPosCorrectionAsVelocity = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.PosCorrectionAsVelocity")); + if (CVarPosCorrectionAsVelocity->GetBool()) + { + // Convert PosDiff to a velocity + const FVector PosDiffVelocity = PosDiff / PosCorrectionTime; + + // Add PosDiffVelocity to LinVelDiff to get BlendedTargetVelocity + const FVector BlendedTargetVelocity = LinVelDiff + PosDiffVelocity; + + // Add BlendedTargetVelocity onto current velocity + + RepLinVel = CurrentState.LinVel + (BlendedTargetVelocity * Alpha); + } + else // Positional correction as position shift + { + // Calculate the PosDiff amount to correct this tick + const FVector PosDiffVelocityDelta = PosDiff * (DeltaSeconds / PosCorrectionTime); // Same as (PosDiff / PosCorrectionTime) * DeltaSeconds + + // Add velocity diff onto current velocity + RepLinVel = CurrentState.LinVel + (LinVelDiff * Alpha); + + + // Apply positional correction + Handle->SetX(Handle->GetX() + PosDiffVelocityDelta); + } + + // Apply velocity replication + + Handle->SetV(RepLinVel); + +#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) + static const auto CVarDrawDebugVectors = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.PredictiveInterpolation.DrawDebugVectors")); + if (CVarDrawDebugVectors->GetBool()) + { + const FVector Offset = FVector(0.0f, 0.0f, 50.0f); + const FVector OffsetAdd = FVector(0.0f, 0.0f, 10.0f); + const FVector StartPos = TargetPos + Offset; + FVector Direction = TargetLinVel; + Direction.Normalize(); + Chaos::FDebugDrawQueue::GetInstance().DrawDebugDirectionalArrow((StartPos + OffsetAdd * 0), (StartPos + OffsetAdd * 0) + TargetLinVel * 0.5f, 5.0f, FColor::Green, false, -1.0f, 0, 2.0f); + Chaos::FDebugDrawQueue::GetInstance().DrawDebugDirectionalArrow((StartPos + OffsetAdd * 1), (StartPos + OffsetAdd * 1) + CurrentState.LinVel * 0.5f, 5.0f, FColor::Blue, false, -1.0f, 0, 2.0f); + Chaos::FDebugDrawQueue::GetInstance().DrawDebugDirectionalArrow((StartPos + OffsetAdd * 2), (StartPos + OffsetAdd * 2) + (Target.PrevLinVel - CurrentState.LinVel) * 0.5f, 5.0f, FColor::Red, false, -1.0f, 0, 2.0f); + Chaos::FDebugDrawQueue::GetInstance().DrawDebugDirectionalArrow((StartPos + OffsetAdd * 3), (StartPos + OffsetAdd * 3) + RepLinVel * 0.5f, 5.0f, FColor::Magenta, false, -1.0f, 0, 2.0f); + Chaos::FDebugDrawQueue::GetInstance().DrawDebugDirectionalArrow((StartPos + OffsetAdd * 4), (StartPos + OffsetAdd * 4) + (Target.PrevLinVel - RepLinVel) * 0.5f, 5.0f, FColor::Orange, false, -1.0f, 0, 2.0f); + Chaos::FDebugDrawQueue::GetInstance().DrawDebugDirectionalArrow((StartPos + OffsetAdd * 5), (StartPos + OffsetAdd * 5) + Direction * RTT, 5.0f, FColor::White, false, -1.0f, 0, 2.0f); + Chaos::FDebugDrawQueue::GetInstance().DrawDebugDirectionalArrow((StartPos + OffsetAdd * 6), (StartPos + OffsetAdd * 6) + Direction * InterpolationTime, 5.0f, FColor::Yellow, false, -1.0f, 0, 2.0f); + } +#endif + // Cache data for next replication + Target.PrevLinVel = FVector(RepLinVel); + } + + { // --- Angular Velocity Replication --- + /* Todo, Implement InterpolationTime */ + + // Extrapolate current rotation along current angular velocity to see where we would end up + float CurAngVelSize; + FVector CurAngVelAxis; + CurrentState.AngVel.FVector::ToDirectionAndLength(CurAngVelAxis, CurAngVelSize); + const FQuat CurRotExtrapDelta = FQuat(CurAngVelAxis, CurAngVelSize * DeltaSeconds); + const FQuat CurRotExtrap = CurRotExtrapDelta * CurrentState.Quaternion; + + // Slerp from the extrapolated current rotation towards the target rotation + // This takes current angular velocity into account + const float RotCorrectionAmount = FMath::Clamp(DeltaSeconds / RotCorrectionTime, 0.0f, 1.0f); + const FQuat TargetRotBlended = FQuat::Slerp(CurRotExtrap, TargetRot, RotCorrectionAmount); + + // Get the rotational offset between the blended rotation target and the current rotation + const FQuat TargetRotDelta = TargetRotBlended * CurrentState.Quaternion.Inverse(); + + // Convert the rotational delta to angular velocity + float WAngle; + FVector WAxis; + TargetRotDelta.ToAxisAndAngle(WAxis, WAngle); + const FVector TargetRotDeltaBlend = FVector(WAxis * (WAngle / (DeltaSeconds * SettingsCurrent.PredictiveInterpolationSettings.GetRotInterpolationTimeMultiplier()))); + const FVector RepAngVel = FMath::DegreesToRadians(TargetAngVel) + TargetRotDeltaBlend; + + Handle->SetW(RepAngVel); + } + + // Cache data for next replication + Target.PrevPos = FVector(CurrentState.Position); + + if (bSoftSnap) + { + const FVector SoftSnapPos = FMath::Lerp(FVector(CurrentState.Position), + SettingsCurrent.PredictiveInterpolationSettings.GetSoftSnapToSource() ? Target.PrevPosTarget : Target.TargetState.Position, + FMath::Clamp(SettingsCurrent.PredictiveInterpolationSettings.GetSoftSnapPosStrength(), 0.0f, 1.0f)); + + const FQuat SoftSnapRot = FQuat::Slerp(CurrentState.Quaternion, + SettingsCurrent.PredictiveInterpolationSettings.GetSoftSnapToSource() ? Target.PrevRotTarget : Target.TargetState.Quaternion, + FMath::Clamp(SettingsCurrent.PredictiveInterpolationSettings.GetSoftSnapRotStrength(), 0.0f, 1.0f)); + + Handle->SetX(SoftSnapPos); + Handle->SetP(SoftSnapPos); + Handle->SetR(SoftSnapRot); + Handle->SetQ(SoftSnapRot); + } + } + + return EndReplicationHelper(Target, false); +} + +/** Static function to extrapolate a target for N ticks using X DeltaSeconds */ +void FPhysicsReplicationAsyncVR::ExtrapolateTarget(FReplicatedPhysicsTargetAsync& Target, const int32 ExtrapolateFrames, const float DeltaSeconds) +{ + const float ExtrapolationTime = DeltaSeconds * static_cast(ExtrapolateFrames); + + // Extrapolate target position + Target.TargetState.Position = Target.TargetState.Position + Target.TargetState.LinVel * ExtrapolationTime; + + // Extrapolate target rotation + float TargetAngVelSize; + FVector TargetAngVelAxis; + Target.TargetState.AngVel.FVector::ToDirectionAndLength(TargetAngVelAxis, TargetAngVelSize); + TargetAngVelSize = FMath::DegreesToRadians(TargetAngVelSize); + const FQuat TargetRotExtrapDelta = FQuat(TargetAngVelAxis, TargetAngVelSize * ExtrapolationTime); + Target.TargetState.Quaternion = TargetRotExtrapDelta * Target.TargetState.Quaternion; +} + +/** Compare states and trigger resimulation if needed */ +bool FPhysicsReplicationAsyncVR::ResimulationReplication(Chaos::FPBDRigidParticleHandle* Handle, FReplicatedPhysicsTargetAsync& Target, const float DeltaSeconds) +{ + Chaos::FPBDRigidsSolver* RigidsSolver = static_cast(GetSolver()); + if (RigidsSolver == nullptr) + { + return true; + } + + Chaos::FRewindData* RewindData = RigidsSolver->GetRewindData(); + if (RewindData == nullptr) + { + return true; + } + + const int32 LocalFrame = Target.ServerFrame - Target.FrameOffset; + + if (LocalFrame >= RewindData->CurrentFrame() || LocalFrame < RewindData->GetEarliestFrame_Internal()) + { + if (LocalFrame > 0 && (RewindData->CurrentFrame() - RewindData->GetEarliestFrame_Internal()) == RewindData->Capacity()) + { + UE_LOG(LogPhysics, Warning, TEXT("FPhysicsReplication::ResimulationReplication target frame (%d) out of rewind data bounds (%d,%d)"), + LocalFrame, RewindData->GetEarliestFrame_Internal(), RewindData->CurrentFrame()); + } + return true; + } + + bool bClearTarget = true; + + + static constexpr Chaos::FFrameAndPhase::EParticleHistoryPhase RewindPhase = Chaos::FFrameAndPhase::EParticleHistoryPhase::PostPushData; + + const float ResimErrorThreshold = SettingsCurrent.ResimulationSettings.GetResimulationErrorThreshold(Chaos::FPhysicsSolverBase::ResimulationErrorThreshold()); + const Chaos::FGeometryParticleState PastState = RewindData->GetPastStateAtFrame(*Handle, LocalFrame, RewindPhase); + + const FVector ErrorOffset = (Target.TargetState.Position - PastState.GetX()); + const float ErrorDistance = ErrorOffset.Size(); + const bool ShouldTriggerResim = ErrorDistance >= ResimErrorThreshold; + + +#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) + + if (Chaos::FPhysicsSolverBase::CanDebugNetworkPhysicsPrediction()) + { + UE_LOG(LogTemp, Log, TEXT("Apply Rigid body state at local frame %d with offset = %d"), LocalFrame, Target.FrameOffset); + UE_LOG(LogTemp, Log, TEXT("Particle Position Error = %f | Should Trigger Resim = %s | Server Frame = %d | Client Frame = %d"), ErrorDistance, (ShouldTriggerResim ? TEXT("True") : TEXT("False")), Target.ServerFrame, LocalFrame); + UE_LOG(LogTemp, Log, TEXT("Particle Target Position = %s | Current Position = %s"), *Target.TargetState.Position.ToString(), *PastState.GetX().ToString()); + UE_LOG(LogTemp, Log, TEXT("Particle Target Velocity = %s | Current Velocity = %s"), *Target.TargetState.LinVel.ToString(), *PastState.GetV().ToString()); + UE_LOG(LogTemp, Log, TEXT("Particle Target Quaternion = %s | Current Quaternion = %s"), *Target.TargetState.Quaternion.ToString(), *PastState.GetR().ToString()); + UE_LOG(LogTemp, Log, TEXT("Particle Target Omega = %s | Current Omega= %s"), *Target.TargetState.AngVel.ToString(), *PastState.GetW().ToString()); + } + + static const auto CVarResimDrawDebug = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.Resim.DrawDebug")); + if (CVarResimDrawDebug->GetBool()) + { + static constexpr float BoxSize = 5.0f; + const float ColorLerp = ShouldTriggerResim ? 1.0f : 0.0f; + const FColor DebugColor = FLinearColor::LerpUsingHSV(FLinearColor::Green, FLinearColor::Red, ColorLerp).ToFColor(false); + + static const auto CVarNetCorrectionLifetime = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetCorrectionLifetime")); + Chaos::FDebugDrawQueue::GetInstance().DrawDebugBox(Target.TargetState.Position, FVector(BoxSize, BoxSize, BoxSize), Target.TargetState.Quaternion, FColor::Orange, true, CVarNetCorrectionLifetime->GetFloat(), 0, 1.0f); + Chaos::FDebugDrawQueue::GetInstance().DrawDebugBox(PastState.GetX(), FVector(6, 6, 6), PastState.GetR(), DebugColor, true, CVarNetCorrectionLifetime->GetFloat(), 0, 1.0f); + Chaos::FDebugDrawQueue::GetInstance().DrawDebugDirectionalArrow(PastState.GetX(), Target.TargetState.Position, 5.0f, FColor::MakeRandomSeededColor(LocalFrame), true, CVarNetCorrectionLifetime->GetFloat(), 0, 0.5f); + } +#endif + + if (LocalFrame > RewindData->GetBlockedResimFrame()) + { + if (ShouldTriggerResim && Target.TickCount == 0) + { + // Trigger resimulation + RigidsSolver->GetEvolution()->GetIslandManager().SetParticleResimFrame(Handle, LocalFrame); + + int32 ResimFrame = RewindData->GetResimFrame(); + ResimFrame = (ResimFrame == INDEX_NONE) ? LocalFrame : FMath::Min(ResimFrame, LocalFrame); + RewindData->SetResimFrame(ResimFrame); + } + else if (SettingsCurrent.ResimulationSettings.GetRuntimeCorrectionEnabled()) + + { + const int32 NumPredictedFrames = RigidsSolver->GetCurrentFrame() - LocalFrame - Target.TickCount; + + + + if (Target.TickCount <= NumPredictedFrames && NumPredictedFrames > 0) + { + // Positional Correction + const float CorrectionAmountX = SettingsCurrent.ResimulationSettings.GetPosStabilityMultiplier() / NumPredictedFrames; + const FVector PosDiffCorrection = ErrorOffset * CorrectionAmountX; // Same result as (ErrorOffset / NumPredictedFrames) * PosStabilityMultiplier + const FVector CorrectedX = Handle->GetX() + PosDiffCorrection; + + + // Rotational Correction + const float CorrectionAmountR = SettingsCurrent.ResimulationSettings.GetRotStabilityMultiplier() / NumPredictedFrames; + + const FQuat DeltaQuat = PastState.GetR().Inverse() * Target.TargetState.Quaternion; + const FQuat TargetCorrectionR = Handle->GetR() * DeltaQuat; + const FQuat CorrectedR = FQuat::Slerp(Handle->GetR(), TargetCorrectionR, CorrectionAmountR); + + if (SettingsCurrent.ResimulationSettings.GetRuntimeVelocityCorrectionEnabled()) + { + // Linear Velocity Correction + const FVector LinVelDiff = Target.TargetState.LinVel - PastState.GetV(); // Velocity vector that the server covers but the client doesn't + const float CorrectionAmountV = SettingsCurrent.ResimulationSettings.GetVelStabilityMultiplier() / NumPredictedFrames; + const FVector VelCorrection = LinVelDiff * CorrectionAmountV; // Same result as (LinVelDiff / NumPredictedFrames) * VelStabilityMultiplier + const FVector CorrectedV = Handle->GetV() + VelCorrection; + + // Angular Velocity Correction + const FVector AngVelDiff = Target.TargetState.AngVel - PastState.GetW(); // Angular velocity vector that the server covers but the client doesn't + const float CorrectionAmountW = SettingsCurrent.ResimulationSettings.GetAngVelStabilityMultiplier() / NumPredictedFrames; + const FVector AngVelCorrection = AngVelDiff * CorrectionAmountW; // Same result as (AngVelDiff / NumPredictedFrames) * VelStabilityMultiplier + const FVector CorrectedW = Handle->GetW() + AngVelCorrection; + + // Apply correction to velocities + Handle->SetV(CorrectedV); + Handle->SetW(CorrectedW); + } + + +#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) + if (CVarResimDrawDebug->GetBool()) + { + static const auto CVarNetCorrectionLifetime = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetCorrectionLifetime")); + Chaos::FDebugDrawQueue::GetInstance().DrawDebugDirectionalArrow(Handle->GetX(), CorrectedX, 5.0f, FColor::MakeRandomSeededColor(LocalFrame), true, CVarNetCorrectionLifetime->GetFloat(), 0, 0.5f); + } +#endif + // Apply correction to position and rotation + static const auto CVarResimRuntimeCorrectConnectedBodies = IConsoleManager::Get().FindConsoleVariable(TEXT("np2.Resim.RuntimeCorrectConnectedBodies")); + RigidsSolver->GetEvolution()->ApplyParticleTransformCorrection(Handle, CorrectedX, CorrectedR, CVarResimRuntimeCorrectConnectedBodies->GetBool()); + } + + // Keep target for NumPredictedFrames time to perform runtime corrections with until a new target is received + bClearTarget = Target.TickCount >= NumPredictedFrames; + } + } + return bClearTarget; +} + +FName FPhysicsReplicationAsyncVR::GetFNameForStatId() const +{ + const static FLazyName StaticName("FPhysicsReplicationAsyncCallback"); + return StaticName; +} + +#pragma endregion // FPhysicsReplicationAsync \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableSkeletalMeshActor.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableSkeletalMeshActor.cpp new file mode 100644 index 0000000..b1a36b3 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableSkeletalMeshActor.cpp @@ -0,0 +1,1028 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Grippables/GrippableSkeletalMeshActor.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GrippableSkeletalMeshActor) + +#include "TimerManager.h" +#include "GameFramework/PlayerController.h" +#include "GameFramework/PlayerState.h" +#include "GripMotionControllerComponent.h" +#include "VRExpansionFunctionLibrary.h" +#include "Misc/BucketUpdateSubsystem.h" +#include "Net/UnrealNetwork.h" +#include "PhysicsReplication.h" +#include "Physics/Experimental/PhysScene_Chaos.h" +#include "PhysicsEngine/PhysicsAsset.h" // Tmp until epic bug fixes skeletal welding +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + +UOptionalRepSkeletalMeshComponent::UOptionalRepSkeletalMeshComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + bReplicateMovement = true; +} + +void UOptionalRepSkeletalMeshComponent::PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) +{ + Super::PreReplication(ChangedPropertyTracker); + + // Don't replicate if set to not do it + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeLocation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeRotation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeScale3D, bReplicateMovement); +} + +void UOptionalRepSkeletalMeshComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty >& OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UOptionalRepSkeletalMeshComponent, bReplicateMovement, PushModelParams); +} + +void UOptionalRepSkeletalMeshComponent::SetReplicateMovement(bool bNewReplicateMovement) +{ + bReplicateMovement = bNewReplicateMovement; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UOptionalRepSkeletalMeshComponent, bReplicateMovement, this); +#endif +} + +void UOptionalRepSkeletalMeshComponent::GetWeldedBodies(TArray& OutWeldedBodies, TArray& OutLabels, bool bIncludingAutoWeld) +{ + UPhysicsAsset* PhysicsAsset = GetPhysicsAsset(); + + for (int32 BodyIdx = 0; BodyIdx < Bodies.Num(); ++BodyIdx) + { + FBodyInstance* BI = Bodies[BodyIdx]; + if (BI && (BI->WeldParent != nullptr || (bIncludingAutoWeld && BI->bAutoWeld))) + { + OutWeldedBodies.Add(BI); + if (PhysicsAsset) + { + if (UBodySetup* PhysicsAssetBodySetup = PhysicsAsset->SkeletalBodySetups[BodyIdx]) + { + OutLabels.Add(PhysicsAssetBodySetup->BoneName); + } + else + { + OutLabels.Add(NAME_None); + } + } + else + { + OutLabels.Add(NAME_None); + } + + } + } + + for (USceneComponent* Child : GetAttachChildren()) + { + if (UPrimitiveComponent* PrimChild = Cast(Child)) + { + PrimChild->GetWeldedBodies(OutWeldedBodies, OutLabels, bIncludingAutoWeld); + } + } +} + +FBodyInstance* UOptionalRepSkeletalMeshComponent::GetBodyInstance(FName BoneName, bool bGetWelded, int32) const +{ + UPhysicsAsset* const PhysicsAsset = GetPhysicsAsset(); + FBodyInstance* BodyInst = NULL; + + if (PhysicsAsset != NULL) + { + // A name of NAME_None indicates 'root body' + if (BoneName == NAME_None) + { + if (Bodies.IsValidIndex(RootBodyData.BodyIndex)) + { + BodyInst = Bodies[RootBodyData.BodyIndex]; + } + } + // otherwise, look for the body + else + { + int32 BodyIndex = PhysicsAsset->FindBodyIndex(BoneName); + if (Bodies.IsValidIndex(BodyIndex)) + { + BodyInst = Bodies[BodyIndex]; + } + } + + BodyInst = (bGetWelded && BodyInstance.WeldParent) ? BodyInstance.WeldParent : BodyInst; + } + + return BodyInst; +} + +//============================================================================= +AGrippableSkeletalMeshActor::AGrippableSkeletalMeshActor(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer.SetDefaultSubobjectClass(TEXT("SkeletalMeshComponent0"))) +{ + VRGripInterfaceSettings.bDenyGripping = false; + VRGripInterfaceSettings.OnTeleportBehavior = EGripInterfaceTeleportBehavior::TeleportAllComponents; + VRGripInterfaceSettings.bSimulateOnDrop = true; + VRGripInterfaceSettings.SlotDefaultGripType = EGripCollisionType::InteractiveCollisionWithPhysics; + VRGripInterfaceSettings.FreeDefaultGripType = EGripCollisionType::InteractiveCollisionWithPhysics; + VRGripInterfaceSettings.SecondaryGripType = ESecondaryGripType::SG_None; + VRGripInterfaceSettings.MovementReplicationType = EGripMovementReplicationSettings::ForceClientSideMovement; + VRGripInterfaceSettings.LateUpdateSetting = EGripLateUpdateSettings::NotWhenCollidingOrDoubleGripping; + VRGripInterfaceSettings.ConstraintStiffness = 1500.0f; + VRGripInterfaceSettings.ConstraintDamping = 200.0f; + VRGripInterfaceSettings.ConstraintBreakDistance = 100.0f; + VRGripInterfaceSettings.SecondarySlotRange = 20.0f; + VRGripInterfaceSettings.PrimarySlotRange = 20.0f; + + VRGripInterfaceSettings.bIsHeld = false; + + // Default replication on for multiplayer + //this->bNetLoadOnClient = false; + SetReplicatingMovement(true); + bReplicates = true; + + bRepGripSettingsAndGameplayTags = true; + bReplicateGripScripts = false; + + // #TODO we can register them maybe in the future + // Don't use the replicated list, use our custom replication instead + bReplicateUsingRegisteredSubObjectList = false; + + bAllowIgnoringAttachOnOwner = true; + + // Setting a minimum of every 3rd frame (VR 90fps) for replication consideration + // Otherwise we will get some massive slow downs if the replication is allowed to hit the 2 per second minimum default + MinNetUpdateFrequency = 30.0f; +} + +void AGrippableSkeletalMeshActor::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty >& OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableSkeletalMeshActor, bReplicateGripScripts, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableSkeletalMeshActor, bRepGripSettingsAndGameplayTags, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableSkeletalMeshActor, bAllowIgnoringAttachOnOwner, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableSkeletalMeshActor, ClientAuthReplicationData, PushModelParams); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableSkeletalMeshActor, GripLogicScripts, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableSkeletalMeshActor, VRGripInterfaceSettings, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableSkeletalMeshActor, GameplayTags, PushModelParamsWithCondition); + + DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, AttachmentReplication); + + FDoRepLifetimeParams AttachmentReplicationParams{ COND_Custom, REPNOTIFY_Always, /*bIsPushBased=*/true }; + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableSkeletalMeshActor, AttachmentWeldReplication, AttachmentReplicationParams); +} + +void AGrippableSkeletalMeshActor::PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) +{ + // Don't replicate if set to not do it + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AGrippableSkeletalMeshActor, VRGripInterfaceSettings, bRepGripSettingsAndGameplayTags); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AGrippableSkeletalMeshActor, GameplayTags, bRepGripSettingsAndGameplayTags); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AGrippableSkeletalMeshActor, GripLogicScripts, bReplicateGripScripts); + + //Super::PreReplication(ChangedPropertyTracker); + +#if WITH_PUSH_MODEL + const AActor* const OldAttachParent = AttachmentWeldReplication.AttachParent; + const UActorComponent* const OldAttachComponent = AttachmentWeldReplication.AttachComponent; +#endif + + // Attachment replication gets filled in by GatherCurrentMovement(), but in the case of a detached root we need to trigger remote detachment. + AttachmentWeldReplication.AttachParent = nullptr; + AttachmentWeldReplication.AttachComponent = nullptr; + + GatherCurrentMovement(); + + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AActor, ReplicatedMovement, IsReplicatingMovement()); + + // Don't need to replicate AttachmentReplication if the root component replicates, because it already handles it. + DOREPLIFETIME_ACTIVE_OVERRIDE(AGrippableSkeletalMeshActor, AttachmentWeldReplication, RootComponent && !RootComponent->GetIsReplicated()); + + // Don't need to replicate AttachmentReplication if the root component replicates, because it already handles it. + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AActor, AttachmentReplication, false);// RootComponent && !RootComponent->GetIsReplicated()); + + +#if WITH_PUSH_MODEL + if (UNLIKELY(OldAttachParent != AttachmentWeldReplication.AttachParent || OldAttachComponent != AttachmentWeldReplication.AttachComponent)) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, AttachmentWeldReplication, this); + } +#endif + + /*PRAGMA_DISABLE_DEPRECATION_WARNINGS + UBlueprintGeneratedClass* BPClass = Cast(GetClass()); + if (BPClass != nullptr) + { + BPClass->InstancePreReplication(this, ChangedPropertyTracker); + } + PRAGMA_ENABLE_DEPRECATION_WARNINGS*/ +} + +void AGrippableSkeletalMeshActor::GatherCurrentMovement() +{ + if (IsReplicatingMovement() || (RootComponent && RootComponent->GetAttachParent())) + { + bool bWasAttachmentModified = false; + bool bWasRepMovementModified = false; + + AActor* OldAttachParent = AttachmentWeldReplication.AttachParent; + USceneComponent* OldAttachComponent = AttachmentWeldReplication.AttachComponent; + + AttachmentWeldReplication.AttachParent = nullptr; + AttachmentWeldReplication.AttachComponent = nullptr; + + FRepMovement& RepMovement = GetReplicatedMovement_Mutable(); + + UPrimitiveComponent* RootPrimComp = Cast(GetRootComponent()); + if (RootPrimComp && RootPrimComp->IsSimulatingPhysics()) + { +#if UE_WITH_IRIS + const bool bPrevRepPhysics = GetReplicatedMovement_Mutable().bRepPhysics; +#endif // UE_WITH_IRIS + + bool bFoundInCache = false; + + UWorld* World = GetWorld(); + int ServerFrame = 0; + if (FPhysScene_Chaos* Scene = static_cast(World->GetPhysicsScene())) + { + if (const FRigidBodyState* FoundState = Scene->GetStateFromReplicationCache(RootPrimComp, ServerFrame)) + { + RepMovement.FillFrom(*FoundState, this, Scene->ReplicationCache.ServerFrame); + bFoundInCache = true; + } + } + + if (!bFoundInCache) + { + // fallback to GT data + FRigidBodyState RBState; + RootPrimComp->GetRigidBodyState(RBState); + RepMovement.FillFrom(RBState, this, 0); + } + + // Don't replicate movement if we're welded to another parent actor. + // Their replication will affect our position indirectly since we are attached. + RepMovement.bRepPhysics = !RootPrimComp->IsWelded(); + + if (!RepMovement.bRepPhysics) + { + if (RootComponent->GetAttachParent() != nullptr) + { + // Networking for attachments assumes the RootComponent of the AttachParent actor. + // If that's not the case, we can't update this, as the client wouldn't be able to resolve the Component and would detach as a result. + AttachmentWeldReplication.AttachParent = RootComponent->GetAttachParent()->GetAttachmentRootActor(); + if (AttachmentWeldReplication.AttachParent != nullptr) + { + AttachmentWeldReplication.LocationOffset = RootComponent->GetRelativeLocation(); + AttachmentWeldReplication.RotationOffset = RootComponent->GetRelativeRotation(); + AttachmentWeldReplication.RelativeScale3D = RootComponent->GetRelativeScale3D(); + AttachmentWeldReplication.AttachComponent = RootComponent->GetAttachParent(); + AttachmentWeldReplication.AttachSocket = RootComponent->GetAttachSocketName(); + AttachmentWeldReplication.bIsWelded = RootPrimComp ? RootPrimComp->IsWelded() : false; + + // Technically, the values might have stayed the same, but we'll just assume they've changed. + bWasAttachmentModified = true; + +#if UE_WITH_IRIS + // If RepPhysics has changed value then notify the ReplicationSystem + if (bPrevRepPhysics != GetReplicatedMovement_Mutable().bRepPhysics) + { + UpdateReplicatePhysicsCondition(); + } +#endif // UE_WITH_IRIS + } + } + } + + // Technically, the values might have stayed the same, but we'll just assume they've changed. + bWasRepMovementModified = true; + } + else if (RootComponent != nullptr) + { + // If we are attached, don't replicate absolute position, use AttachmentReplication instead. + if (RootComponent->GetAttachParent() != nullptr) + { + // Networking for attachments assumes the RootComponent of the AttachParent actor. + // If that's not the case, we can't update this, as the client wouldn't be able to resolve the Component and would detach as a result. + AttachmentWeldReplication.AttachParent = RootComponent->GetAttachParentActor(); + if (AttachmentWeldReplication.AttachParent != nullptr) + { + AttachmentWeldReplication.LocationOffset = RootComponent->GetRelativeLocation(); + AttachmentWeldReplication.RotationOffset = RootComponent->GetRelativeRotation(); + AttachmentWeldReplication.RelativeScale3D = RootComponent->GetRelativeScale3D(); + AttachmentWeldReplication.AttachComponent = RootComponent->GetAttachParent(); + AttachmentWeldReplication.AttachSocket = RootComponent->GetAttachSocketName(); + AttachmentWeldReplication.bIsWelded = RootPrimComp ? RootPrimComp->IsWelded() : false; + + // Technically, the values might have stayed the same, but we'll just assume they've changed. + bWasAttachmentModified = true; + } + } + else + { + RepMovement.Location = FRepMovement::RebaseOntoZeroOrigin(RootComponent->GetComponentLocation(), this); + RepMovement.Rotation = RootComponent->GetComponentRotation(); + RepMovement.LinearVelocity = GetVelocity(); + RepMovement.AngularVelocity = FVector::ZeroVector; + + // Technically, the values might have stayed the same, but we'll just assume they've changed. + bWasRepMovementModified = true; + } + + bWasRepMovementModified = (bWasRepMovementModified || RepMovement.bRepPhysics); + RepMovement.bRepPhysics = false; + } +#if WITH_PUSH_MODEL + if (bWasRepMovementModified) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AActor, ReplicatedMovement, this); + } + + if (bWasAttachmentModified || + OldAttachParent != AttachmentWeldReplication.AttachParent || + OldAttachComponent != AttachmentWeldReplication.AttachComponent) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, AttachmentWeldReplication, this); + } +#endif + } +} + +bool AGrippableSkeletalMeshActor::ReplicateSubobjects(UActorChannel* Channel, class FOutBunch* Bunch, FReplicationFlags* RepFlags) +{ + bool WroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags); + + if (bReplicateGripScripts) + { + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script && IsValid(Script)) + { + WroteSomething |= Channel->ReplicateSubobject(Script, *Bunch, *RepFlags); + } + } + } + + return WroteSomething; +} + +/*void AGrippableSkeletalMeshActor::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + DOREPLIFETIME(AGrippableSkeletalMeshActor, VRGripInterfaceSettings); +}*/ + +//============================================================================= +AGrippableSkeletalMeshActor::~AGrippableSkeletalMeshActor() +{ +} + +void AGrippableSkeletalMeshActor::BeginPlay() +{ + // Call the base class + Super::BeginPlay(); + + // Call all grip scripts begin play events so they can perform any needed logic + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script) + { + Script->BeginPlay(this); + } + } +} + +void AGrippableSkeletalMeshActor::SetDenyGripping(bool bDenyGripping) +{ + VRGripInterfaceSettings.bDenyGripping = bDenyGripping; +} + +void AGrippableSkeletalMeshActor::SetGripPriority(int NewGripPriority) +{ + VRGripInterfaceSettings.AdvancedGripSettings.GripPriority = NewGripPriority; +} + +void AGrippableSkeletalMeshActor::TickGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation, float DeltaTime) {} +void AGrippableSkeletalMeshActor::OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) { } +void AGrippableSkeletalMeshActor::OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) { } +void AGrippableSkeletalMeshActor::OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) {} +void AGrippableSkeletalMeshActor::OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) {} +void AGrippableSkeletalMeshActor::OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripAdded.Broadcast(GripOwningController, GripInformation); } +void AGrippableSkeletalMeshActor::OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripRemoved.Broadcast(GripOwningController, GripInformation); } +void AGrippableSkeletalMeshActor::OnUsed_Implementation() {} +void AGrippableSkeletalMeshActor::OnEndUsed_Implementation() {} +void AGrippableSkeletalMeshActor::OnSecondaryUsed_Implementation() {} +void AGrippableSkeletalMeshActor::OnEndSecondaryUsed_Implementation() {} +void AGrippableSkeletalMeshActor::OnInput_Implementation(FKey Key, EInputEvent KeyEvent) {} +bool AGrippableSkeletalMeshActor::RequestsSocketing_Implementation(USceneComponent*& ParentToSocketTo, FName& OptionalSocketName, FTransform_NetQuantize& RelativeTransform) { return false; } + +bool AGrippableSkeletalMeshActor::DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator) +{ + return VRGripInterfaceSettings.bDenyGripping; +} + + +EGripInterfaceTeleportBehavior AGrippableSkeletalMeshActor::TeleportBehavior_Implementation() +{ + return VRGripInterfaceSettings.OnTeleportBehavior; +} + +bool AGrippableSkeletalMeshActor::SimulateOnDrop_Implementation() +{ + return VRGripInterfaceSettings.bSimulateOnDrop; +} + +EGripCollisionType AGrippableSkeletalMeshActor::GetPrimaryGripType_Implementation(bool bIsSlot) +{ + return bIsSlot ? VRGripInterfaceSettings.SlotDefaultGripType : VRGripInterfaceSettings.FreeDefaultGripType; +} + +ESecondaryGripType AGrippableSkeletalMeshActor::SecondaryGripType_Implementation() +{ + return VRGripInterfaceSettings.SecondaryGripType; +} + +EGripMovementReplicationSettings AGrippableSkeletalMeshActor::GripMovementReplicationType_Implementation() +{ + return VRGripInterfaceSettings.MovementReplicationType; +} + +EGripLateUpdateSettings AGrippableSkeletalMeshActor::GripLateUpdateSetting_Implementation() +{ + return VRGripInterfaceSettings.LateUpdateSetting; +} + +void AGrippableSkeletalMeshActor::GetGripStiffnessAndDamping_Implementation(float& GripStiffnessOut, float& GripDampingOut) +{ + GripStiffnessOut = VRGripInterfaceSettings.ConstraintStiffness; + GripDampingOut = VRGripInterfaceSettings.ConstraintDamping; +} + +FBPAdvGripSettings AGrippableSkeletalMeshActor::AdvancedGripSettings_Implementation() +{ + return VRGripInterfaceSettings.AdvancedGripSettings; +} + +float AGrippableSkeletalMeshActor::GripBreakDistance_Implementation() +{ + return VRGripInterfaceSettings.ConstraintBreakDistance; +} + +void AGrippableSkeletalMeshActor::ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool& bHadSlotInRange, FTransform& SlotWorldTransform, FName& SlotName, UGripMotionControllerComponent* CallingController, FName OverridePrefix) +{ + if (OverridePrefix.IsNone()) + bSecondarySlot ? OverridePrefix = "VRGripS" : OverridePrefix = "VRGripP"; + + UVRExpansionFunctionLibrary::GetGripSlotInRangeByTypeName(OverridePrefix, this, WorldLocation, bSecondarySlot ? VRGripInterfaceSettings.SecondarySlotRange : VRGripInterfaceSettings.PrimarySlotRange, bHadSlotInRange, SlotWorldTransform, SlotName, CallingController); +} + +bool AGrippableSkeletalMeshActor::AllowsMultipleGrips_Implementation() +{ + return VRGripInterfaceSettings.bAllowMultipleGrips; +} + +void AGrippableSkeletalMeshActor::IsHeld_Implementation(TArray& HoldingControllers, bool& bIsHeld) +{ + HoldingControllers = VRGripInterfaceSettings.HoldingControllers; + bIsHeld = VRGripInterfaceSettings.bIsHeld; +} + +bool AGrippableSkeletalMeshActor::AddToClientReplicationBucket() +{ + if (ShouldWeSkipAttachmentReplication(false)) + { + // The subsystem automatically removes entries with the same function signature so its safe to just always add here + GetWorld()->GetSubsystem()->AddObjectToBucket(ClientAuthReplicationData.UpdateRate, this, FName(TEXT("PollReplicationEvent"))); + ClientAuthReplicationData.bIsCurrentlyClientAuth = true; + + if (UWorld* World = GetWorld()) + ClientAuthReplicationData.TimeAtInitialThrow = World->GetTimeSeconds(); + + return true; + } + + return false; +} + +bool AGrippableSkeletalMeshActor::RemoveFromClientReplicationBucket() +{ + if (ClientAuthReplicationData.bIsCurrentlyClientAuth) + { + GetWorld()->GetSubsystem()->RemoveObjectFromBucketByFunctionName(this, FName(TEXT("PollReplicationEvent"))); + CeaseReplicationBlocking(); + return true; + } + + return false; +} + +void AGrippableSkeletalMeshActor::Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed) +{ + if (bGripped) + { + OnGripped.Broadcast(Controller, GripInformation); + } + else + { + OnDropped.Broadcast(Controller, GripInformation, bWasSocketed); + } +} + +void AGrippableSkeletalMeshActor::SetHeld_Implementation(UGripMotionControllerComponent* HoldingController, uint8 GripID, bool bIsHeld) +{ + if (bIsHeld) + { + VRGripInterfaceSettings.HoldingControllers.AddUnique(FBPGripPair(HoldingController, GripID)); + RemoveFromClientReplicationBucket(); + + VRGripInterfaceSettings.bWasHeld = true; + VRGripInterfaceSettings.bIsHeld = VRGripInterfaceSettings.HoldingControllers.Num() > 0; + } + else + { + VRGripInterfaceSettings.HoldingControllers.Remove(FBPGripPair(HoldingController, GripID)); + VRGripInterfaceSettings.bIsHeld = VRGripInterfaceSettings.HoldingControllers.Num() > 0; + + if (ClientAuthReplicationData.bUseClientAuthThrowing && !VRGripInterfaceSettings.bIsHeld) + { + bool bWasLocallyOwned = HoldingController ? HoldingController->IsLocallyControlled() : false; + if (bWasLocallyOwned && ShouldWeSkipAttachmentReplication(false)) + { + if (UPrimitiveComponent* PrimComp = Cast(GetRootComponent())) + { + if (PrimComp->IsSimulatingPhysics()) + { + AddToClientReplicationBucket(); + } + } + } + } + } +} + +/*FBPInteractionSettings AGrippableSkeletalMeshActor::GetInteractionSettings_Implementation() +{ + return VRGripInterfaceSettings.InteractionSettings; +}*/ + +bool AGrippableSkeletalMeshActor::GetGripScripts_Implementation(TArray& ArrayReference) +{ + ArrayReference = GripLogicScripts; + return GripLogicScripts.Num() > 0; +} + +bool AGrippableSkeletalMeshActor::PollReplicationEvent() +{ + if (!ClientAuthReplicationData.bIsCurrentlyClientAuth || !this->HasLocalNetOwner() || VRGripInterfaceSettings.bIsHeld) + return false; // Tell the bucket subsystem to remove us from consideration + + UWorld* OurWorld = GetWorld(); + if (!OurWorld) + return false; // Tell the bucket subsystem to remove us from consideration + + bool bRemoveBlocking = false; + + if ((OurWorld->GetTimeSeconds() - ClientAuthReplicationData.TimeAtInitialThrow) > 10.0f) + { + // Lets time out sending, its been 10 seconds since we threw the object and its likely that it is conflicting with some server + // Authed movement that is forcing it to keep momentum. + //return false; // Tell the bucket subsystem to remove us from consideration + bRemoveBlocking = true; + } + + // Store current transform for resting check + FTransform CurTransform = this->GetActorTransform(); + + if (!bRemoveBlocking) + { + if (!CurTransform.GetRotation().Equals(ClientAuthReplicationData.LastActorTransform.GetRotation()) || !CurTransform.GetLocation().Equals(ClientAuthReplicationData.LastActorTransform.GetLocation())) + { + ClientAuthReplicationData.LastActorTransform = CurTransform; + + if (UPrimitiveComponent* PrimComp = Cast(RootComponent)) + { + // Need to clamp to a max time since start, to handle cases with conflicting collisions + if (PrimComp->IsSimulatingPhysics() && ShouldWeSkipAttachmentReplication(false)) + { + FRepMovementVR ClientAuthMovementRep; + if (ClientAuthMovementRep.GatherActorsMovement(this)) + { + Server_GetClientAuthReplication(ClientAuthMovementRep); + + if (PrimComp->RigidBodyIsAwake()) + { + return true; + } + } + } + } + else + { + bRemoveBlocking = true; + //return false; // Tell the bucket subsystem to remove us from consideration + } + } + //else + // { + // Difference is too small, lets end sending location + //ClientAuthReplicationData.LastActorTransform = FTransform::Identity; + // } + } + + bool TimedBlockingRelease = false; + + AActor* TopOwner = GetOwner(); + if (TopOwner != nullptr) + { + AActor* tempOwner = TopOwner->GetOwner(); + + // I have an owner so search that for the top owner + while (tempOwner) + { + TopOwner = tempOwner; + tempOwner = TopOwner->GetOwner(); + } + + if (APlayerController* PlayerController = Cast(TopOwner)) + { + if (APlayerState* PlayerState = PlayerController->PlayerState) + { + if (ClientAuthReplicationData.ResetReplicationHandle.IsValid()) + { + OurWorld->GetTimerManager().ClearTimer(ClientAuthReplicationData.ResetReplicationHandle); + } + + // Lets clamp the ping to a min / max value just in case + float clampedPing = FMath::Clamp(PlayerState->ExactPing * 0.001f, 0.0f, 1000.0f); + OurWorld->GetTimerManager().SetTimer(ClientAuthReplicationData.ResetReplicationHandle, this, &AGrippableSkeletalMeshActor::CeaseReplicationBlocking, clampedPing, false); + TimedBlockingRelease = true; + } + } + } + + if (!TimedBlockingRelease) + { + CeaseReplicationBlocking(); + } + + // Tell server to kill us + Server_EndClientAuthReplication(); + return false; // Tell the bucket subsystem to remove us from consideration +} + +void AGrippableSkeletalMeshActor::CeaseReplicationBlocking() +{ + if (ClientAuthReplicationData.bIsCurrentlyClientAuth) + ClientAuthReplicationData.bIsCurrentlyClientAuth = false; + + ClientAuthReplicationData.LastActorTransform = FTransform::Identity; + + if (ClientAuthReplicationData.ResetReplicationHandle.IsValid()) + { + if (UWorld* OurWorld = GetWorld()) + { + OurWorld->GetTimerManager().ClearTimer(ClientAuthReplicationData.ResetReplicationHandle); + } + } +} + +void AGrippableSkeletalMeshActor::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + RemoveFromClientReplicationBucket(); + + // Call all grip scripts begin play events so they can perform any needed logic + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script) + { + Script->EndPlay(EndPlayReason); + } + } + + Super::EndPlay(EndPlayReason); +} + +bool AGrippableSkeletalMeshActor::Server_EndClientAuthReplication_Validate() +{ + return true; +} + +void AGrippableSkeletalMeshActor::Server_EndClientAuthReplication_Implementation() +{ + if (UWorld* World = GetWorld()) + { + if (FPhysScene* PhysScene = World->GetPhysicsScene()) + { + if (IPhysicsReplication* PhysicsReplication = PhysScene->GetPhysicsReplication()) + { + PhysicsReplication->RemoveReplicatedTarget(this->GetSkeletalMeshComponent()); + } + } + } +} + +bool AGrippableSkeletalMeshActor::Server_GetClientAuthReplication_Validate(const FRepMovementVR& newMovement) +{ + return true; +} + +void AGrippableSkeletalMeshActor::Server_GetClientAuthReplication_Implementation(const FRepMovementVR& newMovement) +{ + if (!VRGripInterfaceSettings.bIsHeld) + { + if (!newMovement.Location.ContainsNaN() && !newMovement.Rotation.ContainsNaN()) + { + FRepMovement& MovementRep = GetReplicatedMovement_Mutable(); + newMovement.CopyTo(MovementRep); + OnRep_ReplicatedMovement(); + } + } +} + +bool AGrippableSkeletalMeshActor::ShouldWeSkipAttachmentReplication(bool bConsiderHeld) const +{ + if ((bConsiderHeld && !VRGripInterfaceSettings.bWasHeld) || GetNetMode() < ENetMode::NM_Client) + return false; + + if (VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive || + VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep) + { + // First return if we are locally held (owner may not have replicated yet) + for (const FBPGripPair& Grip : VRGripInterfaceSettings.HoldingControllers) + { + if (IsValid(Grip.HoldingController) && Grip.HoldingController->IsLocallyControlled()) + { + return true; + } + } + + // then return if we have a local net owner + return HasLocalNetOwner(); + } + else + return false; +} + +void AGrippableSkeletalMeshActor::OnRep_AttachmentReplication() +{ + if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) + //if (bAllowIgnoringAttachOnOwner && ShouldWeSkipAttachmentReplication()) + { + return; + } + + if (AttachmentWeldReplication.AttachParent) + { + if (RootComponent) + { + USceneComponent* AttachParentComponent = (AttachmentWeldReplication.AttachComponent ? ToRawPtr(AttachmentWeldReplication.AttachComponent) : AttachmentWeldReplication.AttachParent->GetRootComponent()); + + if (AttachParentComponent) + { + RootComponent->SetRelativeLocation_Direct(AttachmentWeldReplication.LocationOffset); + RootComponent->SetRelativeRotation_Direct(AttachmentWeldReplication.RotationOffset); + RootComponent->SetRelativeScale3D_Direct(AttachmentWeldReplication.RelativeScale3D); + + // If we're already attached to the correct Parent and Socket, then the update must be position only. + // AttachToComponent would early out in this case. + // Note, we ignore the special case for simulated bodies in AttachToComponent as AttachmentReplication shouldn't get updated + // if the body is simulated (see AActor::GatherMovement). + const bool bAlreadyAttached = (AttachParentComponent == RootComponent->GetAttachParent() && AttachmentWeldReplication.AttachSocket == RootComponent->GetAttachSocketName() && AttachParentComponent->GetAttachChildren().Contains(RootComponent)); + if (bAlreadyAttached) + { + // Note, this doesn't match AttachToComponent, but we're assuming it's safe to skip physics (see comment above). + RootComponent->UpdateComponentToWorld(EUpdateTransformFlags::SkipPhysicsUpdate, ETeleportType::None); + } + else + { + FAttachmentTransformRules attachRules = FAttachmentTransformRules::KeepRelativeTransform; + attachRules.bWeldSimulatedBodies = AttachmentWeldReplication.bIsWelded; + RootComponent->AttachToComponent(AttachParentComponent, attachRules, AttachmentWeldReplication.AttachSocket); + } + } + } + } + else + { + DetachFromActor(FDetachmentTransformRules::KeepWorldTransform); + + // Handle the case where an object was both detached and moved on the server in the same frame. + // Calling this extraneously does not hurt but will properly fire events if the movement state changed while attached. + // This is needed because client side movement is ignored when attached + if (IsReplicatingMovement()) + { + OnRep_ReplicatedMovement(); + } + } +} + +void AGrippableSkeletalMeshActor::OnRep_ReplicateMovement() +{ + if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) + //if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) + { + return; + } + + if (RootComponent) + { + const FRepAttachment ReplicationAttachment = GetAttachmentReplication(); + if (!ReplicationAttachment.AttachParent) + { + const FRepMovement& RepMove = GetReplicatedMovement(); + + // This "fix" corrects the simulation state not replicating over correctly + // If you turn off movement replication, simulate an object, turn movement replication back on and un-simulate, it never knows the difference + // This change ensures that it is checking against the current state + if (RootComponent->IsSimulatingPhysics() != RepMove.bRepPhysics)//SavedbRepPhysics != ReplicatedMovement.bRepPhysics) + { + // Turn on/off physics sim to match server. + SyncReplicatedPhysicsSimulation(); + + // It doesn't really hurt to run it here, the super can call it again but it will fail out as they already match + } + } + } + + Super::OnRep_ReplicateMovement(); +} + +void AGrippableSkeletalMeshActor::OnRep_ReplicatedMovement() +{ + if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) + //if (ClientAuthReplicationData.bIsCurrentlyClientAuth && ShouldWeSkipAttachmentReplication(false)) + { + return; + } + + Super::OnRep_ReplicatedMovement(); +} + +void AGrippableSkeletalMeshActor::PostNetReceivePhysicState() +{ + if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) + //if ((ClientAuthReplicationData.bIsCurrentlyClientAuth || VRGripInterfaceSettings.bIsHeld) && bAllowIgnoringAttachOnOwner && ShouldWeSkipAttachmentReplication(false)) + { + return; + } + + Super::PostNetReceivePhysicState(); +} + +void AGrippableSkeletalMeshActor::MarkComponentsAsGarbage(bool bModify) +{ + Super::MarkComponentsAsGarbage(bModify); + + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject* SubObject = GripLogicScripts[i]) + { + SubObject->MarkAsGarbage(); + } + } + + GripLogicScripts.Empty(); +} + +void AGrippableSkeletalMeshActor::PreDestroyFromReplication() +{ + Super::PreDestroyFromReplication(); + + // Destroy any sub-objects we created + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject* SubObject = GripLogicScripts[i]) + { + OnSubobjectDestroyFromReplication(SubObject); //-V595 + SubObject->PreDestroyFromReplication(); + SubObject->MarkAsGarbage(); + } + } + + for (UActorComponent* ActorComp : GetComponents()) + { + // Pending kill components should have already had this called as they were network spawned and are being killed + if (ActorComp && IsValid(ActorComp) && ActorComp->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + ActorComp->PreDestroyFromReplication(); + } + + GripLogicScripts.Empty(); +} + +void AGrippableSkeletalMeshActor::BeginDestroy() +{ + Super::BeginDestroy(); + + for (int32 i = 0; i < GripLogicScripts.Num(); i++) + { + if (UObject* SubObject = GripLogicScripts[i]) + { + SubObject->MarkAsGarbage(); + } + } + + GripLogicScripts.Empty(); +} + +void AGrippableSkeletalMeshActor::GetSubobjectsWithStableNamesForNetworking(TArray& ObjList) +{ + Super::GetSubobjectsWithStableNamesForNetworking(ObjList); + + if (bReplicateGripScripts) + { + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject* SubObject = GripLogicScripts[i]) + { + ObjList.Add(SubObject); + } + } + } +} + +///////////////////////////////////////////////// +//- Push networking getter / setter functions +///////////////////////////////////////////////// + +void AGrippableSkeletalMeshActor::SetReplicateGripScripts(bool bNewReplicateGripScripts) +{ + bReplicateGripScripts = bNewReplicateGripScripts; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, bReplicateGripScripts, this); +#endif +} + +TArray>& AGrippableSkeletalMeshActor::GetGripLogicScripts() +{ +#if WITH_PUSH_MODEL + if (bReplicateGripScripts) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, GripLogicScripts, this); + } +#endif + + return GripLogicScripts; +} + +void AGrippableSkeletalMeshActor::SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags) +{ + bRepGripSettingsAndGameplayTags = bNewRepGripSettingsAndGameplayTags; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, bRepGripSettingsAndGameplayTags, this); +#endif +} + +void AGrippableSkeletalMeshActor::SetAllowIgnoringAttachOnOwner(bool bNewAllowIgnoringAttachOnOwner) +{ + bAllowIgnoringAttachOnOwner = bNewAllowIgnoringAttachOnOwner; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, bAllowIgnoringAttachOnOwner, this); +#endif +} + +FVRClientAuthReplicationData& AGrippableSkeletalMeshActor::GetClientAuthReplicationData(FVRClientAuthReplicationData& ClientAuthData) +{ +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, ClientAuthReplicationData, this); +#endif + return ClientAuthReplicationData; +} + +FBPInterfaceProperties& AGrippableSkeletalMeshActor::GetVRGripInterfaceSettings(bool bMarkDirty) +{ +#if WITH_PUSH_MODEL + if (bMarkDirty && bRepGripSettingsAndGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, VRGripInterfaceSettings, this); + } +#endif + + return VRGripInterfaceSettings; +} + +FGameplayTagContainer& AGrippableSkeletalMeshActor::GetGameplayTags() +{ +#if WITH_PUSH_MODEL + if (bRepGripSettingsAndGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, GameplayTags, this); + } +#endif + + return GameplayTags; +} + +///////////////////////////////////////////////// +//- End Push networking getter / setter functions +///////////////////////////////////////////////// \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableSkeletalMeshComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableSkeletalMeshComponent.cpp new file mode 100644 index 0000000..4059705 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableSkeletalMeshComponent.cpp @@ -0,0 +1,470 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Grippables/GrippableSkeletalMeshComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GrippableSkeletalMeshComponent) + +#include "GripMotionControllerComponent.h" +#include "VRExpansionFunctionLibrary.h" +#include "GripScripts/VRGripScriptBase.h" +#include "PhysicsEngine/PhysicsAsset.h" // Tmp until epic bug fixes skeletal welding +#include "Net/UnrealNetwork.h" +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + + //============================================================================= +UGrippableSkeletalMeshComponent::UGrippableSkeletalMeshComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + VRGripInterfaceSettings.bDenyGripping = false; + VRGripInterfaceSettings.OnTeleportBehavior = EGripInterfaceTeleportBehavior::DropOnTeleport; + VRGripInterfaceSettings.bSimulateOnDrop = true; + VRGripInterfaceSettings.SlotDefaultGripType = EGripCollisionType::ManipulationGrip; + VRGripInterfaceSettings.FreeDefaultGripType = EGripCollisionType::ManipulationGrip; + VRGripInterfaceSettings.SecondaryGripType = ESecondaryGripType::SG_None; + VRGripInterfaceSettings.MovementReplicationType = EGripMovementReplicationSettings::ForceClientSideMovement; + VRGripInterfaceSettings.LateUpdateSetting = EGripLateUpdateSettings::LateUpdatesAlwaysOff; + VRGripInterfaceSettings.ConstraintStiffness = 1500.0f; + VRGripInterfaceSettings.ConstraintDamping = 200.0f; + VRGripInterfaceSettings.ConstraintBreakDistance = 100.0f; + VRGripInterfaceSettings.SecondarySlotRange = 20.0f; + VRGripInterfaceSettings.PrimarySlotRange = 20.0f; + + VRGripInterfaceSettings.bIsHeld = false; + + bReplicateMovement = false; + //this->bReplicates = true; + + bRepGripSettingsAndGameplayTags = true; + bReplicateGripScripts = false; + + // #TODO we can register them maybe in the future + // Don't use the replicated list, use our custom replication instead + bReplicateUsingRegisteredSubObjectList = false; +} + +void UGrippableSkeletalMeshComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSkeletalMeshComponent, bReplicateGripScripts, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSkeletalMeshComponent, bRepGripSettingsAndGameplayTags, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSkeletalMeshComponent, bReplicateMovement, PushModelParams); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSkeletalMeshComponent, GripLogicScripts, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSkeletalMeshComponent, VRGripInterfaceSettings, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSkeletalMeshComponent, GameplayTags, PushModelParamsWithCondition); +} + +void UGrippableSkeletalMeshComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) +{ + Super::PreReplication(ChangedPropertyTracker); + + // Don't replicate if set to not do it + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UGrippableSkeletalMeshComponent, VRGripInterfaceSettings, bRepGripSettingsAndGameplayTags); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UGrippableSkeletalMeshComponent, GameplayTags, bRepGripSettingsAndGameplayTags); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UGrippableSkeletalMeshComponent, GripLogicScripts, bReplicateGripScripts); + + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeLocation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeRotation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeScale3D, bReplicateMovement); +} + +bool UGrippableSkeletalMeshComponent::ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) +{ + bool WroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags); + + if (bReplicateGripScripts && !IsUsingRegisteredSubObjectList()) + { + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script && IsValid(Script)) + { + WroteSomething |= Channel->ReplicateSubobject(Script, *Bunch, *RepFlags); + } + } + } + + return WroteSomething; +} + +//============================================================================= +UGrippableSkeletalMeshComponent::~UGrippableSkeletalMeshComponent() +{ +} + +void UGrippableSkeletalMeshComponent::BeginPlay() +{ + // Call the base class + Super::BeginPlay(); + + // Call all grip scripts begin play events so they can perform any needed logic + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script) + { + Script->BeginPlay(this); + } + } + + bOriginalReplicatesMovement = bReplicateMovement; +} + +void UGrippableSkeletalMeshComponent::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + // Call the base class + Super::EndPlay(EndPlayReason); + + // Call all grip scripts begin play events so they can perform any needed logic + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script) + { + Script->EndPlay(EndPlayReason); + } + } +} + +void UGrippableSkeletalMeshComponent::SetDenyGripping(bool bDenyGripping) +{ + VRGripInterfaceSettings.bDenyGripping = bDenyGripping; +} + +void UGrippableSkeletalMeshComponent::SetGripPriority(int NewGripPriority) +{ + VRGripInterfaceSettings.AdvancedGripSettings.GripPriority = NewGripPriority; +} + +void UGrippableSkeletalMeshComponent::TickGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation, float DeltaTime) {} +void UGrippableSkeletalMeshComponent::OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) { } +void UGrippableSkeletalMeshComponent::OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) { } +void UGrippableSkeletalMeshComponent::OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) {} +void UGrippableSkeletalMeshComponent::OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) {} +void UGrippableSkeletalMeshComponent::OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripAdded.Broadcast(GripOwningController, GripInformation); } +void UGrippableSkeletalMeshComponent::OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripRemoved.Broadcast(GripOwningController, GripInformation); } +void UGrippableSkeletalMeshComponent::OnUsed_Implementation() {} +void UGrippableSkeletalMeshComponent::OnEndUsed_Implementation() {} +void UGrippableSkeletalMeshComponent::OnSecondaryUsed_Implementation() {} +void UGrippableSkeletalMeshComponent::OnEndSecondaryUsed_Implementation() {} +void UGrippableSkeletalMeshComponent::OnInput_Implementation(FKey Key, EInputEvent KeyEvent) {} +bool UGrippableSkeletalMeshComponent::RequestsSocketing_Implementation(USceneComponent *& ParentToSocketTo, FName & OptionalSocketName, FTransform_NetQuantize & RelativeTransform) { return false; } + +bool UGrippableSkeletalMeshComponent::DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator) +{ + return VRGripInterfaceSettings.bDenyGripping; +} + +EGripInterfaceTeleportBehavior UGrippableSkeletalMeshComponent::TeleportBehavior_Implementation() +{ + return VRGripInterfaceSettings.OnTeleportBehavior; +} + +bool UGrippableSkeletalMeshComponent::SimulateOnDrop_Implementation() +{ + return VRGripInterfaceSettings.bSimulateOnDrop; +} + +EGripCollisionType UGrippableSkeletalMeshComponent::GetPrimaryGripType_Implementation(bool bIsSlot) +{ + return bIsSlot ? VRGripInterfaceSettings.SlotDefaultGripType : VRGripInterfaceSettings.FreeDefaultGripType; +} + +ESecondaryGripType UGrippableSkeletalMeshComponent::SecondaryGripType_Implementation() +{ + return VRGripInterfaceSettings.SecondaryGripType; +} + +EGripMovementReplicationSettings UGrippableSkeletalMeshComponent::GripMovementReplicationType_Implementation() +{ + return VRGripInterfaceSettings.MovementReplicationType; +} + +EGripLateUpdateSettings UGrippableSkeletalMeshComponent::GripLateUpdateSetting_Implementation() +{ + return VRGripInterfaceSettings.LateUpdateSetting; +} + +void UGrippableSkeletalMeshComponent::GetGripStiffnessAndDamping_Implementation(float &GripStiffnessOut, float &GripDampingOut) +{ + GripStiffnessOut = VRGripInterfaceSettings.ConstraintStiffness; + GripDampingOut = VRGripInterfaceSettings.ConstraintDamping; +} + +FBPAdvGripSettings UGrippableSkeletalMeshComponent::AdvancedGripSettings_Implementation() +{ + return VRGripInterfaceSettings.AdvancedGripSettings; +} + +float UGrippableSkeletalMeshComponent::GripBreakDistance_Implementation() +{ + return VRGripInterfaceSettings.ConstraintBreakDistance; +} + +void UGrippableSkeletalMeshComponent::ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool & bHadSlotInRange, FTransform & SlotWorldTransform, FName & SlotName, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ + if (OverridePrefix.IsNone()) + bSecondarySlot ? OverridePrefix = "VRGripS" : OverridePrefix = "VRGripP"; + + UVRExpansionFunctionLibrary::GetGripSlotInRangeByTypeName_Component(OverridePrefix, this, WorldLocation, bSecondarySlot ? VRGripInterfaceSettings.SecondarySlotRange : VRGripInterfaceSettings.PrimarySlotRange, bHadSlotInRange, SlotWorldTransform, SlotName, CallingController); +} + +bool UGrippableSkeletalMeshComponent::AllowsMultipleGrips_Implementation() +{ + return VRGripInterfaceSettings.bAllowMultipleGrips; +} + +void UGrippableSkeletalMeshComponent::IsHeld_Implementation(TArray & HoldingControllers, bool & bIsHeld) +{ + HoldingControllers = VRGripInterfaceSettings.HoldingControllers; + bIsHeld = VRGripInterfaceSettings.bIsHeld; +} + +void UGrippableSkeletalMeshComponent::Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed) +{ + if (bGripped) + { + OnGripped.Broadcast(Controller, GripInformation); + } + else + { + OnDropped.Broadcast(Controller, GripInformation, bWasSocketed); + } +} + +void UGrippableSkeletalMeshComponent::SetHeld_Implementation(UGripMotionControllerComponent * HoldingController, uint8 GripID, bool bIsHeld) +{ + if (bIsHeld) + { + if (VRGripInterfaceSettings.MovementReplicationType != EGripMovementReplicationSettings::ForceServerSideMovement) + { + if (!VRGripInterfaceSettings.bIsHeld) + bOriginalReplicatesMovement = bReplicateMovement; + bReplicateMovement = false; + } + + VRGripInterfaceSettings.bWasHeld = true; + VRGripInterfaceSettings.HoldingControllers.AddUnique(FBPGripPair(HoldingController, GripID)); + } + else + { + if (VRGripInterfaceSettings.MovementReplicationType != EGripMovementReplicationSettings::ForceServerSideMovement) + { + bReplicateMovement = bOriginalReplicatesMovement; + } + + VRGripInterfaceSettings.HoldingControllers.Remove(FBPGripPair(HoldingController, GripID)); + } + + VRGripInterfaceSettings.bIsHeld = VRGripInterfaceSettings.HoldingControllers.Num() > 0; +} + +/*FBPInteractionSettings UGrippableSkeletalMeshComponent::GetInteractionSettings_Implementation() +{ + return VRGripInterfaceSettings.InteractionSettings; +}*/ + +bool UGrippableSkeletalMeshComponent::GetGripScripts_Implementation(TArray & ArrayReference) +{ + ArrayReference = GripLogicScripts; + return GripLogicScripts.Num() > 0; +} + +void UGrippableSkeletalMeshComponent::PreDestroyFromReplication() +{ + Super::PreDestroyFromReplication(); + + // Destroy any sub-objects we created + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject *SubObject = GripLogicScripts[i]) + { + SubObject->PreDestroyFromReplication(); + SubObject->MarkAsGarbage(); + } + } + + GripLogicScripts.Empty(); +} + +void UGrippableSkeletalMeshComponent::GetSubobjectsWithStableNamesForNetworking(TArray &ObjList) +{ + if (bReplicateGripScripts) + { + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject* SubObject = GripLogicScripts[i]) + { + ObjList.Add(SubObject); + } + } + } +} + +void UGrippableSkeletalMeshComponent::OnComponentDestroyed(bool bDestroyingHierarchy) +{ + // Call the super at the end, after we've done what we needed to do + Super::OnComponentDestroyed(bDestroyingHierarchy); + + // Don't set these in editor preview window and the like, it causes saving issues + if (UWorld * World = GetWorld()) + { + EWorldType::Type WorldType = World->WorldType; + if (WorldType == EWorldType::Editor || WorldType == EWorldType::EditorPreview) + { + return; + } + } + + for (int32 i = 0; i < GripLogicScripts.Num(); i++) + { + if (UObject *SubObject = GripLogicScripts[i]) + { + SubObject->MarkAsGarbage(); + } + } + + GripLogicScripts.Empty(); +} + +void UGrippableSkeletalMeshComponent::GetWeldedBodies(TArray& OutWeldedBodies, TArray& OutLabels, bool bIncludingAutoWeld) +{ + UPhysicsAsset* PhysicsAsset = GetPhysicsAsset(); + + for (int32 BodyIdx = 0; BodyIdx < Bodies.Num(); ++BodyIdx) + { + FBodyInstance* BI = Bodies[BodyIdx]; + if (BI && (BI->WeldParent != nullptr || (bIncludingAutoWeld && BI->bAutoWeld))) + { + OutWeldedBodies.Add(BI); + if (PhysicsAsset) + { + if (UBodySetup* PhysicsAssetBodySetup = PhysicsAsset->SkeletalBodySetups[BodyIdx]) + { + OutLabels.Add(PhysicsAssetBodySetup->BoneName); + } + else + { + OutLabels.Add(NAME_None); + } + } + else + { + OutLabels.Add(NAME_None); + } + + } + } + + for (USceneComponent* Child : GetAttachChildren()) + { + if (UPrimitiveComponent* PrimChild = Cast(Child)) + { + PrimChild->GetWeldedBodies(OutWeldedBodies, OutLabels, bIncludingAutoWeld); + } + } +} + +FBodyInstance* UGrippableSkeletalMeshComponent::GetBodyInstance(FName BoneName, bool bGetWelded, int32) const +{ + UPhysicsAsset* const PhysicsAsset = GetPhysicsAsset(); + FBodyInstance* BodyInst = NULL; + + if (PhysicsAsset != NULL) + { + // A name of NAME_None indicates 'root body' + if (BoneName == NAME_None) + { + if (Bodies.IsValidIndex(RootBodyData.BodyIndex)) + { + BodyInst = Bodies[RootBodyData.BodyIndex]; + } + } + // otherwise, look for the body + else + { + int32 BodyIndex = PhysicsAsset->FindBodyIndex(BoneName); + if (Bodies.IsValidIndex(BodyIndex)) + { + BodyInst = Bodies[BodyIndex]; + } + } + + BodyInst = (bGetWelded && BodyInstance.WeldParent) ? BodyInstance.WeldParent : BodyInst; + } + + return BodyInst; +} + +///////////////////////////////////////////////// +//- Push networking getter / setter functions +///////////////////////////////////////////////// + +void UGrippableSkeletalMeshComponent::SetReplicateGripScripts(bool bNewReplicateGripScripts) +{ + bReplicateGripScripts = bNewReplicateGripScripts; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSkeletalMeshComponent, bReplicateGripScripts, this); +#endif +} + +TArray>& UGrippableSkeletalMeshComponent::GetGripLogicScripts() +{ +#if WITH_PUSH_MODEL + if (bReplicateGripScripts) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSkeletalMeshComponent, GripLogicScripts, this); + } +#endif + + return GripLogicScripts; +} + +void UGrippableSkeletalMeshComponent::SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags) +{ + bRepGripSettingsAndGameplayTags = bNewRepGripSettingsAndGameplayTags; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSkeletalMeshComponent, bRepGripSettingsAndGameplayTags, this); +#endif +} + +void UGrippableSkeletalMeshComponent::SetReplicateMovement(bool bNewReplicateMovement) +{ + bReplicateMovement = bNewReplicateMovement; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSkeletalMeshComponent, bReplicateMovement, this); +#endif +} + +FBPInterfaceProperties& UGrippableSkeletalMeshComponent::GetVRGripInterfaceSettings(bool bMarkDirty) +{ +#if WITH_PUSH_MODEL + if (bMarkDirty && bRepGripSettingsAndGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSkeletalMeshComponent, VRGripInterfaceSettings, this); + } +#endif + + return VRGripInterfaceSettings; +} + +FGameplayTagContainer& UGrippableSkeletalMeshComponent::GetGameplayTags() +{ +#if WITH_PUSH_MODEL + if (bRepGripSettingsAndGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSkeletalMeshComponent, GameplayTags, this); + } +#endif + + return GameplayTags; +} + +///////////////////////////////////////////////// +//- End Push networking getter / setter functions +///////////////////////////////////////////////// \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableSphereComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableSphereComponent.cpp new file mode 100644 index 0000000..6fca280 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableSphereComponent.cpp @@ -0,0 +1,403 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Grippables/GrippableSphereComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GrippableSphereComponent) + +#include "GripMotionControllerComponent.h" +#include "VRExpansionFunctionLibrary.h" +#include "GripScripts/VRGripScriptBase.h" +#include "Net/UnrealNetwork.h" + +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + + + //============================================================================= +UGrippableSphereComponent::UGrippableSphereComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + VRGripInterfaceSettings.bDenyGripping = false; + VRGripInterfaceSettings.OnTeleportBehavior = EGripInterfaceTeleportBehavior::DropOnTeleport; + VRGripInterfaceSettings.bSimulateOnDrop = true; + VRGripInterfaceSettings.SlotDefaultGripType = EGripCollisionType::ManipulationGrip; + VRGripInterfaceSettings.FreeDefaultGripType = EGripCollisionType::ManipulationGrip; + VRGripInterfaceSettings.SecondaryGripType = ESecondaryGripType::SG_None; + VRGripInterfaceSettings.MovementReplicationType = EGripMovementReplicationSettings::ForceClientSideMovement; + VRGripInterfaceSettings.LateUpdateSetting = EGripLateUpdateSettings::LateUpdatesAlwaysOff; + VRGripInterfaceSettings.ConstraintStiffness = 1500.0f; + VRGripInterfaceSettings.ConstraintDamping = 200.0f; + VRGripInterfaceSettings.ConstraintBreakDistance = 100.0f; + VRGripInterfaceSettings.SecondarySlotRange = 20.0f; + VRGripInterfaceSettings.PrimarySlotRange = 20.0f; + + bReplicateMovement = false; + //this->bReplicates = true; + + VRGripInterfaceSettings.bIsHeld = false; + bRepGripSettingsAndGameplayTags = true; + bReplicateGripScripts = false; + + // #TODO we can register them maybe in the future + // Don't use the replicated list, use our custom replication instead + bReplicateUsingRegisteredSubObjectList = false; +} + +void UGrippableSphereComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSphereComponent, bReplicateGripScripts, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSphereComponent, bRepGripSettingsAndGameplayTags, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSphereComponent, bReplicateMovement, PushModelParams); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSphereComponent, GripLogicScripts, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSphereComponent, VRGripInterfaceSettings, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSphereComponent, GameplayTags, PushModelParamsWithCondition); +} + +void UGrippableSphereComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) +{ + Super::PreReplication(ChangedPropertyTracker); + + // Don't replicate if set to not do it + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UGrippableSphereComponent, VRGripInterfaceSettings, bRepGripSettingsAndGameplayTags); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UGrippableSphereComponent, GameplayTags, bRepGripSettingsAndGameplayTags); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UGrippableSphereComponent, GripLogicScripts, bReplicateGripScripts); + + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeLocation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeRotation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeScale3D, bReplicateMovement); +} + +bool UGrippableSphereComponent::ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) +{ + bool WroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags); + + if (bReplicateGripScripts && !IsUsingRegisteredSubObjectList()) + { + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script && IsValid(Script)) + { + WroteSomething |= Channel->ReplicateSubobject(Script, *Bunch, *RepFlags); + } + } + } + + return WroteSomething; +} + +//============================================================================= +UGrippableSphereComponent::~UGrippableSphereComponent() +{ +} + +void UGrippableSphereComponent::BeginPlay() +{ + // Call the base class + Super::BeginPlay(); + + // Call all grip scripts begin play events so they can perform any needed logic + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script) + { + Script->BeginPlay(this); + } + } + + bOriginalReplicatesMovement = bReplicateMovement; +} + +void UGrippableSphereComponent::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + // Call the base class + Super::EndPlay(EndPlayReason); + + // Call all grip scripts begin play events so they can perform any needed logic + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script) + { + Script->EndPlay(EndPlayReason); + } + } +} + +void UGrippableSphereComponent::SetDenyGripping(bool bDenyGripping) +{ + VRGripInterfaceSettings.bDenyGripping = bDenyGripping; +} + +void UGrippableSphereComponent::SetGripPriority(int NewGripPriority) +{ + VRGripInterfaceSettings.AdvancedGripSettings.GripPriority = NewGripPriority; +} + +void UGrippableSphereComponent::TickGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation, float DeltaTime) {} +void UGrippableSphereComponent::OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) {} +void UGrippableSphereComponent::OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) { } +void UGrippableSphereComponent::OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) {} +void UGrippableSphereComponent::OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) {} +void UGrippableSphereComponent::OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripAdded.Broadcast(GripOwningController, GripInformation); } +void UGrippableSphereComponent::OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripRemoved.Broadcast(GripOwningController, GripInformation); } +void UGrippableSphereComponent::OnUsed_Implementation() {} +void UGrippableSphereComponent::OnEndUsed_Implementation() {} +void UGrippableSphereComponent::OnSecondaryUsed_Implementation() {} +void UGrippableSphereComponent::OnEndSecondaryUsed_Implementation() {} +void UGrippableSphereComponent::OnInput_Implementation(FKey Key, EInputEvent KeyEvent) {} +bool UGrippableSphereComponent::RequestsSocketing_Implementation(USceneComponent *& ParentToSocketTo, FName & OptionalSocketName, FTransform_NetQuantize & RelativeTransform) { return false; } + +bool UGrippableSphereComponent::DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator) +{ + return VRGripInterfaceSettings.bDenyGripping; +} + +EGripInterfaceTeleportBehavior UGrippableSphereComponent::TeleportBehavior_Implementation() +{ + return VRGripInterfaceSettings.OnTeleportBehavior; +} + +bool UGrippableSphereComponent::SimulateOnDrop_Implementation() +{ + return VRGripInterfaceSettings.bSimulateOnDrop; +} + +EGripCollisionType UGrippableSphereComponent::GetPrimaryGripType_Implementation(bool bIsSlot) +{ + return bIsSlot ? VRGripInterfaceSettings.SlotDefaultGripType : VRGripInterfaceSettings.FreeDefaultGripType; +} + +ESecondaryGripType UGrippableSphereComponent::SecondaryGripType_Implementation() +{ + return VRGripInterfaceSettings.SecondaryGripType; +} + +EGripMovementReplicationSettings UGrippableSphereComponent::GripMovementReplicationType_Implementation() +{ + return VRGripInterfaceSettings.MovementReplicationType; +} + +EGripLateUpdateSettings UGrippableSphereComponent::GripLateUpdateSetting_Implementation() +{ + return VRGripInterfaceSettings.LateUpdateSetting; +} + +void UGrippableSphereComponent::GetGripStiffnessAndDamping_Implementation(float &GripStiffnessOut, float &GripDampingOut) +{ + GripStiffnessOut = VRGripInterfaceSettings.ConstraintStiffness; + GripDampingOut = VRGripInterfaceSettings.ConstraintDamping; +} + +FBPAdvGripSettings UGrippableSphereComponent::AdvancedGripSettings_Implementation() +{ + return VRGripInterfaceSettings.AdvancedGripSettings; +} + +float UGrippableSphereComponent::GripBreakDistance_Implementation() +{ + return VRGripInterfaceSettings.ConstraintBreakDistance; +} + +void UGrippableSphereComponent::ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool & bHadSlotInRange, FTransform & SlotWorldTransform, FName & SlotName, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ + if (OverridePrefix.IsNone()) + bSecondarySlot ? OverridePrefix = "VRGripS" : OverridePrefix = "VRGripP"; + + UVRExpansionFunctionLibrary::GetGripSlotInRangeByTypeName_Component(OverridePrefix, this, WorldLocation, bSecondarySlot ? VRGripInterfaceSettings.SecondarySlotRange : VRGripInterfaceSettings.PrimarySlotRange, bHadSlotInRange, SlotWorldTransform, SlotName, CallingController); +} + +bool UGrippableSphereComponent::AllowsMultipleGrips_Implementation() +{ + return VRGripInterfaceSettings.bAllowMultipleGrips; +} + +void UGrippableSphereComponent::IsHeld_Implementation(TArray & HoldingControllers, bool & bIsHeld) +{ + HoldingControllers = VRGripInterfaceSettings.HoldingControllers; + bIsHeld = VRGripInterfaceSettings.bIsHeld; +} + +void UGrippableSphereComponent::Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed) +{ + if (bGripped) + { + OnGripped.Broadcast(Controller, GripInformation); + } + else + { + OnDropped.Broadcast(Controller, GripInformation, bWasSocketed); + } +} + +void UGrippableSphereComponent::SetHeld_Implementation(UGripMotionControllerComponent * HoldingController, uint8 GripID, bool bIsHeld) +{ + if (bIsHeld) + { + if (VRGripInterfaceSettings.MovementReplicationType != EGripMovementReplicationSettings::ForceServerSideMovement) + { + if (!VRGripInterfaceSettings.bIsHeld) + bOriginalReplicatesMovement = bReplicateMovement; + bReplicateMovement = false; + } + + VRGripInterfaceSettings.bWasHeld = true; + VRGripInterfaceSettings.HoldingControllers.AddUnique(FBPGripPair(HoldingController, GripID)); + } + else + { + if (VRGripInterfaceSettings.MovementReplicationType != EGripMovementReplicationSettings::ForceServerSideMovement) + { + bReplicateMovement = bOriginalReplicatesMovement; + } + + VRGripInterfaceSettings.HoldingControllers.Remove(FBPGripPair(HoldingController, GripID)); + } + + VRGripInterfaceSettings.bIsHeld = VRGripInterfaceSettings.HoldingControllers.Num() > 0; +} + +/*FBPInteractionSettings UGrippableSphereComponent::GetInteractionSettings_Implementation() +{ + return VRGripInterfaceSettings.InteractionSettings; +}*/ + + +bool UGrippableSphereComponent::GetGripScripts_Implementation(TArray & ArrayReference) +{ + ArrayReference = GripLogicScripts; + return GripLogicScripts.Num() > 0; +} + +void UGrippableSphereComponent::PreDestroyFromReplication() +{ + Super::PreDestroyFromReplication(); + + // Destroy any sub-objects we created + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject *SubObject = GripLogicScripts[i]) + { + SubObject->PreDestroyFromReplication(); + SubObject->MarkAsGarbage(); + } + } + + GripLogicScripts.Empty(); +} + +void UGrippableSphereComponent::GetSubobjectsWithStableNamesForNetworking(TArray &ObjList) +{ + if (bReplicateGripScripts) + { + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject* SubObject = GripLogicScripts[i]) + { + ObjList.Add(SubObject); + } + } + } +} + +void UGrippableSphereComponent::OnComponentDestroyed(bool bDestroyingHierarchy) +{ + // Call the super at the end, after we've done what we needed to do + Super::OnComponentDestroyed(bDestroyingHierarchy); + + // Don't set these in editor preview window and the like, it causes saving issues + if (UWorld * World = GetWorld()) + { + EWorldType::Type WorldType = World->WorldType; + if (WorldType == EWorldType::Editor || WorldType == EWorldType::EditorPreview) + { + return; + } + } + + for (int32 i = 0; i < GripLogicScripts.Num(); i++) + { + if (UObject *SubObject = GripLogicScripts[i]) + { + SubObject->MarkAsGarbage(); + } + } + + GripLogicScripts.Empty(); +} + + +///////////////////////////////////////////////// +//- Push networking getter / setter functions +///////////////////////////////////////////////// + +void UGrippableSphereComponent::SetReplicateGripScripts(bool bNewReplicateGripScripts) +{ + bReplicateGripScripts = bNewReplicateGripScripts; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSphereComponent, bReplicateGripScripts, this); +#endif +} + +TArray>& UGrippableSphereComponent::GetGripLogicScripts() +{ +#if WITH_PUSH_MODEL + if (bReplicateGripScripts) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSphereComponent, GripLogicScripts, this); + } +#endif + + return GripLogicScripts; +} + +void UGrippableSphereComponent::SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags) +{ + bRepGripSettingsAndGameplayTags = bNewRepGripSettingsAndGameplayTags; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSphereComponent, bRepGripSettingsAndGameplayTags, this); +#endif +} + +void UGrippableSphereComponent::SetReplicateMovement(bool bNewReplicateMovement) +{ + bReplicateMovement = bNewReplicateMovement; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSphereComponent, bReplicateMovement, this); +#endif +} + +FBPInterfaceProperties& UGrippableSphereComponent::GetVRGripInterfaceSettings(bool bMarkDirty) +{ +#if WITH_PUSH_MODEL + if (bMarkDirty && bRepGripSettingsAndGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSphereComponent, VRGripInterfaceSettings, this); + } +#endif + + return VRGripInterfaceSettings; +} + +FGameplayTagContainer& UGrippableSphereComponent::GetGameplayTags() +{ +#if WITH_PUSH_MODEL + if (bRepGripSettingsAndGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSphereComponent, GameplayTags, this); + } +#endif + + return GameplayTags; +} + +///////////////////////////////////////////////// +//- End Push networking getter / setter functions +///////////////////////////////////////////////// \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableStaticMeshActor.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableStaticMeshActor.cpp new file mode 100644 index 0000000..74dec5c --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableStaticMeshActor.cpp @@ -0,0 +1,974 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Grippables/GrippableStaticMeshActor.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GrippableStaticMeshActor) + +#include "TimerManager.h" +#include "GameFramework/PlayerController.h" +#include "GameFramework/PlayerState.h" +#include "GripMotionControllerComponent.h" +#include "VRExpansionFunctionLibrary.h" +#include "Misc/BucketUpdateSubsystem.h" +#include "Net/UnrealNetwork.h" +#include "PhysicsReplication.h" +#include "GripScripts/VRGripScriptBase.h" +#include "DrawDebugHelpers.h" +#include "Physics/Experimental/PhysScene_Chaos.h" + +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + +// #TODO: Pull request this? This macro could be very useful +/*#define DOREPLIFETIME_CHANGE_NOTIFY(c,v,rncond) \ +{ \ + static UProperty* sp##v = GetReplicatedProperty(StaticClass(), c::StaticClass(),GET_MEMBER_NAME_CHECKED(c,v)); \ + bool bFound = false; \ + for ( int32 i = 0; i < OutLifetimeProps.Num(); i++ ) \ + { \ + if ( OutLifetimeProps[i].RepIndex == sp##v->RepIndex ) \ + { \ + for ( int32 j = 0; j < sp##v->ArrayDim; j++ ) \ + { \ + OutLifetimeProps[i + j].RepNotifyCondition = rncond; \ + } \ + bFound = true; \ + break; \ + } \ + } \ + check( bFound ); \ +}*/ + + +UOptionalRepStaticMeshComponent::UOptionalRepStaticMeshComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + bReplicateMovement = true; +} + +void UOptionalRepStaticMeshComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) +{ + Super::PreReplication(ChangedPropertyTracker); + + // Don't replicate if set to not do it + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeLocation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeRotation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeScale3D, bReplicateMovement); + + +} + +void UOptionalRepStaticMeshComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + DOREPLIFETIME(UOptionalRepStaticMeshComponent, bReplicateMovement); +} + + //============================================================================= +AGrippableStaticMeshActor::AGrippableStaticMeshActor(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer.SetDefaultSubobjectClass(TEXT("StaticMeshComponent0"))) +{ + VRGripInterfaceSettings.bDenyGripping = false; + VRGripInterfaceSettings.OnTeleportBehavior = EGripInterfaceTeleportBehavior::TeleportAllComponents; + VRGripInterfaceSettings.bSimulateOnDrop = true; + VRGripInterfaceSettings.SlotDefaultGripType = EGripCollisionType::InteractiveCollisionWithPhysics; + VRGripInterfaceSettings.FreeDefaultGripType = EGripCollisionType::InteractiveCollisionWithPhysics; + VRGripInterfaceSettings.SecondaryGripType = ESecondaryGripType::SG_None; + VRGripInterfaceSettings.MovementReplicationType = EGripMovementReplicationSettings::ForceClientSideMovement; + VRGripInterfaceSettings.LateUpdateSetting = EGripLateUpdateSettings::NotWhenCollidingOrDoubleGripping; + VRGripInterfaceSettings.ConstraintStiffness = 1500.0f; + VRGripInterfaceSettings.ConstraintDamping = 200.0f; + VRGripInterfaceSettings.ConstraintBreakDistance = 100.0f; + VRGripInterfaceSettings.SecondarySlotRange = 20.0f; + VRGripInterfaceSettings.PrimarySlotRange = 20.0f; + + VRGripInterfaceSettings.bIsHeld = false; + + this->SetMobility(EComponentMobility::Movable); + + // Default replication on for multiplayer + //this->bNetLoadOnClient = false; + SetReplicatingMovement(true); + this->bReplicates = true; + + bRepGripSettingsAndGameplayTags = true; + bReplicateGripScripts = false; + + // #TODO we can register them maybe in the future + // Don't use the replicated list, use our custom replication instead + bReplicateUsingRegisteredSubObjectList = false; + + bAllowIgnoringAttachOnOwner = true; + + // Setting a minimum of every 3rd frame (VR 90fps) for replication consideration + // Otherwise we will get some massive slow downs if the replication is allowed to hit the 2 per second minimum default + MinNetUpdateFrequency = 30.0f; +} + +void AGrippableStaticMeshActor::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableStaticMeshActor, bReplicateGripScripts, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableStaticMeshActor, bRepGripSettingsAndGameplayTags, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableStaticMeshActor, bAllowIgnoringAttachOnOwner, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableStaticMeshActor, ClientAuthReplicationData, PushModelParams); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableStaticMeshActor, GripLogicScripts, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableStaticMeshActor, VRGripInterfaceSettings, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableStaticMeshActor, GameplayTags, PushModelParamsWithCondition); + + DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, AttachmentReplication); + + FDoRepLifetimeParams AttachmentReplicationParams{ COND_Custom, REPNOTIFY_Always, /*bIsPushBased=*/true }; + DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableStaticMeshActor, AttachmentWeldReplication, AttachmentReplicationParams); +} + +void AGrippableStaticMeshActor::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) +{ + //Super::PreReplication(ChangedPropertyTracker); + + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AGrippableStaticMeshActor, VRGripInterfaceSettings, bRepGripSettingsAndGameplayTags); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AGrippableStaticMeshActor, GameplayTags, bRepGripSettingsAndGameplayTags); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AGrippableStaticMeshActor, GripLogicScripts, bReplicateGripScripts); + + //Super::PreReplication(ChangedPropertyTracker); + +#if WITH_PUSH_MODEL + const AActor* const OldAttachParent = AttachmentWeldReplication.AttachParent; + const UActorComponent* const OldAttachComponent = AttachmentWeldReplication.AttachComponent; +#endif + + // Attachment replication gets filled in by GatherCurrentMovement(), but in the case of a detached root we need to trigger remote detachment. + AttachmentWeldReplication.AttachParent = nullptr; + AttachmentWeldReplication.AttachComponent = nullptr; + + GatherCurrentMovement(); + + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AActor, ReplicatedMovement, IsReplicatingMovement()); + + // Don't need to replicate AttachmentReplication if the root component replicates, because it already handles it. + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AGrippableStaticMeshActor, AttachmentWeldReplication, RootComponent && !RootComponent->GetIsReplicated()); + + // Don't need to replicate AttachmentReplication if the root component replicates, because it already handles it. + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AActor, AttachmentReplication, false);// RootComponent && !RootComponent->GetIsReplicated()); + + +#if WITH_PUSH_MODEL + if (UNLIKELY(OldAttachParent != AttachmentWeldReplication.AttachParent || OldAttachComponent != AttachmentWeldReplication.AttachComponent)) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, AttachmentWeldReplication, this); + } +#endif + + /*PRAGMA_DISABLE_DEPRECATION_WARNINGS + UBlueprintGeneratedClass* BPClass = Cast(GetClass()); + if (BPClass != nullptr) + { + BPClass->InstancePreReplication(this, ChangedPropertyTracker); + } + PRAGMA_ENABLE_DEPRECATION_WARNINGS*/ + +} + +void AGrippableStaticMeshActor::GatherCurrentMovement() +{ + if (IsReplicatingMovement() || (RootComponent && RootComponent->GetAttachParent())) + { + bool bWasAttachmentModified = false; + bool bWasRepMovementModified = false; + + AActor* OldAttachParent = AttachmentWeldReplication.AttachParent; + USceneComponent* OldAttachComponent = AttachmentWeldReplication.AttachComponent; + + AttachmentWeldReplication.AttachParent = nullptr; + AttachmentWeldReplication.AttachComponent = nullptr; + + FRepMovement& RepMovement = GetReplicatedMovement_Mutable(); + + UPrimitiveComponent* RootPrimComp = Cast(GetRootComponent()); + if (RootPrimComp && RootPrimComp->IsSimulatingPhysics()) + { +#if UE_WITH_IRIS + const bool bPrevRepPhysics = GetReplicatedMovement_Mutable().bRepPhysics; +#endif // UE_WITH_IRIS + + bool bFoundInCache = false; + + UWorld* World = GetWorld(); + int ServerFrame = 0; + if (FPhysScene_Chaos* Scene = static_cast(World->GetPhysicsScene())) + { + if (const FRigidBodyState* FoundState = Scene->GetStateFromReplicationCache(RootPrimComp, ServerFrame)) + { + RepMovement.FillFrom(*FoundState, this, Scene->ReplicationCache.ServerFrame); + bFoundInCache = true; + } + } + + if (!bFoundInCache) + { + // fallback to GT data + FRigidBodyState RBState; + RootPrimComp->GetRigidBodyState(RBState); + RepMovement.FillFrom(RBState, this, 0); + } + + // Don't replicate movement if we're welded to another parent actor. + // Their replication will affect our position indirectly since we are attached. + RepMovement.bRepPhysics = !RootPrimComp->IsWelded(); + + if (!RepMovement.bRepPhysics) + { + if (RootComponent->GetAttachParent() != nullptr) + { + // Networking for attachments assumes the RootComponent of the AttachParent actor. + // If that's not the case, we can't update this, as the client wouldn't be able to resolve the Component and would detach as a result. + AttachmentWeldReplication.AttachParent = RootComponent->GetAttachParent()->GetAttachmentRootActor(); + if (AttachmentWeldReplication.AttachParent != nullptr) + { + AttachmentWeldReplication.LocationOffset = RootComponent->GetRelativeLocation(); + AttachmentWeldReplication.RotationOffset = RootComponent->GetRelativeRotation(); + AttachmentWeldReplication.RelativeScale3D = RootComponent->GetRelativeScale3D(); + AttachmentWeldReplication.AttachComponent = RootComponent->GetAttachParent(); + AttachmentWeldReplication.AttachSocket = RootComponent->GetAttachSocketName(); + AttachmentWeldReplication.bIsWelded = RootPrimComp ? RootPrimComp->IsWelded() : false; + + // Technically, the values might have stayed the same, but we'll just assume they've changed. + bWasAttachmentModified = true; + } + } + } + + // Technically, the values might have stayed the same, but we'll just assume they've changed. + bWasRepMovementModified = true; + +#if UE_WITH_IRIS + // If RepPhysics has changed value then notify the ReplicationSystem + if (bPrevRepPhysics != GetReplicatedMovement_Mutable().bRepPhysics) + { + UpdateReplicatePhysicsCondition(); + } +#endif // UE_WITH_IRIS + } + else if (RootComponent != nullptr) + { + // If we are attached, don't replicate absolute position, use AttachmentReplication instead. + if (RootComponent->GetAttachParent() != nullptr) + { + // Networking for attachments assumes the RootComponent of the AttachParent actor. + // If that's not the case, we can't update this, as the client wouldn't be able to resolve the Component and would detach as a result. + AttachmentWeldReplication.AttachParent = RootComponent->GetAttachParentActor(); + if (AttachmentWeldReplication.AttachParent != nullptr) + { + AttachmentWeldReplication.LocationOffset = RootComponent->GetRelativeLocation(); + AttachmentWeldReplication.RotationOffset = RootComponent->GetRelativeRotation(); + AttachmentWeldReplication.RelativeScale3D = RootComponent->GetRelativeScale3D(); + AttachmentWeldReplication.AttachComponent = RootComponent->GetAttachParent(); + AttachmentWeldReplication.AttachSocket = RootComponent->GetAttachSocketName(); + AttachmentWeldReplication.bIsWelded = RootPrimComp ? RootPrimComp->IsWelded() : false; + + // Technically, the values might have stayed the same, but we'll just assume they've changed. + bWasAttachmentModified = true; + } + } + else + { + RepMovement.Location = FRepMovement::RebaseOntoZeroOrigin(RootComponent->GetComponentLocation(), this); + RepMovement.Rotation = RootComponent->GetComponentRotation(); + RepMovement.LinearVelocity = GetVelocity(); + RepMovement.AngularVelocity = FVector::ZeroVector; + + // Technically, the values might have stayed the same, but we'll just assume they've changed. + bWasRepMovementModified = true; + } + + bWasRepMovementModified = (bWasRepMovementModified || RepMovement.bRepPhysics); + RepMovement.bRepPhysics = false; + } +#if WITH_PUSH_MODEL + if (bWasRepMovementModified) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AActor, ReplicatedMovement, this); + } + + if (bWasAttachmentModified || + OldAttachParent != AttachmentWeldReplication.AttachParent || + OldAttachComponent != AttachmentWeldReplication.AttachComponent) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, AttachmentWeldReplication, this); + } +#endif + } +} + +bool AGrippableStaticMeshActor::ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) +{ + bool WroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags); + + if (bReplicateGripScripts && !IsUsingRegisteredSubObjectList()) + { + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script && IsValid(Script)) + { + WroteSomething |= Channel->ReplicateSubobject(Script, *Bunch, *RepFlags); + } + } + } + + return WroteSomething; +} + +//============================================================================= +AGrippableStaticMeshActor::~AGrippableStaticMeshActor() +{ +} + +void AGrippableStaticMeshActor::BeginPlay() +{ + // Call the base class + Super::BeginPlay(); + + // Call all grip scripts begin play events so they can perform any needed logic + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script) + { + Script->BeginPlay(this); + } + } +} + +void AGrippableStaticMeshActor::SetDenyGripping(bool bDenyGripping) +{ + VRGripInterfaceSettings.bDenyGripping = bDenyGripping; +} + +void AGrippableStaticMeshActor::SetGripPriority(int NewGripPriority) +{ + VRGripInterfaceSettings.AdvancedGripSettings.GripPriority = NewGripPriority; +} + +void AGrippableStaticMeshActor::TickGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation, float DeltaTime) {} +void AGrippableStaticMeshActor::OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) { } +void AGrippableStaticMeshActor::OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) { } +void AGrippableStaticMeshActor::OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) {} +void AGrippableStaticMeshActor::OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) {} +void AGrippableStaticMeshActor::OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripAdded.Broadcast(GripOwningController, GripInformation); } +void AGrippableStaticMeshActor::OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripRemoved.Broadcast(GripOwningController, GripInformation); } +void AGrippableStaticMeshActor::OnUsed_Implementation() {} +void AGrippableStaticMeshActor::OnEndUsed_Implementation() {} +void AGrippableStaticMeshActor::OnSecondaryUsed_Implementation() {} +void AGrippableStaticMeshActor::OnEndSecondaryUsed_Implementation() {} +void AGrippableStaticMeshActor::OnInput_Implementation(FKey Key, EInputEvent KeyEvent) {} +bool AGrippableStaticMeshActor::RequestsSocketing_Implementation(USceneComponent *& ParentToSocketTo, FName & OptionalSocketName, FTransform_NetQuantize & RelativeTransform) { return false; } + +bool AGrippableStaticMeshActor::DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator) +{ + return VRGripInterfaceSettings.bDenyGripping; +} + + +EGripInterfaceTeleportBehavior AGrippableStaticMeshActor::TeleportBehavior_Implementation() +{ + return VRGripInterfaceSettings.OnTeleportBehavior; +} + +bool AGrippableStaticMeshActor::SimulateOnDrop_Implementation() +{ + return VRGripInterfaceSettings.bSimulateOnDrop; +} + +EGripCollisionType AGrippableStaticMeshActor::GetPrimaryGripType_Implementation(bool bIsSlot) +{ + return bIsSlot ? VRGripInterfaceSettings.SlotDefaultGripType : VRGripInterfaceSettings.FreeDefaultGripType; +} + +ESecondaryGripType AGrippableStaticMeshActor::SecondaryGripType_Implementation() +{ + return VRGripInterfaceSettings.SecondaryGripType; +} + +EGripMovementReplicationSettings AGrippableStaticMeshActor::GripMovementReplicationType_Implementation() +{ + return VRGripInterfaceSettings.MovementReplicationType; +} + +EGripLateUpdateSettings AGrippableStaticMeshActor::GripLateUpdateSetting_Implementation() +{ + return VRGripInterfaceSettings.LateUpdateSetting; +} + +void AGrippableStaticMeshActor::GetGripStiffnessAndDamping_Implementation(float &GripStiffnessOut, float &GripDampingOut) +{ + GripStiffnessOut = VRGripInterfaceSettings.ConstraintStiffness; + GripDampingOut = VRGripInterfaceSettings.ConstraintDamping; +} + +FBPAdvGripSettings AGrippableStaticMeshActor::AdvancedGripSettings_Implementation() +{ + return VRGripInterfaceSettings.AdvancedGripSettings; +} + +float AGrippableStaticMeshActor::GripBreakDistance_Implementation() +{ + return VRGripInterfaceSettings.ConstraintBreakDistance; +} + +void AGrippableStaticMeshActor::ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool & bHadSlotInRange, FTransform & SlotWorldTransform, FName & SlotName, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ + if (OverridePrefix.IsNone()) + bSecondarySlot ? OverridePrefix = "VRGripS" : OverridePrefix = "VRGripP"; + + UVRExpansionFunctionLibrary::GetGripSlotInRangeByTypeName(OverridePrefix, this, WorldLocation, bSecondarySlot ? VRGripInterfaceSettings.SecondarySlotRange : VRGripInterfaceSettings.PrimarySlotRange, bHadSlotInRange, SlotWorldTransform, SlotName, CallingController); +} + +bool AGrippableStaticMeshActor::AllowsMultipleGrips_Implementation() +{ + return VRGripInterfaceSettings.bAllowMultipleGrips; +} + +void AGrippableStaticMeshActor::IsHeld_Implementation(TArray & HoldingControllers, bool & bIsHeld) +{ + HoldingControllers = VRGripInterfaceSettings.HoldingControllers; + bIsHeld = VRGripInterfaceSettings.bIsHeld; +} + +bool AGrippableStaticMeshActor::AddToClientReplicationBucket() +{ + if (ShouldWeSkipAttachmentReplication(false)) + { + // The subsystem automatically removes entries with the same function signature so its safe to just always add here + GetWorld()->GetSubsystem()->AddObjectToBucket(ClientAuthReplicationData.UpdateRate, this, FName(TEXT("PollReplicationEvent"))); + ClientAuthReplicationData.bIsCurrentlyClientAuth = true; + + if (UWorld * World = GetWorld()) + ClientAuthReplicationData.TimeAtInitialThrow = World->GetTimeSeconds(); + + return true; + } + + return false; +} + +bool AGrippableStaticMeshActor::RemoveFromClientReplicationBucket() +{ + if (ClientAuthReplicationData.bIsCurrentlyClientAuth) + { + GetWorld()->GetSubsystem()->RemoveObjectFromBucketByFunctionName(this, FName(TEXT("PollReplicationEvent"))); + CeaseReplicationBlocking(); + return true; + } + + return false; +} + +void AGrippableStaticMeshActor::Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed) +{ + if (bGripped) + { + OnGripped.Broadcast(Controller, GripInformation); + } + else + { + OnDropped.Broadcast(Controller, GripInformation, bWasSocketed); + } +} + +void AGrippableStaticMeshActor::SetHeld_Implementation(UGripMotionControllerComponent* HoldingController, uint8 GripID, bool bIsHeld) +{ + if (bIsHeld) + { + VRGripInterfaceSettings.HoldingControllers.AddUnique(FBPGripPair(HoldingController, GripID)); + RemoveFromClientReplicationBucket(); + + VRGripInterfaceSettings.bWasHeld = true; + VRGripInterfaceSettings.bIsHeld = VRGripInterfaceSettings.HoldingControllers.Num() > 0; + } + else + { + VRGripInterfaceSettings.HoldingControllers.Remove(FBPGripPair(HoldingController, GripID)); + VRGripInterfaceSettings.bIsHeld = VRGripInterfaceSettings.HoldingControllers.Num() > 0; + + if (ClientAuthReplicationData.bUseClientAuthThrowing && !VRGripInterfaceSettings.bIsHeld) + { + bool bWasLocallyOwned = HoldingController ? HoldingController->IsLocallyControlled() : false; + if (bWasLocallyOwned && ShouldWeSkipAttachmentReplication(false)) + { + if (UPrimitiveComponent* PrimComp = Cast(GetRootComponent())) + { + if (PrimComp->IsSimulatingPhysics()) + { + AddToClientReplicationBucket(); + } + } + } + } + } +} + +bool AGrippableStaticMeshActor::GetGripScripts_Implementation(TArray & ArrayReference) +{ + ArrayReference = GripLogicScripts; + return GripLogicScripts.Num() > 0; +} + +bool AGrippableStaticMeshActor::PollReplicationEvent() +{ + if (!ClientAuthReplicationData.bIsCurrentlyClientAuth || !this->HasLocalNetOwner() || VRGripInterfaceSettings.bIsHeld) + return false; // Tell the bucket subsystem to remove us from consideration + + UWorld *OurWorld = GetWorld(); + if (!OurWorld) + return false; // Tell the bucket subsystem to remove us from consideration + + bool bRemoveBlocking = false; + + if ((OurWorld->GetTimeSeconds() - ClientAuthReplicationData.TimeAtInitialThrow) > 10.0f) + { + // Lets time out sending, its been 10 seconds since we threw the object and its likely that it is conflicting with some server + // Authed movement that is forcing it to keep momentum. + //return false; // Tell the bucket subsystem to remove us from consideration + bRemoveBlocking = true; + } + + // Store current transform for resting check + FTransform CurTransform = this->GetActorTransform(); + + if (!bRemoveBlocking) + { + if (!CurTransform.GetRotation().Equals(ClientAuthReplicationData.LastActorTransform.GetRotation()) || !CurTransform.GetLocation().Equals(ClientAuthReplicationData.LastActorTransform.GetLocation())) + { + ClientAuthReplicationData.LastActorTransform = CurTransform; + + if (UPrimitiveComponent * PrimComp = Cast(RootComponent)) + { + // Need to clamp to a max time since start, to handle cases with conflicting collisions + if (PrimComp->IsSimulatingPhysics() && ShouldWeSkipAttachmentReplication(false)) + { + FRepMovementVR ClientAuthMovementRep; + if (ClientAuthMovementRep.GatherActorsMovement(this)) + { + Server_GetClientAuthReplication(ClientAuthMovementRep); + + if (PrimComp->RigidBodyIsAwake()) + { + return true; + } + } + } + } + else + { + bRemoveBlocking = true; + //return false; // Tell the bucket subsystem to remove us from consideration + } + } + //else + // { + // Difference is too small, lets end sending location + //ClientAuthReplicationData.LastActorTransform = FTransform::Identity; + // } + } + + bool TimedBlockingRelease = false; + + AActor* TopOwner = GetOwner(); + if (TopOwner != nullptr) + { + AActor * tempOwner = TopOwner->GetOwner(); + + // I have an owner so search that for the top owner + while (tempOwner) + { + TopOwner = tempOwner; + tempOwner = TopOwner->GetOwner(); + } + + if (APlayerController* PlayerController = Cast(TopOwner)) + { + if (APlayerState* PlayerState = PlayerController->PlayerState) + { + if (ClientAuthReplicationData.ResetReplicationHandle.IsValid()) + { + OurWorld->GetTimerManager().ClearTimer(ClientAuthReplicationData.ResetReplicationHandle); + } + + // Lets clamp the ping to a min / max value just in case + float clampedPing = FMath::Clamp(PlayerState->ExactPing * 0.001f, 0.0f, 1000.0f); + OurWorld->GetTimerManager().SetTimer(ClientAuthReplicationData.ResetReplicationHandle, this, &AGrippableStaticMeshActor::CeaseReplicationBlocking, clampedPing, false); + TimedBlockingRelease = true; + } + } + } + + if (!TimedBlockingRelease) + { + CeaseReplicationBlocking(); + } + + // Tell server to kill us + Server_EndClientAuthReplication(); + return false; // Tell the bucket subsystem to remove us from consideration +} + +void AGrippableStaticMeshActor::CeaseReplicationBlocking() +{ + if(ClientAuthReplicationData.bIsCurrentlyClientAuth) + ClientAuthReplicationData.bIsCurrentlyClientAuth = false; + + ClientAuthReplicationData.LastActorTransform = FTransform::Identity; + + if (ClientAuthReplicationData.ResetReplicationHandle.IsValid()) + { + if (UWorld * OurWorld = GetWorld()) + { + OurWorld->GetTimerManager().ClearTimer(ClientAuthReplicationData.ResetReplicationHandle); + } + } +} + +void AGrippableStaticMeshActor::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + RemoveFromClientReplicationBucket(); + + // Call all grip scripts begin play events so they can perform any needed logic + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script) + { + Script->EndPlay(EndPlayReason); + } + } + + Super::EndPlay(EndPlayReason); +} + +bool AGrippableStaticMeshActor::Server_EndClientAuthReplication_Validate() +{ + return true; +} + +void AGrippableStaticMeshActor::Server_EndClientAuthReplication_Implementation() +{ + if (UWorld* World = GetWorld()) + { + if (FPhysScene* PhysScene = World->GetPhysicsScene()) + { + if (IPhysicsReplication* PhysicsReplication = PhysScene->GetPhysicsReplication()) + { + PhysicsReplication->RemoveReplicatedTarget(this->GetStaticMeshComponent()); + } + } + } +} + +bool AGrippableStaticMeshActor::Server_GetClientAuthReplication_Validate(const FRepMovementVR & newMovement) +{ + return true; +} + +void AGrippableStaticMeshActor::Server_GetClientAuthReplication_Implementation(const FRepMovementVR & newMovement) +{ + if (!VRGripInterfaceSettings.bIsHeld) + { + if (!newMovement.Location.ContainsNaN() && !newMovement.Rotation.ContainsNaN()) + { + FRepMovement& MovementRep = GetReplicatedMovement_Mutable(); + newMovement.CopyTo(MovementRep); + OnRep_ReplicatedMovement(); + } + } +} + +bool AGrippableStaticMeshActor::ShouldWeSkipAttachmentReplication(bool bConsiderHeld) const +{ + if ((bConsiderHeld && !VRGripInterfaceSettings.bWasHeld) || GetNetMode() < ENetMode::NM_Client) + return false; + + if (VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive || + VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep) + { + // First return if we are locally held (owner may not have replicated yet) + for (const FBPGripPair& Grip : VRGripInterfaceSettings.HoldingControllers) + { + if (IsValid(Grip.HoldingController) && Grip.HoldingController->IsLocallyControlled()) + { + return true; + } + } + + // then return if we have a local net owner + return HasLocalNetOwner(); + } + else + return false; +} + +void AGrippableStaticMeshActor::OnRep_AttachmentReplication() +{ + if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) + //if (bAllowIgnoringAttachOnOwner && ShouldWeSkipAttachmentReplication()) + { + return; + } + + if (AttachmentWeldReplication.AttachParent) + { + if (RootComponent) + { + USceneComponent* AttachParentComponent = (AttachmentWeldReplication.AttachComponent ? ToRawPtr(AttachmentWeldReplication.AttachComponent) : AttachmentWeldReplication.AttachParent->GetRootComponent()); + + if (AttachParentComponent) + { + RootComponent->SetRelativeLocation_Direct(AttachmentWeldReplication.LocationOffset); + RootComponent->SetRelativeRotation_Direct(AttachmentWeldReplication.RotationOffset); + RootComponent->SetRelativeScale3D_Direct(AttachmentWeldReplication.RelativeScale3D); + + // If we're already attached to the correct Parent and Socket, then the update must be position only. + // AttachToComponent would early out in this case. + // Note, we ignore the special case for simulated bodies in AttachToComponent as AttachmentReplication shouldn't get updated + // if the body is simulated (see AActor::GatherMovement). + const bool bAlreadyAttached = (AttachParentComponent == RootComponent->GetAttachParent() && AttachmentWeldReplication.AttachSocket == RootComponent->GetAttachSocketName() && AttachParentComponent->GetAttachChildren().Contains(RootComponent)); + if (bAlreadyAttached) + { + // Note, this doesn't match AttachToComponent, but we're assuming it's safe to skip physics (see comment above). + RootComponent->UpdateComponentToWorld(EUpdateTransformFlags::SkipPhysicsUpdate, ETeleportType::None); + } + else + { + FAttachmentTransformRules attachRules = FAttachmentTransformRules::KeepRelativeTransform; + attachRules.bWeldSimulatedBodies = AttachmentWeldReplication.bIsWelded; + RootComponent->AttachToComponent(AttachParentComponent, attachRules, AttachmentWeldReplication.AttachSocket); + } + } + } + } + else + { + DetachFromActor(FDetachmentTransformRules::KeepWorldTransform); + + // Handle the case where an object was both detached and moved on the server in the same frame. + // Calling this extraneously does not hurt but will properly fire events if the movement state changed while attached. + // This is needed because client side movement is ignored when attached + if (IsReplicatingMovement()) + { + OnRep_ReplicatedMovement(); + } + } +} + +void AGrippableStaticMeshActor::OnRep_ReplicateMovement() +{ + if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) + //if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) + { + return; + } + + if (RootComponent) + { + const FRepAttachment ReplicationAttachment = GetAttachmentReplication(); + if (!ReplicationAttachment.AttachParent) + { + const FRepMovement& RepMove = GetReplicatedMovement(); + + // This "fix" corrects the simulation state not replicating over correctly + // If you turn off movement replication, simulate an object, turn movement replication back on and un-simulate, it never knows the difference + // This change ensures that it is checking against the current state + if (RootComponent->IsSimulatingPhysics() != RepMove.bRepPhysics)//SavedbRepPhysics != ReplicatedMovement.bRepPhysics) + { + // Turn on/off physics sim to match server. + SyncReplicatedPhysicsSimulation(); + + // It doesn't really hurt to run it here, the super can call it again but it will fail out as they already match + } + } + } + + Super::OnRep_ReplicateMovement(); +} + +void AGrippableStaticMeshActor::OnRep_ReplicatedMovement() +{ + if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) + //if (ClientAuthReplicationData.bIsCurrentlyClientAuth && ShouldWeSkipAttachmentReplication(false)) + { + return; + } + + if (VRGripInterfaceSettings.HoldingControllers.Num() > 0) + { + ShouldWeSkipAttachmentReplication(); + int gg = 0; + } + + Super::OnRep_ReplicatedMovement(); +} + +void AGrippableStaticMeshActor::PostNetReceivePhysicState() +{ + if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) + //if ((ClientAuthReplicationData.bIsCurrentlyClientAuth || VRGripInterfaceSettings.bIsHeld) && bAllowIgnoringAttachOnOwner && ShouldWeSkipAttachmentReplication(false)) + { + return; + } + + Super::PostNetReceivePhysicState(); +} + +void AGrippableStaticMeshActor::MarkComponentsAsGarbage(bool bModify) +{ + Super::MarkComponentsAsGarbage(bModify); + + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject *SubObject = GripLogicScripts[i]) + { + SubObject->MarkAsGarbage(); + } + } + + GripLogicScripts.Empty(); +} + +void AGrippableStaticMeshActor::PreDestroyFromReplication() +{ + Super::PreDestroyFromReplication(); + + // Destroy any sub-objects we created + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject *SubObject = GripLogicScripts[i]) + { + OnSubobjectDestroyFromReplication(SubObject); //-V595 + SubObject->PreDestroyFromReplication(); + SubObject->MarkAsGarbage(); + } + } + + for (UActorComponent * ActorComp : GetComponents()) + { + // Pending kill components should have already had this called as they were network spawned and are being killed + // We only call this on our interfaced components since they are the only ones that should implement grip scripts + if (ActorComp && IsValid(ActorComp) && ActorComp->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + ActorComp->PreDestroyFromReplication(); + } + + GripLogicScripts.Empty(); +} + +void AGrippableStaticMeshActor::BeginDestroy() +{ + Super::BeginDestroy(); + + for (int32 i = 0; i < GripLogicScripts.Num(); i++) + { + if (UObject *SubObject = GripLogicScripts[i]) + { + SubObject->MarkAsGarbage(); + } + } + + GripLogicScripts.Empty(); +} + +void AGrippableStaticMeshActor::GetSubobjectsWithStableNamesForNetworking(TArray& ObjList) +{ + Super::GetSubobjectsWithStableNamesForNetworking(ObjList); + + if (bReplicateGripScripts) + { + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject* SubObject = GripLogicScripts[i]) + { + ObjList.Add(SubObject); + } + } + } +} + +///////////////////////////////////////////////// +//- Push networking getter / setter functions +///////////////////////////////////////////////// + +void AGrippableStaticMeshActor::SetReplicateGripScripts(bool bNewReplicateGripScripts) +{ + bReplicateGripScripts = bNewReplicateGripScripts; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, bReplicateGripScripts, this); +#endif +} + +TArray>& AGrippableStaticMeshActor::GetGripLogicScripts() +{ +#if WITH_PUSH_MODEL + if (bReplicateGripScripts) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, GripLogicScripts, this); + } +#endif + + return GripLogicScripts; +} + +void AGrippableStaticMeshActor::SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags) +{ + bRepGripSettingsAndGameplayTags = bNewRepGripSettingsAndGameplayTags; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, bRepGripSettingsAndGameplayTags, this); +#endif +} + +void AGrippableStaticMeshActor::SetAllowIgnoringAttachOnOwner(bool bNewAllowIgnoringAttachOnOwner) +{ + bAllowIgnoringAttachOnOwner = bNewAllowIgnoringAttachOnOwner; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, bAllowIgnoringAttachOnOwner, this); +#endif +} + +FVRClientAuthReplicationData& AGrippableStaticMeshActor::GetClientAuthReplicationData(FVRClientAuthReplicationData& ClientAuthData) +{ +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, ClientAuthReplicationData, this); +#endif + return ClientAuthReplicationData; +} + +FBPInterfaceProperties& AGrippableStaticMeshActor::GetVRGripInterfaceSettings(bool bMarkDirty) +{ +#if WITH_PUSH_MODEL + if (bMarkDirty && bRepGripSettingsAndGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, VRGripInterfaceSettings, this); + } +#endif + + return VRGripInterfaceSettings; +} + +FGameplayTagContainer& AGrippableStaticMeshActor::GetGameplayTags() +{ +#if WITH_PUSH_MODEL + if (bRepGripSettingsAndGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, GameplayTags, this); + } +#endif + + return GameplayTags; +} + +///////////////////////////////////////////////// +//- End Push networking getter / setter functions +///////////////////////////////////////////////// \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableStaticMeshComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableStaticMeshComponent.cpp new file mode 100644 index 0000000..1f6b0bc --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/GrippableStaticMeshComponent.cpp @@ -0,0 +1,395 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Grippables/GrippableStaticMeshComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(GrippableStaticMeshComponent) + +#include "GripMotionControllerComponent.h" +#include "VRExpansionFunctionLibrary.h" +#include "GripScripts/VRGripScriptBase.h" +#include "Net/UnrealNetwork.h" +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + + //============================================================================= +UGrippableStaticMeshComponent::UGrippableStaticMeshComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + VRGripInterfaceSettings.bDenyGripping = false; + VRGripInterfaceSettings.OnTeleportBehavior = EGripInterfaceTeleportBehavior::DropOnTeleport; + VRGripInterfaceSettings.bSimulateOnDrop = true; + VRGripInterfaceSettings.SlotDefaultGripType = EGripCollisionType::ManipulationGrip; + VRGripInterfaceSettings.FreeDefaultGripType = EGripCollisionType::ManipulationGrip; + VRGripInterfaceSettings.SecondaryGripType = ESecondaryGripType::SG_None; + VRGripInterfaceSettings.MovementReplicationType = EGripMovementReplicationSettings::ForceClientSideMovement; + VRGripInterfaceSettings.LateUpdateSetting = EGripLateUpdateSettings::LateUpdatesAlwaysOff; + VRGripInterfaceSettings.ConstraintStiffness = 1500.0f; + VRGripInterfaceSettings.ConstraintDamping = 200.0f; + VRGripInterfaceSettings.ConstraintBreakDistance = 100.0f; + VRGripInterfaceSettings.SecondarySlotRange = 20.0f; + VRGripInterfaceSettings.PrimarySlotRange = 20.0f; + + VRGripInterfaceSettings.bIsHeld = false; + + bReplicateMovement = false; + //this->bReplicates = true; + + bRepGripSettingsAndGameplayTags = true; + bReplicateGripScripts = false; + + // #TODO we can register them maybe in the future + // Don't use the replicated list, use our custom replication instead + bReplicateUsingRegisteredSubObjectList = false; +} + +void UGrippableStaticMeshComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableStaticMeshComponent, bReplicateGripScripts, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableStaticMeshComponent, bRepGripSettingsAndGameplayTags, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableStaticMeshComponent, bReplicateMovement, PushModelParams); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableStaticMeshComponent, GripLogicScripts, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableStaticMeshComponent, VRGripInterfaceSettings, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableStaticMeshComponent, GameplayTags, PushModelParamsWithCondition); +} + +void UGrippableStaticMeshComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) +{ + Super::PreReplication(ChangedPropertyTracker); + + // Don't replicate if set to not do it + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UGrippableStaticMeshComponent, VRGripInterfaceSettings, bRepGripSettingsAndGameplayTags); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UGrippableStaticMeshComponent, GameplayTags, bRepGripSettingsAndGameplayTags); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UGrippableStaticMeshComponent, GripLogicScripts, bReplicateGripScripts); + + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeLocation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeRotation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeScale3D, bReplicateMovement); +} + +bool UGrippableStaticMeshComponent::ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) +{ + bool WroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags); + + if (bReplicateGripScripts && !IsUsingRegisteredSubObjectList()) + { + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script && IsValid(Script)) + { + WroteSomething |= Channel->ReplicateSubobject(Script, *Bunch, *RepFlags); + } + } + } + + return WroteSomething; +} + +//============================================================================= +UGrippableStaticMeshComponent::~UGrippableStaticMeshComponent() +{ +} + +void UGrippableStaticMeshComponent::BeginPlay() +{ + // Call the base class + Super::BeginPlay(); + + // Call all grip scripts begin play events so they can perform any needed logic + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script) + { + Script->BeginPlay(this); + } + } + + bOriginalReplicatesMovement = bReplicateMovement; +} + +void UGrippableStaticMeshComponent::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + // Call the base class + Super::EndPlay(EndPlayReason); + + // Call all grip scripts begin play events so they can perform any needed logic + for (UVRGripScriptBase* Script : GripLogicScripts) + { + if (Script) + { + Script->EndPlay(EndPlayReason); + } + } +} + +void UGrippableStaticMeshComponent::SetDenyGripping(bool bDenyGripping) +{ + VRGripInterfaceSettings.bDenyGripping = bDenyGripping; +} + +void UGrippableStaticMeshComponent::SetGripPriority(int NewGripPriority) +{ + VRGripInterfaceSettings.AdvancedGripSettings.GripPriority = NewGripPriority; +} + +void UGrippableStaticMeshComponent::TickGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation, float DeltaTime) {} +void UGrippableStaticMeshComponent::OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) { } +void UGrippableStaticMeshComponent::OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) { } +void UGrippableStaticMeshComponent::OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) {} +void UGrippableStaticMeshComponent::OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) {} +void UGrippableStaticMeshComponent::OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripAdded.Broadcast(GripOwningController, GripInformation); } +void UGrippableStaticMeshComponent::OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripRemoved.Broadcast(GripOwningController, GripInformation); } +void UGrippableStaticMeshComponent::OnUsed_Implementation() {} +void UGrippableStaticMeshComponent::OnEndUsed_Implementation() {} +void UGrippableStaticMeshComponent::OnSecondaryUsed_Implementation() {} +void UGrippableStaticMeshComponent::OnEndSecondaryUsed_Implementation() {} +void UGrippableStaticMeshComponent::OnInput_Implementation(FKey Key, EInputEvent KeyEvent) {} +bool UGrippableStaticMeshComponent::RequestsSocketing_Implementation(USceneComponent *& ParentToSocketTo, FName & OptionalSocketName, FTransform_NetQuantize & RelativeTransform) { return false; } + +bool UGrippableStaticMeshComponent::DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator) +{ + return VRGripInterfaceSettings.bDenyGripping; +} + +EGripInterfaceTeleportBehavior UGrippableStaticMeshComponent::TeleportBehavior_Implementation() +{ + return VRGripInterfaceSettings.OnTeleportBehavior; +} + +bool UGrippableStaticMeshComponent::SimulateOnDrop_Implementation() +{ + return VRGripInterfaceSettings.bSimulateOnDrop; +} + +EGripCollisionType UGrippableStaticMeshComponent::GetPrimaryGripType_Implementation(bool bIsSlot) +{ + return bIsSlot ? VRGripInterfaceSettings.SlotDefaultGripType : VRGripInterfaceSettings.FreeDefaultGripType; +} + +ESecondaryGripType UGrippableStaticMeshComponent::SecondaryGripType_Implementation() +{ + return VRGripInterfaceSettings.SecondaryGripType; +} + +EGripMovementReplicationSettings UGrippableStaticMeshComponent::GripMovementReplicationType_Implementation() +{ + return VRGripInterfaceSettings.MovementReplicationType; +} + +EGripLateUpdateSettings UGrippableStaticMeshComponent::GripLateUpdateSetting_Implementation() +{ + return VRGripInterfaceSettings.LateUpdateSetting; +} + +void UGrippableStaticMeshComponent::GetGripStiffnessAndDamping_Implementation(float &GripStiffnessOut, float &GripDampingOut) +{ + GripStiffnessOut = VRGripInterfaceSettings.ConstraintStiffness; + GripDampingOut = VRGripInterfaceSettings.ConstraintDamping; +} + +FBPAdvGripSettings UGrippableStaticMeshComponent::AdvancedGripSettings_Implementation() +{ + return VRGripInterfaceSettings.AdvancedGripSettings; +} + +float UGrippableStaticMeshComponent::GripBreakDistance_Implementation() +{ + return VRGripInterfaceSettings.ConstraintBreakDistance; +} + +void UGrippableStaticMeshComponent::ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool & bHadSlotInRange, FTransform & SlotWorldTransform, FName & SlotName, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ + if (OverridePrefix.IsNone()) + bSecondarySlot ? OverridePrefix = "VRGripS" : OverridePrefix = "VRGripP"; + + UVRExpansionFunctionLibrary::GetGripSlotInRangeByTypeName_Component(OverridePrefix, this, WorldLocation, bSecondarySlot ? VRGripInterfaceSettings.SecondarySlotRange : VRGripInterfaceSettings.PrimarySlotRange, bHadSlotInRange, SlotWorldTransform, SlotName, CallingController); +} + +bool UGrippableStaticMeshComponent::AllowsMultipleGrips_Implementation() +{ + return VRGripInterfaceSettings.bAllowMultipleGrips; +} + +void UGrippableStaticMeshComponent::IsHeld_Implementation(TArray & HoldingControllers, bool & bIsHeld) +{ + HoldingControllers = VRGripInterfaceSettings.HoldingControllers; + bIsHeld = VRGripInterfaceSettings.bIsHeld; +} + +void UGrippableStaticMeshComponent::Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed) +{ + if (bGripped) + { + OnGripped.Broadcast(Controller, GripInformation); + } + else + { + OnDropped.Broadcast(Controller, GripInformation, bWasSocketed); + } +} + +void UGrippableStaticMeshComponent::SetHeld_Implementation(UGripMotionControllerComponent * HoldingController, uint8 GripID, bool bIsHeld) +{ + if (bIsHeld) + { + if (VRGripInterfaceSettings.MovementReplicationType != EGripMovementReplicationSettings::ForceServerSideMovement) + { + if (!VRGripInterfaceSettings.bIsHeld) + bOriginalReplicatesMovement = bReplicateMovement; + bReplicateMovement = false; + } + + VRGripInterfaceSettings.bWasHeld = true; + VRGripInterfaceSettings.HoldingControllers.AddUnique(FBPGripPair(HoldingController, GripID)); + } + else + { + if (VRGripInterfaceSettings.MovementReplicationType != EGripMovementReplicationSettings::ForceServerSideMovement) + { + bReplicateMovement = bOriginalReplicatesMovement; + } + + VRGripInterfaceSettings.HoldingControllers.Remove(FBPGripPair(HoldingController, GripID)); + } + + VRGripInterfaceSettings.bIsHeld = VRGripInterfaceSettings.HoldingControllers.Num() > 0; +} + +bool UGrippableStaticMeshComponent::GetGripScripts_Implementation(TArray & ArrayReference) +{ + ArrayReference = GripLogicScripts; + return GripLogicScripts.Num() > 0; +} + +void UGrippableStaticMeshComponent::PreDestroyFromReplication() +{ + Super::PreDestroyFromReplication(); + + // Destroy any sub-objects we created + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject *SubObject = GripLogicScripts[i]) + { + SubObject->PreDestroyFromReplication(); + SubObject->MarkAsGarbage(); + } + } + + GripLogicScripts.Empty(); +} + +void UGrippableStaticMeshComponent::GetSubobjectsWithStableNamesForNetworking(TArray &ObjList) +{ + if (bReplicateGripScripts) + { + for (int32 i = 0; i < GripLogicScripts.Num(); ++i) + { + if (UObject* SubObject = GripLogicScripts[i]) + { + ObjList.Add(SubObject); + } + } + } +} + +void UGrippableStaticMeshComponent::OnComponentDestroyed(bool bDestroyingHierarchy) +{ + // Call the super at the end, after we've done what we needed to do + Super::OnComponentDestroyed(bDestroyingHierarchy); + + // Don't set these in editor preview window and the like, it causes saving issues + if (UWorld * World = GetWorld()) + { + EWorldType::Type WorldType = World->WorldType; + if (WorldType == EWorldType::Editor || WorldType == EWorldType::EditorPreview) + { + return; + } + } + + for (int32 i = 0; i < GripLogicScripts.Num(); i++) + { + if (UObject *SubObject = GripLogicScripts[i]) + { + SubObject->MarkAsGarbage(); + } + } + + GripLogicScripts.Empty(); +} + +///////////////////////////////////////////////// +//- Push networking getter / setter functions +///////////////////////////////////////////////// + +void UGrippableStaticMeshComponent::SetReplicateGripScripts(bool bNewReplicateGripScripts) +{ + bReplicateGripScripts = bNewReplicateGripScripts; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableStaticMeshComponent, bReplicateGripScripts, this); +#endif +} + +TArray>& UGrippableStaticMeshComponent::GetGripLogicScripts() +{ +#if WITH_PUSH_MODEL + if (bReplicateGripScripts) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableStaticMeshComponent, GripLogicScripts, this); + } +#endif + + return GripLogicScripts; +} + +void UGrippableStaticMeshComponent::SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags) +{ + bRepGripSettingsAndGameplayTags = bNewRepGripSettingsAndGameplayTags; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableStaticMeshComponent, bRepGripSettingsAndGameplayTags, this); +#endif +} + +void UGrippableStaticMeshComponent::SetReplicateMovement(bool bNewReplicateMovement) +{ + bReplicateMovement = bNewReplicateMovement; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableStaticMeshComponent, bReplicateMovement, this); +#endif +} + +FBPInterfaceProperties& UGrippableStaticMeshComponent::GetVRGripInterfaceSettings(bool bMarkDirty) +{ +#if WITH_PUSH_MODEL + if (bMarkDirty && bRepGripSettingsAndGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableStaticMeshComponent, VRGripInterfaceSettings, this); + } +#endif + + return VRGripInterfaceSettings; +} + +FGameplayTagContainer& UGrippableStaticMeshComponent::GetGameplayTags() +{ +#if WITH_PUSH_MODEL + if (bRepGripSettingsAndGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableStaticMeshComponent, GameplayTags, this); + } +#endif + + return GameplayTags; +} + +///////////////////////////////////////////////// +//- End Push networking getter / setter functions +///////////////////////////////////////////////// \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/HandSocketComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/HandSocketComponent.cpp new file mode 100644 index 0000000..d11ad29 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Grippables/HandSocketComponent.cpp @@ -0,0 +1,1036 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Grippables/HandSocketComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(HandSocketComponent) + +#include "CoreMinimal.h" +#include "UObject/UObjectIterator.h" +#include "Engine/CollisionProfile.h" +#include "BoneContainer.h" +#include "Animation/AnimSequence.h" +#include "Animation/AnimInstanceProxy.h" +#include "Animation/PoseSnapshot.h" +#include "Animation/AnimData/AnimDataModel.h" +#include "Engine/SkinnedAssetCommon.h" +#include "Engine/SkinnedAsset.h" +//#include "VRExpansionFunctionLibrary.h" +#include "Components/SkeletalMeshComponent.h" +#include "Components/PoseableMeshComponent.h" +#include "GripMotionControllerComponent.h" +//#include "VRGripInterface.h" +//#include "VRBPDatatypes.h" +#include "Engine/SkinnedAssetCommon.h" +#include "Net/UnrealNetwork.h" +#include "Serialization/CustomVersion.h" + +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + +DEFINE_LOG_CATEGORY(LogVRHandSocketComponent); + +const FGuid FVRHandSocketCustomVersion::GUID(0x5A018B7F, 0x48A7AFDE, 0xAFBEB580, 0xAD575412); + +// Register the custom version with core +FCustomVersionRegistration GRegisterHandSocketCustomVersion(FVRHandSocketCustomVersion::GUID, FVRHandSocketCustomVersion::LatestVersion, TEXT("HandSocketVer")); + + +void UHandSocketComponent::Serialize(FArchive& Ar) +{ + Super::Serialize(Ar); + + Ar.UsingCustomVersion(FVRHandSocketCustomVersion::GUID); + +#if WITH_EDITORONLY_DATA + const int32 CustomHandSocketVersion = Ar.CustomVer(FVRHandSocketCustomVersion::GUID); + + if (CustomHandSocketVersion < FVRHandSocketCustomVersion::HandSocketStoringSetState) + { + bDecoupled = bDecoupleMeshPlacement; + } +#endif +} + + //============================================================================= +UHandSocketComponent::UHandSocketComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + bReplicateMovement = false; + PrimaryComponentTick.bCanEverTick = false; + PrimaryComponentTick.bStartWithTickEnabled = false; + // Setting absolute scale so we don't have to care about our parents scale + this->SetUsingAbsoluteScale(true); + //this->bReplicates = true; + + bRepGameplayTags = true; + +#if WITH_EDITORONLY_DATA + bTickedPose = false; + bDecoupled = false; + bShowVisualizationMesh = true; + bMirrorVisualizationMesh = false; + bShowRangeVisualization = false; + bFilterBonesByPostfix = false; + FilterPostfix = FString(TEXT("_r")); +#endif + + HandRelativePlacement = FTransform::Identity; + bAlwaysInRange = false; + bDisabled = false; + bLockInPlace = false; + bMatchRotation = false; + OverrideDistance = 0.0f; + SlotPrefix = FName("VRGripP"); + bUseCustomPoseDeltas = false; + HandTargetAnimation = nullptr; + MirroredScale = FVector(1.f, 1.f, -1.f); + bOnlySnapMesh = false; + bOnlyUseHandPose = false; + bIgnoreAttachBone = false; + bFlipForLeftHand = false; + bLeftHandDominant = false; + bOnlyFlipRotation = false; + + MirrorAxis = EVRAxis::X; + FlipAxis = EVRAxis::Y; +} + +UAnimSequence* UHandSocketComponent::GetTargetAnimation() +{ + return HandTargetAnimation; +} + +void UHandSocketComponent::GetAllHandSocketComponents(TArray& OutHandSockets) +{ + for (TObjectIterator It; It; ++It) + { + UHandSocketComponent* HandSocket = *It; + if (IsValid(HandSocket) && !HandSocket->IsTemplate()) + { + OutHandSockets.Add(HandSocket); + } + } +} + +bool UHandSocketComponent::GetAllHandSocketComponentsInRange(FVector SearchFromWorldLocation, float SearchRange, TArray& OutHandSockets) +{ + float SearchDistSq = FMath::Square(SearchRange); + + UHandSocketComponent* HandSocket = nullptr; + FTransform HandSocketTrans; + for (TObjectIterator It; It; ++It) + { + HandSocket = *It; + if (IsValid(HandSocket) && !HandSocket->IsTemplate()) + { + HandSocketTrans = HandSocket->GetRelativeTransform() * HandSocket->GetOwner()->GetActorTransform(); + if (FVector::DistSquared(HandSocketTrans.GetLocation(), SearchFromWorldLocation) <= SearchDistSq) + { + OutHandSockets.Add(HandSocket); + } + } + } + + return OutHandSockets.Num() > 0; +} + +UHandSocketComponent* UHandSocketComponent::GetClosestHandSocketComponentInRange(FVector SearchFromWorldLocation, float SearchRange) +{ + float SearchDistSq = FMath::Square(SearchRange); + UHandSocketComponent* ClosestHandSocket = nullptr; + float LastDist = 0.0f; + float DistSq = 0.0f; + + bool bFoundOne = false; + UHandSocketComponent* HandSocket = nullptr; + FTransform HandSocketTrans; + for (TObjectIterator It; It; ++It) + { + HandSocket = *It; + if (IsValid(HandSocket) && !HandSocket->IsTemplate()) + { + HandSocketTrans = HandSocket->GetRelativeTransform() * HandSocket->GetOwner()->GetActorTransform(); + DistSq = FVector::DistSquared(HandSocketTrans.GetLocation(), SearchFromWorldLocation); + if (DistSq <= SearchDistSq && (!bFoundOne || DistSq < LastDist)) + { + bFoundOne = true; + ClosestHandSocket = HandSocket; + LastDist = DistSq; + } + } + } + + return ClosestHandSocket; +} + +bool UHandSocketComponent::GetAnimationSequenceAsPoseSnapShot(UAnimSequence* InAnimationSequence, FPoseSnapshot& OutPoseSnapShot, USkeletalMeshComponent* TargetMesh, bool bSkipRootBone, bool bFlipHand) +{ + if (InAnimationSequence) + { + OutPoseSnapShot.SkeletalMeshName = /*TargetMesh ? TargetMesh->SkeletalMesh->GetFName(): */InAnimationSequence->GetSkeleton()->GetFName(); + OutPoseSnapShot.SnapshotName = InAnimationSequence->GetFName(); + OutPoseSnapShot.BoneNames.Empty(); + OutPoseSnapShot.LocalTransforms.Empty(); + + TArray AnimSeqNames; + + if (USkeleton* AnimationSkele = InAnimationSequence->GetSkeleton()) + { + // pre-size the array to avoid unnecessary reallocation + OutPoseSnapShot.BoneNames.AddUninitialized(AnimationSkele->GetReferenceSkeleton().GetNum()); + for (int32 i = 0; i < AnimationSkele->GetReferenceSkeleton().GetNum(); i++) + { + OutPoseSnapShot.BoneNames[i] = AnimationSkele->GetReferenceSkeleton().GetBoneName(i); + if (bFlipHand) + { + FString bName = OutPoseSnapShot.BoneNames[i].ToString(); + + if (bName.Contains("_r")) + { + bName = bName.Replace(TEXT("_r"), TEXT("_l")); + } + else + { + bName = bName.Replace(TEXT("_l"), TEXT("_r")); + } + + OutPoseSnapShot.BoneNames[i] = FName(bName); + } + } + } + else + { + return false; + } + + const FReferenceSkeleton& RefSkeleton = (TargetMesh) ? TargetMesh->GetSkinnedAsset()->GetRefSkeleton() : InAnimationSequence->GetSkeleton()->GetReferenceSkeleton(); + FTransform LocalTransform; + + const TArray& TrackMap = InAnimationSequence->GetCompressedTrackToSkeletonMapTable(); + int32 TrackIndex = INDEX_NONE; + + OutPoseSnapShot.LocalTransforms.Reserve(OutPoseSnapShot.BoneNames.Num()); + + for (int32 BoneNameIndex = 0; BoneNameIndex < OutPoseSnapShot.BoneNames.Num(); ++BoneNameIndex) + { + + const FName& BoneName = OutPoseSnapShot.BoneNames[BoneNameIndex]; + + TrackIndex = INDEX_NONE; + if (BoneNameIndex != INDEX_NONE && BoneNameIndex < TrackMap.Num() && TrackMap[BoneNameIndex].BoneTreeIndex == BoneNameIndex) + { + TrackIndex = BoneNameIndex; + } + else + { + // This shouldn't happen but I need a fallback + // Don't currently want to reconstruct the map inversely + for (int i = 0; i < TrackMap.Num(); ++i) + { + if (TrackMap[i].BoneTreeIndex == BoneNameIndex) + { + TrackIndex = i; + break; + } + } + } + + if (TrackIndex != INDEX_NONE && (!bSkipRootBone || TrackIndex != 0)) + { + double TrackLocation = 0.0f; + InAnimationSequence->GetBoneTransform(LocalTransform, FSkeletonPoseBoneIndex(TrackMap[TrackIndex].BoneTreeIndex), TrackLocation, false); + } + else + { + // otherwise, get ref pose if exists + const int32 BoneIDX = RefSkeleton.FindBoneIndex(BoneName); + if (BoneIDX != INDEX_NONE) + { + LocalTransform = RefSkeleton.GetRefBonePose()[BoneIDX]; + } + else + { + LocalTransform = FTransform::Identity; + } + } + + if (bFlipHand && (!bSkipRootBone || TrackIndex != 0)) + { + FMatrix M = LocalTransform.ToMatrixWithScale(); + M.Mirror(EAxis::X, EAxis::X); + M.Mirror(EAxis::Y, EAxis::Y); + M.Mirror(EAxis::Z, EAxis::Z); + LocalTransform.SetFromMatrix(M); + } + + OutPoseSnapShot.LocalTransforms.Add(LocalTransform); + } + + OutPoseSnapShot.bIsValid = true; + return true; + } + + return false; +} + +bool UHandSocketComponent::GetBlendedPoseSnapShot(FPoseSnapshot& PoseSnapShot, USkeletalMeshComponent* TargetMesh, bool bSkipRootBone, bool bFlipHand) +{ + if (HandTargetAnimation)// && bUseCustomPoseDeltas && CustomPoseDeltas.Num() > 0) + { + PoseSnapShot.SkeletalMeshName = HandTargetAnimation->GetSkeleton()->GetFName(); + PoseSnapShot.SnapshotName = HandTargetAnimation->GetFName(); + PoseSnapShot.BoneNames.Empty(); + PoseSnapShot.LocalTransforms.Empty(); + TArray OrigBoneNames; + + if(USkeleton * AnimationSkele = HandTargetAnimation->GetSkeleton()) + { + // pre-size the array to avoid unnecessary reallocation + PoseSnapShot.BoneNames.AddUninitialized(AnimationSkele->GetReferenceSkeleton().GetNum()); + OrigBoneNames.AddUninitialized(AnimationSkele->GetReferenceSkeleton().GetNum()); + for (int32 i = 0; i < AnimationSkele->GetReferenceSkeleton().GetNum(); i++) + { + PoseSnapShot.BoneNames[i] = AnimationSkele->GetReferenceSkeleton().GetBoneName(i); + OrigBoneNames[i] = PoseSnapShot.BoneNames[i]; + if (bFlipHand) + { + FString bName = PoseSnapShot.BoneNames[i].ToString(); + + if (bName.Contains("_r")) + { + bName = bName.Replace(TEXT("_r"), TEXT("_l")); + } + else + { + bName = bName.Replace(TEXT("_l"), TEXT("_r")); + } + + PoseSnapShot.BoneNames[i] = FName(bName); + } + } + } + else + { + return false; + } + + const FReferenceSkeleton& RefSkeleton = (TargetMesh) ? TargetMesh->GetSkinnedAsset()->GetRefSkeleton() : HandTargetAnimation->GetSkeleton()->GetReferenceSkeleton(); + FTransform LocalTransform; + + const TArray& TrackMap = HandTargetAnimation->GetCompressedTrackToSkeletonMapTable(); + int32 TrackIndex = INDEX_NONE; + + for (int32 BoneNameIndex = 0; BoneNameIndex < PoseSnapShot.BoneNames.Num(); ++BoneNameIndex) + { + TrackIndex = INDEX_NONE; + if (BoneNameIndex < TrackMap.Num() && TrackMap[BoneNameIndex].BoneTreeIndex == BoneNameIndex) + { + TrackIndex = BoneNameIndex; + } + else + { + // This shouldn't happen but I need a fallback + // Don't currently want to reconstruct the map inversely + for (int i = 0; i < TrackMap.Num(); ++i) + { + if (TrackMap[i].BoneTreeIndex == BoneNameIndex) + { + TrackIndex = i; + break; + } + } + } + + const FName& BoneName = PoseSnapShot.BoneNames[BoneNameIndex]; + + if (TrackIndex != INDEX_NONE && (!bSkipRootBone || TrackIndex != 0)) + { + double TrackLocation = 0.0f; + HandTargetAnimation->GetBoneTransform(LocalTransform, FSkeletonPoseBoneIndex(TrackMap[TrackIndex].BoneTreeIndex), TrackLocation, false); + } + else + { + // otherwise, get ref pose if exists + const int32 BoneIDX = RefSkeleton.FindBoneIndex(BoneName); + if (BoneIDX != INDEX_NONE) + { + LocalTransform = RefSkeleton.GetRefBonePose()[BoneIDX]; + } + else + { + LocalTransform = FTransform::Identity; + } + } + + if (bUseCustomPoseDeltas) + { + FQuat DeltaQuat = FQuat::Identity; + if (FBPVRHandPoseBonePair* HandPair = CustomPoseDeltas.FindByKey(OrigBoneNames[BoneNameIndex])) + { + DeltaQuat = HandPair->DeltaPose; + } + + LocalTransform.ConcatenateRotation(DeltaQuat); + LocalTransform.NormalizeRotation(); + } + + if (bFlipHand && (!bSkipRootBone || TrackIndex != 0)) + { + FMatrix M = LocalTransform.ToMatrixWithScale(); + M.Mirror(EAxis::X, EAxis::X); + M.Mirror(EAxis::Y, EAxis::Y); + M.Mirror(EAxis::Z, EAxis::Z); + LocalTransform.SetFromMatrix(M); + } + + PoseSnapShot.LocalTransforms.Add(LocalTransform); + } + + PoseSnapShot.bIsValid = true; + return true; + } + else if (bUseCustomPoseDeltas && CustomPoseDeltas.Num() && TargetMesh) + { + PoseSnapShot.SkeletalMeshName = TargetMesh->GetSkinnedAsset()->GetSkeleton()->GetFName(); + PoseSnapShot.SnapshotName = FName(TEXT("RawDeltaPose")); + PoseSnapShot.BoneNames.Empty(); + PoseSnapShot.LocalTransforms.Empty(); + TargetMesh->GetBoneNames(PoseSnapShot.BoneNames); + + PoseSnapShot.LocalTransforms = TargetMesh->GetSkinnedAsset()->GetSkeleton()->GetRefLocalPoses(); + + FQuat DeltaQuat = FQuat::Identity; + FName TargetBoneName = NAME_None; + + for (FBPVRHandPoseBonePair& HandPair : CustomPoseDeltas) + { + if (bFlipHand) + { + FString bName = HandPair.BoneName.ToString(); + + if (bName.Contains("_r")) + { + bName = bName.Replace(TEXT("_r"), TEXT("_l")); + } + else + { + bName = bName.Replace(TEXT("_l"), TEXT("_r")); + } + + TargetBoneName = FName(bName); + } + else + { + TargetBoneName = HandPair.BoneName; + } + + int32 BoneIdx = TargetMesh->GetBoneIndex(TargetBoneName); + if (BoneIdx != INDEX_NONE) + { + DeltaQuat = HandPair.DeltaPose; + + if (bFlipHand) + { + FTransform DeltaTrans(DeltaQuat); + FMatrix M = DeltaTrans.ToMatrixWithScale(); + M.Mirror(EAxis::X, EAxis::X); + M.Mirror(EAxis::Y, EAxis::Y); + M.Mirror(EAxis::Z, EAxis::Z); + DeltaTrans.SetFromMatrix(M); + DeltaQuat = DeltaTrans.GetRotation(); + } + + PoseSnapShot.LocalTransforms[BoneIdx].ConcatenateRotation(DeltaQuat); + PoseSnapShot.LocalTransforms[BoneIdx].NormalizeRotation(); + + } + } + + PoseSnapShot.bIsValid = true; + return true; + } + + return false; +} + +FTransform UHandSocketComponent::GetHandRelativePlacement() +{ + // Optionally mirror for left hand + + if (bDecoupleMeshPlacement) + { + if (USceneComponent* ParentComp = GetAttachParent()) + { + return HandRelativePlacement.GetRelativeTransform(this->GetRelativeTransform()); + //FTransform curTrans = HandRelativePlacement * ParentComp->GetComponentTransform(); + //return curTrans.GetRelativeTransform(this->GetComponentTransform()); + } + } + + return HandRelativePlacement; +} + +FTransform UHandSocketComponent::GetHandSocketTransform(UGripMotionControllerComponent* QueryController, bool bIgnoreOnlySnapMesh) +{ + // Optionally mirror for left hand + + if (!bIgnoreOnlySnapMesh && bOnlySnapMesh) + { + if (!QueryController) + { + // No controller input + UE_LOG(LogVRMotionController, Warning, TEXT("HandSocketComponent::GetHandSocketTransform was missing required motion controller for bOnlySnapMesh! Check that you are passing a controller into GetClosestSocketInRange!")); + } + else + { + return QueryController->GetPivotTransform(); + } + } + + if (bFlipForLeftHand) + { + if (!QueryController) + { + // No controller input + UE_LOG(LogVRMotionController, Warning, TEXT("HandSocketComponent::GetHandSocketTransform was missing required motion controller for bFlipForLeftand! Check that you are passing a controller into GetClosestSocketInRange!")); + } + else + { + EControllerHand HandType; + QueryController->GetHandType(HandType); + bool bIsRightHand = HandType == EControllerHand::Right; + if (bLeftHandDominant == bIsRightHand) + { + FTransform ReturnTrans = this->GetRelativeTransform(); + if (USceneComponent* AttParent = this->GetAttachParent()) + { + ReturnTrans.Mirror(GetAsEAxis(MirrorAxis), GetAsEAxis(FlipAxis)); + if (bOnlyFlipRotation) + { + ReturnTrans.SetTranslation(this->GetRelativeLocation()); + } + + if (this->GetAttachSocketName() != NAME_None) + { + ReturnTrans = ReturnTrans * AttParent->GetSocketTransform(GetAttachSocketName(), RTS_Component); + } + + ReturnTrans = ReturnTrans * AttParent->GetComponentTransform(); + } + + return ReturnTrans; + } + } + } + + + if (bLockInPlace) + { + FTransform ReturnTrans = this->GetRelativeTransform(); + + if (USceneComponent* AttParent = this->GetAttachParent()) + { + if (this->GetAttachSocketName() != NAME_None) + { + ReturnTrans = ReturnTrans * AttParent->GetSocketTransform(GetAttachSocketName(), RTS_Component); + } + + ReturnTrans = ReturnTrans * AttParent->GetComponentTransform(); + } + else + { + ReturnTrans = this->GetComponentTransform(); // Fallback + } + + return ReturnTrans; + } + else + { + return this->GetComponentTransform(); + } +} + +FTransform UHandSocketComponent::GetMeshRelativeTransform(bool bIsRightHand, bool bUseParentScale, bool bUseMirrorScale) +{ + // Optionally mirror for left hand + + // Failsafe + if (!this->GetAttachParent()) + return FTransform::Identity; + + FTransform relTrans = this->GetRelativeTransform(); + FTransform HandTrans = GetHandRelativePlacement(); + FTransform ReturnTrans = FTransform::Identity; + + // Fix the scale + if (!bUseParentScale && this->IsUsingAbsoluteScale() /*&& !bDecoupleMeshPlacement*/) + { + FVector ParentScale = this->GetAttachParent()->GetComponentScale(); + // Take parent scale out of our relative transform early + relTrans.ScaleTranslation(ParentScale); + ReturnTrans = HandTrans * relTrans; + // We add in the inverse of the parent scale to adjust the hand mesh + ReturnTrans.ScaleTranslation((FVector(1.0f) / ParentScale)); + ReturnTrans.SetScale3D(FVector(1.0f)); + } + else + { + ReturnTrans = HandTrans * relTrans; + } + + // If we should mirror the transform, do it now that it is in our parent relative space + if ((bFlipForLeftHand && (bLeftHandDominant == bIsRightHand))) + { + //FTransform relTrans = this->GetRelativeTransform(); + MirrorHandTransform(ReturnTrans, relTrans); + + if (bUseMirrorScale) + { + ReturnTrans.SetScale3D(ReturnTrans.GetScale3D() * MirroredScale.GetSignVector()); + } + } + + if (bIgnoreAttachBone && this->GetAttachSocketName() != NAME_None) + { + ReturnTrans = ReturnTrans * GetAttachParent()->GetSocketTransform(GetAttachSocketName(), RTS_Component); + } + + + return ReturnTrans; +} + +#if WITH_EDITORONLY_DATA +FTransform UHandSocketComponent::GetBoneTransformAtTime(UAnimSequence* MyAnimSequence, /*float AnimTime,*/ int BoneIdx, FName BoneName, bool bUseRawDataOnly) +{ + double tracklen = MyAnimSequence->GetPlayLength(); + FTransform BoneTransform = FTransform::Identity; + IAnimationDataController& AnimController = MyAnimSequence->GetController(); + + if (const IAnimationDataModel* AnimModel = AnimController.GetModel()) + { + const TArray& TrackMap = MyAnimSequence->GetCompressedTrackToSkeletonMapTable(); + + int32 TrackIndex = INDEX_NONE; + if (BoneIdx != INDEX_NONE && BoneIdx < TrackMap.Num() && TrackMap[BoneIdx].BoneTreeIndex == BoneIdx) + { + TrackIndex = BoneIdx; + } + else + { + // This shouldn't happen but I need a fallback + // Don't currently want to reconstruct the map inversely + for (int i = 0; i < TrackMap.Num(); ++i) + { + if (TrackMap[i].BoneTreeIndex == BoneIdx) + { + TrackIndex = i; + break; + } + } + } + + if (TrackIndex != INDEX_NONE) + { + FSkeletonPoseBoneIndex BoneIndex(TrackMap[TrackIndex].BoneTreeIndex); + if (BoneIndex.IsValid()) + { + MyAnimSequence->GetBoneTransform(BoneTransform, BoneIndex, /*AnimTime*/ tracklen, bUseRawDataOnly); + return BoneTransform; + } + } + else + { + return FTransform::Identity; + } + } + + return FTransform::Identity; +} +#endif + +void UHandSocketComponent::OnRegister() +{ + + + UWorld* MyWorld = GetWorld(); + + if (!MyWorld) + return; + + TEnumAsByte MyWorldType = MyWorld->WorldType; + +#if WITH_EDITORONLY_DATA + AActor* MyOwner = GetOwner(); + if (bShowVisualizationMesh && (MyOwner != nullptr) && !IsRunningCommandlet()) + { + if (HandVisualizerComponent == nullptr && bShowVisualizationMesh && (MyWorldType == EWorldType::EditorPreview || MyWorldType == EWorldType::Editor)) + { + HandVisualizerComponent = NewObject(MyOwner, NAME_None, RF_Transactional | RF_TextExportTransient); + HandVisualizerComponent->SetupAttachment(this); + HandVisualizerComponent->SetIsVisualizationComponent(true); + HandVisualizerComponent->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName); + HandVisualizerComponent->CastShadow = false; + HandVisualizerComponent->CreationMethod = CreationMethod; + //HandVisualizerComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision); + HandVisualizerComponent->SetComponentTickEnabled(false); + HandVisualizerComponent->SetHiddenInGame(true); + HandVisualizerComponent->RegisterComponentWithWorld(GetWorld()); + //HandVisualizerComponent->SetUsingAbsoluteScale(true); + } + else if (/*!bShowVisualizationMesh && */HandVisualizerComponent) + { + HandVisualizerComponent->SetVisibility(false); + HandVisualizerComponent->DestroyComponent(); + HandVisualizerComponent = nullptr; + } + + if (HandVisualizerComponent) + { + bTickedPose = false; + + if (VisualizationMesh) + { + if (HandPreviewMaterial) + { + HandVisualizerComponent->SetMaterial(0, (UMaterialInterface*)HandPreviewMaterial); + } + HandVisualizerComponent->SetSkinnedAssetAndUpdate(VisualizationMesh); + } + + PositionVisualizationMesh(); + PoseVisualizationToAnimation(true); + } + } + +#endif // WITH_EDITORONLY_DATA + + if (bLockInPlace && (MyWorldType != EWorldType::EditorPreview && MyWorldType != EWorldType::Editor)) + { + // Store current starting relative transform + //LockedRelativeTransform = GetRelativeTransform(); + + // Kill off child updates + SetUsingAbsoluteLocation(true); + SetUsingAbsoluteRotation(true); + } + + Super::OnRegister(); +} + +#if WITH_EDITORONLY_DATA + +void UHandSocketComponent::PositionVisualizationMesh() +{ + if (!HandVisualizerComponent) + { + return; + } + + if (USceneComponent* ParentAttach = this->GetAttachParent()) + { + FTransform relTrans = this->GetRelativeTransform(); + + if (bDecoupled != bDecoupleMeshPlacement) + { + if (bDecoupleMeshPlacement) + { + HandRelativePlacement = HandRelativePlacement * GetRelativeTransform(); + } + else + { + HandRelativePlacement = HandRelativePlacement.GetRelativeTransform(GetRelativeTransform()); + } + } + + FTransform HandPlacement = GetHandRelativePlacement(); + FTransform ReturnTrans = (HandPlacement * relTrans); + + if (bMirrorVisualizationMesh)//(bFlipForLeftHand && !bIsRightHand)) + { + MirrorHandTransform(ReturnTrans, relTrans); + } + + if ((bLeftHandDominant && !bMirrorVisualizationMesh) || (!bLeftHandDominant && bMirrorVisualizationMesh)) + { + ReturnTrans.SetScale3D(ReturnTrans.GetScale3D() * MirroredScale); + } + + HandVisualizerComponent->SetRelativeTransform(ReturnTrans.GetRelativeTransform(relTrans)/*newRel*/); + } +} + +void UHandSocketComponent::HideVisualizationMesh() +{ + if (!bShowVisualizationMesh && HandVisualizerComponent) + { + HandVisualizerComponent->SetVisibility(false); + HandVisualizerComponent->DestroyComponent(); + HandVisualizerComponent = nullptr; + } +} + +#endif + +#if WITH_EDITORONLY_DATA +void UHandSocketComponent::PoseVisualizationToAnimation(bool bForceRefresh) +{ + + if (!HandVisualizerComponent || !HandVisualizerComponent->GetSkinnedAsset()) + return; + + TArray LocalPoses; + if (!HandTargetAnimation) + { + // Store local poses for posing + LocalPoses = HandVisualizerComponent->GetSkinnedAsset()->GetSkeleton()->GetRefLocalPoses(); + } + + // Check out of the skin cache, the poses don't update otherwise when enabled + int32 NumLODs = HandVisualizerComponent->GetNumLODs(); + HandVisualizerComponent->SkinCacheUsage.Empty(NumLODs); + + for (int nLODs = 0; nLODs <= NumLODs; ++nLODs) + { + HandVisualizerComponent->SkinCacheUsage.Add(ESkinCacheUsage::Disabled); + } + + // Now Pose the bones + TArray BonesNames; + HandVisualizerComponent->GetBoneNames(BonesNames); + int32 Bones = HandVisualizerComponent->GetNumBones(); + + for (int32 i = 0; i < Bones; i++) + { + if (!HandTargetAnimation && !bUseCustomPoseDeltas) + { + if (HandVisualizerComponent->GetBoneSpaceTransforms().Num() > 0) + { + HandVisualizerComponent->ResetBoneTransformByName(BonesNames[i]); + } + continue; + } + + FName ParentBone = HandVisualizerComponent->GetParentBone(BonesNames[i]); + FTransform ParentTrans = FTransform::Identity; + if (ParentBone != NAME_None) + { + ParentTrans = HandVisualizerComponent->GetBoneTransformByName(ParentBone, EBoneSpaces::ComponentSpace); + } + + + FQuat DeltaQuat = FQuat::Identity; + if (bUseCustomPoseDeltas) + { + for (FBPVRHandPoseBonePair BonePairC : CustomPoseDeltas) + { + if (BonePairC.BoneName == BonesNames[i]) + { + DeltaQuat = BonePairC.DeltaPose; + DeltaQuat.Normalize(); + break; + } + } + } + + FTransform BoneTrans = FTransform::Identity; + + if (HandTargetAnimation) + { + BoneTrans = GetBoneTransformAtTime(HandTargetAnimation, /*FLT_MAX,*/ i, BonesNames[i], false); // true; + } + else + { + BoneTrans = LocalPoses[i]; + } + + BoneTrans = BoneTrans * ParentTrans;// *HandVisualizerComponent->GetComponentTransform(); + BoneTrans.NormalizeRotation(); + + //DeltaQuat *= HandVisualizerComponent->GetComponentTransform().GetRotation().Inverse(); + + BoneTrans.ConcatenateRotation(DeltaQuat); + BoneTrans.NormalizeRotation(); + HandVisualizerComponent->SetBoneTransformByName(BonesNames[i], BoneTrans, EBoneSpaces::ComponentSpace); + + } + + if (HandVisualizerComponent && (!bTickedPose || bForceRefresh)) + { + // Tick Pose first + if (HandVisualizerComponent->IsRegistered()) + { + bTickedPose = true; + HandVisualizerComponent->TickPose(1.0f, false); + if (HandVisualizerComponent->LeaderPoseComponent.IsValid()) + { + HandVisualizerComponent->UpdateFollowerComponent(); + } + else + { + HandVisualizerComponent->RefreshBoneTransforms(&HandVisualizerComponent->PrimaryComponentTick); + } + } + } +} + +void UHandSocketComponent::AddReferencedObjects(UObject* InThis, FReferenceCollector& Collector) +{ + UHandSocketComponent* This = CastChecked(InThis); + Collector.AddReferencedObject(This->HandVisualizerComponent); + + Super::AddReferencedObjects(InThis, Collector); +} + +void UHandSocketComponent::OnComponentDestroyed(bool bDestroyingHierarchy) +{ + Super::OnComponentDestroyed(bDestroyingHierarchy); + + if (HandVisualizerComponent) + { + HandVisualizerComponent->DestroyComponent(); + } +} + +#endif + +void UHandSocketComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UHandSocketComponent, bRepGameplayTags, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UHandSocketComponent, bReplicateMovement, PushModelParams); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UHandSocketComponent, GameplayTags, PushModelParamsWithCondition); +} + +void UHandSocketComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) +{ + Super::PreReplication(ChangedPropertyTracker); + + // Don't replicate if set to not do it + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UHandSocketComponent, GameplayTags, bRepGameplayTags); + + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeLocation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeRotation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeScale3D, bReplicateMovement); +} + +//============================================================================= +UHandSocketComponent::~UHandSocketComponent() +{ +} + +#if WITH_EDITOR + +void UHandSocketComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) +{ + Super::PostEditChangeProperty(PropertyChangedEvent); + + FProperty* PropertyThatChanged = PropertyChangedEvent.Property; + + if (PropertyThatChanged != nullptr) + { +#if WITH_EDITORONLY_DATA + if (PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UHandSocketComponent, HandTargetAnimation) || + PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UHandSocketComponent, VisualizationMesh) + ) + { + PositionVisualizationMesh(); + PoseVisualizationToAnimation(true); + } + else if (PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UHandSocketComponent, CustomPoseDeltas)) + { + PoseVisualizationToAnimation(true); + } + else if (PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UHandSocketComponent, HandRelativePlacement)) + { + PositionVisualizationMesh(); + } + else if (PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UHandSocketComponent, bShowVisualizationMesh)) + { + HideVisualizationMesh(); + } +#endif + } +} +#endif + +UHandSocketComponent* UHandSocketComponent::GetHandSocketComponentFromObject(UObject* ObjectToCheck, FName SocketName) +{ + if (AActor* OwningActor = Cast(ObjectToCheck)) + { + if (USceneComponent* OwningRoot = Cast(OwningActor->GetRootComponent())) + { + TArray AttachChildren = OwningRoot->GetAttachChildren(); + for (USceneComponent* AttachChild : AttachChildren) + { + if (AttachChild && AttachChild->IsA() && AttachChild->GetFName() == SocketName) + { + return Cast(AttachChild); + } + } + } + } + else if (USceneComponent* OwningRoot = Cast(ObjectToCheck)) + { + TArray AttachChildren = OwningRoot->GetAttachChildren(); + for (USceneComponent* AttachChild : AttachChildren) + { + if (AttachChild && AttachChild->IsA() && AttachChild->GetFName() == SocketName) + { + return Cast(AttachChild); + } + } + } + + return nullptr; +} + +///////////////////////////////////////////////// +//- Push networking getter / setter functions +///////////////////////////////////////////////// + +void UHandSocketComponent::SetRepGameplayTags(bool bNewRepGameplayTags) +{ + bRepGameplayTags = bNewRepGameplayTags; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UHandSocketComponent, bRepGameplayTags, this); +#endif +} + +void UHandSocketComponent::SetReplicateMovement(bool bNewReplicateMovement) +{ + bReplicateMovement = bNewReplicateMovement; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UHandSocketComponent, bReplicateMovement, this); +#endif +} + +FGameplayTagContainer& UHandSocketComponent::GetGameplayTags() +{ +#if WITH_PUSH_MODEL + if (bRepGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UHandSocketComponent, GameplayTags, this); + } +#endif + + return GameplayTags; +} + +///////////////////////////////////////////////// +//- End Push networking getter / setter functions +///////////////////////////////////////////////// + +void UHandSocketAnimInstance::NativeInitializeAnimation() +{ + Super::NativeInitializeAnimation(); + + OwningSocket = Cast(GetOwningComponent()->GetAttachParent()); +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRButtonComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRButtonComponent.cpp new file mode 100644 index 0000000..e9da277 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRButtonComponent.cpp @@ -0,0 +1,460 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Interactibles/VRButtonComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRButtonComponent) + +#include "Net/UnrealNetwork.h" +//#include "VRGripInterface.h" +#include "GripMotionControllerComponent.h" +#include "GameFramework/Character.h" +#include "GameFramework/PlayerController.h" + +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + + //============================================================================= +UVRButtonComponent::UVRButtonComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + this->SetGenerateOverlapEvents(true); + this->PrimaryComponentTick.bStartWithTickEnabled = false; + PrimaryComponentTick.bCanEverTick = true; + + LastToggleTime = 0.0f; + DepressDistance = 8.0f; + ButtonEngageDepth = 8.0f; + DepressSpeed = 50.0f; + + ButtonAxis = EVRInteractibleAxis::Axis_Z; + ButtonType = EVRButtonType::Btn_Toggle_Return; + + MinTimeBetweenEngaging = 0.1f; + + bIsEnabled = true; + StateChangeAuthorityType = EVRStateChangeAuthorityType::CanChangeState_All; + bButtonState = false; + + this->SetCollisionResponseToAllChannels(ECR_Overlap); + + bSkipOverlapFiltering = false; + InitialRelativeTransform = FTransform::Identity; + + bReplicateMovement = false; +} + +//============================================================================= +UVRButtonComponent::~UVRButtonComponent() +{ +} + +void UVRButtonComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UVRButtonComponent, InitialRelativeTransform, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UVRButtonComponent, bReplicateMovement, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UVRButtonComponent, StateChangeAuthorityType, PushModelParams); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_InitialOnly, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UVRButtonComponent, bButtonState, PushModelParamsWithCondition); +} + +void UVRButtonComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) +{ + Super::PreReplication(ChangedPropertyTracker); + + // Replicate the levers initial transform if we are replicating movement + //DOREPLIFETIME_ACTIVE_OVERRIDE(UVRButtonComponent, InitialRelativeTransform, bReplicateMovement); + + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeLocation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeRotation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeScale3D, bReplicateMovement); +} + +void UVRButtonComponent::OnRegister() +{ + Super::OnRegister(); + ResetInitialButtonLocation(); +} + +void UVRButtonComponent::BeginPlay() +{ + // Call the base class + Super::BeginPlay(); + + SetButtonToRestingPosition(); + + OnComponentBeginOverlap.AddUniqueDynamic(this, &UVRButtonComponent::OnOverlapBegin); + OnComponentEndOverlap.AddUniqueDynamic(this, &UVRButtonComponent::OnOverlapEnd); +} + +void UVRButtonComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) +{ + // Call supers tick (though I don't think any of the base classes to this actually implement it) + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + const float WorldTime = GetWorld()->GetRealTimeSeconds(); + + if (IsValid(LocalInteractingComponent)) + { + // If button was set to inactive during use + if (!bIsEnabled) + { + // Remove interacting component and return, next tick will begin lerping back + LocalInteractingComponent = nullptr; + return; + } + + FTransform OriginalBaseTransform = CalcNewComponentToWorld(InitialRelativeTransform); + + float CheckDepth = FMath::Clamp(GetAxisValue(InitialLocation) - GetAxisValue(OriginalBaseTransform.InverseTransformPosition(LocalInteractingComponent->GetComponentLocation())), 0.0f, DepressDistance); + + if (CheckDepth > 0.0f) + { + + float ClampMinDepth = 0.0f; + + // If active and a toggled stay, then clamp min to the toggled stay location + if (ButtonType == EVRButtonType::Btn_Toggle_Stay && bButtonState) + ClampMinDepth = -(ButtonEngageDepth + (1.e-2f)); // + NOT_SO_UE_KINDA_SMALL_NUMBER + + float NewDepth = FMath::Clamp(GetAxisValue(InitialComponentLoc) + (-CheckDepth), -DepressDistance, ClampMinDepth); + this->SetRelativeLocation(InitialRelativeTransform.TransformPosition(SetAxisValue(NewDepth)), false); + + if (ButtonType == EVRButtonType::Btn_Toggle_Return || ButtonType == EVRButtonType::Btn_Toggle_Stay) + { + if ((StateChangeAuthorityType == EVRStateChangeAuthorityType::CanChangeState_All) || + (StateChangeAuthorityType == EVRStateChangeAuthorityType::CanChangeState_Server && GetNetMode() < ENetMode::NM_Client) || + (StateChangeAuthorityType == EVRStateChangeAuthorityType::CanChangeState_Owner && IsValid(LocalLastInteractingActor) && LocalLastInteractingActor->HasLocalNetOwner())) + { + if (!bToggledThisTouch && NewDepth <= (-ButtonEngageDepth) + UE_KINDA_SMALL_NUMBER && (WorldTime - LastToggleTime) >= MinTimeBetweenEngaging) + { + LastToggleTime = WorldTime; + bToggledThisTouch = true; + bButtonState = !bButtonState; + ReceiveButtonStateChanged(bButtonState, LocalLastInteractingActor.Get(), LocalLastInteractingComponent.Get()); + OnButtonStateChanged.Broadcast(bButtonState, LocalLastInteractingActor.Get(), LocalLastInteractingComponent.Get()); + } + } + } + } + } + else + { + // Std precision tolerance should be fine + if (this->GetRelativeLocation().Equals(GetTargetRelativeLocation())) + { + this->SetComponentTickEnabled(false); + + OnButtonEndInteraction.Broadcast(LocalLastInteractingActor.Get(), LocalLastInteractingComponent.Get()); + ReceiveButtonEndInteraction(LocalLastInteractingActor.Get(), LocalLastInteractingComponent.Get()); + + LocalInteractingComponent = nullptr; // Just reset it here so it only does it once + LocalLastInteractingComponent = nullptr; + } + else + this->SetRelativeLocation(FMath::VInterpConstantTo(this->GetRelativeLocation(), GetTargetRelativeLocation(), DeltaTime, DepressSpeed), false); + } + + + // Press buttons always get checked, both during press AND during lerping for if they are active or not. + if (ButtonType == EVRButtonType::Btn_Press) + { + if ((StateChangeAuthorityType == EVRStateChangeAuthorityType::CanChangeState_All) || + (StateChangeAuthorityType == EVRStateChangeAuthorityType::CanChangeState_Server && GetNetMode() < ENetMode::NM_Client) || + (StateChangeAuthorityType == EVRStateChangeAuthorityType::CanChangeState_Owner && IsValid(LocalLastInteractingActor) && LocalLastInteractingActor->HasLocalNetOwner())) + { + // Check for if we should set the state of the button, done here as for the press button the lerp counts for input + bool bCheckState = (GetAxisValue(InitialRelativeTransform.InverseTransformPosition(this->GetRelativeLocation())) <= (-ButtonEngageDepth) + UE_KINDA_SMALL_NUMBER); + if (bButtonState != bCheckState && (WorldTime - LastToggleTime) >= MinTimeBetweenEngaging) + + { + LastToggleTime = WorldTime; + bButtonState = bCheckState; + ReceiveButtonStateChanged(bButtonState, LocalLastInteractingActor.Get(), LocalLastInteractingComponent.Get()); + OnButtonStateChanged.Broadcast(bButtonState, LocalLastInteractingActor.Get(), LocalLastInteractingComponent.Get()); + } + } + } + +} + +bool UVRButtonComponent::IsValidOverlap_Implementation(UPrimitiveComponent * OverlapComponent) +{ + + // Early out on the simple checks + if (!OverlapComponent || OverlapComponent == GetAttachParent() || OverlapComponent->GetAttachParent() == GetAttachParent()) + return false; + + // Should return faster checking for owning character + AActor * OverlapOwner = OverlapComponent->GetOwner(); + + if (IsValid(OverlapOwner)) + { + if (OverlapOwner->IsA(ACharacter::StaticClass())) + return true; + + const AActor* OverlapNetOwner = OverlapOwner->GetNetOwner(); + if (IsValid(OverlapNetOwner) && (OverlapNetOwner->IsA(APlayerController::StaticClass()) || OverlapNetOwner->IsA(ACharacter::StaticClass()))) + return true; + } + + // Because epic motion controllers are not owned by characters have to check here too in case someone implements it like that + // Now since our grip controllers are a subclass to the std ones we only need to check for the base one instead of both. + USceneComponent * OurAttachParent = OverlapComponent->GetAttachParent(); + if (OurAttachParent && OurAttachParent->IsA(UMotionControllerComponent::StaticClass())) + return true; + + // Now check for if it is a grippable object and if it is currently held + if (OverlapComponent->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + TArray Controllers; + bool bIsHeld; + IVRGripInterface::Execute_IsHeld(OverlapComponent, Controllers, bIsHeld); + + if (bIsHeld) + return true; + } + else if(OverlapOwner && OverlapOwner->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + TArray Controllers; + bool bIsHeld; + IVRGripInterface::Execute_IsHeld(OverlapOwner, Controllers, bIsHeld); + + if (bIsHeld) + return true; + } + + return false; +} + +void UVRButtonComponent::SetLastInteractingActor() +{ + + // Early out on the simple checks + if (!IsValid(LocalInteractingComponent) || LocalInteractingComponent == GetAttachParent() || LocalInteractingComponent->GetAttachParent() == GetAttachParent()) + { + LocalLastInteractingActor = nullptr; + LocalLastInteractingComponent = nullptr; + return; + } + + LocalLastInteractingComponent = LocalInteractingComponent; + + // Should return faster checking for owning character + AActor * OverlapOwner = LocalInteractingComponent->GetOwner(); + if (OverlapOwner && OverlapOwner->IsA(ACharacter::StaticClass())) + { + LocalLastInteractingActor = OverlapOwner; + return; + } + + // Now check for if it is a grippable object and if it is currently held + if (LocalInteractingComponent->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + TArray Controllers; + bool bIsHeld; + IVRGripInterface::Execute_IsHeld(LocalLastInteractingComponent.Get(), Controllers, bIsHeld); + + if (bIsHeld && Controllers.Num()) + { + AActor * ControllerOwner = Controllers[0].HoldingController != nullptr ? Controllers[0].HoldingController->GetOwner() : nullptr; + if (ControllerOwner) + { + LocalLastInteractingActor = ControllerOwner; + return; + } + } + } + else if (OverlapOwner && OverlapOwner->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + TArray Controllers; + bool bIsHeld; + IVRGripInterface::Execute_IsHeld(OverlapOwner, Controllers, bIsHeld); + + if (bIsHeld && Controllers.Num()) + { + AActor * ControllerOwner = Controllers[0].HoldingController != nullptr ? Controllers[0].HoldingController->GetOwner() : nullptr; + if (ControllerOwner) + { + LocalLastInteractingActor = ControllerOwner; + return; + } + } + } + + // Fall back to the owner, wasn't held and wasn't a character + if (OverlapOwner) + { + LocalLastInteractingActor = OverlapOwner; + return; + } + + LocalLastInteractingActor = nullptr; + return; +} + +void UVRButtonComponent::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) +{ + // Other Actor is the actor that triggered the event. Check that is not ourself. + if (bIsEnabled && !IsValid(LocalInteractingComponent) && (bSkipOverlapFiltering || IsValidOverlap(OtherComp))) + { + LocalInteractingComponent = OtherComp; + + FTransform OriginalBaseTransform = CalcNewComponentToWorld(InitialRelativeTransform); + FVector loc = LocalInteractingComponent->GetComponentLocation(); + InitialLocation = OriginalBaseTransform.InverseTransformPosition(LocalInteractingComponent->GetComponentLocation()); + InitialComponentLoc = OriginalBaseTransform.InverseTransformPosition(this->GetComponentLocation()); + bToggledThisTouch = false; + + this->SetComponentTickEnabled(true); + + if (LocalInteractingComponent != LocalLastInteractingComponent.Get()) + { + SetLastInteractingActor(); + OnButtonBeginInteraction.Broadcast(LocalLastInteractingActor.Get(), LocalLastInteractingComponent.Get()); + ReceiveButtonBeginInteraction(LocalLastInteractingActor.Get(), LocalLastInteractingComponent.Get()); + } + } +} + +void UVRButtonComponent::OnOverlapEnd(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) +{ + if (IsValid(LocalInteractingComponent) && OtherComp == LocalInteractingComponent) + { + LocalInteractingComponent = nullptr; + } +} + +FVector UVRButtonComponent::GetTargetRelativeLocation() +{ + // If target is the half pressed + if (ButtonType == EVRButtonType::Btn_Toggle_Stay && bButtonState) + { + // 1.e-2f = MORE_UE_KINDA_SMALL_NUMBER + return InitialRelativeTransform.TransformPosition(SetAxisValue(-(ButtonEngageDepth + (1.e-2f)))); + } + + // Else return going all the way back + return InitialRelativeTransform.GetTranslation(); + +} + +void UVRButtonComponent::SetButtonToRestingPosition(bool bLerpToPosition) +{ + switch (ButtonType) + { + case EVRButtonType::Btn_Press: + { + }break; + case EVRButtonType::Btn_Toggle_Return: + {}break; + case EVRButtonType::Btn_Toggle_Stay: + { + if (!bLerpToPosition) + { + float ClampMinDepth = 0.0f; + + // If active and a toggled stay, then clamp min to the toggled stay location + if (bButtonState) + ClampMinDepth = -(ButtonEngageDepth + (1.e-2f)); // + NOT_SO_UE_KINDA_SMALL_NUMBER + + float NewDepth = FMath::Clamp(ClampMinDepth, -DepressDistance, ClampMinDepth); + this->SetRelativeLocation(InitialRelativeTransform.TransformPosition(SetAxisValue(NewDepth)), false); + } + else + this->SetComponentTickEnabled(true); // This will trigger the lerp to resting position + + }break; + default:break; + } +} + +void UVRButtonComponent::SetButtonState(bool bNewButtonState, bool bCallButtonChangedEvent, bool bSnapIntoPosition) +{ + // No change + if (bButtonState == bNewButtonState) + return; + + bButtonState = bNewButtonState; + SetButtonToRestingPosition(!bSnapIntoPosition); + LastToggleTime = GetWorld()->GetRealTimeSeconds(); + + if (bCallButtonChangedEvent) + { + ReceiveButtonStateChanged(bButtonState, LocalLastInteractingActor.Get(), LocalLastInteractingComponent.Get()); + OnButtonStateChanged.Broadcast(bButtonState, LocalLastInteractingActor.Get(), LocalLastInteractingComponent.Get()); + } +} + +void UVRButtonComponent::ResetInitialButtonLocation() +{ + // Get our initial relative transform to our parent (or not if un-parented). + InitialRelativeTransform = this->GetRelativeTransform(); +} + +bool UVRButtonComponent::IsButtonInUse() +{ + return IsValid(LocalInteractingComponent); +} + +float UVRButtonComponent::GetAxisValue(FVector CheckLocation) +{ + switch (ButtonAxis) + { + case EVRInteractibleAxis::Axis_X: + return CheckLocation.X; break; + case EVRInteractibleAxis::Axis_Y: + return CheckLocation.Y; break; + case EVRInteractibleAxis::Axis_Z: + return CheckLocation.Z; break; + default:return 0.0f; break; + } +} + +FVector UVRButtonComponent::SetAxisValue(float SetValue) +{ + FVector vec = FVector::ZeroVector; + + switch (ButtonAxis) + { + case EVRInteractibleAxis::Axis_X: + vec.X = SetValue; break; + case EVRInteractibleAxis::Axis_Y: + vec.Y = SetValue; break; + case EVRInteractibleAxis::Axis_Z: + vec.Z = SetValue; break; + } + + return vec; +} + +void UVRButtonComponent::SetReplicateMovement(bool bNewReplicateMovement) +{ + bReplicateMovement = bNewReplicateMovement; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UVRButtonComponent, bReplicateMovement, this); +#endif +} + +void UVRButtonComponent::SetStateChangeAuthorityType(EVRStateChangeAuthorityType NewStateChangeAuthorityType) +{ + StateChangeAuthorityType = NewStateChangeAuthorityType; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UVRButtonComponent, StateChangeAuthorityType, this); +#endif +} + +void UVRButtonComponent::SetButtonState(bool bNewButtonState) +{ + bButtonState = bNewButtonState; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UVRButtonComponent, bButtonState, this); +#endif +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRDialComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRDialComponent.cpp new file mode 100644 index 0000000..7930efc --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRDialComponent.cpp @@ -0,0 +1,666 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Interactibles/VRDialComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRDialComponent) + +#include "VRExpansionFunctionLibrary.h" +#include "GripMotionControllerComponent.h" +#include "Net/UnrealNetwork.h" + +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + + //============================================================================= +UVRDialComponent::UVRDialComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + this->SetGenerateOverlapEvents(true); + this->PrimaryComponentTick.bStartWithTickEnabled = false; + PrimaryComponentTick.bCanEverTick = true; + + bRepGameplayTags = false; + + // Defaulting these true so that they work by default in networked environments + bReplicateMovement = true; + + DialRotationAxis = EVRInteractibleAxis::Axis_Z; + InteractorRotationAxis = EVRInteractibleAxis::Axis_X; + + bDialUsesAngleSnap = false; + bDialUseSnapAngleList = false; + SnapAngleThreshold = 45.0f; + SnapAngleIncrement = 45.0f; + LastSnapAngle = 0.0f; + RotationScaler = 1.0f; + + ClockwiseMaximumDialAngle = 180.0f; + CClockwiseMaximumDialAngle = 180.0f; + bDenyGripping = false; + + PrimarySlotRange = 100.f; + SecondarySlotRange = 100.f; + GripPriority = 1; + + MovementReplicationSetting = EGripMovementReplicationSettings::ForceClientSideMovement; + BreakDistance = 100.0f; + + bLerpBackOnRelease = false; + bSendDialEventsDuringLerp = false; + DialReturnSpeed = 90.0f; + bIsLerping = false; + + bDialUseDirectHandRotation = false; + LastGripRot = 0.0f; + InitialGripRot = 0.f; + InitialRotBackEnd = 0.f; + bUseRollover = false; +} + +//============================================================================= +UVRDialComponent::~UVRDialComponent() +{ +} + + +void UVRDialComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UVRDialComponent, InitialRelativeTransform, PushModelParams); + //DOREPLIFETIME_CONDITION(UVRDialComponent, bIsLerping, COND_InitialOnly); + + DOREPLIFETIME_WITH_PARAMS_FAST(UVRDialComponent, bRepGameplayTags, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UVRDialComponent, bReplicateMovement, PushModelParams); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UVRDialComponent, GameplayTags, PushModelParamsWithCondition); +} + +void UVRDialComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) +{ + Super::PreReplication(ChangedPropertyTracker); + + // Don't replicate if set to not do it + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UVRDialComponent, GameplayTags, bRepGameplayTags); + + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeLocation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeRotation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeScale3D, bReplicateMovement); +} + +void UVRDialComponent::OnRegister() +{ + Super::OnRegister(); + ResetInitialDialLocation(); // Load the original dial location +} + +void UVRDialComponent::BeginPlay() +{ + // Call the base class + Super::BeginPlay(); + CalculateDialProgress(); + + bOriginalReplicatesMovement = bReplicateMovement; +} + +void UVRDialComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) +{ + if (bIsLerping) + { + if (bUseRollover) + { + this->SetDialAngle(FMath::FInterpConstantTo(CurRotBackEnd, 0.f, DeltaTime, DialReturnSpeed), bSendDialEventsDuringLerp); + } + else + { + // Flip lerp direction if we are on the other side + if (CurrentDialAngle > ClockwiseMaximumDialAngle) + this->SetDialAngle(FMath::FInterpConstantTo(CurRotBackEnd, 360.f, DeltaTime, DialReturnSpeed), bSendDialEventsDuringLerp); + else + this->SetDialAngle(FMath::FInterpConstantTo(CurRotBackEnd, 0.f, DeltaTime, DialReturnSpeed), bSendDialEventsDuringLerp); + } + + if (CurRotBackEnd == 0.f) + { + this->SetComponentTickEnabled(false); + bIsLerping = false; + OnDialFinishedLerping.Broadcast(); + ReceiveDialFinishedLerping(); + } + } + else + { + this->SetComponentTickEnabled(false); + } +} + +void UVRDialComponent::TickGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation, float DeltaTime) +{ + + // #TODO: Should this use a pivot rotation? it wouldn't make that much sense to me? + float DeltaRot = 0.0f; + + if (!bDialUseDirectHandRotation) + { + FTransform CurrentRelativeTransform = InitialRelativeTransform * UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(this); + FVector CurInteractorLocation = CurrentRelativeTransform.InverseTransformPosition(GrippingController->GetPivotLocation()); + + float NewRot = FRotator::ClampAxis(UVRInteractibleFunctionLibrary::GetAtan2Angle(DialRotationAxis, CurInteractorLocation)); + //DeltaRot = RotationScaler * ( NewRot - LastGripRot); + + DeltaRot = RotationScaler * FMath::FindDeltaAngleDegrees(LastGripRot, NewRot); + + float LimitTest = FRotator::ClampAxis(((NewRot - InitialGripRot) + InitialRotBackEnd)); + float MaxCheckValue = bUseRollover ? -CClockwiseMaximumDialAngle : 360.0f - CClockwiseMaximumDialAngle; + + if (FMath::IsNearlyZero(CClockwiseMaximumDialAngle)) + { + if (LimitTest > ClockwiseMaximumDialAngle && (CurRotBackEnd == ClockwiseMaximumDialAngle || CurRotBackEnd == 0.f)) + { + DeltaRot = 0.f; + } + } + else if (FMath::IsNearlyZero(ClockwiseMaximumDialAngle)) + { + if (LimitTest < MaxCheckValue && (CurRotBackEnd == MaxCheckValue || CurRotBackEnd == 0.f)) + { + DeltaRot = 0.f; + } + } + else if (LimitTest > ClockwiseMaximumDialAngle && LimitTest < MaxCheckValue && (CurRotBackEnd == ClockwiseMaximumDialAngle || CurRotBackEnd == MaxCheckValue)) + { + DeltaRot = 0.f; + } + + LastGripRot = NewRot; + } + else + { + FRotator curRotation = GrippingController->GetComponentRotation(); + DeltaRot = RotationScaler * UVRInteractibleFunctionLibrary::GetAxisValue(InteractorRotationAxis, (curRotation - LastRotation).GetNormalized()); + LastRotation = curRotation; + } + + AddDialAngle(DeltaRot, true); + + // Handle the auto drop + if (BreakDistance > 0.f && GrippingController->HasGripAuthority(GripInformation) && FVector::DistSquared(InitialDropLocation, this->GetComponentTransform().InverseTransformPosition(GrippingController->GetPivotLocation())) >= FMath::Square(BreakDistance)) + { + if (GrippingController->OnGripOutOfRange.IsBound()) + { + uint8 GripID = GripInformation.GripID; + GrippingController->OnGripOutOfRange.Broadcast(GripInformation, GripInformation.GripDistance); + } + else + { + GrippingController->DropObjectByInterface(this, HoldingGrip.GripID); + } + return; + } +} + +void UVRDialComponent::OnGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) +{ + FTransform CurrentRelativeTransform = InitialRelativeTransform * UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(this); + + // This lets me use the correct original location over the network without changes + FTransform ReversedRelativeTransform = FTransform(GripInformation.RelativeTransform.ToInverseMatrixWithScale()); + FTransform CurrentTransform = this->GetComponentTransform(); + FTransform RelativeToGripTransform = ReversedRelativeTransform * CurrentTransform; + + //FTransform InitialTrans = RelativeToGripTransform.GetRelativeTransform(CurrentRelativeTransform); + + InitialInteractorLocation = CurrentRelativeTransform.InverseTransformPosition(RelativeToGripTransform.GetTranslation()); + InitialDropLocation = ReversedRelativeTransform.GetTranslation(); + + if (!bDialUseDirectHandRotation) + { + LastGripRot = FRotator::ClampAxis(UVRInteractibleFunctionLibrary::GetAtan2Angle(DialRotationAxis, InitialInteractorLocation)); + InitialGripRot = LastGripRot; + InitialRotBackEnd = CurRotBackEnd; + } + else + { + LastRotation = RelativeToGripTransform.GetRotation().Rotator(); // Forcing into world space now so that initial can be correct over the network + } + + bIsLerping = false; + + //OnGripped.Broadcast(GrippingController, GripInformation); +} + +void UVRDialComponent::OnGripRelease_Implementation(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed) +{ + if (bDialUsesAngleSnap && bDialUseSnapAngleList) + { + float closestAngle = 0.f; + float closestVal = FMath::Abs(closestAngle - CurRotBackEnd); + float closestValt = 0.f; + for (float val : DialSnapAngleList) + { + closestValt = FMath::Abs(val - CurRotBackEnd); + if (closestValt < closestVal) + { + closestAngle = val; + closestVal = closestValt; + } + } + + if (closestAngle != LastSnapAngle) + { + this->SetRelativeRotation((FTransform(UVRInteractibleFunctionLibrary::SetAxisValueRot(DialRotationAxis, FMath::UnwindDegrees(closestAngle), FRotator::ZeroRotator)) * InitialRelativeTransform).Rotator()); + CurrentDialAngle = FMath::RoundToFloat(closestAngle); + CurRotBackEnd = CurrentDialAngle; + + if (!FMath::IsNearlyEqual(LastSnapAngle, CurrentDialAngle)) + { + ReceiveDialHitSnapAngle(CurrentDialAngle); + OnDialHitSnapAngle.Broadcast(CurrentDialAngle); + LastSnapAngle = CurrentDialAngle; + } + } + } + else if (bDialUsesAngleSnap && SnapAngleIncrement > 0.f)// && FMath::Abs(FMath::Fmod(CurRotBackEnd, SnapAngleIncrement)) <= FMath::Min(SnapAngleIncrement, SnapAngleThreshold)) + { + + float AngleOffsetCheck = FMath::Abs(FRotator::ClampAxis(CurRotBackEnd) - FRotator::ClampAxis(LastSnapAngle)); + float TargetSnap = FMath::RoundToFloat(FMath::GridSnap(CurRotBackEnd, SnapAngleIncrement)); + + if (FMath::Abs(FRotator::ClampAxis(CurRotBackEnd) - TargetSnap) <= FMath::Min(SnapAngleIncrement, SnapAngleThreshold)) + { + if (AngleOffsetCheck >= SnapAngleThreshold)//FMath::Min(SnapAngleIncrement, SnapAngleThreshold)) + { + this->SetRelativeRotation((FTransform(UVRInteractibleFunctionLibrary::SetAxisValueRot(DialRotationAxis, FMath::GridSnap(CurRotBackEnd, SnapAngleIncrement), FRotator::ZeroRotator)) * InitialRelativeTransform).Rotator()); + CurRotBackEnd = FMath::GridSnap(CurRotBackEnd, SnapAngleIncrement); + } + } + + if (bUseRollover) + { + CurrentDialAngle = FMath::RoundToFloat(CurRotBackEnd); + } + else + { + CurrentDialAngle = FRotator::ClampAxis(FMath::RoundToFloat(CurRotBackEnd)); + } + + if (!FMath::IsNearlyEqual(LastSnapAngle, CurrentDialAngle)) + { + ReceiveDialHitSnapAngle(CurrentDialAngle); + OnDialHitSnapAngle.Broadcast(CurrentDialAngle); + LastSnapAngle = CurrentDialAngle; + } + } + + if (bLerpBackOnRelease) + { + bIsLerping = true; + this->SetComponentTickEnabled(true); + } + else + this->SetComponentTickEnabled(false); + + //OnDropped.Broadcast(ReleasingController, GripInformation, bWasSocketed); +} + +void UVRDialComponent::SetGripPriority(int NewGripPriority) +{ + GripPriority = NewGripPriority; +} + +void UVRDialComponent::OnChildGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) {} +void UVRDialComponent::OnChildGripRelease_Implementation(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed) {} +void UVRDialComponent::OnSecondaryGrip_Implementation(UGripMotionControllerComponent * GripOwningController, USceneComponent * SecondaryGripComponent, const FBPActorGripInformation & GripInformation) {} +void UVRDialComponent::OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent * GripOwningController, USceneComponent * ReleasingSecondaryGripComponent, const FBPActorGripInformation & GripInformation) {} +void UVRDialComponent::OnUsed_Implementation() {} +void UVRDialComponent::OnEndUsed_Implementation() {} +void UVRDialComponent::OnSecondaryUsed_Implementation() {} +void UVRDialComponent::OnEndSecondaryUsed_Implementation() {} +void UVRDialComponent::OnInput_Implementation(FKey Key, EInputEvent KeyEvent) {} +bool UVRDialComponent::RequestsSocketing_Implementation(USceneComponent *& ParentToSocketTo, FName & OptionalSocketName, FTransform_NetQuantize & RelativeTransform) { return false; } + +bool UVRDialComponent::DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator) +{ + return bDenyGripping; +} + +EGripInterfaceTeleportBehavior UVRDialComponent::TeleportBehavior_Implementation() +{ + return EGripInterfaceTeleportBehavior::DropOnTeleport; +} + +bool UVRDialComponent::SimulateOnDrop_Implementation() +{ + return false; +} + +/*EGripCollisionType UVRDialComponent::SlotGripType_Implementation() +{ + return EGripCollisionType::CustomGrip; +} + +EGripCollisionType UVRDialComponent::FreeGripType_Implementation() +{ + return EGripCollisionType::CustomGrip; +}*/ + +EGripCollisionType UVRDialComponent::GetPrimaryGripType_Implementation(bool bIsSlot) +{ + return EGripCollisionType::CustomGrip; +} + +ESecondaryGripType UVRDialComponent::SecondaryGripType_Implementation() +{ + return ESecondaryGripType::SG_None; +} + + +EGripMovementReplicationSettings UVRDialComponent::GripMovementReplicationType_Implementation() +{ + return MovementReplicationSetting; +} + +EGripLateUpdateSettings UVRDialComponent::GripLateUpdateSetting_Implementation() +{ + return EGripLateUpdateSettings::LateUpdatesAlwaysOff; +} + +/*float UVRDialComponent::GripStiffness_Implementation() +{ + return 1500.0f; +} + +float UVRDialComponent::GripDamping_Implementation() +{ + return 200.0f; +}*/ + +void UVRDialComponent::GetGripStiffnessAndDamping_Implementation(float &GripStiffnessOut, float &GripDampingOut) +{ + GripStiffnessOut = 0.0f; + GripDampingOut = 0.0f; +} + +FBPAdvGripSettings UVRDialComponent::AdvancedGripSettings_Implementation() +{ + return FBPAdvGripSettings(GripPriority); +} + +float UVRDialComponent::GripBreakDistance_Implementation() +{ + return BreakDistance; +} + +/*void UVRDialComponent::ClosestSecondarySlotInRange_Implementation(FVector WorldLocation, bool & bHadSlotInRange, FTransform & SlotWorldTransform, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ + bHadSlotInRange = false; +} + +void UVRDialComponent::ClosestPrimarySlotInRange_Implementation(FVector WorldLocation, bool & bHadSlotInRange, FTransform & SlotWorldTransform, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ + bHadSlotInRange = false; +}*/ + +void UVRDialComponent::ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool & bHadSlotInRange, FTransform & SlotWorldTransform, FName & SlotName, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ + if (OverridePrefix.IsNone()) + bSecondarySlot ? OverridePrefix = "VRGripS" : OverridePrefix = "VRGripP"; + + UVRExpansionFunctionLibrary::GetGripSlotInRangeByTypeName_Component(OverridePrefix, this, WorldLocation, bSecondarySlot ? SecondarySlotRange : PrimarySlotRange, bHadSlotInRange, SlotWorldTransform, SlotName, CallingController); +} + +bool UVRDialComponent::AllowsMultipleGrips_Implementation() +{ + return false; +} + +void UVRDialComponent::IsHeld_Implementation(TArray & CurHoldingControllers, bool & bCurIsHeld) +{ + CurHoldingControllers.Empty(); + if (HoldingGrip.IsValid()) + { + CurHoldingControllers.Add(HoldingGrip); + bCurIsHeld = bIsHeld; + } + else + { + bCurIsHeld = false; + } +} + +void UVRDialComponent::Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed) +{ + if (bGripped) + { + OnGripped.Broadcast(Controller, GripInformation); + } + else + { + OnDropped.Broadcast(Controller, GripInformation, bWasSocketed); + } +} + +void UVRDialComponent::SetHeld_Implementation(UGripMotionControllerComponent * NewHoldingController, uint8 GripID, bool bNewIsHeld) +{ + if (bNewIsHeld) + { + HoldingGrip = FBPGripPair(NewHoldingController, GripID); + if (MovementReplicationSetting != EGripMovementReplicationSettings::ForceServerSideMovement) + { + if(!bIsHeld) + bOriginalReplicatesMovement = bReplicateMovement; + bReplicateMovement = false; + } + } + else + { + HoldingGrip.Clear(); + if (MovementReplicationSetting != EGripMovementReplicationSettings::ForceServerSideMovement) + { + bReplicateMovement = bOriginalReplicatesMovement; + } + } + + bIsHeld = bNewIsHeld; +} + +/*FBPInteractionSettings UVRDialComponent::GetInteractionSettings_Implementation() +{ + return FBPInteractionSettings(); +}*/ + +bool UVRDialComponent::GetGripScripts_Implementation(TArray & ArrayReference) +{ + return false; +} + +void UVRDialComponent::SetDialAngle(float DialAngle, bool bCallEvents) +{ + CurRotBackEnd = DialAngle; + AddDialAngle(0.0f, bCallEvents); +} + +void UVRDialComponent::AddDialAngle(float DialAngleDelta, bool bCallEvents, bool bSkipSettingRot) +{ + //FindDeltaAngleDegrees + /** Utility to ensure angle is between +/- 180 degrees by unwinding. */ +//static float UnwindDegrees(float A) + float MaxCheckValue = bUseRollover ? -CClockwiseMaximumDialAngle : 360.0f - CClockwiseMaximumDialAngle; + + float DeltaRot = DialAngleDelta; + float tempCheck = bUseRollover ? CurRotBackEnd + DeltaRot : FRotator::ClampAxis(CurRotBackEnd + DeltaRot); + + // Clamp it to the boundaries + if (FMath::IsNearlyZero(CClockwiseMaximumDialAngle)) + { + CurRotBackEnd = FMath::Clamp(CurRotBackEnd + DeltaRot, 0.0f, ClockwiseMaximumDialAngle); + } + else if (FMath::IsNearlyZero(ClockwiseMaximumDialAngle)) + { + if (bUseRollover) + { + CurRotBackEnd = FMath::Clamp(CurRotBackEnd + DeltaRot, -CClockwiseMaximumDialAngle, 0.0f); + } + else + { + if (CurRotBackEnd < MaxCheckValue) + CurRotBackEnd = FMath::Clamp(360.0f + DeltaRot, MaxCheckValue, 360.0f); + else + CurRotBackEnd = FMath::Clamp(CurRotBackEnd + DeltaRot, MaxCheckValue, 360.0f); + } + } + else if (!bUseRollover && tempCheck > ClockwiseMaximumDialAngle && tempCheck < MaxCheckValue) + { + if (CurRotBackEnd < MaxCheckValue) + { + CurRotBackEnd = ClockwiseMaximumDialAngle; + } + else + { + CurRotBackEnd = MaxCheckValue; + } + } + else if (bUseRollover) + { + if (tempCheck > ClockwiseMaximumDialAngle) + { + CurRotBackEnd = ClockwiseMaximumDialAngle; + } + else if (tempCheck < MaxCheckValue) + { + CurRotBackEnd = MaxCheckValue; + } + else + { + CurRotBackEnd = tempCheck; + } + } + else + { + CurRotBackEnd = tempCheck; + } + + if (bDialUsesAngleSnap && bDialUseSnapAngleList) + { + float closestAngle = 0.f; + // Always default 0.0f to the list + float closestVal = FMath::Abs(closestAngle - CurRotBackEnd); + float closestValt = 0.f; + for (float val : DialSnapAngleList) + { + closestValt = FMath::Abs(val - CurRotBackEnd); + if (closestValt < closestVal) + { + closestAngle = val; + closestVal = closestValt; + } + } + + if (closestAngle != LastSnapAngle) + { + if (!bSkipSettingRot) + this->SetRelativeRotation((FTransform(UVRInteractibleFunctionLibrary::SetAxisValueRot(DialRotationAxis, FMath::UnwindDegrees(closestAngle), FRotator::ZeroRotator)) * InitialRelativeTransform).Rotator()); + CurrentDialAngle = FMath::RoundToFloat(closestAngle); + + if (bCallEvents && !FMath::IsNearlyEqual(LastSnapAngle, CurrentDialAngle)) + { + ReceiveDialHitSnapAngle(CurrentDialAngle); + OnDialHitSnapAngle.Broadcast(CurrentDialAngle); + } + + LastSnapAngle = CurrentDialAngle; + } + } + else if (bDialUsesAngleSnap && SnapAngleIncrement > 0.f)// && FMath::Abs(FMath::Fmod(CurRotBackEnd, SnapAngleIncrement)) <= FMath::Min(SnapAngleIncrement, SnapAngleThreshold)) + { + float AngleOffsetCheck = FMath::Abs(FRotator::ClampAxis(CurRotBackEnd) - FRotator::ClampAxis(LastSnapAngle)); + float TargetSnap = FMath::RoundToFloat(FMath::GridSnap(CurRotBackEnd, SnapAngleIncrement)); + + if (FMath::Abs(FRotator::ClampAxis(CurRotBackEnd) - TargetSnap) <= FMath::Min(SnapAngleIncrement, SnapAngleThreshold)) + { + if (AngleOffsetCheck >= SnapAngleThreshold)//FMath::Min(SnapAngleIncrement, SnapAngleThreshold)) + { + if (!bSkipSettingRot) + this->SetRelativeRotation((FTransform(UVRInteractibleFunctionLibrary::SetAxisValueRot(DialRotationAxis, FMath::UnwindDegrees(FMath::GridSnap(CurRotBackEnd, SnapAngleIncrement)), FRotator::ZeroRotator)) * InitialRelativeTransform).Rotator()); + CurrentDialAngle = FMath::RoundToFloat(FMath::GridSnap(CurRotBackEnd, SnapAngleIncrement)); + + if (bCallEvents && !FMath::IsNearlyEqual(LastSnapAngle, CurrentDialAngle)) + { + ReceiveDialHitSnapAngle(CurrentDialAngle); + OnDialHitSnapAngle.Broadcast(CurrentDialAngle); + } + + LastSnapAngle = CurrentDialAngle; + } + } + else + { + if (!bSkipSettingRot) + this->SetRelativeRotation((FTransform(UVRInteractibleFunctionLibrary::SetAxisValueRot(DialRotationAxis, FMath::UnwindDegrees(CurRotBackEnd), FRotator::ZeroRotator)) * InitialRelativeTransform).Rotator()); + CurrentDialAngle = FMath::RoundToFloat(CurRotBackEnd); + } + } + else + { + if (!bSkipSettingRot) + this->SetRelativeRotation((FTransform(UVRInteractibleFunctionLibrary::SetAxisValueRot(DialRotationAxis, FMath::UnwindDegrees(CurRotBackEnd), FRotator::ZeroRotator)) * InitialRelativeTransform).Rotator()); + CurrentDialAngle = FMath::RoundToFloat(CurRotBackEnd); + } + +} + +void UVRDialComponent::ResetInitialDialLocation() +{ + // Get our initial relative transform to our parent (or not if un-parented). + InitialRelativeTransform = this->GetRelativeTransform(); + +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UVRDialComponent, InitialRelativeTransform, this); +#endif + + CurRotBackEnd = 0.0f; + CalculateDialProgress(); +} + +void UVRDialComponent::CalculateDialProgress() +{ + FTransform CurRelativeTransform = this->GetComponentTransform().GetRelativeTransform(UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(this)); + LastGripRot = UVRInteractibleFunctionLibrary::GetDeltaAngleFromTransforms(DialRotationAxis, InitialRelativeTransform, CurRelativeTransform); + CurRotBackEnd = LastGripRot; + AddDialAngle(0.0f, false, true); +} + + +void UVRDialComponent::SetRepGameplayTags(bool bNewRepGameplayTags) +{ + bRepGameplayTags = bNewRepGameplayTags; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UVRDialComponent, bRepGameplayTags, this); +#endif +} + +void UVRDialComponent::SetReplicateMovement(bool bNewReplicateMovement) +{ + bReplicateMovement = bNewReplicateMovement; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UVRDialComponent, bReplicateMovement, this); +#endif +} + +FGameplayTagContainer& UVRDialComponent::GetGameplayTags() +{ +#if WITH_PUSH_MODEL + if (bRepGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UVRDialComponent, GameplayTags, this); + } +#endif + + return GameplayTags; +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRInteractibleFunctionLibrary.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRInteractibleFunctionLibrary.cpp new file mode 100644 index 0000000..4ec29f9 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRInteractibleFunctionLibrary.cpp @@ -0,0 +1,8 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "Interactibles/VRInteractibleFunctionLibrary.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRInteractibleFunctionLibrary) + +//#include "Engine/Engine.h" + +//General Log +DEFINE_LOG_CATEGORY(VRInteractibleFunctionLibraryLog); \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRLeverComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRLeverComponent.cpp new file mode 100644 index 0000000..44ca29f --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRLeverComponent.cpp @@ -0,0 +1,863 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Interactibles/VRLeverComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRLeverComponent) + +#include "GripMotionControllerComponent.h" +#include "VRExpansionFunctionLibrary.h" +#include "Net/UnrealNetwork.h" + +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + + //============================================================================= +UVRLeverComponent::UVRLeverComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + this->SetGenerateOverlapEvents(true); + this->PrimaryComponentTick.bStartWithTickEnabled = false; + PrimaryComponentTick.bCanEverTick = true; + + bRepGameplayTags = false; + + // Defaulting these true so that they work by default in networked environments + bReplicateMovement = true; + + MovementReplicationSetting = EGripMovementReplicationSettings::ForceClientSideMovement; + BreakDistance = 100.0f; + Stiffness = 1500.0f; + Damping = 200.0f; + + //SceneIndex = 0; + + ParentComponent = nullptr; + LeverRotationAxis = EVRInteractibleLeverAxis::Axis_X; + + LeverLimitNegative = 0.0f; + LeverLimitPositive = 90.0f; + FlightStickYawLimit = 180.0f; + bLeverState = false; + LeverTogglePercentage = 0.8f; + + LastDeltaAngle = 0.0f; + FullCurrentAngle = 0.0f; + + LeverReturnTypeWhenReleased = EVRInteractibleLeverReturnType::ReturnToZero; + LeverReturnSpeed = 50.0f; + + MomentumAtDrop = 0.0f; + LeverMomentumFriction = 5.0f; + MaxLeverMomentum = 180.0f; + FramesToAverage = 3; + + bBlendAxisValuesByAngleThreshold = false; + AngleThreshold = 90.0f; + + LastLeverAngle = 0.0f; + + bSendLeverEventsDuringLerp = false; + + InitialRelativeTransform = FTransform::Identity; + InitialInteractorLocation = FVector::ZeroVector; + InteractorOffsetTransform = FTransform::Identity; + AllCurrentLeverAngles = FRotator::ZeroRotator; + InitialGripRot = 0.0f; + qRotAtGrab = FQuat::Identity; + bIsLerping = false; + bUngripAtTargetRotation = false; + bDenyGripping = false; + + bIsLocked = false; + bAutoDropWhenLocked = true; + + PrimarySlotRange = 100.f; + SecondarySlotRange = 100.f; + GripPriority = 1; + + // Set to only overlap with things so that its not ruined by touching over actors + this->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Overlap); +} + +//============================================================================= +UVRLeverComponent::~UVRLeverComponent() +{ +} + + +void UVRLeverComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UVRLeverComponent, InitialRelativeTransform, PushModelParams); + //DOREPLIFETIME_CONDITION(UVRDialComponent, bIsLerping, COND_InitialOnly); + + DOREPLIFETIME_WITH_PARAMS_FAST(UVRLeverComponent, bRepGameplayTags, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UVRLeverComponent, bReplicateMovement, PushModelParams); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UVRLeverComponent, GameplayTags, PushModelParamsWithCondition); +} + +void UVRLeverComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) +{ + Super::PreReplication(ChangedPropertyTracker); + + // Replicate the levers initial transform if we are replicating movement + //DOREPLIFETIME_ACTIVE_OVERRIDE(UVRLeverComponent, InitialRelativeTransform, bReplicateMovement); + + // Don't replicate if set to not do it + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UVRLeverComponent, GameplayTags, bRepGameplayTags); + + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeLocation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeRotation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeScale3D, bReplicateMovement); +} + +void UVRLeverComponent::OnRegister() +{ + Super::OnRegister(); + ResetInitialLeverLocation(); // Load the original lever location +} + +void UVRLeverComponent::BeginPlay() +{ + // Call the base class + Super::BeginPlay(); + ReCalculateCurrentAngle(true); + bOriginalReplicatesMovement = bReplicateMovement; +} + +void UVRLeverComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) +{ + // Call supers tick (though I don't think any of the base classes to this actually implement it) + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + bool bWasLerping = bIsLerping; + + // If we are locked then end the lerp, no point + if (bIsLocked) + { + + if (bWasLerping) + { + bIsLerping = false; + + // If we start lerping while locked, just end it + OnLeverFinishedLerping.Broadcast(CurrentLeverAngle); + ReceiveLeverFinishedLerping(CurrentLeverAngle); + } + + return; + } + + if (bIsLerping) + { + FTransform CurRelativeTransform = this->GetComponentTransform().GetRelativeTransform(UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(this)); + + switch (LeverRotationAxis) + { + case EVRInteractibleLeverAxis::Axis_X: + case EVRInteractibleLeverAxis::Axis_Y: + case EVRInteractibleLeverAxis::Axis_Z: + { + LerpAxis(FullCurrentAngle, DeltaTime); + }break; + case EVRInteractibleLeverAxis::Axis_XY: + case EVRInteractibleLeverAxis::FlightStick_XY: + { + // Only supporting LerpToZero with this mode currently + FQuat LerpedQuat = FMath::QInterpConstantTo(CurRelativeTransform.GetRelativeTransform(InitialRelativeTransform).GetRotation(), FQuat::Identity, DeltaTime, FMath::DegreesToRadians(LeverReturnSpeed)); + + if (LerpedQuat.IsIdentity()) + { + this->SetComponentTickEnabled(false); + bIsLerping = false; + bReplicateMovement = bOriginalReplicatesMovement; + this->SetRelativeRotation(InitialRelativeTransform.Rotator()); + } + else + { + this->SetRelativeRotation((FTransform(LerpedQuat) * InitialRelativeTransform).GetRotation()); + } + }break; + default:break; + } + } + + FTransform CurrentRelativeTransform = this->GetComponentTransform().GetRelativeTransform(UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(this)); + CalculateCurrentAngle(CurrentRelativeTransform); + + + if (!bWasLerping && LeverReturnTypeWhenReleased == EVRInteractibleLeverReturnType::RetainMomentum) + { + // Rolling average across num samples + MomentumAtDrop -= MomentumAtDrop / FramesToAverage; + MomentumAtDrop += ((FullCurrentAngle - LastLeverAngle) / DeltaTime) / FramesToAverage; + + MomentumAtDrop = FMath::Min(MaxLeverMomentum, MomentumAtDrop); + + LastLeverAngle = FullCurrentAngle; + } + + // Check for events and set current state and check for auto drop + ProccessCurrentState(bWasLerping, true, true); + + // If the lerping state changed from the above + if (bWasLerping && !bIsLerping) + { + OnLeverFinishedLerping.Broadcast(CurrentLeverAngle); + ReceiveLeverFinishedLerping(CurrentLeverAngle); + } +} + +void UVRLeverComponent::ProccessCurrentState(bool bWasLerping, bool bThrowEvents, bool bCheckAutoDrop) +{ + bool bNewLeverState = (!FMath::IsNearlyZero(LeverLimitNegative) && FullCurrentAngle <= -(LeverLimitNegative * LeverTogglePercentage)) || (!FMath::IsNearlyZero(LeverLimitPositive) && FullCurrentAngle >= (LeverLimitPositive * LeverTogglePercentage)); + //if (FMath::Abs(CurrentLeverAngle) >= LeverLimit ) + if (bNewLeverState != bLeverState) + { + bLeverState = bNewLeverState; + + if (bThrowEvents && (bSendLeverEventsDuringLerp || !bWasLerping)) + { + ReceiveLeverStateChanged(bLeverState, FullCurrentAngle >= 0.0f ? EVRInteractibleLeverEventType::LeverPositive : EVRInteractibleLeverEventType::LeverNegative, CurrentLeverAngle, FullCurrentAngle); + OnLeverStateChanged.Broadcast(bLeverState, FullCurrentAngle >= 0.0f ? EVRInteractibleLeverEventType::LeverPositive : EVRInteractibleLeverEventType::LeverNegative, CurrentLeverAngle, FullCurrentAngle); + } + + if (bCheckAutoDrop) + { + if (!bWasLerping && bUngripAtTargetRotation && bLeverState && HoldingGrip.IsValid()) + { + FBPActorGripInformation GripInformation; + EBPVRResultSwitch result; + HoldingGrip.HoldingController->GetGripByID(GripInformation, HoldingGrip.GripID, result); + if (result == EBPVRResultSwitch::OnSucceeded && HoldingGrip.HoldingController->HasGripAuthority(GripInformation)) + { + HoldingGrip.HoldingController->DropObjectByInterface(this, HoldingGrip.GripID); + } + } + } + } +} + +void UVRLeverComponent::OnUnregister() +{ + Super::OnUnregister(); +} + +bool UVRLeverComponent::CheckAutoDrop(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) +{ + // Converted to a relative value now so it should be correct + if (BreakDistance > 0.f && GrippingController->HasGripAuthority(GripInformation) && FVector::DistSquared(InitialInteractorDropLocation, this->GetComponentTransform().InverseTransformPosition(GrippingController->GetPivotLocation())) >= FMath::Square(BreakDistance)) + { + if (GrippingController->OnGripOutOfRange.IsBound()) + { + uint8 GripID = GripInformation.GripID; + GrippingController->OnGripOutOfRange.Broadcast(GripInformation, GripInformation.GripDistance); + } + else + { + GrippingController->DropObjectByInterface(this, HoldingGrip.GripID); + } + + return true; + } + + return false; +} + +void UVRLeverComponent::TickGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation, float DeltaTime) +{ + if (bIsLocked) + { + if (bAutoDropWhenLocked) + { + // Check if we should auto drop + CheckAutoDrop(GrippingController, GripInformation); + } + + return; + } + + // Handle manual tracking here + FTransform ParentTransform = UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(this); + FTransform CurrentRelativeTransform = InitialRelativeTransform * ParentTransform; + FTransform PivotTransform = GrippingController->GetPivotTransform(); + FVector CurInteractorLocation = (InteractorOffsetTransform * PivotTransform).GetRelativeTransform(CurrentRelativeTransform).GetTranslation(); + + switch (LeverRotationAxis) + { + case EVRInteractibleLeverAxis::Axis_XY: + case EVRInteractibleLeverAxis::FlightStick_XY: + { + FRotator Rot; + + FVector nAxis; + float nAngle = 0.0f; + + FQuat::FindBetweenVectors(qRotAtGrab.UnrotateVector(InitialInteractorLocation), CurInteractorLocation).ToAxisAndAngle(nAxis, nAngle); + float MaxAngle = FMath::DegreesToRadians(LeverLimitPositive); + + bool bWasClamped = nAngle > MaxAngle; + nAngle = FMath::Clamp(nAngle, 0.0f, MaxAngle); + Rot = FQuat(nAxis, nAngle).Rotator(); + + if (LeverRotationAxis == EVRInteractibleLeverAxis::FlightStick_XY) + { + // Store our projected relative transform + FTransform CalcTransform = (FTransform(Rot) * InitialRelativeTransform); + + // Fixup yaw if this is a flight stick + + if (bWasClamped) + { + // If we clamped the angle due to limits then lets re-project the hand back to get the correct facing again + // This is only when things have been clamped to avoid the extra calculations + FTransform NewPivTrans = PivotTransform.GetRelativeTransform((CalcTransform * ParentTransform)); + CurInteractorLocation = NewPivTrans.GetTranslation(); + + FVector OffsetVal = CurInteractorLocation + NewPivTrans.GetRotation().RotateVector(InteractorOffsetTransform.GetTranslation()); + OffsetVal.Z = 0; + + CurInteractorLocation -= OffsetVal; + } + else + { + CurInteractorLocation = (CalcTransform * ParentTransform).InverseTransformPosition(GrippingController->GetPivotLocation()); + } + + float CurrentLeverYawAngle = FRotator::NormalizeAxis(UVRInteractibleFunctionLibrary::GetAtan2Angle(EVRInteractibleAxis::Axis_Z, CurInteractorLocation, InitialGripRot)); + + if (FlightStickYawLimit < 180.0f) + { + CurrentLeverYawAngle = FMath::Clamp(CurrentLeverYawAngle, -FlightStickYawLimit, FlightStickYawLimit); + } + + FQuat newLocalRot = CalcTransform.GetRotation() * FQuat(FVector::UpVector, FMath::DegreesToRadians(CurrentLeverYawAngle)); + this->SetRelativeRotation(newLocalRot.Rotator()); + } + else + { + this->SetRelativeRotation((FTransform(Rot) * InitialRelativeTransform).Rotator()); + } + } + break; + case EVRInteractibleLeverAxis::Axis_X: + case EVRInteractibleLeverAxis::Axis_Y: + case EVRInteractibleLeverAxis::Axis_Z: + { + float DeltaAngle = CalcAngle(LeverRotationAxis, CurInteractorLocation); + LastDeltaAngle = DeltaAngle; + FTransform CalcTransform = (FTransform(UVRInteractibleFunctionLibrary::SetAxisValueRot((EVRInteractibleAxis)LeverRotationAxis, DeltaAngle, FRotator::ZeroRotator)) * InitialRelativeTransform); + this->SetRelativeRotation(CalcTransform.Rotator()); + }break; + default:break; + } + + // Recalc current angle + CurrentRelativeTransform = this->GetComponentTransform().GetRelativeTransform(UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(this)); + CalculateCurrentAngle(CurrentRelativeTransform); + + // Check for events and set current state and check for auto drop + ProccessCurrentState(bIsLerping, true, true); + + // Check if we should auto drop + CheckAutoDrop(GrippingController, GripInformation); +} + +void UVRLeverComponent::OnGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) +{ + ParentComponent = this->GetAttachParent(); + + FTransform CurrentRelativeTransform = InitialRelativeTransform * UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(this); + + // This lets me use the correct original location over the network without changes + FTransform ReversedRelativeTransform = FTransform(GripInformation.RelativeTransform.ToInverseMatrixWithScale()); + FTransform CurrentTransform = this->GetComponentTransform(); + FTransform RelativeToGripTransform = FTransform::Identity; + + if (LeverRotationAxis == EVRInteractibleLeverAxis::FlightStick_XY) + { + // Offset the grip to the same height on the cross axis and centered on the lever + FVector InitialInteractorOffset = ReversedRelativeTransform.GetTranslation(); + FTransform InitTrans = ReversedRelativeTransform; + InitialInteractorOffset.X = 0; + InitialInteractorOffset.Y = 0; + InteractorOffsetTransform = ReversedRelativeTransform; + InteractorOffsetTransform.AddToTranslation(-InitialInteractorOffset); + InteractorOffsetTransform = FTransform(InteractorOffsetTransform.ToInverseMatrixWithScale()); + + InitialInteractorOffset = ReversedRelativeTransform.GetTranslation(); + InitialInteractorOffset.Z = 0; + + InitTrans.AddToTranslation(-InitialInteractorOffset); + RelativeToGripTransform = InitTrans * CurrentTransform; + } + else + { + RelativeToGripTransform = ReversedRelativeTransform * CurrentTransform; + InteractorOffsetTransform = FTransform::Identity; + } + + InitialInteractorLocation = CurrentRelativeTransform.InverseTransformPosition(RelativeToGripTransform.GetTranslation()); + InitialInteractorDropLocation = ReversedRelativeTransform.GetTranslation(); + + switch (LeverRotationAxis) + { + case EVRInteractibleLeverAxis::Axis_XY: + { + qRotAtGrab = this->GetComponentTransform().GetRelativeTransform(CurrentRelativeTransform).GetRotation(); + }break; + case EVRInteractibleLeverAxis::FlightStick_XY: + { + qRotAtGrab = this->GetComponentTransform().GetRelativeTransform(CurrentRelativeTransform).GetRotation(); + InitialGripRot = UVRInteractibleFunctionLibrary::GetAtan2Angle(EVRInteractibleAxis::Axis_Z, ReversedRelativeTransform.GetTranslation()); + }break; + case EVRInteractibleLeverAxis::Axis_X: + case EVRInteractibleLeverAxis::Axis_Y: + { + // Get our initial interactor rotation + InitialGripRot = UVRInteractibleFunctionLibrary::GetAtan2Angle((EVRInteractibleAxis)LeverRotationAxis, InitialInteractorLocation); + }break; + + case EVRInteractibleLeverAxis::Axis_Z: + { + // Get our initial interactor rotation + InitialGripRot = UVRInteractibleFunctionLibrary::GetAtan2Angle((EVRInteractibleAxis)LeverRotationAxis, InitialInteractorLocation); + }break; + + default:break; + } + + // Get out current rotation at grab + RotAtGrab = UVRInteractibleFunctionLibrary::GetDeltaAngleFromTransforms((EVRInteractibleAxis)LeverRotationAxis, CurrentRelativeTransform, CurrentTransform); + + LastLeverAngle = CurrentLeverAngle; + bIsLerping = false; + bIsInFirstTick = true; + MomentumAtDrop = 0.0f; + + this->SetComponentTickEnabled(true); + + //OnGripped.Broadcast(GrippingController, GripInformation); +} + +void UVRLeverComponent::OnGripRelease_Implementation(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed) +{ + if (LeverReturnTypeWhenReleased != EVRInteractibleLeverReturnType::Stay) + { + bIsLerping = true; + this->SetComponentTickEnabled(true); + if (MovementReplicationSetting != EGripMovementReplicationSettings::ForceServerSideMovement) + bReplicateMovement = false; + } + else + { + this->SetComponentTickEnabled(false); + bReplicateMovement = bOriginalReplicatesMovement; + } + + //OnDropped.Broadcast(ReleasingController, GripInformation, bWasSocketed); +} + +void UVRLeverComponent::SetGripPriority(int NewGripPriority) +{ + GripPriority = NewGripPriority; +} + +void UVRLeverComponent::SetIsLocked(bool bNewLockedState) +{ + bIsLocked = bNewLockedState; +} + +void UVRLeverComponent::OnChildGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) {} +void UVRLeverComponent::OnChildGripRelease_Implementation(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed) {} +void UVRLeverComponent::OnSecondaryGrip_Implementation(UGripMotionControllerComponent * GripOwningController, USceneComponent * SecondaryGripComponent, const FBPActorGripInformation & GripInformation) {} +void UVRLeverComponent::OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent * GripOwningController, USceneComponent * ReleasingSecondaryGripComponent, const FBPActorGripInformation & GripInformation) {} +void UVRLeverComponent::OnUsed_Implementation() {} +void UVRLeverComponent::OnEndUsed_Implementation() {} +void UVRLeverComponent::OnSecondaryUsed_Implementation() {} +void UVRLeverComponent::OnEndSecondaryUsed_Implementation() {} +void UVRLeverComponent::OnInput_Implementation(FKey Key, EInputEvent KeyEvent) {} +bool UVRLeverComponent::RequestsSocketing_Implementation(USceneComponent *& ParentToSocketTo, FName & OptionalSocketName, FTransform_NetQuantize & RelativeTransform) { return false; } + +bool UVRLeverComponent::DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator) +{ + return bDenyGripping; +} + +EGripInterfaceTeleportBehavior UVRLeverComponent::TeleportBehavior_Implementation() +{ + return EGripInterfaceTeleportBehavior::DropOnTeleport; +} + +bool UVRLeverComponent::SimulateOnDrop_Implementation() +{ + return false; +} + + +EGripCollisionType UVRLeverComponent::GetPrimaryGripType_Implementation(bool bIsSlot) +{ + return EGripCollisionType::CustomGrip; +} + +ESecondaryGripType UVRLeverComponent::SecondaryGripType_Implementation() +{ + return ESecondaryGripType::SG_None; +} + + +EGripMovementReplicationSettings UVRLeverComponent::GripMovementReplicationType_Implementation() +{ + return MovementReplicationSetting; +} + +EGripLateUpdateSettings UVRLeverComponent::GripLateUpdateSetting_Implementation() +{ + return EGripLateUpdateSettings::LateUpdatesAlwaysOff; +} + +/*float UVRLeverComponent::GripStiffness_Implementation() +{ + return Stiffness; +} + +float UVRLeverComponent::GripDamping_Implementation() +{ + return Damping; +}*/ +void UVRLeverComponent::GetGripStiffnessAndDamping_Implementation(float &GripStiffnessOut, float &GripDampingOut) +{ + GripStiffnessOut = Stiffness; + GripDampingOut = Damping; +} + +FBPAdvGripSettings UVRLeverComponent::AdvancedGripSettings_Implementation() +{ + return FBPAdvGripSettings(GripPriority); +} + +float UVRLeverComponent::GripBreakDistance_Implementation() +{ + return BreakDistance; +} + +/*void UVRLeverComponent::ClosestSecondarySlotInRange_Implementation(FVector WorldLocation, bool & bHadSlotInRange, FTransform & SlotWorldTransform, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ + bHadSlotInRange = false; +} + +void UVRLeverComponent::ClosestPrimarySlotInRange_Implementation(FVector WorldLocation, bool & bHadSlotInRange, FTransform & SlotWorldTransform, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ + bHadSlotInRange = false; +}*/ + +void UVRLeverComponent::ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool & bHadSlotInRange, FTransform & SlotWorldTransform, FName & SlotName, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ + if (OverridePrefix.IsNone()) + bSecondarySlot ? OverridePrefix = "VRGripS" : OverridePrefix = "VRGripP"; + + UVRExpansionFunctionLibrary::GetGripSlotInRangeByTypeName_Component(OverridePrefix, this, WorldLocation, bSecondarySlot ? SecondarySlotRange : PrimarySlotRange, bHadSlotInRange, SlotWorldTransform, SlotName, CallingController); +} + +bool UVRLeverComponent::AllowsMultipleGrips_Implementation() +{ + return false; +} + +void UVRLeverComponent::IsHeld_Implementation(TArray & CurHoldingControllers, bool & bCurIsHeld) +{ + CurHoldingControllers.Empty(); + if (HoldingGrip.IsValid()) + { + CurHoldingControllers.Add(HoldingGrip); + bCurIsHeld = bIsHeld; + } + else + { + bCurIsHeld = false; + } +} + +void UVRLeverComponent::Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed) +{ + if (bGripped) + { + OnGripped.Broadcast(Controller, GripInformation); + } + else + { + OnDropped.Broadcast(Controller, GripInformation, bWasSocketed); + } +} + +void UVRLeverComponent::SetHeld_Implementation(UGripMotionControllerComponent * NewHoldingController, uint8 GripID, bool bNewIsHeld) +{ + if (bNewIsHeld) + { + HoldingGrip = FBPGripPair(NewHoldingController, GripID); + if (MovementReplicationSetting != EGripMovementReplicationSettings::ForceServerSideMovement) + { + if (!bIsHeld && !bIsLerping) + bOriginalReplicatesMovement = bReplicateMovement; + bReplicateMovement = false; + } + } + else + { + HoldingGrip.Clear(); + if (MovementReplicationSetting != EGripMovementReplicationSettings::ForceServerSideMovement) + { + bReplicateMovement = bOriginalReplicatesMovement; + } + } + + bIsHeld = bNewIsHeld; +} + +/*FBPInteractionSettings UVRLeverComponent::GetInteractionSettings_Implementation() +{ + return FBPInteractionSettings(); +}*/ + +bool UVRLeverComponent::GetGripScripts_Implementation(TArray & ArrayReference) +{ + return false; +} + +float UVRLeverComponent::ReCalculateCurrentAngle(bool bAllowThrowingEvents) +{ + FTransform CurRelativeTransform = this->GetComponentTransform().GetRelativeTransform(UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(this)); + CalculateCurrentAngle(CurRelativeTransform); + ProccessCurrentState(bIsLerping, bAllowThrowingEvents, bAllowThrowingEvents); + return CurrentLeverAngle; +} + +void UVRLeverComponent::SetLeverAngle(float NewAngle, FVector DualAxisForwardVector, bool bAllowThrowingEvents) +{ + NewAngle = -NewAngle; // Need to inverse the sign + + FVector ForwardVector = DualAxisForwardVector; + switch (LeverRotationAxis) + { + case EVRInteractibleLeverAxis::Axis_X: + ForwardVector = FVector(FMath::Sign(NewAngle), 0.0f, 0.0f); break; + case EVRInteractibleLeverAxis::Axis_Y: + ForwardVector = FVector(0.0f, FMath::Sign(NewAngle), 0.0f); break; + case EVRInteractibleLeverAxis::Axis_Z: + ForwardVector = FVector(0.0f, 0.0f, FMath::Sign(NewAngle)); break; + default:break; + } + + FQuat NewLeverRotation(ForwardVector, FMath::DegreesToRadians(FMath::Abs(NewAngle))); + + this->SetRelativeTransform(FTransform(NewLeverRotation) * InitialRelativeTransform); + ReCalculateCurrentAngle(bAllowThrowingEvents); +} + +void UVRLeverComponent::ResetInitialLeverLocation(bool bAllowThrowingEvents) +{ + // Get our initial relative transform to our parent (or not if un-parented). + InitialRelativeTransform = this->GetRelativeTransform(); + +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UVRLeverComponent, InitialRelativeTransform, this); +#endif + + CalculateCurrentAngle(InitialRelativeTransform); + ProccessCurrentState(bIsLerping, bAllowThrowingEvents, bAllowThrowingEvents); +} + +void UVRLeverComponent::CalculateCurrentAngle(FTransform & CurrentTransform) +{ + float Angle; + switch (LeverRotationAxis) + { + case EVRInteractibleLeverAxis::Axis_XY: + case EVRInteractibleLeverAxis::FlightStick_XY: + { + FTransform RelativeToSpace = CurrentTransform.GetRelativeTransform(InitialRelativeTransform); + FQuat CurrentRelRot = RelativeToSpace.GetRotation();// CurrentTransform.GetRotation(); + FVector UpVec = CurrentRelRot.GetUpVector(); + + CurrentLeverForwardVector = FVector::VectorPlaneProject(UpVec, FVector::UpVector); + CurrentLeverForwardVector.Normalize(); + + FullCurrentAngle = FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(UpVec, FVector::UpVector))); + CurrentLeverAngle = FMath::RoundToFloat(FullCurrentAngle); + + AllCurrentLeverAngles.Roll = FMath::Sign(UpVec.Y) * FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(FVector(0.0f, UpVec.Y, UpVec.Z).GetSafeNormal(), FVector::UpVector))); + AllCurrentLeverAngles.Pitch = FMath::Sign(UpVec.X) * FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(FVector(UpVec.X, 0.0f, UpVec.Z).GetSafeNormal(), FVector::UpVector))); + + if (bBlendAxisValuesByAngleThreshold) + { + FVector ProjectedLoc = FVector(UpVec.X, UpVec.Y, 0.0f).GetSafeNormal(); + AllCurrentLeverAngles.Pitch *= FMath::Clamp(1.0f - (FMath::Abs(FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(ProjectedLoc, FMath::Sign(UpVec.X) * FVector::ForwardVector)))) / AngleThreshold), 0.0f, 1.0f); + AllCurrentLeverAngles.Roll *= FMath::Clamp(1.0f - (FMath::Abs(FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(ProjectedLoc, FMath::Sign(UpVec.Y) * FVector::RightVector)))) / AngleThreshold), 0.0f, 1.0f); + } + + AllCurrentLeverAngles.Roll = FMath::RoundToFloat(AllCurrentLeverAngles.Roll); + AllCurrentLeverAngles.Pitch = FMath::RoundToFloat(AllCurrentLeverAngles.Pitch); + + if (LeverRotationAxis == EVRInteractibleLeverAxis::FlightStick_XY) + { + AllCurrentLeverAngles.Yaw = FRotator::NormalizeAxis(FMath::RoundToFloat(UVRExpansionFunctionLibrary::GetHMDPureYaw_I(CurrentRelRot.Rotator()).Yaw)); + if (FlightStickYawLimit < 180.0f) + { + AllCurrentLeverAngles.Yaw = FMath::Clamp(AllCurrentLeverAngles.Yaw, -FlightStickYawLimit, FlightStickYawLimit); + } + } + else + AllCurrentLeverAngles.Yaw = 0.0f; + + }break; + default: + { + Angle = UVRInteractibleFunctionLibrary::GetDeltaAngleFromTransforms((EVRInteractibleAxis)LeverRotationAxis, InitialRelativeTransform, CurrentTransform); + FullCurrentAngle = Angle; + CurrentLeverAngle = FMath::RoundToFloat(FullCurrentAngle); + CurrentLeverForwardVector = UVRInteractibleFunctionLibrary::SetAxisValueVec((EVRInteractibleAxis)LeverRotationAxis, FMath::Sign(Angle)); + AllCurrentLeverAngles = UVRInteractibleFunctionLibrary::SetAxisValueRot((EVRInteractibleAxis)LeverRotationAxis, CurrentLeverAngle, FRotator::ZeroRotator); + + }break; + } +} + +void UVRLeverComponent::LerpAxis(float CurrentAngle, float DeltaTime) +{ + float TargetAngle = 0.0f; + float FinalReturnSpeed = LeverReturnSpeed; + + switch (LeverReturnTypeWhenReleased) + { + case EVRInteractibleLeverReturnType::LerpToMax: + { + if (CurrentAngle >= 0) + TargetAngle = FMath::RoundToFloat(LeverLimitPositive); + else + TargetAngle = -FMath::RoundToFloat(LeverLimitNegative); + }break; + case EVRInteractibleLeverReturnType::LerpToMaxIfOverThreshold: + { + if ((!FMath::IsNearlyZero(LeverLimitPositive) && CurrentAngle >= (LeverLimitPositive * LeverTogglePercentage))) + TargetAngle = FMath::RoundToFloat(LeverLimitPositive); + else if ((!FMath::IsNearlyZero(LeverLimitNegative) && CurrentAngle <= -(LeverLimitNegative * LeverTogglePercentage))) + TargetAngle = -FMath::RoundToFloat(LeverLimitNegative); + }break; + case EVRInteractibleLeverReturnType::RetainMomentum: + { + if (FMath::IsNearlyZero(MomentumAtDrop * DeltaTime, 0.1f)) + { + MomentumAtDrop = 0.0f; + this->SetComponentTickEnabled(false); + bIsLerping = false; + bReplicateMovement = bOriginalReplicatesMovement; + return; + } + else + { + MomentumAtDrop = FMath::FInterpTo(MomentumAtDrop, 0.0f, DeltaTime, LeverMomentumFriction); + + FinalReturnSpeed = FMath::Abs(MomentumAtDrop); + + if (MomentumAtDrop >= 0.0f) + TargetAngle = FMath::RoundToFloat(LeverLimitPositive); + else + TargetAngle = -FMath::RoundToFloat(LeverLimitNegative); + } + + }break; + case EVRInteractibleLeverReturnType::ReturnToZero: + default: + {}break; + } + + //float LerpedVal = FMath::FixedTurn(CurrentAngle, TargetAngle, FinalReturnSpeed * DeltaTime); + float LerpedVal = FMath::FInterpConstantTo(CurrentAngle, TargetAngle, DeltaTime, FinalReturnSpeed); + + if (FMath::IsNearlyEqual(LerpedVal, TargetAngle)) + { + if (LeverRestitution > 0.0f) + { + MomentumAtDrop = -(MomentumAtDrop * LeverRestitution); + FTransform CalcTransform = (FTransform(UVRInteractibleFunctionLibrary::SetAxisValueRot((EVRInteractibleAxis)LeverRotationAxis, TargetAngle, FRotator::ZeroRotator)) * InitialRelativeTransform); + this->SetRelativeRotation(CalcTransform.Rotator()); + } + else + { + this->SetComponentTickEnabled(false); + bIsLerping = false; + bReplicateMovement = bOriginalReplicatesMovement; + FTransform CalcTransform = (FTransform(UVRInteractibleFunctionLibrary::SetAxisValueRot((EVRInteractibleAxis)LeverRotationAxis, TargetAngle, FRotator::ZeroRotator)) * InitialRelativeTransform); + this->SetRelativeRotation(CalcTransform.Rotator()); + } + } + else + { + FTransform CalcTransform = (FTransform(UVRInteractibleFunctionLibrary::SetAxisValueRot((EVRInteractibleAxis)LeverRotationAxis, LerpedVal, FRotator::ZeroRotator)) * InitialRelativeTransform); + this->SetRelativeRotation(CalcTransform.Rotator()); + } +} + +float UVRLeverComponent::CalcAngle(EVRInteractibleLeverAxis AxisToCalc, FVector CurInteractorLocation, bool bSkipLimits) +{ + float ReturnAxis = 0.0f; + + ReturnAxis = UVRInteractibleFunctionLibrary::GetAtan2Angle((EVRInteractibleAxis)AxisToCalc, CurInteractorLocation, InitialGripRot); + + if (bSkipLimits) + return ReturnAxis; + + if (LeverLimitPositive > 0.0f && LeverLimitNegative > 0.0f && FMath::IsNearlyEqual(LeverLimitNegative, 180.f, 0.01f) && FMath::IsNearlyEqual(LeverLimitPositive, 180.f, 0.01f)) + { + // Don't run the clamping or the flip detection, we are a 360 degree lever + } + else + { + ReturnAxis = FMath::ClampAngle(FRotator::NormalizeAxis(RotAtGrab + ReturnAxis), -LeverLimitNegative, LeverLimitPositive); + + // Ignore rotations that would flip the angle of the lever to the other side, with a 90 degree allowance + if (!bIsInFirstTick && ((LeverLimitPositive > 0.0f && LastDeltaAngle >= LeverLimitPositive) || (LeverLimitNegative > 0.0f && LastDeltaAngle <= -LeverLimitNegative)) && FMath::Sign(LastDeltaAngle) != FMath::Sign(ReturnAxis)) + { + ReturnAxis = LastDeltaAngle; + } + } + + bIsInFirstTick = false; + return ReturnAxis; +} + +void UVRLeverComponent::SetRepGameplayTags(bool bNewRepGameplayTags) +{ + bRepGameplayTags = bNewRepGameplayTags; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UVRLeverComponent, bRepGameplayTags, this); +#endif +} + +void UVRLeverComponent::SetReplicateMovement(bool bNewReplicateMovement) +{ + bReplicateMovement = bNewReplicateMovement; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UVRLeverComponent, bReplicateMovement, this); +#endif +} + +FGameplayTagContainer& UVRLeverComponent::GetGameplayTags() +{ +#if WITH_PUSH_MODEL + if (bRepGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UVRLeverComponent, GameplayTags, this); + } +#endif + + return GameplayTags; +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRMountComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRMountComponent.cpp new file mode 100644 index 0000000..115e95a --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRMountComponent.cpp @@ -0,0 +1,629 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Interactibles/VRMountComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRMountComponent) + +#include "VRExpansionFunctionLibrary.h" +#include "GripMotionControllerComponent.h" +//#include "PhysicsPublic.h" +//#include "PhysicsEngine/ConstraintInstance.h" +#include "Net/UnrealNetwork.h" + +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + +//============================================================================= +UVRMountComponent::UVRMountComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + this->SetGenerateOverlapEvents(true); + this->PrimaryComponentTick.bStartWithTickEnabled = false; + PrimaryComponentTick.bCanEverTick = true; + + bRepGameplayTags = false; + + // Defaulting these true so that they work by default in networked environments + bReplicateMovement = true; + + MovementReplicationSetting = EGripMovementReplicationSettings::ForceClientSideMovement; + BreakDistance = 100.0f; + Stiffness = 1500.0f; + Damping = 200.0f; + + MountRotationAxis = EVRInteractibleMountAxis::Axis_XZ; + + + InitialRelativeTransform = FTransform::Identity; + InitialInteractorLocation = FVector::ZeroVector; + InitialGripRot = 0.0f; + qRotAtGrab = FQuat::Identity; + + bDenyGripping = false; + + PrimarySlotRange = 100.f; + SecondarySlotRange = 100.f; + GripPriority = 1; + + FlipingZone = 0.4; + FlipReajustYawSpeed = 7.7; + + // Set to only overlap with things so that its not ruined by touching over actors + this->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Overlap); +} + +//============================================================================= +UVRMountComponent::~UVRMountComponent() +{ +} + + +void UVRMountComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UVRMountComponent, bRepGameplayTags, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UVRMountComponent, bReplicateMovement, PushModelParams); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UVRMountComponent, GameplayTags, PushModelParamsWithCondition); +} + +void UVRMountComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) +{ + Super::PreReplication(ChangedPropertyTracker); + + // Don't replicate if set to not do it + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UVRMountComponent, GameplayTags, bRepGameplayTags); + + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeLocation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeRotation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeScale3D, bReplicateMovement); +} + +void UVRMountComponent::OnRegister() +{ + Super::OnRegister(); + ResetInitialMountLocation(); // Load the original mount location +} + +void UVRMountComponent::BeginPlay() +{ + // Call the base class + Super::BeginPlay(); +} + +void UVRMountComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) +{ + // Call supers tick (though I don't think any of the base classes to this actually implement it) + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + +} + +void UVRMountComponent::OnUnregister() +{ + Super::OnUnregister(); +} + +void UVRMountComponent::TickGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation, float DeltaTime) +{ + // Handle manual tracking here + + FTransform CurrentRelativeTransform = InitialRelativeTransform * UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(this); + FVector CurInteractorLocation = CurrentRelativeTransform.InverseTransformPosition(GrippingController->GetPivotLocation()); + + switch (MountRotationAxis) + { + case EVRInteractibleMountAxis::Axis_XZ: + { + //The current Mount to target location vector. + FVector MountToTarget; + + //In case the Mount is initially gripped on the back (negative of relative x axis) + if (GrippedOnBack) + { + CurInteractorLocation = CurInteractorLocation *-1; + } + + //Rotate the Initial Grip relative to the Forward Axis so it represents the current correct vector after Mount is rotated. + FRotator RelativeRot = GetRelativeRotation(); + FVector CurToForwardAxisVec = FRotator(RelativeRot.Pitch, RelativeRot.Yaw, TwistDiff).RotateVector(InitialGripToForwardVec); + + //The Current InteractorLocation based on current interactor location to intersection point on sphere with forward axis. + CurInteractorLocation = (CurInteractorLocation.GetSafeNormal() * InitialInteractorLocation.Size() + CurToForwardAxisVec).GetSafeNormal()*CurInteractorLocation.Size(); + + FRotator Rot; + + //If we are inside the fliping zone defined from Cone Area on top or bottom. ToDo: This probably can be combined with later FlipZone. + if (bIsInsideFrontFlipingZone || bIsInsideBackFlipZone) + { + // Entering the flip zone for the first time, a initial forward plane is made to ajust currentinteractorlocation relative x and y. This immitates a mechanical pull/push + if (!bFirstEntryToHalfFlipZone) + { + //Unmodified Right vector can still be used here to create the plane, before it will be changed later. + ForwardPullPlane = FPlane(FVector::ZeroVector, FVector(EntryRightVec.X, EntryRightVec.Y, 0).GetSafeNormal()); + + bFirstEntryToHalfFlipZone = true; + bLerpingOutOfFlipZone = false; + + CurInterpGripLoc = CurInteractorLocation; + + CurPointOnForwardPlane = FPlane::PointPlaneProject(CurInteractorLocation, ForwardPullPlane); + } + + LastPointOnForwardPlane = CurPointOnForwardPlane; + + CurPointOnForwardPlane = FPlane::PointPlaneProject(CurInteractorLocation, ForwardPullPlane); + + FVector ForwardPlainDiffVec = CurPointOnForwardPlane - LastPointOnForwardPlane; + + //Add the difference to how much we moved trough the forward plane since the last frame. + CurInterpGripLoc += ForwardPlainDiffVec; + + // InterpTo the current projected point on forward plane over time when inside the FlipZone. + CurInterpGripLoc = FMath::VInterpConstantTo(CurInterpGripLoc, CurPointOnForwardPlane, GetWorld()->GetDeltaSeconds(), 50); + + //The current location of the motion controller projected on to the forward plane. Only x and y is used from interpolation. + MountToTarget = FVector(CurInterpGripLoc.X, CurInterpGripLoc.Y, CurInteractorLocation.Z).GetSafeNormal(); + + //Save the CurInteractorLocation once to modify roll with it later + CurInteractorLocation = FVector(CurInterpGripLoc.X, CurInterpGripLoc.Y, CurInteractorLocation.Z); + } + else + { + //When going out of whole FlipZone Lerp yaw back to curinteractorlocation in case relative entry xy deviates to much from when leaving area + if (bLerpingOutOfFlipZone) + { + //If projected point on plane is not close enough to the "real" motion controller location lerp + if ((CurInterpGripLoc - CurInteractorLocation).Size() >= 1.0f) + { + //How fast yaw should rotate back when leaving flipzone. ToDo: For LerpOutSpeed maybe better us distance deviation + LerpOutAlpha = FMath::Clamp(LerpOutAlpha + FlipReajustYawSpeed / 100.0f, 0.0f, 1.0f); + + //Lerp + CurInterpGripLoc = CurInterpGripLoc + LerpOutAlpha * (CurInteractorLocation - CurInterpGripLoc); + + //The new vector to make rotation from. + MountToTarget = CurInterpGripLoc.GetSafeNormal(); + + //We left the flipzone completly, set everything back to normal. + if (LerpOutAlpha >= 0.97f) + { + bLerpingOutOfFlipZone = false; + bIsInsideBackFlipZone = false; + } + } + else + { + //If we are already near the real controller location just snap back + bLerpingOutOfFlipZone = false; + bIsInsideBackFlipZone = false; + MountToTarget = CurInteractorLocation.GetSafeNormal(); + } + } + else + { + //There is still a possibility here maybe to be inside backflipzone, but Mount is actually already outside. So just use unmodified rotation. + MountToTarget = CurInteractorLocation.GetSafeNormal(); + bIsInsideBackFlipZone = false; + } + + } + + //Setting the relative rotation once before using "accumulated" relative rotation to calculate roll onto it. + Rot = MountToTarget.Rotation(); + this->SetRelativeRotation((FTransform(FRotator(Rot.Pitch, Rot.Yaw, 0))*InitialRelativeTransform).Rotator()); + + + FVector nAxis; + float FlipAngle; + FQuat::FindBetweenVectors(FVector(0, 0, 1), CurInteractorLocation.GetSafeNormal()).ToAxisAndAngle(nAxis, FlipAngle); + + // This part takes care of the roll rotation ff Mount is inside flipping zone on top or on bottom. + if (FlipAngle < FlipingZone || FlipAngle > PI - FlipingZone) + { + //When entering FlipZone for the first time setup initial properties + if (!bIsInsideFrontFlipingZone && !bIsInsideBackFlipZone) + { + //We entered the FrontFlipzone + bIsInsideFrontFlipingZone = true; + + //Up and Right Vector when entering the FlipZone. Parent Rotation is accounted for. + if (USceneComponent * ParentComp = GetAttachParent()) + { + EntryUpVec = ParentComp->GetComponentRotation().UnrotateVector(GetUpVector()); + EntryRightVec = ParentComp->GetComponentRotation().UnrotateVector(GetRightVector()); + } + else + { + EntryUpVec = GetUpVector(); + EntryRightVec = GetRightVector(); + } + + //Only relative x and y is important for a Mount which has XY rotation limitation for the flip plane. + EntryUpXYNeg = FVector(EntryUpVec.X, EntryUpVec.Y, 0).GetSafeNormal()*-1; + //If flipping over the bottom + if (FlipAngle > PI - FlipingZone) + { + EntryUpXYNeg *= -1; + } + + //A Plane perpendicular to the FlipZone relative EntryPoint XY UpVector. This plane determines when the roll has to be turned by 180 degree + FlipPlane = FPlane(FVector::ZeroVector, EntryUpXYNeg); + } + + //CurInteractor vector to its projected point on flipplane + FVector CurInteractorToFlipPlaneVec = CurInteractorLocation - FPlane::PointPlaneProject(CurInteractorLocation, FlipPlane); + + if (bIsInsideFrontFlipingZone) + { + //If Mount rotation is on or over flipplane but still inside frontflipzone flip the roll. + if (FVector::DotProduct(CurInteractorToFlipPlaneVec, EntryUpXYNeg) <= 0) + { + bIsInsideFrontFlipingZone = false; + bIsInsideBackFlipZone = true; + + bIsFlipped = !bIsFlipped; + + if (bIsFlipped) + { + TwistDiff = 180; + } + else + { + TwistDiff = 0; + } + } + else + { + //If Mount Rotation is still inside FrontFlipZone ajust the roll so it looks naturally when moving the Mount against the FlipPlane + + FVector RelativeUpVec = GetUpVector(); + + if(USceneComponent * ParentComp = GetAttachParent()) + RelativeUpVec = ParentComp->GetComponentRotation().UnrotateVector(RelativeUpVec); + + FVector CurrentUpVec = FVector(RelativeUpVec.X, RelativeUpVec.Y, 0).GetSafeNormal(); + + //If rotating over the top ajust relative UpVector + if (FlipAngle < FlipingZone) + { + CurrentUpVec *= -1; + } + + float EntryTwist = FMath::Atan2(EntryUpXYNeg.Y, EntryUpXYNeg.X); + float CurTwist = FMath::Atan2(CurrentUpVec.Y, CurrentUpVec.X); + + //Rotate the roll so relative up vector x y looks at the flip plane + if (bIsFlipped) + { + TwistDiff = FMath::RadiansToDegrees(EntryTwist - CurTwist - PI); + } + else + { + TwistDiff = FMath::RadiansToDegrees(EntryTwist - CurTwist); + } + } + } + else + { + //If Inside Back Flip Zone just flip the roll. ToDo: Dont just ajust roll to 0 or 180. Calculate Twist diff according to up vector to FlipPlane. + if (bIsInsideBackFlipZone) + { + if (FVector::DotProduct(CurInteractorToFlipPlaneVec, EntryUpXYNeg) >= 0) + { + bIsInsideFrontFlipingZone = true; + bIsInsideBackFlipZone = false; + + bIsFlipped = !bIsFlipped; + + if (bIsFlipped) + { + TwistDiff = 180; + } + else + { + TwistDiff = 0; + } + } + } + } + + } + else + { + //If the Mount went into the flipping zone and back out without going over flip plane reset roll + bIsInsideFrontFlipingZone = false; + bIsInsideBackFlipZone = false; + + if (bIsFlipped) + { + TwistDiff = 180; + } + else + { + TwistDiff = 0; + } + + if (bFirstEntryToHalfFlipZone) + { + //If never left FlipZone before but doing now it now, reset first time entry bool. ToDo: Maybe better to do this elsewhere. + bFirstEntryToHalfFlipZone = false; + LerpOutAlpha = 0; + + //We left the flipzone so rotate yaw back from interpolated controller position on forward pull plane back to "real" one. + bLerpingOutOfFlipZone = true; + } + + } + + //Add Roll modifications to accumulated LocalRotation. + this->AddLocalRotation(FRotator(0, 0, -TwistDiff)); + + }break; + default:break; + } + + // #TODO: This drop code is incorrect, it is based off of the initial point and not the location at grip - revise it at some point + // Also set it to after rotation + if (BreakDistance > 0.f && GrippingController->HasGripAuthority(GripInformation) && FVector::DistSquared(InitialInteractorDropLocation, this->GetComponentTransform().InverseTransformPosition(GrippingController->GetPivotLocation())) >= FMath::Square(BreakDistance)) + { + if (GrippingController->OnGripOutOfRange.IsBound()) + { + uint8 GripID = GripInformation.GripID; + GrippingController->OnGripOutOfRange.Broadcast(GripInformation, GripInformation.GripDistance); + } + else + { + GrippingController->DropObjectByInterface(this, HoldingGrip.GripID); + } + return; + } +} + +void UVRMountComponent::OnGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) +{ + FTransform CurrentRelativeTransform = InitialRelativeTransform * UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(this); + + // This lets me use the correct original location over the network without changes + FTransform ReversedRelativeTransform = FTransform(GripInformation.RelativeTransform.ToInverseMatrixWithScale()); + FTransform RelativeToGripTransform = ReversedRelativeTransform * this->GetComponentTransform(); + + //continue here CurToForwardAxis is based on last gripped location ---> change this + InitialInteractorLocation = CurrentRelativeTransform.InverseTransformPosition(RelativeToGripTransform.GetTranslation()); + InitialInteractorDropLocation = ReversedRelativeTransform.GetTranslation(); + + switch (MountRotationAxis) + { + case EVRInteractibleMountAxis::Axis_XZ: + { + //spaceharry + + qRotAtGrab = this->GetComponentTransform().GetRelativeTransform(CurrentRelativeTransform).GetRotation(); + + FVector ForwardVectorToUse = GetForwardVector(); + + if (USceneComponent * ParentComp = GetAttachParent()) + { + ForwardVectorToUse = ParentComp->GetComponentRotation().UnrotateVector(ForwardVectorToUse); + } + + InitialForwardVector = InitialInteractorLocation.Size() * ForwardVectorToUse; + + if (FVector::DotProduct(InitialInteractorLocation, ForwardVectorToUse) <= 0) + { + GrippedOnBack = true; + InitialGripToForwardVec = (InitialForwardVector + InitialInteractorLocation); + } + else + { + InitialGripToForwardVec = InitialForwardVector - InitialInteractorLocation; + GrippedOnBack = false; + } + + FRotator RelativeRot = GetRelativeRotation(); + InitialGripToForwardVec = FRotator(RelativeRot.Pitch, RelativeRot.Yaw, TwistDiff).UnrotateVector(InitialGripToForwardVec); + + }break; + default:break; + } + + + + + this->SetComponentTickEnabled(true); +} + +void UVRMountComponent::OnGripRelease_Implementation(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed) +{ + this->SetComponentTickEnabled(false); +} + +void UVRMountComponent::SetGripPriority(int NewGripPriority) +{ + GripPriority = NewGripPriority; +} + +void UVRMountComponent::OnChildGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) {} +void UVRMountComponent::OnChildGripRelease_Implementation(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed) {} +void UVRMountComponent::OnSecondaryGrip_Implementation(UGripMotionControllerComponent * GripOwningController, USceneComponent * SecondaryGripComponent, const FBPActorGripInformation & GripInformation) {} +void UVRMountComponent::OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent * GripOwningController, USceneComponent * ReleasingSecondaryGripComponent, const FBPActorGripInformation & GripInformation) {} +void UVRMountComponent::OnUsed_Implementation() {} +void UVRMountComponent::OnEndUsed_Implementation() {} +void UVRMountComponent::OnSecondaryUsed_Implementation() {} +void UVRMountComponent::OnEndSecondaryUsed_Implementation() {} +void UVRMountComponent::OnInput_Implementation(FKey Key, EInputEvent KeyEvent) {} +bool UVRMountComponent::RequestsSocketing_Implementation(USceneComponent *& ParentToSocketTo, FName & OptionalSocketName, FTransform_NetQuantize & RelativeTransform) { return false; } + +bool UVRMountComponent::DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator) +{ + return bDenyGripping; +} + +EGripInterfaceTeleportBehavior UVRMountComponent::TeleportBehavior_Implementation() +{ + return EGripInterfaceTeleportBehavior::DropOnTeleport; +} + +bool UVRMountComponent::SimulateOnDrop_Implementation() +{ + return false; +} + + +EGripCollisionType UVRMountComponent::GetPrimaryGripType_Implementation(bool bIsSlot) +{ + return EGripCollisionType::CustomGrip; +} + +ESecondaryGripType UVRMountComponent::SecondaryGripType_Implementation() +{ + return ESecondaryGripType::SG_None; +} + + +EGripMovementReplicationSettings UVRMountComponent::GripMovementReplicationType_Implementation() +{ + return MovementReplicationSetting; +} + +EGripLateUpdateSettings UVRMountComponent::GripLateUpdateSetting_Implementation() +{ + return EGripLateUpdateSettings::LateUpdatesAlwaysOff; +} + +/*float UVRMountComponent::GripStiffness_Implementation() +{ +return Stiffness; +} + +float UVRMountComponent::GripDamping_Implementation() +{ +return Damping; +}*/ +void UVRMountComponent::GetGripStiffnessAndDamping_Implementation(float &GripStiffnessOut, float &GripDampingOut) +{ + GripStiffnessOut = Stiffness; + GripDampingOut = Damping; +} + +FBPAdvGripSettings UVRMountComponent::AdvancedGripSettings_Implementation() +{ + return FBPAdvGripSettings(GripPriority); +} + +float UVRMountComponent::GripBreakDistance_Implementation() +{ + return BreakDistance; +} + +/*void UVRMountComponent::ClosestSecondarySlotInRange_Implementation(FVector WorldLocation, bool & bHadSlotInRange, FTransform & SlotWorldTransform, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ +bHadSlotInRange = false; +} + +void UVRMountComponent::ClosestPrimarySlotInRange_Implementation(FVector WorldLocation, bool & bHadSlotInRange, FTransform & SlotWorldTransform, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ +bHadSlotInRange = false; +}*/ + +void UVRMountComponent::ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool & bHadSlotInRange, FTransform & SlotWorldTransform, FName & SlotName, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ + if (OverridePrefix.IsNone()) + bSecondarySlot ? OverridePrefix = "VRGripS" : OverridePrefix = "VRGripP"; + + UVRExpansionFunctionLibrary::GetGripSlotInRangeByTypeName_Component(OverridePrefix, this, WorldLocation, bSecondarySlot ? SecondarySlotRange : PrimarySlotRange, bHadSlotInRange, SlotWorldTransform, SlotName, CallingController); +} + +bool UVRMountComponent::AllowsMultipleGrips_Implementation() +{ + return false; +} + +void UVRMountComponent::IsHeld_Implementation(TArray & CurHoldingControllers, bool & bCurIsHeld) +{ + CurHoldingControllers.Empty(); + if (HoldingGrip.IsValid()) + { + CurHoldingControllers.Add(HoldingGrip); + bCurIsHeld = bIsHeld; + } + else + { + bCurIsHeld = false; + } +} + +void UVRMountComponent::SetHeld_Implementation(UGripMotionControllerComponent * NewHoldingController, uint8 GripID, bool bNewIsHeld) +{ + if (bNewIsHeld) + { + HoldingGrip = FBPGripPair(NewHoldingController, GripID); + if (MovementReplicationSetting != EGripMovementReplicationSettings::ForceServerSideMovement) + { + if (!bIsHeld) + bOriginalReplicatesMovement = bReplicateMovement; + bReplicateMovement = false; + } + } + else + { + HoldingGrip.Clear(); + if (MovementReplicationSetting != EGripMovementReplicationSettings::ForceServerSideMovement) + { + bReplicateMovement = bOriginalReplicatesMovement; + } + } + + bIsHeld = bNewIsHeld; +} + +/*FBPInteractionSettings UVRMountComponent::GetInteractionSettings_Implementation() +{ + return FBPInteractionSettings(); +}*/ + +void UVRMountComponent::ResetInitialMountLocation() +{ + // Get our initial relative transform to our parent (or not if un-parented). + InitialRelativeTransform = this->GetRelativeTransform(); +} + + +bool UVRMountComponent::GetGripScripts_Implementation(TArray & ArrayReference) +{ + return false; +} + +void UVRMountComponent::SetRepGameplayTags(bool bNewRepGameplayTags) +{ + bRepGameplayTags = bNewRepGameplayTags; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UVRMountComponent, bRepGameplayTags, this); +#endif +} + +void UVRMountComponent::SetReplicateMovement(bool bNewReplicateMovement) +{ + bReplicateMovement = bNewReplicateMovement; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UVRMountComponent, bReplicateMovement, this); +#endif +} + +FGameplayTagContainer& UVRMountComponent::GetGameplayTags() +{ +#if WITH_PUSH_MODEL + if (bRepGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UVRMountComponent, GameplayTags, this); + } +#endif + + return GameplayTags; +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRSliderComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRSliderComponent.cpp new file mode 100644 index 0000000..9113d33 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Interactibles/VRSliderComponent.cpp @@ -0,0 +1,1041 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Interactibles/VRSliderComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRSliderComponent) + +#include "VRExpansionFunctionLibrary.h" +#include "Components/SplineComponent.h" +#include "GripMotionControllerComponent.h" +#include "Net/UnrealNetwork.h" + +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + + //============================================================================= +UVRSliderComponent::UVRSliderComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + this->SetGenerateOverlapEvents(true); + this->PrimaryComponentTick.bStartWithTickEnabled = false; + PrimaryComponentTick.bCanEverTick = true; + + bRepGameplayTags = false; + + // Defaulting these true so that they work by default in networked environments + bReplicateMovement = true; + + MovementReplicationSetting = EGripMovementReplicationSettings::ForceClientSideMovement; + BreakDistance = 100.0f; + + InitialRelativeTransform = FTransform::Identity; + bDenyGripping = false; + + bUpdateInTick = false; + bPassThrough = false; + + MinSlideDistance = FVector::ZeroVector; + MaxSlideDistance = FVector(10.0f, 0.f, 0.f); + SliderRestitution = 0.0f; + CurrentSliderProgress = 0.0f; + LastSliderProgress = FVector::ZeroVector;//0.0f; + SplineLastSliderProgress = 0.0f; + + MomentumAtDrop = FVector::ZeroVector;// 0.0f; + SplineMomentumAtDrop = 0.0f; + SliderMomentumFriction = 3.0f; + MaxSliderMomentum = 1.0f; + FramesToAverage = 3; + + InitialInteractorLocation = FVector::ZeroVector; + InitialGripLoc = FVector::ZeroVector; + + bSlideDistanceIsInParentSpace = true; + bUseLegacyLogic = false; + bIsLocked = false; + bAutoDropWhenLocked = true; + + SplineComponentToFollow = nullptr; + + bFollowSplineRotationAndScale = false; + SplineLerpType = EVRInteractibleSliderLerpType::Lerp_None; + SplineLerpValue = 8.f; + + PrimarySlotRange = 100.f; + SecondarySlotRange = 100.f; + GripPriority = 1; + LastSliderProgressState = -1.0f; + LastInputKey = 0.0f; + + bSliderUsesSnapPoints = false; + SnapIncrement = 0.1f; + SnapThreshold = 0.1f; + bIncrementProgressBetweenSnapPoints = false; + EventThrowThreshold = 1.0f; + bHitEventThreshold = false; + + // Set to only overlap with things so that its not ruined by touching over actors + this->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Overlap); +} + +//============================================================================= +UVRSliderComponent::~UVRSliderComponent() +{ +} + + +void UVRSliderComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UVRSliderComponent, InitialRelativeTransform, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UVRSliderComponent, SplineComponentToFollow, PushModelParams); + //DOREPLIFETIME_CONDITION(UVRDialComponent, bIsLerping, COND_InitialOnly); + + DOREPLIFETIME_WITH_PARAMS_FAST(UVRSliderComponent, bRepGameplayTags, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(UVRSliderComponent, bReplicateMovement, PushModelParams); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UVRSliderComponent, GameplayTags, PushModelParamsWithCondition); +} + +void UVRSliderComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) +{ + Super::PreReplication(ChangedPropertyTracker); + + // Replicate the levers initial transform if we are replicating movement + //DOREPLIFETIME_ACTIVE_OVERRIDE(UVRSliderComponent, InitialRelativeTransform, bReplicateMovement); + //DOREPLIFETIME_ACTIVE_OVERRIDE(UVRSliderComponent, SplineComponentToFollow, bReplicateMovement); + + // Don't replicate if set to not do it + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(UVRSliderComponent, GameplayTags, bRepGameplayTags); + + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeLocation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeRotation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeScale3D, bReplicateMovement); +} + +void UVRSliderComponent::OnRegister() +{ + Super::OnRegister(); + + // Init the slider settings + if (USplineComponent * ParentSpline = Cast(GetAttachParent())) + { + SetSplineComponentToFollow(ParentSpline); + } + else + { + ResetInitialSliderLocation(); + } +} + +void UVRSliderComponent::BeginPlay() +{ + // Call the base class + Super::BeginPlay(); + + CalculateSliderProgress(); + + bOriginalReplicatesMovement = bReplicateMovement; +} + +void UVRSliderComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) +{ + // Call supers tick (though I don't think any of the base classes to this actually implement it) + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + if (bIsHeld && bUpdateInTick && HoldingGrip.HoldingController) + { + FBPActorGripInformation GripInfo; + EBPVRResultSwitch Result; + HoldingGrip.HoldingController->GetGripByID(GripInfo, HoldingGrip.GripID, Result); + + if (Result == EBPVRResultSwitch::OnSucceeded) + { + bPassThrough = true; + TickGrip_Implementation(HoldingGrip.HoldingController, GripInfo, DeltaTime); + bPassThrough = false; + } + return; + } + + // If we are locked then end the lerp, no point + if (bIsLocked) + { + // Notify the end user + OnSliderFinishedLerping.Broadcast(CurrentSliderProgress); + ReceiveSliderFinishedLerping(CurrentSliderProgress); + + this->SetComponentTickEnabled(false); + bReplicateMovement = bOriginalReplicatesMovement; + + return; + } + + if (bIsLerping) + { + if ((SplineComponentToFollow && FMath::IsNearlyZero((SplineMomentumAtDrop * DeltaTime), 0.00001f)) || (!SplineComponentToFollow && (MomentumAtDrop * DeltaTime).IsNearlyZero(0.00001f))) + { + bIsLerping = false; + } + else + { + if (this->SplineComponentToFollow) + { + SplineMomentumAtDrop = FMath::FInterpTo(SplineMomentumAtDrop, 0.0f, DeltaTime, SliderMomentumFriction); + float newProgress = CurrentSliderProgress + (SplineMomentumAtDrop * DeltaTime); + + if (newProgress < 0.0f || FMath::IsNearlyEqual(newProgress, 0.0f, 0.00001f)) + { + if (SliderRestitution > 0.0f) + { + // Reverse the momentum + SplineMomentumAtDrop = -(SplineMomentumAtDrop * SliderRestitution); + this->SetSliderProgress(0.0f); + } + else + { + bIsLerping = false; + this->SetSliderProgress(0.0f); + } + } + else if (newProgress > 1.0f || FMath::IsNearlyEqual(newProgress, 1.0f, 0.00001f)) + { + if (SliderRestitution > 0.0f) + { + // Reverse the momentum + SplineMomentumAtDrop = -(SplineMomentumAtDrop * SliderRestitution); + this->SetSliderProgress(1.0f); + } + else + { + bIsLerping = false; + this->SetSliderProgress(1.0f); + } + } + else + { + this->SetSliderProgress(newProgress); + } + } + else + { + MomentumAtDrop = FMath::VInterpTo(MomentumAtDrop, FVector::ZeroVector, DeltaTime, SliderMomentumFriction); + + FVector ClampedLocation = ClampSlideVector(InitialRelativeTransform.InverseTransformPosition(this->GetRelativeLocation()) + (MomentumAtDrop * DeltaTime)); + this->SetRelativeLocation(InitialRelativeTransform.TransformPosition(ClampedLocation)); + CurrentSliderProgress = GetCurrentSliderProgress(bSlideDistanceIsInParentSpace ? ClampedLocation * InitialRelativeTransform.GetScale3D() : ClampedLocation); + float newProgress = CurrentSliderProgress; + if (SliderRestitution > 0.0f) + { + // Implement bounce + FVector CurLoc = ClampedLocation; + + if ( + (FMath::Abs(MinSlideDistance.X) > 0.0f && CurLoc.X <= -FMath::Abs(this->MinSlideDistance.X)) || + (FMath::Abs(MinSlideDistance.Y) > 0.0f && CurLoc.Y <= -FMath::Abs(this->MinSlideDistance.Y)) || + (FMath::Abs(MinSlideDistance.Z) > 0.0f && CurLoc.Z <= -FMath::Abs(this->MinSlideDistance.Z)) || + (FMath::Abs(MaxSlideDistance.X) > 0.0f && CurLoc.X >= FMath::Abs(this->MaxSlideDistance.X)) || + (FMath::Abs(MaxSlideDistance.Y) > 0.0f && CurLoc.Y >= FMath::Abs(this->MaxSlideDistance.Y)) || + (FMath::Abs(MaxSlideDistance.Z) > 0.0f && CurLoc.Z >= FMath::Abs(this->MaxSlideDistance.Z)) + ) + { + MomentumAtDrop = (-MomentumAtDrop * SliderRestitution); + } + } + else + { + if (newProgress < 0.0f || FMath::IsNearlyEqual(newProgress, 0.0f, 0.00001f)) + { + bIsLerping = false; + this->SetSliderProgress(0.0f); + } + else if (newProgress > 1.0f || FMath::IsNearlyEqual(newProgress, 1.0f, 0.00001f)) + { + bIsLerping = false; + this->SetSliderProgress(1.0f); + } + } + } + } + + if (!bIsLerping) + { + // Notify the end user + OnSliderFinishedLerping.Broadcast(CurrentSliderProgress); + ReceiveSliderFinishedLerping(CurrentSliderProgress); + + this->SetComponentTickEnabled(false); + bReplicateMovement = bOriginalReplicatesMovement; + } + + // Check for the hit point always + CheckSliderProgress(); + } +} + +void UVRSliderComponent::TickGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation, float DeltaTime) +{ + + // Skip this tick if its not triggered from the pass through + if (bUpdateInTick && !bPassThrough) + return; + + // If the sliders progress is locked then just exit early + if (bIsLocked) + { + if (bAutoDropWhenLocked) + { + // Check if we should auto drop + CheckAutoDrop(GrippingController, GripInformation); + } + + return; + } + + // Handle manual tracking here + FTransform ParentTransform = UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(this); + FTransform CurrentRelativeTransform = InitialRelativeTransform * ParentTransform; + FVector CurInteractorLocation = CurrentRelativeTransform.InverseTransformPosition(GrippingController->GetPivotLocation()); + + FVector CalculatedLocation = InitialGripLoc + (CurInteractorLocation - InitialInteractorLocation); + + float SplineProgress = CurrentSliderProgress; + if (SplineComponentToFollow != nullptr) + { + FVector WorldCalculatedLocation = CurrentRelativeTransform.TransformPosition(CalculatedLocation); + float ClosestKey = SplineComponentToFollow->FindInputKeyClosestToWorldLocation(WorldCalculatedLocation); + + if (bSliderUsesSnapPoints) + { + float SplineLength = SplineComponentToFollow->GetSplineLength(); + SplineProgress = GetCurrentSliderProgress(WorldCalculatedLocation, true, ClosestKey); + + SplineProgress = UVRInteractibleFunctionLibrary::Interactible_GetThresholdSnappedValue(SplineProgress, SnapIncrement, SnapThreshold); + + const int32 NumPoints = SplineComponentToFollow->SplineCurves.Position.Points.Num(); + + if (SplineComponentToFollow->SplineCurves.Position.Points.Num() > 1) + { + ClosestKey = SplineComponentToFollow->SplineCurves.ReparamTable.Eval(SplineProgress * SplineLength, 0.0f); + } + + WorldCalculatedLocation = SplineComponentToFollow->GetLocationAtSplineInputKey(ClosestKey, ESplineCoordinateSpace::World); + } + + bool bLerpToNewKey = true; + bool bChangedLocation = false; + + if (bEnforceSplineLinearity && LastInputKey >= 0.0f && + FMath::Abs((FMath::TruncToFloat(ClosestKey) - FMath::TruncToFloat(LastInputKey))) > 1.0f && + (!bSliderUsesSnapPoints || (SplineProgress - CurrentSliderProgress > SnapIncrement)) + ) + { + bLerpToNewKey = false; + } + else + { + LerpedKey = ClosestKey; + } + + if (bFollowSplineRotationAndScale) + { + FTransform trans; + if (SplineLerpType != EVRInteractibleSliderLerpType::Lerp_None && LastInputKey >= 0.0f && !FMath::IsNearlyEqual(LerpedKey, LastInputKey)) + { + GetLerpedKey(LerpedKey, DeltaTime); + trans = SplineComponentToFollow->GetTransformAtSplineInputKey(LerpedKey, ESplineCoordinateSpace::World, true); + bChangedLocation = true; + } + else if (bLerpToNewKey) + { + trans = SplineComponentToFollow->FindTransformClosestToWorldLocation(WorldCalculatedLocation, ESplineCoordinateSpace::World, true); + bChangedLocation = true; + } + + if (bChangedLocation) + { + trans.MultiplyScale3D(InitialRelativeTransform.GetScale3D()); + trans = trans * ParentTransform.Inverse(); + this->SetRelativeTransform(trans); + } + } + else + { + FVector WorldLocation; + if (SplineLerpType != EVRInteractibleSliderLerpType::Lerp_None && LastInputKey >= 0.0f && !FMath::IsNearlyEqual(LerpedKey, LastInputKey)) + { + GetLerpedKey(LerpedKey, DeltaTime); + WorldLocation = SplineComponentToFollow->GetLocationAtSplineInputKey(LerpedKey, ESplineCoordinateSpace::World); + bChangedLocation = true; + } + else if (bLerpToNewKey) + { + WorldLocation = SplineComponentToFollow->FindLocationClosestToWorldLocation(WorldCalculatedLocation, ESplineCoordinateSpace::World); + bChangedLocation = true; + } + + if (bChangedLocation) + this->SetRelativeLocation(ParentTransform.InverseTransformPosition(WorldLocation)); + } + + CurrentSliderProgress = GetCurrentSliderProgress(WorldCalculatedLocation, true, bLerpToNewKey ? LerpedKey : ClosestKey); + if (bLerpToNewKey) + { + LastInputKey = LerpedKey; + } + } + else + { + FVector ClampedLocation = ClampSlideVector(CalculatedLocation); + this->SetRelativeLocation(InitialRelativeTransform.TransformPosition(ClampedLocation)); + CurrentSliderProgress = GetCurrentSliderProgress(bSlideDistanceIsInParentSpace ? ClampedLocation * InitialRelativeTransform.GetScale3D() : ClampedLocation); + } + + if (SliderBehaviorWhenReleased == EVRInteractibleSliderDropBehavior::RetainMomentum) + { + if (SplineComponentToFollow) + { + // Rolling average across num samples + SplineMomentumAtDrop -= SplineMomentumAtDrop / FramesToAverage; + SplineMomentumAtDrop += ((CurrentSliderProgress - SplineLastSliderProgress) / DeltaTime) / FramesToAverage; + + float momentumSign = FMath::Sign(SplineMomentumAtDrop); + SplineMomentumAtDrop = momentumSign * FMath::Min(MaxSliderMomentum, FMath::Abs(SplineMomentumAtDrop)); + + SplineLastSliderProgress = CurrentSliderProgress; + } + else + { + // Rolling average across num samples + MomentumAtDrop -= MomentumAtDrop / FramesToAverage; + FVector CurProgress = InitialRelativeTransform.InverseTransformPosition(this->GetRelativeLocation()); + if (bSlideDistanceIsInParentSpace) + CurProgress *= FVector(1.0f) / InitialRelativeTransform.GetScale3D(); + + MomentumAtDrop += ((/*CurrentSliderProgress*/CurProgress - LastSliderProgress) / DeltaTime) / FramesToAverage; + + //MomentumAtDrop = FMath::Min(MaxSliderMomentum, MomentumAtDrop); + + LastSliderProgress = CurProgress;//CurrentSliderProgress; + } + } + + CheckSliderProgress(); + + // Check if we should auto drop + CheckAutoDrop(GrippingController, GripInformation); +} + +bool UVRSliderComponent::CheckAutoDrop(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) +{ + // Converted to a relative value now so it should be correct + if (BreakDistance > 0.f && GrippingController->HasGripAuthority(GripInformation) && FVector::DistSquared(InitialDropLocation, this->GetComponentTransform().InverseTransformPosition(GrippingController->GetPivotLocation())) >= FMath::Square(BreakDistance)) + { + if (GrippingController->OnGripOutOfRange.IsBound()) + { + uint8 GripID = GripInformation.GripID; + GrippingController->OnGripOutOfRange.Broadcast(GripInformation, GripInformation.GripDistance); + } + else + { + GrippingController->DropObjectByInterface(this, HoldingGrip.GripID); + } + return true; + } + + return false; +} + +void UVRSliderComponent::CheckSliderProgress() +{ + // Skip first check, this will skip an event throw on rounded + if (LastSliderProgressState < 0.0f) + { + // Skip first tick, this is our resting position + if (!bSliderUsesSnapPoints) + LastSliderProgressState = FMath::RoundToFloat(CurrentSliderProgress); // Ensure it is rounded to 0 or 1 + else + LastSliderProgressState = CurrentSliderProgress; + } + else if ((LastSliderProgressState != CurrentSliderProgress) || bHitEventThreshold) + { + float ModValue = FMath::Fmod(CurrentSliderProgress, SnapIncrement); + if ((!bSliderUsesSnapPoints && (CurrentSliderProgress == 1.0f || CurrentSliderProgress == 0.0f)) || + (bSliderUsesSnapPoints && SnapIncrement > 0.f && (FMath::IsNearlyEqual(ModValue, 0.0f, 0.001f) || FMath::IsNearlyEqual(ModValue, SnapIncrement, 0.00001f))) + ) + { + // I am working with exacts here because of the clamping, it should actually work with no precision issues + // I wanted to ABS(Last-Cur) == 1.0 but it would cause an initial miss on whatever one last was inited to. + + if (!bSliderUsesSnapPoints) + LastSliderProgressState = FMath::RoundToFloat(CurrentSliderProgress); // Ensure it is rounded to 0 or 1 + else + LastSliderProgressState = CurrentSliderProgress; + + ReceiveSliderHitPoint(LastSliderProgressState); + OnSliderHitPoint.Broadcast(LastSliderProgressState); + bHitEventThreshold = false; + } + } + + if (FMath::Abs(LastSliderProgressState - CurrentSliderProgress) >= (bSliderUsesSnapPoints ? FMath::Min(EventThrowThreshold, SnapIncrement / 2.0f) : EventThrowThreshold)) + { + bHitEventThreshold = true; + } +} + +void UVRSliderComponent::OnGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) +{ + FTransform CurrentRelativeTransform = InitialRelativeTransform * UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(this); + + // This lets me use the correct original location over the network without changes + FTransform ReversedRelativeTransform = FTransform(GripInformation.RelativeTransform.ToInverseMatrixWithScale()); + FTransform RelativeToGripTransform = ReversedRelativeTransform * this->GetComponentTransform(); + + InitialInteractorLocation = CurrentRelativeTransform.InverseTransformPosition(RelativeToGripTransform.GetTranslation()); + InitialGripLoc = InitialRelativeTransform.InverseTransformPosition(this->GetRelativeLocation()); + InitialDropLocation = ReversedRelativeTransform.GetTranslation(); + LastInputKey = -1.0f; + LerpedKey = 0.0f; + bHitEventThreshold = false; + //LastSliderProgressState = -1.0f; + LastSliderProgress = InitialGripLoc;//CurrentSliderProgress; + SplineLastSliderProgress = CurrentSliderProgress; + + bIsLerping = false; + MomentumAtDrop = FVector::ZeroVector;//0.0f; + SplineMomentumAtDrop = 0.0f; + + if (GripInformation.GripMovementReplicationSetting != EGripMovementReplicationSettings::ForceServerSideMovement) + { + bReplicateMovement = false; + } + + if (bUpdateInTick) + SetComponentTickEnabled(true); + + //OnGripped.Broadcast(GrippingController, GripInformation); + +} + +void UVRSliderComponent::OnGripRelease_Implementation(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed) +{ + //this->SetComponentTickEnabled(false); + // #TODO: Handle letting go and how lerping works, specifically with the snap points it may be an issue + if (SliderBehaviorWhenReleased != EVRInteractibleSliderDropBehavior::Stay) + { + bIsLerping = true; + this->SetComponentTickEnabled(true); + + FVector Len = (MinSlideDistance.GetAbs() + MaxSlideDistance.GetAbs()); + if(bSlideDistanceIsInParentSpace) + Len *= (FVector(1.0f) / InitialRelativeTransform.GetScale3D()); + + float TotalDistance = Len.Size(); + + if (!SplineComponentToFollow) + { + if (MaxSliderMomentum * TotalDistance < MomentumAtDrop.Size()) + { + MomentumAtDrop = MomentumAtDrop.GetSafeNormal() * (TotalDistance * MaxSliderMomentum); + } + } + + if(MovementReplicationSetting != EGripMovementReplicationSettings::ForceServerSideMovement) + bReplicateMovement = false; + } + else + { + this->SetComponentTickEnabled(false); + bReplicateMovement = bOriginalReplicatesMovement; + } + + //OnDropped.Broadcast(ReleasingController, GripInformation, bWasSocketed); +} + +void UVRSliderComponent::SetIsLocked(bool bNewLockedState) +{ + bIsLocked = bNewLockedState; +} + +void UVRSliderComponent::SetGripPriority(int NewGripPriority) +{ + GripPriority = NewGripPriority; +} + +void UVRSliderComponent::OnChildGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) {} +void UVRSliderComponent::OnChildGripRelease_Implementation(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed) {} +void UVRSliderComponent::OnSecondaryGrip_Implementation(UGripMotionControllerComponent * GripOwningController, USceneComponent * SecondaryGripComponent, const FBPActorGripInformation & GripInformation) {} +void UVRSliderComponent::OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent * GripOwningController, USceneComponent * ReleasingSecondaryGripComponent, const FBPActorGripInformation & GripInformation) {} +void UVRSliderComponent::OnUsed_Implementation() {} +void UVRSliderComponent::OnEndUsed_Implementation() {} +void UVRSliderComponent::OnSecondaryUsed_Implementation() {} +void UVRSliderComponent::OnEndSecondaryUsed_Implementation() {} +void UVRSliderComponent::OnInput_Implementation(FKey Key, EInputEvent KeyEvent) {} +bool UVRSliderComponent::RequestsSocketing_Implementation(USceneComponent *& ParentToSocketTo, FName & OptionalSocketName, FTransform_NetQuantize & RelativeTransform) { return false; } + +bool UVRSliderComponent::DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator) +{ + return bDenyGripping; +} + +EGripInterfaceTeleportBehavior UVRSliderComponent::TeleportBehavior_Implementation() +{ + return EGripInterfaceTeleportBehavior::DropOnTeleport; +} + +bool UVRSliderComponent::SimulateOnDrop_Implementation() +{ + return false; +} + +/*EGripCollisionType UVRSliderComponent::SlotGripType_Implementation() +{ + return EGripCollisionType::CustomGrip; +} + +EGripCollisionType UVRSliderComponent::FreeGripType_Implementation() +{ + return EGripCollisionType::CustomGrip; +}*/ + +EGripCollisionType UVRSliderComponent::GetPrimaryGripType_Implementation(bool bIsSlot) +{ + return EGripCollisionType::CustomGrip; +} + +ESecondaryGripType UVRSliderComponent::SecondaryGripType_Implementation() +{ + return ESecondaryGripType::SG_None; +} + + +EGripMovementReplicationSettings UVRSliderComponent::GripMovementReplicationType_Implementation() +{ + return MovementReplicationSetting; +} + +EGripLateUpdateSettings UVRSliderComponent::GripLateUpdateSetting_Implementation() +{ + return EGripLateUpdateSettings::LateUpdatesAlwaysOff; +} + +/*float UVRSliderComponent::GripStiffness_Implementation() +{ + return 0.0f; +} + +float UVRSliderComponent::GripDamping_Implementation() +{ + return 0.0f; +}*/ +void UVRSliderComponent::GetGripStiffnessAndDamping_Implementation(float &GripStiffnessOut, float &GripDampingOut) +{ + GripStiffnessOut = 0.0f; + GripDampingOut = 0.0f; +} + +FBPAdvGripSettings UVRSliderComponent::AdvancedGripSettings_Implementation() +{ + return FBPAdvGripSettings(GripPriority); +} + +float UVRSliderComponent::GripBreakDistance_Implementation() +{ + return BreakDistance; +} + +/*void UVRSliderComponent::ClosestSecondarySlotInRange_Implementation(FVector WorldLocation, bool & bHadSlotInRange, FTransform & SlotWorldTransform, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ + bHadSlotInRange = false; +} + +void UVRSliderComponent::ClosestPrimarySlotInRange_Implementation(FVector WorldLocation, bool & bHadSlotInRange, FTransform & SlotWorldTransform, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ + bHadSlotInRange = false; +}*/ + +void UVRSliderComponent::ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool & bHadSlotInRange, FTransform & SlotWorldTransform, FName & SlotName, UGripMotionControllerComponent * CallingController, FName OverridePrefix) +{ + if (OverridePrefix.IsNone()) + bSecondarySlot ? OverridePrefix = "VRGripS" : OverridePrefix = "VRGripP"; + + UVRExpansionFunctionLibrary::GetGripSlotInRangeByTypeName_Component(OverridePrefix, this, WorldLocation, bSecondarySlot ? SecondarySlotRange : PrimarySlotRange, bHadSlotInRange, SlotWorldTransform, SlotName, CallingController); +} + +bool UVRSliderComponent::AllowsMultipleGrips_Implementation() +{ + return false; +} + +void UVRSliderComponent::IsHeld_Implementation(TArray & CurHoldingControllers, bool & bCurIsHeld) +{ + CurHoldingControllers.Empty(); + if (HoldingGrip.IsValid()) + { + CurHoldingControllers.Add(HoldingGrip); + bCurIsHeld = bIsHeld; + } + else + { + bCurIsHeld = false; + } +} + +void UVRSliderComponent::Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed) +{ + if (bGripped) + { + OnGripped.Broadcast(Controller, GripInformation); + } + else + { + OnDropped.Broadcast(Controller, GripInformation, bWasSocketed); + } +} + +void UVRSliderComponent::SetHeld_Implementation(UGripMotionControllerComponent * NewHoldingController, uint8 GripID, bool bNewIsHeld) +{ + if (bNewIsHeld) + { + HoldingGrip = FBPGripPair(NewHoldingController, GripID); + if (MovementReplicationSetting != EGripMovementReplicationSettings::ForceServerSideMovement) + { + if (!bIsHeld && !bIsLerping) + bOriginalReplicatesMovement = bReplicateMovement; + bReplicateMovement = false; + } + } + else + { + HoldingGrip.Clear(); + if (MovementReplicationSetting != EGripMovementReplicationSettings::ForceServerSideMovement) + { + bReplicateMovement = bOriginalReplicatesMovement; + } + } + + bIsHeld = bNewIsHeld; +} + +/*FBPInteractionSettings UVRSliderComponent::GetInteractionSettings_Implementation() +{ + return FBPInteractionSettings(); +}*/ + +bool UVRSliderComponent::GetGripScripts_Implementation(TArray & ArrayReference) +{ + return false; +} + +FVector UVRSliderComponent::ClampSlideVector(FVector ValueToClamp) +{ + FVector fScaleFactor = FVector(1.0f); + + if (bSlideDistanceIsInParentSpace) + fScaleFactor = fScaleFactor / InitialRelativeTransform.GetScale3D(); + + FVector MinScale = (bUseLegacyLogic ? MinSlideDistance : MinSlideDistance.GetAbs()) * fScaleFactor; + + FVector Dist = (bUseLegacyLogic ? (MinSlideDistance + MaxSlideDistance) : (MinSlideDistance.GetAbs() + MaxSlideDistance.GetAbs())) * fScaleFactor; + FVector Progress{ + Dist.X > 0.0f ? (ValueToClamp.X - (-MinScale.X)) / Dist.X : 0.f, + Dist.Y > 0.0f ? (ValueToClamp.Y - (-MinScale.Y)) / Dist.Y : 0.f, + Dist.Z > 0.0f ? (ValueToClamp.Z - (-MinScale.Z)) / Dist.Z : 0.f, + }; + + + if (bSliderUsesSnapPoints) + { + Progress.X = FMath::Clamp(UVRInteractibleFunctionLibrary::Interactible_GetThresholdSnappedValue(Progress.X, SnapIncrement, SnapThreshold), 0.0f, 1.0f); + Progress.Y = FMath::Clamp(UVRInteractibleFunctionLibrary::Interactible_GetThresholdSnappedValue(Progress.Y, SnapIncrement, SnapThreshold), 0.0f, 1.0f); + Progress.Z = FMath::Clamp(UVRInteractibleFunctionLibrary::Interactible_GetThresholdSnappedValue(Progress.Z, SnapIncrement, SnapThreshold), 0.0f, 1.0f); + } + else + { + Progress.X = FMath::Clamp(Progress.X, 0.f, 1.f); + Progress.Y = FMath::Clamp(Progress.Y, 0.f, 1.f); + Progress.Z = FMath::Clamp(Progress.Z, 0.f, 1.f); + } + + return (Progress * Dist) - (MinScale); +} + +float UVRSliderComponent::GetDistanceAlongSplineAtSplineInputKey(float InKey) const +{ + + const int32 NumPoints = SplineComponentToFollow->SplineCurves.Position.Points.Num(); + const int32 NumSegments = SplineComponentToFollow->IsClosedLoop() ? NumPoints : NumPoints - 1; + + if ((InKey >= 0) && (InKey < NumSegments)) + { + const int32 ReparamPrevIndex = static_cast(InKey * SplineComponentToFollow->ReparamStepsPerSegment); + const int32 ReparamNextIndex = ReparamPrevIndex + 1; + + const float Alpha = (InKey * SplineComponentToFollow->ReparamStepsPerSegment) - static_cast(ReparamPrevIndex); + + const float PrevDistance = SplineComponentToFollow->SplineCurves.ReparamTable.Points[ReparamPrevIndex].InVal; + const float NextDistance = SplineComponentToFollow->SplineCurves.ReparamTable.Points[ReparamNextIndex].InVal; + + // ReparamTable assumes that distance and input keys have a linear relationship in-between entries. + return FMath::Lerp(PrevDistance, NextDistance, Alpha); + } + else if (InKey >= NumSegments) + { + return SplineComponentToFollow->SplineCurves.GetSplineLength(); + } + + return 0.0f; +} + +FVector UVRSliderComponent::GetPerAxisSliderProgress() +{ + // If we are following a spline per axis makes no sense, return overall progress on all axis's + if (SplineComponentToFollow != nullptr) + { + return FVector(CurrentSliderProgress); + } + + // Get our relative space location + FTransform ParentTransform = UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(this); + FTransform CurrentRelativeTransform = InitialRelativeTransform * ParentTransform; + FVector CalculatedLocation = CurrentRelativeTransform.InverseTransformPosition(this->GetComponentLocation()); + CalculatedLocation = bSlideDistanceIsInParentSpace ? CalculatedLocation * InitialRelativeTransform.GetScale3D() : CalculatedLocation; + + // Should need the clamp normally, but if someone is manually setting locations it could go out of bounds + FVector Progress; + + if (bUseLegacyLogic) + { + if(MinSlideDistance.X != 0.0f || MaxSlideDistance.X != 0.0) + Progress.X = FMath::Clamp(FMath::Abs(-MinSlideDistance.X - CalculatedLocation.X) / FMath::Abs(-MinSlideDistance.X - MaxSlideDistance.X), 0.0f, 1.0f); + if (MinSlideDistance.Y != 0.0f || MaxSlideDistance.Y != 0.0) + Progress.Y = FMath::Clamp(FMath::Abs(-MinSlideDistance.Y - CalculatedLocation.Y) / FMath::Abs(-MinSlideDistance.Y - MaxSlideDistance.Y), 0.0f, 1.0f); + if (MinSlideDistance.Z != 0.0f || MaxSlideDistance.Z != 0.0) + Progress.Z = FMath::Clamp(FMath::Abs(-MinSlideDistance.Z - CalculatedLocation.Z) / FMath::Abs(-MinSlideDistance.Z - MaxSlideDistance.Z), 0.0f, 1.0f); + } + else + { + FVector MinABS = MinSlideDistance.GetAbs(); + FVector MaxABS = MaxSlideDistance.GetAbs(); + + if (MinSlideDistance.X != 0.0f || MaxSlideDistance.X != 0.0) + Progress.X = FMath::Clamp(FMath::Abs(-MinABS.X - CalculatedLocation.X) / FMath::Abs(-MinABS.X - MaxABS.X), 0.0f, 1.0f); + if (MinSlideDistance.Y != 0.0f || MaxSlideDistance.Y != 0.0) + Progress.Y = FMath::Clamp(FMath::Abs(-MinABS.Y - CalculatedLocation.Y) / FMath::Abs(-MinABS.Y - MaxABS.Y), 0.0f, 1.0f); + if (MinSlideDistance.Z != 0.0f || MaxSlideDistance.Z != 0.0) + Progress.Z = FMath::Clamp(FMath::Abs(-MinABS.Z - CalculatedLocation.Z) / FMath::Abs(-MinABS.Z - MaxABS.Z), 0.0f, 1.0f); + } + + // Don't setup snap point calculations for this function for now + + return Progress; +} + +float UVRSliderComponent::GetCurrentSliderProgress(FVector CurLocation, bool bUseKeyInstead, float CurKey) +{ + if (SplineComponentToFollow != nullptr) + { + // In this case it is a world location + float ClosestKey = CurKey; + + if (!bUseKeyInstead) + ClosestKey = SplineComponentToFollow->FindInputKeyClosestToWorldLocation(CurLocation); + + /*int32 primaryKey = FMath::TruncToInt(ClosestKey); + + float distance1 = SplineComponentToFollow->GetDistanceAlongSplineAtSplinePoint(primaryKey); + float distance2 = SplineComponentToFollow->GetDistanceAlongSplineAtSplinePoint(primaryKey + 1); + + float FinalDistance = ((distance2 - distance1) * (ClosestKey - (float)primaryKey)) + distance1; + return FMath::Clamp(FinalDistance / SplineComponentToFollow->GetSplineLength(), 0.0f, 1.0f);*/ + float SplineLength = SplineComponentToFollow->GetSplineLength(); + return GetDistanceAlongSplineAtSplineInputKey(ClosestKey) / SplineLength; + } + + // Should need the clamp normally, but if someone is manually setting locations it could go out of bounds + float Progress = 0.f; + + if (bUseLegacyLogic) + { + Progress = FMath::Clamp(FVector::Dist(-MinSlideDistance, CurLocation) / FVector::Dist(-MinSlideDistance, MaxSlideDistance), 0.0f, 1.0f); + } + else + { + Progress = FMath::Clamp(FVector::Dist(-MinSlideDistance.GetAbs(), CurLocation) / FVector::Dist(-MinSlideDistance.GetAbs(), MaxSlideDistance.GetAbs()), 0.0f, 1.0f); + } + + if (bSliderUsesSnapPoints && SnapThreshold < SnapIncrement) + { + if (FMath::Fmod(Progress, SnapIncrement) < SnapThreshold) + { + Progress = FMath::GridSnap(Progress, SnapIncrement); + } + else if(!bIncrementProgressBetweenSnapPoints) + { + Progress = CurrentSliderProgress; + } + } + + return Progress; +} + +void UVRSliderComponent::GetLerpedKey(float &ClosestKey, float DeltaTime) +{ + switch (SplineLerpType) + { + case EVRInteractibleSliderLerpType::Lerp_Interp: + { + ClosestKey = FMath::FInterpTo(LastInputKey, ClosestKey, DeltaTime, SplineLerpValue); + }break; + case EVRInteractibleSliderLerpType::Lerp_InterpConstantTo: + { + ClosestKey = FMath::FInterpConstantTo(LastInputKey, ClosestKey, DeltaTime, SplineLerpValue); + }break; + + default: break; + } +} + +void UVRSliderComponent::SetSplineComponentToFollow(USplineComponent * SplineToFollow) +{ + SplineComponentToFollow = SplineToFollow; + +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UVRSliderComponent, SplineComponentToFollow, this); +#endif + + if (SplineToFollow != nullptr) + ResetToParentSplineLocation(); + else + CalculateSliderProgress(); +} + +void UVRSliderComponent::ResetInitialSliderLocation() +{ + // Get our initial relative transform to our parent (or not if un-parented). + InitialRelativeTransform = this->GetRelativeTransform(); + +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UVRSliderComponent, InitialRelativeTransform, this); +#endif + + ResetToParentSplineLocation(); + + if (SplineComponentToFollow == nullptr) + CurrentSliderProgress = GetCurrentSliderProgress(FVector(0, 0, 0)); +} + +void UVRSliderComponent::ResetToParentSplineLocation() +{ + if (SplineComponentToFollow != nullptr) + { + FTransform ParentTransform = UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(this); + FTransform WorldTransform = SplineComponentToFollow->FindTransformClosestToWorldLocation(this->GetComponentLocation(), ESplineCoordinateSpace::World, true); + if (bFollowSplineRotationAndScale) + { + WorldTransform.MultiplyScale3D(InitialRelativeTransform.GetScale3D()); + WorldTransform = WorldTransform * ParentTransform.Inverse(); + this->SetRelativeTransform(WorldTransform); + } + else + { + this->SetWorldLocation(WorldTransform.GetLocation()); + } + + CurrentSliderProgress = GetCurrentSliderProgress(WorldTransform.GetLocation()); + } +} + +void UVRSliderComponent::SetSliderProgress(float NewSliderProgress) +{ + NewSliderProgress = FMath::Clamp(NewSliderProgress, 0.0f, 1.0f); + + if (SplineComponentToFollow != nullptr) + { + FTransform ParentTransform = UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(this); + float splineProgress = SplineComponentToFollow->GetSplineLength() * NewSliderProgress; + + if (bFollowSplineRotationAndScale) + { + FTransform trans = SplineComponentToFollow->GetTransformAtDistanceAlongSpline(splineProgress, ESplineCoordinateSpace::World, true); + trans.MultiplyScale3D(InitialRelativeTransform.GetScale3D()); + trans = trans * ParentTransform.Inverse(); + this->SetRelativeTransform(trans); + } + else + { + this->SetRelativeLocation(ParentTransform.InverseTransformPosition(SplineComponentToFollow->GetLocationAtDistanceAlongSpline(splineProgress, ESplineCoordinateSpace::World))); + } + } + else // Not a spline follow + { + // Doing it min+max because the clamp value subtracts the min value + FVector CalculatedLocation = bUseLegacyLogic ? FMath::Lerp(-MinSlideDistance, MaxSlideDistance, NewSliderProgress) : FMath::Lerp(-MinSlideDistance.GetAbs(), MaxSlideDistance.GetAbs(), NewSliderProgress); + + if (bSlideDistanceIsInParentSpace) + CalculatedLocation *= FVector(1.0f) / InitialRelativeTransform.GetScale3D(); + + FVector ClampedLocation = ClampSlideVector(CalculatedLocation); + + //if (bSlideDistanceIsInParentSpace) + // this->SetRelativeLocation(InitialRelativeTransform.TransformPositionNoScale(ClampedLocation)); + //else + this->SetRelativeLocation(InitialRelativeTransform.TransformPosition(ClampedLocation)); + } + + CurrentSliderProgress = NewSliderProgress; +} + +float UVRSliderComponent::CalculateSliderProgress() +{ + if (this->SplineComponentToFollow != nullptr) + { + CurrentSliderProgress = GetCurrentSliderProgress(this->GetComponentLocation()); + } + else + { + FTransform ParentTransform = UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(this); + FTransform CurrentRelativeTransform = InitialRelativeTransform * ParentTransform; + FVector CalculatedLocation = CurrentRelativeTransform.InverseTransformPosition(this->GetComponentLocation()); + + CurrentSliderProgress = GetCurrentSliderProgress(bSlideDistanceIsInParentSpace ? CalculatedLocation * InitialRelativeTransform.GetScale3D() : CalculatedLocation); + } + + return CurrentSliderProgress; +} + +void UVRSliderComponent::SetRepGameplayTags(bool bNewRepGameplayTags) +{ + bRepGameplayTags = bNewRepGameplayTags; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UVRSliderComponent, bRepGameplayTags, this); +#endif +} + +void UVRSliderComponent::SetReplicateMovement(bool bNewReplicateMovement) +{ + bReplicateMovement = bNewReplicateMovement; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UVRSliderComponent, bReplicateMovement, this); +#endif +} + +FGameplayTagContainer& UVRSliderComponent::GetGameplayTags() +{ +#if WITH_PUSH_MODEL + if (bRepGameplayTags) + { + MARK_PROPERTY_DIRTY_FROM_NAME(UVRSliderComponent, GameplayTags, this); + } +#endif + + return GameplayTags; +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/BucketUpdateSubsystem.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/BucketUpdateSubsystem.cpp new file mode 100644 index 0000000..8a20353 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/BucketUpdateSubsystem.cpp @@ -0,0 +1,398 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Misc/BucketUpdateSubsystem.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(BucketUpdateSubsystem) + + bool UBucketUpdateSubsystem::AddObjectToBucket(int32 UpdateHTZ, UObject* InObject, FName FunctionName) + { + if (!InObject || UpdateHTZ < 1) + return false; + + return BucketContainer.AddBucketObject(UpdateHTZ, InObject, FunctionName); + } + + bool UBucketUpdateSubsystem::K2_AddObjectToBucket(int32 UpdateHTZ, UObject* InObject, FName FunctionName) + { + if (!InObject || UpdateHTZ < 1) + return false; + + return BucketContainer.AddBucketObject(UpdateHTZ, InObject, FunctionName); + } + + + bool UBucketUpdateSubsystem::K2_AddObjectEventToBucket(FDynamicBucketUpdateTickSignature Delegate, int32 UpdateHTZ) + { + if (!Delegate.IsBound()) + return false; + + return BucketContainer.AddBucketObject(UpdateHTZ, Delegate); + } + + bool UBucketUpdateSubsystem::RemoveObjectFromBucketByFunctionName(UObject* InObject, FName FunctionName) + { + if (!InObject) + return false; + + return BucketContainer.RemoveBucketObject(InObject, FunctionName); + } + + bool UBucketUpdateSubsystem::RemoveObjectFromBucketByEvent(FDynamicBucketUpdateTickSignature Delegate) + { + if (!Delegate.IsBound()) + return false; + + return BucketContainer.RemoveBucketObject(Delegate); + } + + bool UBucketUpdateSubsystem::RemoveObjectFromAllBuckets(UObject* InObject) + { + if (!InObject) + return false; + + return BucketContainer.RemoveObjectFromAllBuckets(InObject); + } + + bool UBucketUpdateSubsystem::IsObjectFunctionInBucket(UObject* InObject, FName FunctionName) + { + if (!InObject) + return false; + + return BucketContainer.IsObjectFunctionInBucket(InObject, FunctionName); + } + + bool UBucketUpdateSubsystem::IsActive() + { + return BucketContainer.bNeedsUpdate; + } + + void UBucketUpdateSubsystem::Tick(float DeltaTime) + { + BucketContainer.UpdateBuckets(DeltaTime); + } + + bool UBucketUpdateSubsystem::IsTickable() const + { + return BucketContainer.bNeedsUpdate; + } + + UWorld* UBucketUpdateSubsystem::GetTickableGameObjectWorld() const + { + return GetWorld(); + } + + bool UBucketUpdateSubsystem::IsTickableInEditor() const + { + return false; + } + + bool UBucketUpdateSubsystem::IsTickableWhenPaused() const + { + return false; + } + + ETickableTickType UBucketUpdateSubsystem::GetTickableTickType() const + { + if (IsTemplate(RF_ClassDefaultObject)) + return ETickableTickType::Never; + + return ETickableTickType::Conditional; + } + + TStatId UBucketUpdateSubsystem::GetStatId() const + { + RETURN_QUICK_DECLARE_CYCLE_STAT(UVRGripScriptBase, STATGROUP_Tickables); + } + + bool FUpdateBucketDrop::ExecuteBoundCallback() + { + if (NativeCallback.IsBound()) + { + return NativeCallback.Execute(); + } + else if (DynamicCallback.IsBound()) + { + DynamicCallback.Execute(); + return true; + } + + return false; + } + + bool FUpdateBucketDrop::IsBoundToObjectFunction(UObject * Obj, FName & FuncName) + { + return (NativeCallback.IsBoundToObject(Obj) && FunctionName == FuncName); + } + + bool FUpdateBucketDrop::IsBoundToObjectDelegate(FDynamicBucketUpdateTickSignature & DynEvent) + { + return DynamicCallback == DynEvent; + } + + bool FUpdateBucketDrop::IsBoundToObject(UObject * Obj) + { + return (NativeCallback.IsBoundToObject(Obj) || DynamicCallback.IsBoundToObject(Obj)); + } + + FUpdateBucketDrop::FUpdateBucketDrop() + { + FunctionName = NAME_None; + } + + FUpdateBucketDrop::FUpdateBucketDrop(FDynamicBucketUpdateTickSignature & DynCallback) + { + DynamicCallback = DynCallback; + } + + FUpdateBucketDrop::FUpdateBucketDrop(UObject * Obj, FName FuncName) + { + if (Obj && Obj->FindFunction(FuncName)) + { + FunctionName = FuncName; + NativeCallback.BindUFunction(Obj, FunctionName); + } + else + { + FunctionName = NAME_None; + } + } + + bool FUpdateBucket::Update(float DeltaTime) + { + //#TODO: Need to consider batching / spreading out load if there are a lot of updating objects in the bucket + if (Callbacks.Num() < 1) + return false; + + // Check for if this bucket is ready to fire events + nUpdateCount += DeltaTime; + if (nUpdateCount >= nUpdateRate) + { + nUpdateCount = 0.0f; + for (int i = Callbacks.Num() - 1; i >= 0; --i) + { + if (Callbacks[i].ExecuteBoundCallback()) + { + // If this returns true then we keep it in the queue + continue; + } + + // Remove the callback, it is complete or invalid + Callbacks.RemoveAt(i); + } + } + + return Callbacks.Num() > 0; + } + + void FUpdateBucketContainer::UpdateBuckets(float DeltaTime) + { + TArray BucketsToRemove; + for(auto& Bucket : ReplicationBuckets) + { + if (!Bucket.Value.Update(DeltaTime)) + { + // Add Bucket to list to remove at end of update + BucketsToRemove.Add(Bucket.Key); + } + } + + // Remove unused buckets so that they don't get ticked + for (const uint32 Key : BucketsToRemove) + { + ReplicationBuckets.Remove(Key); + } + + if (ReplicationBuckets.Num() < 1) + bNeedsUpdate = false; + } + + bool FUpdateBucketContainer::AddBucketObject(uint32 UpdateHTZ, UObject* InObject, FName FunctionName) + { + if (!InObject || InObject->FindFunction(FunctionName) == nullptr || UpdateHTZ < 1) + return false; + + // First verify that this object isn't already contained in a bucket, if it is then erase it so that we can replace it below + RemoveBucketObject(InObject, FunctionName); + + if (ReplicationBuckets.Contains(UpdateHTZ)) + { + ReplicationBuckets[UpdateHTZ].Callbacks.Add(FUpdateBucketDrop(InObject, FunctionName)); + } + else + { + FUpdateBucket & newBucket = ReplicationBuckets.Add(UpdateHTZ, FUpdateBucket(UpdateHTZ)); + ReplicationBuckets[UpdateHTZ].Callbacks.Add(FUpdateBucketDrop(InObject, FunctionName)); + } + + if (ReplicationBuckets.Num() > 0) + bNeedsUpdate = true; + + return true; + } + + + bool FUpdateBucketContainer::AddBucketObject(uint32 UpdateHTZ, FDynamicBucketUpdateTickSignature &Delegate) + { + if (!Delegate.IsBound() || UpdateHTZ < 1) + return false; + + // First verify that this object isn't already contained in a bucket, if it is then erase it so that we can replace it below + RemoveBucketObject(Delegate); + + if (ReplicationBuckets.Contains(UpdateHTZ)) + { + ReplicationBuckets[UpdateHTZ].Callbacks.Add(FUpdateBucketDrop(Delegate)); + } + else + { + FUpdateBucket & newBucket = ReplicationBuckets.Add(UpdateHTZ, FUpdateBucket(UpdateHTZ)); + ReplicationBuckets[UpdateHTZ].Callbacks.Add(FUpdateBucketDrop(Delegate)); + } + + if (ReplicationBuckets.Num() > 0) + bNeedsUpdate = true; + + return true; + } + + bool FUpdateBucketContainer::RemoveBucketObject(UObject * ObjectToRemove, FName FunctionName) + { + if (!ObjectToRemove || ObjectToRemove->FindFunction(FunctionName) == nullptr) + return false; + + // Store if we ended up removing it + bool bRemovedObject = false; + + TArray BucketsToRemove; + for (auto& Bucket : ReplicationBuckets) + { + for (int i = Bucket.Value.Callbacks.Num() - 1; i >= 0; --i) + { + if (Bucket.Value.Callbacks[i].IsBoundToObjectFunction(ObjectToRemove, FunctionName)) + { + Bucket.Value.Callbacks.RemoveAt(i); + bRemovedObject = true; + + // Leave the loop, this is called in add as well so we should never get duplicate entries + break; + } + } + + if (bRemovedObject) + { + break; + } + } + + return bRemovedObject; + } + + bool FUpdateBucketContainer::RemoveBucketObject(FDynamicBucketUpdateTickSignature &DynEvent) + { + if (!DynEvent.IsBound()) + return false; + + // Store if we ended up removing it + bool bRemovedObject = false; + + TArray BucketsToRemove; + for (auto& Bucket : ReplicationBuckets) + { + for (int i = Bucket.Value.Callbacks.Num() - 1; i >= 0; --i) + { + if (Bucket.Value.Callbacks[i].IsBoundToObjectDelegate(DynEvent)) + { + Bucket.Value.Callbacks.RemoveAt(i); + bRemovedObject = true; + + // Leave the loop, this is called in add as well so we should never get duplicate entries + break; + } + } + + if (bRemovedObject) + { + break; + } + } + + return bRemovedObject; + } + + bool FUpdateBucketContainer::RemoveObjectFromAllBuckets(UObject * ObjectToRemove) + { + if (!ObjectToRemove) + return false; + + // Store if we ended up removing it + bool bRemovedObject = false; + + TArray BucketsToRemove; + for (auto& Bucket : ReplicationBuckets) + { + for (int i = Bucket.Value.Callbacks.Num() - 1; i >= 0; --i) + { + if (Bucket.Value.Callbacks[i].IsBoundToObject(ObjectToRemove)) + { + Bucket.Value.Callbacks.RemoveAt(i); + bRemovedObject = true; + } + } + } + + return bRemovedObject; + } + + bool FUpdateBucketContainer::IsObjectInBucket(UObject * ObjectToRemove) + { + if (!ObjectToRemove) + return false; + for (auto& Bucket : ReplicationBuckets) + { + for (int i = Bucket.Value.Callbacks.Num() - 1; i >= 0; --i) + { + if (Bucket.Value.Callbacks[i].IsBoundToObject(ObjectToRemove)) + { + return true; + } + } + } + + return false; + } + + bool FUpdateBucketContainer::IsObjectFunctionInBucket(UObject * ObjectToRemove, FName FunctionName) + { + if (!ObjectToRemove) + return false; + for (auto& Bucket : ReplicationBuckets) + { + for (int i = Bucket.Value.Callbacks.Num() - 1; i >= 0; --i) + { + if (Bucket.Value.Callbacks[i].IsBoundToObjectFunction(ObjectToRemove, FunctionName)) + { + return true; + } + } + } + + return false; + } + + bool FUpdateBucketContainer::IsObjectDelegateInBucket(FDynamicBucketUpdateTickSignature &DynEvent) + { + if (!DynEvent.IsBound()) + return false; + + for (auto& Bucket : ReplicationBuckets) + { + for (int i = Bucket.Value.Callbacks.Num() - 1; i >= 0; --i) + { + if (Bucket.Value.Callbacks[i].IsBoundToObjectDelegate(DynEvent)) + { + return true; + } + } + } + + return false; + } \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/CollisionIgnoreSubsystem.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/CollisionIgnoreSubsystem.cpp new file mode 100644 index 0000000..0308f80 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/CollisionIgnoreSubsystem.cpp @@ -0,0 +1,600 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Misc/CollisionIgnoreSubsystem.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(CollisionIgnoreSubsystem) + +#include "Components/SkeletalMeshComponent.h" +#include "Engine/World.h" +#include "Runtime/Engine/Classes/Kismet/GameplayStatics.h" +#include "VRGlobalSettings.h" + +//#include "Chaos/ParticleHandle.h" +#include "PhysicsEngine/PhysicsAsset.h" +#include "PhysicsEngine/PhysicsAsset.h" +#include "Physics/Experimental/PhysScene_Chaos.h" +#include "Chaos/KinematicGeometryParticles.h" +#include "PhysicsProxy/SingleParticlePhysicsProxy.h" +#include "PBDRigidsSolver.h" + +#include "Chaos/ContactModification.h" + +DEFINE_LOG_CATEGORY(VRE_CollisionIgnoreLog); + + +void FCollisionIgnoreSubsystemAsyncCallback::OnContactModification_Internal(Chaos::FCollisionContactModifier& Modifier) +{ + const FSimCallbackInputVR* Input = GetConsumerInput_Internal(); + + if (Input && Input->bIsInitialized) + { + for (Chaos::FContactPairModifierIterator ContactIterator = Modifier.Begin(); ContactIterator; ++ContactIterator) + { + if (ContactIterator.IsValid()) + { + Chaos::TVec2 Pair = ContactIterator->GetParticlePair(); + + Chaos::TPBDRigidParticleHandle* ParticleHandle0 = Pair[0]->CastToRigidParticle(); + Chaos::TPBDRigidParticleHandle* ParticleHandle1 = Pair[1]->CastToRigidParticle(); + + + // Chaos has some sort of bug here, the constraint flags are cleared, and for that matter the + // ID0 and ID1 pairs losing collision ignore shouldn't happen as they are still valid always + // Don't use contact modification until after we see if the incoming chaos fixes for constraint collision ignore + // is resolved. + if (ParticleHandle0 && ParticleHandle1) + { + // This lets us pull the transform at time of collision, collision events use the first contact + // for the information to throw out so we should be able to pull it here and keep it for that pair for the frame + //FTransform particleHandle = Chaos::FRigidTransform3(ParticleHandle0->X(), ParticleHandle0->R()); + //FTransform particleHandle2 = Chaos::FRigidTransform3(ParticleHandle0->X(), ParticleHandle1->R()); + + + //bool bHasCollisionFlag = ParticleHandle0->HasCollisionConstraintFlag(Chaos::ECollisionConstraintFlags::CCF_BroadPhaseIgnoreCollisions); + //bool bHadCollisionFlag2 = ParticleHandle1->HasCollisionConstraintFlag(Chaos::ECollisionConstraintFlags::CCF_BroadPhaseIgnoreCollisions); + + //if (bHasCollisionFlag && bHadCollisionFlag2) + { + FChaosParticlePair SearchPair(ParticleHandle0, ParticleHandle1); + + if (Input->ParticlePairs.Contains(SearchPair)) + { + ContactIterator->Disable(); + } + } + } + } + } + } +} + +void UCollisionIgnoreSubsystem::ConstructInput() +{ + if (ContactModifierCallback) + { + FSimCallbackInputVR* Input = ContactModifierCallback->GetProducerInputData_External(); + if (Input->bIsInitialized == false) + { + Input->bIsInitialized = true; + } + + // Clear out the pair array + Input->Reset(); + + for (TPair& CollisionPairArray : CollisionTrackedPairs) + { + for (FCollisionIgnorePair& IgnorePair : CollisionPairArray.Value.PairArray) + { + if (IgnorePair.Actor1 && IgnorePair.Actor2) + { + Input->ParticlePairs.Add(FChaosParticlePair(IgnorePair.Actor1->GetHandle_LowLevel()->CastToRigidParticle(), IgnorePair.Actor2->GetHandle_LowLevel()->CastToRigidParticle())); + } + } + } + } +} + +void UCollisionIgnoreSubsystem::Deinitialize() +{ + Super::Deinitialize(); + + if (UpdateHandle.IsValid()) + { + GetWorld()->GetTimerManager().ClearTimer(UpdateHandle); + } +} + + +void UCollisionIgnoreSubsystem::UpdateTimer(bool bChangesWereMade) +{ + RemovedPairs.Reset(); + const UVRGlobalSettings& VRSettings = *GetDefault(); + + if (CollisionTrackedPairs.Num() > 0) + { + if (!UpdateHandle.IsValid()) + { + // Setup the heartbeat on 1htz checks + GetWorld()->GetTimerManager().SetTimer(UpdateHandle, this, &UCollisionIgnoreSubsystem::CheckActiveFilters, VRSettings.CollisionIgnoreSubsystemUpdateRate, true, VRSettings.CollisionIgnoreSubsystemUpdateRate); + + if (VRSettings.bUseCollisionModificationForCollisionIgnore && !ContactModifierCallback) + { + if (UWorld* World = GetWorld()) + { + if (FPhysScene* PhysScene = World->GetPhysicsScene()) + { + // Register a callback + ContactModifierCallback = PhysScene->GetSolver()->CreateAndRegisterSimCallbackObject_External(/*true*/); + } + } + } + } + + // Need to only add input when changes are made + if (VRSettings.bUseCollisionModificationForCollisionIgnore && ContactModifierCallback && bChangesWereMade) + { + ConstructInput(); + } + } + else if (UpdateHandle.IsValid()) + { + GetWorld()->GetTimerManager().ClearTimer(UpdateHandle); + + if (VRSettings.bUseCollisionModificationForCollisionIgnore && ContactModifierCallback) + { + //FSimCallbackInputVR* Input = ContactModifierCallback->GetProducerInputData_External(); + //Input->bIsInitialized = false; + + if (UWorld* World = GetWorld()) + { + if (FPhysScene* PhysScene = World->GetPhysicsScene()) + { + // UnRegister a callback + PhysScene->GetSolver()->UnregisterAndFreeSimCallbackObject_External(ContactModifierCallback); + ContactModifierCallback = nullptr; + } + } + } + } +} + +void UCollisionIgnoreSubsystem::CheckActiveFilters() +{ + bool bMadeChanges = false; + + for (TPair& KeyPair : CollisionTrackedPairs) + { + // First check for invalid primitives + if (!IsValid(KeyPair.Key.Prim1) || !IsValid(KeyPair.Key.Prim2)) + { + // If we don't have a map element for this pair, then add it now + if (!RemovedPairs.Contains(KeyPair.Key)) + { + RemovedPairs.Add(KeyPair.Key, KeyPair.Value); + bMadeChanges = true; + } + + continue; // skip remaining checks as we have invalid primitives anyway + } + + // Skip this section but leave the code intact in case i need it eventually +#if false + // Now check for lost physics handles + // Implement later + if (FPhysScene* PhysScene = KeyPair.Key.Prim1->GetWorld()->GetPhysicsScene()) + { + Chaos::FIgnoreCollisionManager& IgnoreCollisionManager = PhysScene->GetSolver()->GetEvolution()->GetBroadPhase().GetIgnoreCollisionManager(); + FPhysicsCommand::ExecuteWrite(PhysScene, [&]() + { + using namespace Chaos; + for (int i = KeyPair.Value.PairArray.Num() - 1; i >= 0; i--) + { + FPhysicsActorHandle hand1 = KeyPair.Value.PairArray[i].Actor1; + FPhysicsActorHandle hand2 = KeyPair.Value.PairArray[i].Actor2; + + /*if (bIgnoreCollision) + { + if (!IgnoreCollisionManager.IgnoresCollision(ID0, ID1)) + { + TPBDRigidParticleHandle* ParticleHandle0 = ApplicableBodies[i].BInstance->ActorHandle->GetHandle_LowLevel()->CastToRigidParticle(); + TPBDRigidParticleHandle* ParticleHandle1 = ApplicableBodies2[j].BInstance->ActorHandle->GetHandle_LowLevel()->CastToRigidParticle(); + + if (ParticleHandle0 && ParticleHandle1) + { + ParticleHandle0->AddCollisionConstraintFlag(Chaos::ECollisionConstraintFlags::CCF_BroadPhaseIgnoreCollisions); + IgnoreCollisionManager.AddIgnoreCollisionsFor(ID0, ID1); + + ParticleHandle1->AddCollisionConstraintFlag(Chaos::ECollisionConstraintFlags::CCF_BroadPhaseIgnoreCollisions); + IgnoreCollisionManager.AddIgnoreCollisionsFor(ID1, ID0); + + } + } + }*/ + + if ( + (!KeyPair.Value.PairArray[i].Actor1 || !FPhysicsInterface::IsValid(KeyPair.Value.PairArray[i].Actor1)) || + (!KeyPair.Value.PairArray[i].Actor2 || !FPhysicsInterface::IsValid(KeyPair.Value.PairArray[i].Actor2)) + ) + { + + // We will either be re-initing or deleting from here so it will always involve changes + bMadeChanges = true; + + FName Bone1 = KeyPair.Value.PairArray[i].BoneName1; + FName Bone2 = KeyPair.Value.PairArray[i].BoneName2; + + FBodyInstance* Inst1 = KeyPair.Key.Prim1->GetBodyInstance(Bone1); + FBodyInstance* Inst2 = KeyPair.Key.Prim2->GetBodyInstance(Bone2); + + if (Inst1 && Inst2) + { + // We still have the bones available, lets go ahead and re-init for them + KeyPair.Value.PairArray.RemoveAt(i); + SetComponentCollisionIgnoreState(false, false, KeyPair.Key.Prim1, Bone1, KeyPair.Key.Prim2, Bone2, true, false); + } + else + { + // Its not still available, lets remove the pair. + KeyPair.Value.PairArray.RemoveAt(i); + } + } + else + { + Chaos::FUniqueIdx ID0 = KeyPair.Value.PairArray[i].Actor1->GetParticle_LowLevel()->UniqueIdx(); + Chaos::FUniqueIdx ID1 = KeyPair.Value.PairArray[i].Actor2->GetParticle_LowLevel()->UniqueIdx(); + + if (!IgnoreCollisionManager.IgnoresCollision(ID0, ID1)) + { + auto* pHandle1 = KeyPair.Value.PairArray[i].Actor1->GetHandle_LowLevel(); + auto* pHandle2 = KeyPair.Value.PairArray[i].Actor2->GetHandle_LowLevel(); + + if (pHandle1 && pHandle2) + { + TPBDRigidParticleHandle* ParticleHandle0 = pHandle1->CastToRigidParticle(); + TPBDRigidParticleHandle* ParticleHandle1 = pHandle2->CastToRigidParticle(); + + if (ParticleHandle0 && ParticleHandle1) + { + ParticleHandle0->AddCollisionConstraintFlag(Chaos::ECollisionConstraintFlags::CCF_BroadPhaseIgnoreCollisions); + IgnoreCollisionManager.AddIgnoreCollisionsFor(ID0, ID1); + + ParticleHandle1->AddCollisionConstraintFlag(Chaos::ECollisionConstraintFlags::CCF_BroadPhaseIgnoreCollisions); + IgnoreCollisionManager.AddIgnoreCollisionsFor(ID1, ID0); + } + } + } + } + } + }); + } +#endif + + // If there are no pairs left + if (KeyPair.Value.PairArray.Num() < 1) + { + // Try and remove it, chaos should be cleaning up the ignore setups + if (!RemovedPairs.Contains(KeyPair.Key)) + { + RemovedPairs.Add(KeyPair.Key, KeyPair.Value); + } + } + } + +/*#if WITH_CHAOS + if (FPhysScene* PhysScene2 = GetWorld()->GetPhysicsScene()) + { + Chaos::FIgnoreCollisionManager& IgnoreCollisionManager = PhysScene2->GetSolver()->GetEvolution()->GetBroadPhase().GetIgnoreCollisionManager(); + int32 ExternalTimestamp = PhysScene2->GetSolver()->GetMarshallingManager().GetExternalTimestamp_External(); + + Chaos::FIgnoreCollisionManager::FPendingMap IgnoreSet = IgnoreCollisionManager.GetPendingActivationsForGameThread(ExternalTimestamp); + Chaos::FIgnoreCollisionManager::FDeactivationSet DeactiveSet = IgnoreCollisionManager.GetPendingDeactivationsForGameThread(ExternalTimestamp); + //Chaos::FIgnoreCollisionManager::FDeactivationSet IgnoreSet = + + // Prints out the list of items currently being re-activated after one of their pairs died. + // Chaos automatically cleans up here, I don't need to do anything. + GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Pending activate: %i - Pending deativate: %i"), IgnoreSet.Num(), DeactiveSet.Num())); + } +#endif*/ + + for (const TPair& KeyPair : RemovedPairs) + { + if (CollisionTrackedPairs.Contains(KeyPair.Key)) + { + CollisionTrackedPairs[KeyPair.Key].PairArray.Empty(); + CollisionTrackedPairs.Remove(KeyPair.Key); + } + } + + UpdateTimer(bMadeChanges); +} + +void UCollisionIgnoreSubsystem::RemoveComponentCollisionIgnoreState(UPrimitiveComponent* Prim1) +{ + + if (!Prim1) + return; + + + TMap PairsToRemove; + + for (const TPair& KeyPair : CollisionTrackedPairs) + { + // First check for invalid primitives + if (KeyPair.Key.Prim1 == Prim1 || KeyPair.Key.Prim2 == Prim1) + { + // If we don't have a map element for this pair, then add it now + if (!PairsToRemove.Contains(KeyPair.Key)) + { + PairsToRemove.Add(KeyPair.Key, KeyPair.Value); + } + } + } + + + for (const TPair& KeyPair : PairsToRemove) + { + if (CollisionTrackedPairs.Contains(KeyPair.Key)) + { + for (const FCollisionIgnorePair& newIgnorePair : KeyPair.Value.PairArray) + { + // Clear out current ignores + SetComponentCollisionIgnoreState(false, false, KeyPair.Key.Prim1, newIgnorePair.BoneName1, KeyPair.Key.Prim2, newIgnorePair.BoneName2, false, false); + } + + /*if (CollisionTrackedPairs.Contains(KeyPair.Key)) + { + // Ensure we are empty + CollisionTrackedPairs[KeyPair.Key].PairArray.Empty(); + CollisionTrackedPairs.Remove(KeyPair.Key); + }*/ + } + } + + UpdateTimer(true); +} + +bool UCollisionIgnoreSubsystem::IsComponentIgnoringCollision(UPrimitiveComponent* Prim1) +{ + + if (!Prim1) + return false; + + for (const TPair& KeyPair : CollisionTrackedPairs) + { + // First check for invalid primitives + if (KeyPair.Key.Prim1 == Prim1 || KeyPair.Key.Prim2 == Prim1) + { + return true; + } + } + + return false; +} + +bool UCollisionIgnoreSubsystem::AreComponentsIgnoringCollisions(UPrimitiveComponent* Prim1, UPrimitiveComponent* Prim2) +{ + + if (!Prim1 || !Prim2) + return false; + + TSet CurrentKeys; + int numKeys = CollisionTrackedPairs.GetKeys(CurrentKeys); + + FCollisionPrimPair SearchPair; + SearchPair.Prim1 = Prim1; + SearchPair.Prim2 = Prim2; + + // This checks if we exist already as well as provides an index + if (FCollisionPrimPair* ExistingPair = CurrentKeys.Find(SearchPair)) + { + // These components are ignoring collision + return true; + } + + return false; +} + +void UCollisionIgnoreSubsystem::InitiateIgnore() +{ + +} + +bool UCollisionIgnoreSubsystem::HasCollisionIgnorePairs() +{ + return CollisionTrackedPairs.Num() > 0; +} + +void UCollisionIgnoreSubsystem::SetComponentCollisionIgnoreState(bool bIterateChildren1, bool bIterateChildren2, UPrimitiveComponent* Prim1, FName OptionalBoneName1, UPrimitiveComponent* Prim2, FName OptionalBoneName2, bool bIgnoreCollision, bool bCheckFilters) +{ + if (!Prim1 || !Prim2) + { + UE_LOG(VRE_CollisionIgnoreLog, Error, TEXT("Set Objects Ignore Collision called with invalid object(s)!!")); + return; + } + + if (Prim1->GetCollisionEnabled() == ECollisionEnabled::NoCollision || Prim2->GetCollisionEnabled() == ECollisionEnabled::NoCollision) + { + UE_LOG(VRE_CollisionIgnoreLog, Error, TEXT("Set Objects Ignore Collision called with one or more objects with no collision!! %s, %s"), *Prim1->GetName(), *Prim2->GetName()); + return; + } + + // Appears to work now with the chaos collision ignore setup + /*if (Prim1->Mobility == EComponentMobility::Static || Prim2->Mobility == EComponentMobility::Static) + { + UE_LOG(VRE_CollisionIgnoreLog, Error, TEXT("Set Objects Ignore Collision called with at least one static mobility object (cannot ignore collision with it)!!")); + if (bIgnoreCollision) + { + return; + } + }*/ + + USkeletalMeshComponent* SkeleMesh = nullptr; + USkeletalMeshComponent* SkeleMesh2 = nullptr; + + if (bIterateChildren1) + { + SkeleMesh = Cast(Prim1); + } + + if (bIterateChildren2) + { + SkeleMesh2 = Cast(Prim2); + } + + struct BodyPairStore + { + FBodyInstance* BInstance; + FName BName; + + BodyPairStore(FBodyInstance* BI, FName BoneName) + { + BInstance = BI; + BName = BoneName; + } + }; + + TArray ApplicableBodies; + + if (SkeleMesh) + { + UPhysicsAsset* PhysAsset = SkeleMesh ? SkeleMesh->GetPhysicsAsset() : nullptr; + if (PhysAsset) + { + int32 NumBodiesFound = SkeleMesh->ForEachBodyBelow(OptionalBoneName1, true, false, [PhysAsset, &ApplicableBodies](FBodyInstance* BI) + { + const FName IterBodyName = PhysAsset->SkeletalBodySetups[BI->InstanceBodyIndex]->BoneName; + ApplicableBodies.Add(BodyPairStore(BI, IterBodyName)); + }); + } + } + else + { + FBodyInstance* Inst1 = Prim1->GetBodyInstance(OptionalBoneName1); + if (Inst1) + { + ApplicableBodies.Add(BodyPairStore(Inst1, OptionalBoneName1)); + } + } + + TArray ApplicableBodies2; + if (SkeleMesh2) + { + UPhysicsAsset* PhysAsset = SkeleMesh2 ? SkeleMesh2->GetPhysicsAsset() : nullptr; + if (PhysAsset) + { + int32 NumBodiesFound = SkeleMesh2->ForEachBodyBelow(OptionalBoneName2, true, false, [PhysAsset, &ApplicableBodies2](FBodyInstance* BI) + { + const FName IterBodyName = PhysAsset->SkeletalBodySetups[BI->InstanceBodyIndex]->BoneName; + ApplicableBodies2.Add(BodyPairStore(BI, IterBodyName)); + }); + } + } + else + { + FBodyInstance* Inst1 = Prim2->GetBodyInstance(OptionalBoneName2); + if (Inst1) + { + ApplicableBodies2.Add(BodyPairStore(Inst1, OptionalBoneName2)); + } + } + + + FCollisionPrimPair newPrimPair; + newPrimPair.Prim1 = Prim1; + newPrimPair.Prim2 = Prim2; + + // Check our active filters and handle inconsistencies before we run the next logic + // (This prevents cases where null ptrs get added too) + if (bCheckFilters) + { + CheckActiveFilters(); + } + + // If we don't have a map element for this pair, then add it now + if (bIgnoreCollision && !CollisionTrackedPairs.Contains(newPrimPair)) + { + CollisionTrackedPairs.Add(newPrimPair, FCollisionIgnorePairArray()); + } + else if (!bIgnoreCollision && !CollisionTrackedPairs.Contains(newPrimPair)) + { + // Early out, we don't even have this pair to remove it + return; + } + + for (int i = 0; i < ApplicableBodies.Num(); ++i) + { + for (int j = 0; j < ApplicableBodies2.Num(); ++j) + { + if (ApplicableBodies[i].BInstance && ApplicableBodies2[j].BInstance && ApplicableBodies[i].BInstance->ActorHandle && ApplicableBodies2[j].BInstance->ActorHandle) + { + if (FPhysScene* PhysScene = Prim1->GetWorld()->GetPhysicsScene()) + { + FCollisionIgnorePair newIgnorePair; + newIgnorePair.Actor1 = ApplicableBodies[i].BInstance->ActorHandle; + newIgnorePair.BoneName1 = ApplicableBodies[i].BName; + newIgnorePair.Actor2 = ApplicableBodies2[j].BInstance->ActorHandle; + newIgnorePair.BoneName2 = ApplicableBodies2[j].BName; + + //Chaos::FUniqueIdx ID0 = ApplicableBodies[i].BInstance->ActorHandle->GetParticle_LowLevel()->UniqueIdx(); + //Chaos::FUniqueIdx ID1 = ApplicableBodies2[j].BInstance->ActorHandle->GetParticle_LowLevel()->UniqueIdx(); + + auto* pHandle1 = ApplicableBodies[i].BInstance->ActorHandle->GetHandle_LowLevel(); + auto* pHandle2 = ApplicableBodies2[j].BInstance->ActorHandle->GetHandle_LowLevel(); + + Chaos::FIgnoreCollisionManager& IgnoreCollisionManager = PhysScene->GetSolver()->GetEvolution()->GetBroadPhase().GetIgnoreCollisionManager(); + + FPhysicsCommand::ExecuteWrite(PhysScene, [&]() + { + using namespace Chaos; + + if (bIgnoreCollision && pHandle1 && pHandle2) + { + if (!IgnoreCollisionManager.IgnoresCollision(pHandle1, pHandle2)) + { + IgnoreCollisionManager.AddIgnoreCollisions(pHandle1, pHandle2); + + TSet CurrentKeys; + int numKeys = CollisionTrackedPairs.GetKeys(CurrentKeys); + + // This checks if we exist already as well as provides an index + if (FCollisionPrimPair* CurrentPair = CurrentKeys.Find(newPrimPair)) + { + // Check if the current one has the same primitive ordering as the new check + if (CurrentPair->Prim1 != newPrimPair.Prim1) + { + // If not then lets flip the elements around in order to match it + newIgnorePair.FlipElements(); + } + + CollisionTrackedPairs[newPrimPair].PairArray.AddUnique(newIgnorePair); + } + } + } + else if (pHandle1 && pHandle2) + { + if (IgnoreCollisionManager.IgnoresCollision(pHandle1, pHandle2)) + { + IgnoreCollisionManager.RemoveIgnoreCollisions(pHandle1, pHandle2); + + CollisionTrackedPairs[newPrimPair].PairArray.Remove(newIgnorePair); + if (CollisionTrackedPairs[newPrimPair].PairArray.Num() < 1) + { + CollisionTrackedPairs.Remove(newPrimPair); + } + + // If we don't have a map element for this pair, then add it now + if (!RemovedPairs.Contains(newPrimPair)) + { + RemovedPairs.Add(newPrimPair, FCollisionIgnorePairArray()); + } + RemovedPairs[newPrimPair].PairArray.AddUnique(newIgnorePair); + } + } + }); + } + } + } + } + + // Update our timer state + UpdateTimer(true); +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/OptionalRepSkeletalMeshActor.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/OptionalRepSkeletalMeshActor.cpp new file mode 100644 index 0000000..480b36f --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/OptionalRepSkeletalMeshActor.cpp @@ -0,0 +1,703 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Misc/OptionalRepSkeletalMeshActor.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(OptionalRepSkeletalMeshActor) + +#include "TimerManager.h" +#include "Net/UnrealNetwork.h" +#include "PhysicsReplication.h" +#include "PhysicsEngine/PhysicsAsset.h" +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + +UNoRepSphereComponent::UNoRepSphereComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + this->SetIsReplicatedByDefault(true); + this->PrimaryComponentTick.bCanEverTick = false; + SphereRadius = 4.0f; + SetCollisionEnabled(ECollisionEnabled::PhysicsOnly); + SetCollisionResponseToAllChannels(ECR_Ignore); + //SetAllMassScale(0.0f); Engine hates calling this in constructor + + + BodyInstance.bOverrideMass = true; + BodyInstance.SetMassOverride(0.f); +} + +void UNoRepSphereComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty >& OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UNoRepSphereComponent, bReplicateMovement, PushModelParams); + + RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(USceneComponent, AttachParent, COND_InitialOnly); + RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(USceneComponent, AttachSocketName, COND_InitialOnly); + RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(USceneComponent, AttachChildren, COND_InitialOnly); + RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(USceneComponent, RelativeLocation, COND_InitialOnly); + RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(USceneComponent, RelativeRotation, COND_InitialOnly); + RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(USceneComponent, RelativeScale3D, COND_InitialOnly); + //DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, AttachmentReplication); +} + +void UNoRepSphereComponent::SetReplicateMovement(bool bNewReplicateMovement) +{ + bReplicateMovement = bNewReplicateMovement; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UNoRepSphereComponent, bReplicateMovement, this); +#endif +} + +void UNoRepSphereComponent::PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) +{ + Super::PreReplication(ChangedPropertyTracker); + +} + +void FSkeletalMeshComponentEndPhysicsTickFunctionVR::ExecuteTick(float DeltaTime, enum ELevelTick TickType, ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent) +{ + //QUICK_SCOPE_CYCLE_COUNTER(FSkeletalMeshComponentEndPhysicsTickFunction_ExecuteTick); + //CSV_SCOPED_TIMING_STAT_EXCLUSIVE(Physics); + + FActorComponentTickFunction::ExecuteTickHelper(TargetVR, /*bTickInEditor=*/ false, DeltaTime, TickType, [this](float DilatedTime) + { + TargetVR->EndPhysicsTickComponentVR(*this); + }); +} + +FString FSkeletalMeshComponentEndPhysicsTickFunctionVR::DiagnosticMessage() +{ + if (TargetVR) + { + return TargetVR->GetFullName() + TEXT("[EndPhysicsTickVR]"); + } + return TEXT("[EndPhysicsTick]"); +} + +FName FSkeletalMeshComponentEndPhysicsTickFunctionVR::DiagnosticContext(bool bDetailed) +{ + return FName(TEXT("SkeletalMeshComponentEndPhysicsTickVR")); +} + + +UInversePhysicsSkeletalMeshComponent::UInversePhysicsSkeletalMeshComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + bReplicateMovement = true; + this->EndPhysicsTickFunction.bCanEverTick = false; + bReplicatePhysicsToAutonomousProxy = false; + + EndPhysicsTickFunctionVR.TickGroup = TG_EndPhysics; + EndPhysicsTickFunctionVR.bCanEverTick = true; + EndPhysicsTickFunctionVR.bStartWithTickEnabled = true; +} + +void UInversePhysicsSkeletalMeshComponent::PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) +{ + Super::PreReplication(ChangedPropertyTracker); + + // Don't replicate if set to not do it + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeLocation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeRotation, bReplicateMovement); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeScale3D, bReplicateMovement); +} + + +void UInversePhysicsSkeletalMeshComponent::SetReplicateMovement(bool bNewReplicateMovement) +{ + bReplicateMovement = bNewReplicateMovement; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UInversePhysicsSkeletalMeshComponent, bReplicateMovement, this); +#endif +} + +void UInversePhysicsSkeletalMeshComponent::EndPhysicsTickComponentVR(FSkeletalMeshComponentEndPhysicsTickFunctionVR& ThisTickFunction) +{ + //IMPORTANT! + // + // The decision on whether to use EndPhysicsTickComponent or not is made by ShouldRunEndPhysicsTick() + // Any changes that are made to EndPhysicsTickComponent that affect whether it should be run or not + // have to be reflected in ShouldRunEndPhysicsTick() as well + + // if physics is disabled on dedicated server, no reason to be here. + if (!bEnablePhysicsOnDedicatedServer && IsRunningDedicatedServer()) + { + FinalizeBoneTransform(); + return; + } + + if (IsRegistered() && IsSimulatingPhysics() && RigidBodyIsAwake()) + { + if (bNotifySyncComponentToRBPhysics) + { + OnSyncComponentToRBPhysics(); + } + + SyncComponentToRBPhysics(); + } + + // this used to not run if not rendered, but that causes issues such as bounds not updated + // causing it to not rendered, at the end, I think we should blend body positions + // for example if you're only simulating, this has to happen all the time + // whether looking at it or not, otherwise + // @todo better solution is to check if it has moved by changing SyncComponentToRBPhysics to return true if anything modified + // and run this if that is true or rendered + // that will at least reduce the chance of mismatch + // generally if you move your actor position, this has to happen to approximately match their bounds + if (ShouldBlendPhysicsBones()) + { + if (IsRegistered()) + { + BlendInPhysicsInternalVR(ThisTickFunction); + } + } +} + +void UInversePhysicsSkeletalMeshComponent::BlendInPhysicsInternalVR(FTickFunction& ThisTickFunction) +{ + check(IsInGameThread()); + + // Can't do anything without a SkeletalMesh + if (!GetSkinnedAsset()) + { + return; + } + + // We now have all the animations blended together and final relative transforms for each bone. + // If we don't have or want any physics, we do nothing. + if (Bodies.Num() > 0 && CollisionEnabledHasPhysics(GetCollisionEnabled())) + { + //HandleExistingParallelEvaluationTask(/*bBlockOnTask = */ true, /*bPerformPostAnimEvaluation =*/ true); + // start parallel work + //check(!IsValidRef(ParallelAnimationEvaluationTask)); + + const bool bParallelBlend = false;// !!CVarUseParallelBlendPhysics.GetValueOnGameThread() && FApp::ShouldUseThreadingForPerformance(); + if (bParallelBlend) + { + /*SwapEvaluationContextBuffers(); + + ParallelAnimationEvaluationTask = TGraphTask::CreateTask().ConstructAndDispatchWhenReady(this); + + // set up a task to run on the game thread to accept the results + FGraphEventArray Prerequistes; + Prerequistes.Add(ParallelAnimationEvaluationTask); + + check(!IsValidRef(ParallelBlendPhysicsCompletionTask)); + ParallelBlendPhysicsCompletionTask = TGraphTask::CreateTask(&Prerequistes).ConstructAndDispatchWhenReady(this); + + ThisTickFunction.GetCompletionHandle()->DontCompleteUntil(ParallelBlendPhysicsCompletionTask);*/ + } + else + { + PRAGMA_DISABLE_DEPRECATION_WARNINGS + PerformBlendPhysicsBonesVR(RequiredBones, GetEditableComponentSpaceTransforms(), BoneSpaceTransforms); + PRAGMA_ENABLE_DEPRECATION_WARNINGS + FinalizeAnimationUpdateVR(); + } + } +} + +void UInversePhysicsSkeletalMeshComponent::FinalizeAnimationUpdateVR() +{ + //SCOPE_CYCLE_COUNTER(STAT_FinalizeAnimationUpdate); + + // Flip bone buffer and send 'post anim' notification + FinalizeBoneTransform(); + + if (!bSimulationUpdatesChildTransforms || !IsSimulatingPhysics()) //If we simulate physics the call to MoveComponent already updates the children transforms. If we are confident that animation will not be needed this can be skipped. TODO: this should be handled at the scene component layer + { + //SCOPE_CYCLE_COUNTER(STAT_FinalizeAnimationUpdate_UpdateChildTransforms); + + // Update Child Transform - The above function changes bone transform, so will need to update child transform + // But only children attached to us via a socket. + UpdateChildTransforms(EUpdateTransformFlags::OnlyUpdateIfUsingSocket); + } + + if (bUpdateOverlapsOnAnimationFinalize) + { + //SCOPE_CYCLE_COUNTER(STAT_FinalizeAnimationUpdate_UpdateOverlaps); + + // animation often change overlap. + UpdateOverlaps(); + } + + // update bounds + // *NOTE* This is a private var, I have to remove it for this temp fix + /*if (bSkipBoundsUpdateWhenInterpolating) + { + if (AnimEvaluationContext.bDoEvaluation) + { + //SCOPE_CYCLE_COUNTER(STAT_FinalizeAnimationUpdate_UpdateBounds); + // Cached local bounds are now out of date + InvalidateCachedBounds(); + + UpdateBounds(); + } + } + else*/ + { + //SCOPE_CYCLE_COUNTER(STAT_FinalizeAnimationUpdate_UpdateBounds); + // Cached local bounds are now out of date + InvalidateCachedBounds(); + + UpdateBounds(); + } + + // Need to send new bounds to + MarkRenderTransformDirty(); + + // New bone positions need to be sent to render thread + MarkRenderDynamicDataDirty(); + + // If we have any Slave Components, they need to be refreshed as well. + RefreshFollowerComponents(); +} + +void UInversePhysicsSkeletalMeshComponent::GetWeldedBodies(TArray& OutWeldedBodies, TArray& OutLabels, bool bIncludingAutoWeld) +{ + UPhysicsAsset* PhysicsAsset = GetPhysicsAsset(); + + for (int32 BodyIdx = 0; BodyIdx < Bodies.Num(); ++BodyIdx) + { + FBodyInstance* BI = Bodies[BodyIdx]; + if (BI && (BI->WeldParent != nullptr || (bIncludingAutoWeld && BI->bAutoWeld))) + { + OutWeldedBodies.Add(BI); + if (PhysicsAsset) + { + if (UBodySetup* PhysicsAssetBodySetup = PhysicsAsset->SkeletalBodySetups[BodyIdx]) + { + OutLabels.Add(PhysicsAssetBodySetup->BoneName); + } + else + { + OutLabels.Add(NAME_None); + } + } + else + { + OutLabels.Add(NAME_None); + } + + } + } + + for (USceneComponent* Child : GetAttachChildren()) + { + if (UPrimitiveComponent* PrimChild = Cast(Child)) + { + PrimChild->GetWeldedBodies(OutWeldedBodies, OutLabels, bIncludingAutoWeld); + } + } +} + +FBodyInstance* UInversePhysicsSkeletalMeshComponent::GetBodyInstance(FName BoneName, bool bGetWelded, int32) const +{ + UPhysicsAsset* const PhysicsAsset = GetPhysicsAsset(); + FBodyInstance* BodyInst = NULL; + + if (PhysicsAsset != NULL) + { + // A name of NAME_None indicates 'root body' + if (BoneName == NAME_None) + { + if (Bodies.IsValidIndex(RootBodyData.BodyIndex)) + { + BodyInst = Bodies[RootBodyData.BodyIndex]; + } + } + // otherwise, look for the body + else + { + int32 BodyIndex = PhysicsAsset->FindBodyIndex(BoneName); + if (Bodies.IsValidIndex(BodyIndex)) + { + BodyInst = Bodies[BodyIndex]; + } + } + + BodyInst = (bGetWelded && BodyInstance.WeldParent) ? BodyInstance.WeldParent : BodyInst; + } + + return BodyInst; +} + +struct FAssetWorldBoneTM +{ + FTransform TM; // Should never contain scaling. + bool bUpToDate; // If this equals PhysAssetUpdateNum, then the matrix is up to date. +}; + +typedef TArray> TAssetWorldBoneTMArray; + +void UpdateWorldBoneTMVR(TAssetWorldBoneTMArray& WorldBoneTMs, const TArray& InBoneSpaceTransforms, int32 BoneIndex, USkeletalMeshComponent* SkelComp, const FTransform& LocalToWorldTM, const FVector& Scale3D) +{ + // If its already up to date - do nothing + if (WorldBoneTMs[BoneIndex].bUpToDate) + { + return; + } + + FTransform ParentTM, RelTM; + if (BoneIndex == 0) + { + // If this is the root bone, we use the mesh component LocalToWorld as the parent transform. + ParentTM = LocalToWorldTM; + } + else + { + // If not root, use our cached world-space bone transforms. + int32 ParentIndex = SkelComp->GetSkeletalMeshAsset()->GetRefSkeleton().GetParentIndex(BoneIndex); + UpdateWorldBoneTMVR(WorldBoneTMs, InBoneSpaceTransforms, ParentIndex, SkelComp, LocalToWorldTM, Scale3D); + ParentTM = WorldBoneTMs[ParentIndex].TM; + } + + if (InBoneSpaceTransforms.IsValidIndex(BoneIndex)) + { + RelTM = InBoneSpaceTransforms[BoneIndex]; + RelTM.ScaleTranslation(Scale3D); + + WorldBoneTMs[BoneIndex].TM = RelTM * ParentTM; + WorldBoneTMs[BoneIndex].bUpToDate = true; + } +} + +void UInversePhysicsSkeletalMeshComponent::PerformBlendPhysicsBonesVR(const TArray& InRequiredBones, TArray& InOutComponentSpaceTransforms, TArray& InOutBoneSpaceTransforms) +{ + //SCOPE_CYCLE_COUNTER(STAT_BlendInPhysics); + // Get drawscale from Owner (if there is one) + FVector TotalScale3D = GetComponentTransform().GetScale3D(); + FVector RecipScale3D = TotalScale3D.Reciprocal(); + + UPhysicsAsset* const PhysicsAsset = GetPhysicsAsset(); + check(PhysicsAsset); + + if (InOutComponentSpaceTransforms.Num() == 0) + { + return; + } + + // Get the scene, and do nothing if we can't get one. + FPhysScene* PhysScene = nullptr; + if (GetWorld() != nullptr) + { + PhysScene = GetWorld()->GetPhysicsScene(); + } + + if (PhysScene == nullptr) + { + return; + } + + FMemMark Mark(FMemStack::Get()); + // Make sure scratch space is big enough. + TAssetWorldBoneTMArray WorldBoneTMs; + WorldBoneTMs.AddZeroed(InOutComponentSpaceTransforms.Num()); + + FTransform LocalToWorldTM = GetComponentTransform(); + + // PhysAnim.cpp - PerformBlendPhysicsBones + // This fixes the simulated inversed scaled skeletal mesh bug + LocalToWorldTM.SetScale3D(LocalToWorldTM.GetScale3D().GetSignVector()); + LocalToWorldTM.NormalizeRotation(); + + // Original implementation stomps negative scale values + //LocalToWorldTM.RemoveScaling(); + + struct FBodyTMPair + { + FBodyInstance* BI; + FTransform TM; + }; + + FPhysicsCommand::ExecuteRead(this, [&]() + { + bool bSetParentScale = false; + const bool bSimulatedRootBody = Bodies.IsValidIndex(RootBodyData.BodyIndex) && Bodies[RootBodyData.BodyIndex]->IsInstanceSimulatingPhysics(); + const FTransform NewComponentToWorld = bSimulatedRootBody ? GetComponentTransformFromBodyInstance(Bodies[RootBodyData.BodyIndex]) : FTransform::Identity; + + // For each bone - see if we need to provide some data for it. + for (int32 i = 0; i < InRequiredBones.Num(); i++) + { + int32 BoneIndex = InRequiredBones[i]; + + // See if this is a physics bone.. + int32 BodyIndex = PhysicsAsset->FindBodyIndex(GetSkeletalMeshAsset()->GetRefSkeleton().GetBoneName(BoneIndex)); + // need to update back to physics so that physics knows where it was after blending + FBodyInstance* PhysicsAssetBodyInstance = nullptr; + + // If so - get its world space matrix and its parents world space matrix and calc relative atom. + if (BodyIndex != INDEX_NONE) + { +#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) + // tracking down TTP 280421. Remove this if this doesn't happen. + if (!ensure(Bodies.IsValidIndex(BodyIndex))) + { + UE_LOG(LogPhysics, Warning, TEXT("%s(Mesh %s, PhysicsAsset %s)"), + *GetName(), *GetNameSafe(GetSkeletalMeshAsset()), *GetNameSafe(PhysicsAsset)); + UE_LOG(LogPhysics, Warning, TEXT(" - # of BodySetup (%d), # of Bodies (%d), Invalid BodyIndex(%d)"), + PhysicsAsset->SkeletalBodySetups.Num(), Bodies.Num(), BodyIndex); + continue; + } +#endif + PhysicsAssetBodyInstance = Bodies[BodyIndex]; + + //if simulated body copy back and blend with animation + if (PhysicsAssetBodyInstance->IsInstanceSimulatingPhysics()) + { + FTransform PhysTM = PhysicsAssetBodyInstance->GetUnrealWorldTransform_AssumesLocked(); + + // Store this world-space transform in cache. + WorldBoneTMs[BoneIndex].TM = PhysTM; + WorldBoneTMs[BoneIndex].bUpToDate = true; + + float UsePhysWeight = (bBlendPhysics) ? 1.f : PhysicsAssetBodyInstance->PhysicsBlendWeight; + + // if the body instance is disabled, then we want to use the animation transform and ignore the physics one + if (PhysicsAssetBodyInstance->IsPhysicsDisabled()) + { + UsePhysWeight = 0.0f; + } + + // Find this bones parent matrix. + FTransform ParentWorldTM; + + // if we wan't 'full weight' we just find + if (UsePhysWeight > 0.f) + { + if (!(ensure(InOutBoneSpaceTransforms.Num()))) + { + continue; + } + + if (BoneIndex == 0) + { + ParentWorldTM = LocalToWorldTM; + } + else + { + // If not root, get parent TM from cache (making sure its up-to-date). + int32 ParentIndex = GetSkeletalMeshAsset()->GetRefSkeleton().GetParentIndex(BoneIndex); + UpdateWorldBoneTMVR(WorldBoneTMs, InOutBoneSpaceTransforms, ParentIndex, this, LocalToWorldTM, TotalScale3D); + ParentWorldTM = WorldBoneTMs[ParentIndex].TM; + } + + + // Then calc rel TM and convert to atom. + FTransform RelTM = PhysTM.GetRelativeTransform(ParentWorldTM); + RelTM.RemoveScaling(); + FQuat RelRot(RelTM.GetRotation()); + FVector RelPos = RecipScale3D * RelTM.GetLocation(); + FTransform PhysAtom = FTransform(RelRot, RelPos, InOutBoneSpaceTransforms[BoneIndex].GetScale3D()); + + // Now blend in this atom. See if we are forcing this bone to always be blended in + InOutBoneSpaceTransforms[BoneIndex].Blend(InOutBoneSpaceTransforms[BoneIndex], PhysAtom, UsePhysWeight); + + if (!bSetParentScale) + { + //We must update RecipScale3D based on the atom scale of the root + TotalScale3D *= InOutBoneSpaceTransforms[0].GetScale3D(); + RecipScale3D = TotalScale3D.Reciprocal(); + bSetParentScale = true; + } + + } + } + } + + if (!(ensure(BoneIndex < InOutComponentSpaceTransforms.Num()))) + { + continue; + } + + // Update SpaceBases entry for this bone now + if (BoneIndex == 0) + { + if (!(ensure(InOutBoneSpaceTransforms.Num()))) + { + continue; + } + InOutComponentSpaceTransforms[0] = InOutBoneSpaceTransforms[0]; + } + else + { + if (bLocalSpaceKinematics || BodyIndex == INDEX_NONE || Bodies[BodyIndex]->IsInstanceSimulatingPhysics()) + { + if (!(ensure(BoneIndex < InOutBoneSpaceTransforms.Num()))) + { + continue; + } + const int32 ParentIndex = GetSkeletalMeshAsset()->GetRefSkeleton().GetParentIndex(BoneIndex); + InOutComponentSpaceTransforms[BoneIndex] = InOutBoneSpaceTransforms[BoneIndex] * InOutComponentSpaceTransforms[ParentIndex]; + + /** + * Normalize rotations. + * We want to remove any loss of precision due to accumulation of error. + * i.e. A componentSpace transform is the accumulation of all of its local space parents. The further down the chain, the greater the error. + * SpaceBases are used by external systems, we feed this to Physics, send this to gameplay through bone and socket queries, etc. + * So this is a good place to make sure all transforms are normalized. + */ + InOutComponentSpaceTransforms[BoneIndex].NormalizeRotation(); + } + else if (bSimulatedRootBody) + { + InOutComponentSpaceTransforms[BoneIndex] = Bodies[BodyIndex]->GetUnrealWorldTransform_AssumesLocked().GetRelativeTransform(NewComponentToWorld); + } + } + } + }); //end scope for read lock + +} + +void UInversePhysicsSkeletalMeshComponent::RegisterEndPhysicsTick(bool bRegister) +{ + // For testing if the engine fix is live yet or not + //return Super::RegisterEndPhysicsTick(bRegister); + + if (bRegister != EndPhysicsTickFunctionVR.IsTickFunctionRegistered()) + { + if (bRegister) + { + if (SetupActorComponentTickFunction(&EndPhysicsTickFunctionVR)) + { + EndPhysicsTickFunctionVR.TargetVR = this; + // Make sure our EndPhysicsTick gets called after physics simulation is finished + UWorld* World = GetWorld(); + if (World != nullptr) + { + EndPhysicsTickFunctionVR.AddPrerequisite(World, World->EndPhysicsTickFunction); + } + } + } + else + { + EndPhysicsTickFunctionVR.UnRegisterTickFunction(); + } + } +} + +void UInversePhysicsSkeletalMeshComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) +{ + //CSV_SCOPED_TIMING_STAT_EXCLUSIVE(Animation); + + bool bShouldRunPhysTick = (bEnablePhysicsOnDedicatedServer || !IsNetMode(NM_DedicatedServer)) && // Early out if we are on a dedicated server and not running physics. + ((IsSimulatingPhysics() && RigidBodyIsAwake()) || ShouldBlendPhysicsBones()); + + RegisterEndPhysicsTick(PrimaryComponentTick.IsTickFunctionRegistered() && bShouldRunPhysTick); + //UpdateEndPhysicsTickRegisteredState(); + RegisterClothTick(PrimaryComponentTick.IsTickFunctionRegistered() && ShouldRunClothTick()); + //UpdateClothTickRegisteredState(); + + + // If we are suspended, we will not simulate clothing, but as clothing is simulated in local space + // relative to a root bone we need to extract simulation positions as this bone could be animated. + /*if (bClothingSimulationSuspended && this->GetClothingSimulation() && this->GetClothingSimulation()->ShouldSimulate()) + { + //CSV_SCOPED_TIMING_STAT(Animation, Cloth); + + this->GetClothingSimulation()->GetSimulationData(CurrentSimulationData, this, Cast(MasterPoseComponent.Get())); + }*/ + + Super::Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + PendingRadialForces.Reset(); + + // Update bOldForceRefPose + bOldForceRefPose = bForceRefpose; + + + static const auto CVarAnimationDelaysEndGroup = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("tick.AnimationDelaysEndGroup")); + /** Update the end group and tick priority */ + const bool bDoLateEnd = CVarAnimationDelaysEndGroup->GetValueOnGameThread() > 0; + const bool bRequiresPhysics = EndPhysicsTickFunctionVR.IsTickFunctionRegistered(); + const ETickingGroup EndTickGroup = bDoLateEnd && !bRequiresPhysics ? TG_PostPhysics : TG_PrePhysics; + if (ThisTickFunction) + { + ThisTickFunction->EndTickGroup = TG_PostPhysics;// EndTickGroup; + + // Note that if animation is so long that we are blocked in EndPhysics we may want to reduce the priority. However, there is a risk that this function will not go wide early enough. + // This requires profiling and is very game dependent so cvar for now makes sense + + static const auto CVarHiPriSkinnedMeshesTicks = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("tick.HiPriSkinnedMeshes")); + bool bDoHiPri = CVarHiPriSkinnedMeshesTicks->GetValueOnGameThread() > 0; + if (ThisTickFunction->bHighPriority != bDoHiPri) + { + ThisTickFunction->SetPriorityIncludingPrerequisites(bDoHiPri); + } + } + + // If we are waiting for ParallelEval to complete or if we require Physics, + // then FinalizeBoneTransform will be called and Anim events will be dispatched there. + // We prefer doing it there so these events are triggered once we have a new updated pose. + // Note that it's possible that FinalizeBoneTransform has already been called here if not using ParallelUpdate. + // or it's possible that it hasn't been called at all if we're skipping Evaluate due to not being visible. + // ConditionallyDispatchQueuedAnimEvents will catch that and only Dispatch events if not already done. + if (!IsRunningParallelEvaluation() && !bRequiresPhysics) + { + ///////////////////////////////////////////////////////////////////////////// + // Notify / Event Handling! + // This can do anything to our component (including destroy it) + // Any code added after this point needs to take that into account + ///////////////////////////////////////////////////////////////////////////// + + ConditionallyDispatchQueuedAnimEvents(); + } +} + +void UInversePhysicsSkeletalMeshComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UInversePhysicsSkeletalMeshComponent, bReplicateMovement, PushModelParams); +} + +AOptionalRepGrippableSkeletalMeshActor::AOptionalRepGrippableSkeletalMeshActor(const FObjectInitializer& ObjectInitializer) : + Super(ObjectInitializer.SetDefaultSubobjectClass(TEXT("SkeletalMeshComponent0"))) +{ + bIgnoreAttachmentReplication = false; + bIgnorePhysicsReplication = false; +} + +void AOptionalRepGrippableSkeletalMeshActor::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty >& OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_InitialOnly, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(AOptionalRepGrippableSkeletalMeshActor, bIgnoreAttachmentReplication, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(AOptionalRepGrippableSkeletalMeshActor, bIgnorePhysicsReplication, PushModelParamsWithCondition); + + if (bIgnoreAttachmentReplication) + { + RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(AActor, AttachmentReplication, COND_InitialOnly); + } + //DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, AttachmentReplication); +} + +void AOptionalRepGrippableSkeletalMeshActor::OnRep_ReplicateMovement() +{ + if (bIgnorePhysicsReplication) + { + return; + } + + Super::OnRep_ReplicateMovement(); +} + +void AOptionalRepGrippableSkeletalMeshActor::PostNetReceivePhysicState() +{ + if (bIgnorePhysicsReplication) + { + return; + } + + Super::PostNetReceivePhysicState(); +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRAIPerceptionOverrides.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRAIPerceptionOverrides.cpp new file mode 100644 index 0000000..8dcd672 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRAIPerceptionOverrides.cpp @@ -0,0 +1,1319 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Misc/VRAIPerceptionOverrides.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRAIPerceptionOverrides) + +#include "CoreMinimal.h" +#include "Engine/Engine.h" +#include "Engine/World.h" +//#include "EngineDefines.h" +//#include "EngineGlobals.h" +#include "CollisionQueryParams.h" +//#include "Engine/Engine.h" +#include "AISystem.h" +#include "AIHelpers.h" +#include "Perception/AIPerceptionComponent.h" +#include "VisualLogger/VisualLogger.h" +#include "Perception/AISightTargetInterface.h" +#include "Perception/AISenseConfig_Sight.h" +#include "Perception/AIPerceptionSystem.h" + +#if WITH_GAMEPLAY_DEBUGGER +#include "GameplayDebuggerTypes.h" +#include "GameplayDebuggerCategory.h" +#endif +DEFINE_LOG_CATEGORY(LogAIPerceptionVR); + +#define AISENSE_SIGHT_TIMESLICING_DEBUG 0 + +#define DO_SIGHT_VLOGGINGVR (0 && ENABLE_VISUAL_LOG) + +#if DO_SIGHT_VLOGGINGVR +#define SIGHT_LOG_SEGMENTVR UE_VLOG_SEGMENT +#define SIGHT_LOG_LOCATIONVR UE_VLOG_LOCATION +#else +#define SIGHT_LOG_SEGMENTVR(...) +#define SIGHT_LOG_LOCATIONVR(...) +#endif // DO_SIGHT_VLOGGING + +DECLARE_CYCLE_STAT(TEXT("Perception Sense: Sight"), STAT_AI_Sense_Sight, STATGROUP_AI); +DECLARE_CYCLE_STAT(TEXT("Perception Sense: Sight, Update Sort"), STAT_AI_Sense_Sight_UpdateSort, STATGROUP_AI); +DECLARE_CYCLE_STAT(TEXT("Perception Sense: Sight, Compute visibility"), STAT_AI_Sense_Sight_ComputeVisibility, STATGROUP_AI); +DECLARE_CYCLE_STAT(TEXT("Perception Sense: Sight, Query operations"), STAT_AI_Sense_Sight_QueryOperations, STATGROUP_AI); +DECLARE_CYCLE_STAT(TEXT("Perception Sense: Sight, Listener Update"), STAT_AI_Sense_Sight_ListenerUpdate, STATGROUP_AI); +DECLARE_CYCLE_STAT(TEXT("Perception Sense: Sight, Register Target"), STAT_AI_Sense_Sight_RegisterTarget, STATGROUP_AI); +DECLARE_CYCLE_STAT(TEXT("Perception Sense: Sight, Remove By Listener"), STAT_AI_Sense_Sight_RemoveByListener, STATGROUP_AI); +DECLARE_CYCLE_STAT(TEXT("Perception Sense: Sight, Remove To Target"), STAT_AI_Sense_Sight_RemoveToTarget, STATGROUP_AI); +DECLARE_CYCLE_STAT(TEXT("Perception Sense: Sight, Process pending result"), STAT_AI_Sense_Sight_ProcessPendingQuery, STATGROUP_AI); + + + +constexpr int32 DefaultMaxTracesPerTick = 6; +constexpr int32 DefaultMaxAsyncTracesPerTick = 10; +constexpr int32 DefaultMinQueriesPerTimeSliceCheck = 40; +constexpr float DefaultPendingQueriesBudgetReductionRatio = 0.5f; +constexpr bool bDefaultUseAsynchronousTraceForDefaultSightQueries = false; +constexpr float DefaultStimulusStrength = 1.f; + +enum class EForEachResult : uint8 +{ + Break, + Continue, +}; + +template +EForEachResult ForEach(T& Array, const PREDICATE_CLASS& Predicate) +{ + for (typename T::ElementType& Element : Array) + { + if (Predicate(Element) == EForEachResult::Break) + { + return EForEachResult::Break; + } + } + return EForEachResult::Continue; +} + +enum EReverseForEachResult : uint8 +{ + UnTouched, + Modified, +}; + +template +EReverseForEachResult ReverseForEach(T& Array, const PREDICATE_CLASS& Predicate) +{ + EReverseForEachResult RetVal = EReverseForEachResult::UnTouched; + for (int32 Index = Array.Num() - 1; Index >= 0; --Index) + { + if (Predicate(Array, Index) == EReverseForEachResult::Modified) + { + RetVal = EReverseForEachResult::Modified; + } + } + return RetVal; +} + +//----------------------------------------------------------------------// +// helpers +//----------------------------------------------------------------------// +FORCEINLINE_DEBUGGABLE bool CheckIsTargetInSightPie(const FPerceptionListener& Listener, const UAISense_Sight_VR::FDigestedSightProperties& DigestedProps, const FVector& TargetLocation, const float SightRadiusSq) +{ + if (FVector::DistSquared(Listener.CachedLocation, TargetLocation) <= SightRadiusSq) + { + const FVector DirectionToTarget = (TargetLocation - Listener.CachedLocation).GetUnsafeNormal(); + return FVector::DotProduct(DirectionToTarget, Listener.CachedDirection) > DigestedProps.PeripheralVisionAngleCos; + } + + return false; +} + +//----------------------------------------------------------------------// +// FAISightTargetVR +//----------------------------------------------------------------------// +const FAISightTargetVR::FTargetId FAISightTargetVR::InvalidTargetId = FAISystem::InvalidUnsignedID; + +FAISightTargetVR::FAISightTargetVR(AActor* InTarget, FGenericTeamId InTeamId) + : Target(InTarget), SightTargetInterface(nullptr), TeamId(InTeamId) +{ + if (InTarget) + { + TargetId = InTarget->GetUniqueID(); + } + else + { + TargetId = InvalidTargetId; + } +} + +//----------------------------------------------------------------------// +// FDigestedSightProperties +//----------------------------------------------------------------------// +UAISense_Sight_VR::FDigestedSightProperties::FDigestedSightProperties(const UAISenseConfig_Sight_VR& SenseConfig) +{ + SightRadiusSq = FMath::Square(SenseConfig.SightRadius + SenseConfig.PointOfViewBackwardOffset); + LoseSightRadiusSq = FMath::Square(SenseConfig.LoseSightRadius + SenseConfig.PointOfViewBackwardOffset); + PointOfViewBackwardOffset = SenseConfig.PointOfViewBackwardOffset; + NearClippingRadiusSq = FMath::Square(SenseConfig.NearClippingRadius); + PeripheralVisionAngleCos = FMath::Cos(FMath::Clamp(FMath::DegreesToRadians(SenseConfig.PeripheralVisionAngleDegrees), 0.f, PI)); + AffiliationFlags = SenseConfig.DetectionByAffiliation.GetAsFlags(); + // keep the special value of FAISystem::InvalidRange (-1.f) if it's set. + AutoSuccessRangeSqFromLastSeenLocation = (SenseConfig.AutoSuccessRangeFromLastSeenLocation == FAISystem::InvalidRange) ? FAISystem::InvalidRange : FMath::Square(SenseConfig.AutoSuccessRangeFromLastSeenLocation); +} + +UAISense_Sight_VR::FDigestedSightProperties::FDigestedSightProperties() + : PeripheralVisionAngleCos(0.f), SightRadiusSq(-1.f), AutoSuccessRangeSqFromLastSeenLocation(FAISystem::InvalidRange), LoseSightRadiusSq(-1.f), PointOfViewBackwardOffset(0.0f), NearClippingRadiusSq(0.0f) +{ + AffiliationFlags = FAISenseAffiliationFilter::DetectAllFlags(); +} + + +//----------------------------------------------------------------------// +// UAISense_Sight_VR +//----------------------------------------------------------------------// +UAISense_Sight_VR::UAISense_Sight_VR(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , MaxTracesPerTick(DefaultMaxTracesPerTick) + , MaxAsyncTracesPerTick(DefaultMaxAsyncTracesPerTick) + , MinQueriesPerTimeSliceCheck(DefaultMinQueriesPerTimeSliceCheck) + , MaxTimeSlicePerTick(0.005) // 5ms + , HighImportanceQueryDistanceThreshold(300.f) + , MaxQueryImportance(60.f) + , SightLimitQueryImportance(10.f) + , PendingQueriesBudgetReductionRatio(DefaultPendingQueriesBudgetReductionRatio) + , bUseAsynchronousTraceForDefaultSightQueries(bDefaultUseAsynchronousTraceForDefaultSightQueries) +{ + if (HasAnyFlags(RF_ClassDefaultObject) == false) + { + UAISenseConfig_Sight_VR* SightConfigCDO = GetMutableDefault(); + SightConfigCDO->Implementation = UAISense_Sight_VR::StaticClass(); + + OnNewListenerDelegate.BindUObject(this, &UAISense_Sight_VR::OnNewListenerImpl); + OnListenerUpdateDelegate.BindUObject(this, &UAISense_Sight_VR::OnListenerUpdateImpl); + OnListenerRemovedDelegate.BindUObject(this, &UAISense_Sight_VR::OnListenerRemovedImpl); + + OnPendingCanBeSeenQueryProcessedDelegate.BindUObject(this, &UAISense_Sight_VR::OnPendingCanBeSeenQueryProcessed); + OnPendingTraceQueryProcessedDelegate.BindUObject(this, &UAISense_Sight_VR::OnPendingTraceQueryProcessed); + } + + NotifyType = EAISenseNotifyType::OnPerceptionChange; + + bAutoRegisterAllPawnsAsSources = true; + bNeedsForgettingNotification = true; + + DefaultSightCollisionChannel = GET_AI_CONFIG_VAR(DefaultSightCollisionChannel); +} + +FORCEINLINE_DEBUGGABLE float UAISense_Sight_VR::CalcQueryImportance(const FPerceptionListener& Listener, const FVector& TargetLocation, const float SightRadiusSq) const +{ + const FVector::FReal DistanceSq = FVector::DistSquared(Listener.CachedLocation, TargetLocation); + return DistanceSq <= HighImportanceDistanceSquare ? MaxQueryImportance + : static_cast(FMath::Clamp((SightLimitQueryImportance - MaxQueryImportance) / SightRadiusSq * DistanceSq + MaxQueryImportance, 0.f, MaxQueryImportance)); +} + +void UAISense_Sight_VR::PostInitProperties() +{ + Super::PostInitProperties(); + HighImportanceDistanceSquare = FMath::Square(HighImportanceQueryDistanceThreshold); +} + +#if WITH_EDITOR +void UAISenseConfig_Sight_VR::PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent) +{ + static const FName NAME_AutoSuccessRangeFromLastSeenLocation = GET_MEMBER_NAME_CHECKED(UAISenseConfig_Sight_VR, AutoSuccessRangeFromLastSeenLocation); + + Super::PostEditChangeProperty(PropertyChangedEvent); + + if (PropertyChangedEvent.Property) + { + const FName PropName = PropertyChangedEvent.Property->GetFName(); + if (PropName == NAME_AutoSuccessRangeFromLastSeenLocation) + { + if (AutoSuccessRangeFromLastSeenLocation < 0) + { + AutoSuccessRangeFromLastSeenLocation = FAISystem::InvalidRange; + } + } + } +} +#endif // WITH_EDITOR + +bool UAISense_Sight_VR::ShouldAutomaticallySeeTarget(const FDigestedSightProperties& PropDigest, FAISightQueryVR* SightQuery, FPerceptionListener& Listener, AActor* TargetActor, float& OutStimulusStrength) const +{ + OutStimulusStrength = 1.0f; + + if ((PropDigest.AutoSuccessRangeSqFromLastSeenLocation != FAISystem::InvalidRange) && (SightQuery->LastSeenLocation != FAISystem::InvalidLocation)) + { + // Changed this up to support my VR Characters + const AVRBaseCharacter * VRChar = Cast(TargetActor); + const FVector::FReal DistanceToLastSeenLocationSq = FVector::DistSquared(VRChar != nullptr ? VRChar->GetVRLocation_Inline() : TargetActor->GetActorLocation(), SightQuery->LastSeenLocation); + return (DistanceToLastSeenLocationSq <= PropDigest.AutoSuccessRangeSqFromLastSeenLocation); + } + + return false; +} + + +namespace UE::AISense_SightVR +{ +#if AISENSE_SIGHT_TIMESLICING_DEBUG + struct FTimingSlicingInfo + { + FTimingSlicingInfo() + { + Start(); + } + + double StartTime = 0.; + double EndTime = 0.; + + int32 InRangeCount = 0; + int32 OutOfRangeCount = 0; + + float InRangeAgeSum = 0.f; + float OutOfRangeAgeSum = 0.f; + + void Start() { StartTime = FPlatformTime::Seconds(); } + void Stop() { EndTime = FPlatformTime::Seconds(); } + + void PushQueryInfo(const bool bIsInRange, const float Age) + { + if (bIsInRange) + { + ++InRangeCount; + InRangeAgeSum += Age; + } + else + { + ++OutOfRangeCount; + OutOfRangeAgeSum += Age; + } + } + + FString ToString() const + { + FString Info = FString::Format(TEXT("in {0} seconds"), { EndTime - StartTime }); + if (InRangeCount > 0) + { + Info.Append(FString::Format(TEXT("[{0} InRange Age:{1}]"), { InRangeCount, InRangeAgeSum / InRangeCount })); + } + if (OutOfRangeCount > 0) + { + Info.Append(FString::Format(TEXT("[{0} OutOfRange Age:{1}]"), { OutOfRangeCount, OutOfRangeAgeSum / OutOfRangeCount })); + } + return Info; + } + }; +} +#endif // AISENSE_SIGHT_TIMESLICING_DEBUG + +bool IsTraceConsideredVisible(const FHitResult* HitResult, const AActor* TargetActor) +{ + if (HitResult == nullptr) + { + return true; + } + + const AActor* HitResultActor = HitResult->HitObjectHandle.FetchActor(); + return (HitResultActor ? HitResultActor->IsOwnedBy(TargetActor) : false); +} +} + +float UAISense_Sight_VR::Update() +{ + SCOPE_CYCLE_COUNTER(STAT_AI_Sense_Sight); + + UWorld* World = GEngine->GetWorldFromContextObject(GetPerceptionSystem()->GetOuter(), EGetWorldErrorMode::LogAndReturnNull); + + if (World == nullptr) + { + return SuspendNextUpdate; + } + + UE_MT_SCOPED_WRITE_ACCESS(QueriesListAccessDetector); + + // sort Sight Queries + { + auto RecalcScore = [](FAISightQueryVR& SightQuery)->EForEachResult + { + SightQuery.RecalcScore(); + return EForEachResult::Continue; + }; + + SCOPE_CYCLE_COUNTER(STAT_AI_Sense_Sight_UpdateSort); + // Sort out of range queries + if (bSightQueriesOutOfRangeDirty) + { + ForEach(SightQueriesOutOfRange, RecalcScore); + SightQueriesOutOfRange.Sort(FAISightQueryVR::FSortPredicate()); + NextOutOfRangeIndex = 0; + bSightQueriesOutOfRangeDirty = false; + } + + // Sort in range queries + ForEach(SightQueriesInRange, RecalcScore); + SightQueriesInRange.Sort(FAISightQueryVR::FSortPredicate()); + } + + int32 TracesCount = 0; + int32 AsyncTracesCount = FMath::Max(0, static_cast(PendingQueriesBudgetReductionRatio * SightQueriesPending.Num())); // pending queries should be requesting async collisions traces at this frame, so we might want to restrain ourself in this update + int32 NumQueriesProcessed = 0; + const double TimeSliceEnd = FPlatformTime::Seconds() + MaxTimeSlicePerTick; + bool bHitTimeSliceLimit = false; +#if AISENSE_SIGHT_TIMESLICING_DEBUG + UE::AISense_SightVR::FTimingSlicingInfo SlicingInfo; +#endif // AISENSE_SIGHT_TIMESLICING_DEBUG + constexpr int32 InitialInvalidItemsSize = 16; + enum class EOperationType : uint8 + { + Remove, + SwapList, + MoveToPending + }; + struct FQueryOperation + { + FQueryOperation(bool bInInRange, EOperationType InOpType, int32 InIndex) : bInRange(bInInRange), OpType(InOpType), Index(InIndex) {} + bool bInRange; + EOperationType OpType; + int32 Index; + }; + TArray QueryOperations; + TArray InvalidTargets; + QueryOperations.Reserve(InitialInvalidItemsSize); + InvalidTargets.Reserve(InitialInvalidItemsSize); + + AIPerception::FListenerMap& ListenersMap = *GetListeners(); + + int32 InRangeItr = 0; + int32 OutOfRangeItr = 0; + for (int32 QueryIndex = 0; QueryIndex < SightQueriesInRange.Num() + SightQueriesOutOfRange.Num(); ++QueryIndex) + { + // Time slice limit check - spread out checks to every N queries so we don't spend more time checking timer than doing work + NumQueriesProcessed++; + if ((NumQueriesProcessed % MinQueriesPerTimeSliceCheck) == 0 && FPlatformTime::Seconds() > TimeSliceEnd) + { + bHitTimeSliceLimit = true; + } + + if (bHitTimeSliceLimit || TracesCount >= MaxTracesPerTick || AsyncTracesCount >= MaxAsyncTracesPerTick) + { + break; + } + + // Calculate next in range query + int32 InRangeIndex = SightQueriesInRange.IsValidIndex(InRangeItr) ? InRangeItr : INDEX_NONE; + FAISightQueryVR* InRangeQuery = InRangeIndex != INDEX_NONE ? &SightQueriesInRange[InRangeIndex] : nullptr; + + // Calculate next out of range query + int32 OutOfRangeIndex = SightQueriesOutOfRange.IsValidIndex(OutOfRangeItr) ? (NextOutOfRangeIndex + OutOfRangeItr) % SightQueriesOutOfRange.Num() : INDEX_NONE; + FAISightQueryVR* OutOfRangeQuery = OutOfRangeIndex != INDEX_NONE ? &SightQueriesOutOfRange[OutOfRangeIndex] : nullptr; + if (OutOfRangeQuery) + { + OutOfRangeQuery->RecalcScore(); + } + + // Compare to real find next query + const bool bIsInRangeQuery = (InRangeQuery && OutOfRangeQuery) ? FAISightQueryVR::FSortPredicate()(*InRangeQuery, *OutOfRangeQuery) : !OutOfRangeQuery; + FAISightQueryVR* SightQuery = bIsInRangeQuery ? InRangeQuery : OutOfRangeQuery; + ensure(SightQuery); + +#if AISENSE_SIGHT_TIMESLICING_DEBUG + SlicingInfo.PushQueryInfo(bIsInRangeQuery, SightQuery->GetAge()); +#endif //AISENSE_SIGHT_TIMESLICING_DEBUG + + bIsInRangeQuery ? ++InRangeItr : ++OutOfRangeItr; + + FPerceptionListener& Listener = ListenersMap[SightQuery->ObserverId]; + FAISightTargetVR& Target = ObservedTargets[SightQuery->TargetId]; + + AActor* TargetActor = Target.Target.Get(); + UAIPerceptionComponent* ListenerPtr = Listener.Listener.Get(); + ensure(ListenerPtr); + + + // @todo figure out what should we do if not valid + if (TargetActor && ListenerPtr) + { + const FDigestedSightProperties& PropDigest = DigestedProperties[SightQuery->ObserverId]; + const AActor* ListenerBodyActor = ListenerPtr->GetBodyActor(); + float StimulusStrength = DefaultStimulusStrength; + FVector SeenLocation(0.f); + int32 NumberOfLoSChecksPerformed = 0; + int32 NumberOfAsyncLosCheckRequested = 0; + + const UAISense_Sight::EVisibilityResult VisibilityResult = ComputeVisibility(World, *SightQuery, Listener, ListenerBodyActor, Target, TargetActor, PropDigest, StimulusStrength, SeenLocation, NumberOfLoSChecksPerformed, NumberOfAsyncLosCheckRequested); + + TracesCount += NumberOfLoSChecksPerformed; + AsyncTracesCount += NumberOfAsyncLosCheckRequested; + + if (VisibilityResult == UAISense_Sight::EVisibilityResult::Pending) + { + QueryOperations.Add(FQueryOperation(bIsInRangeQuery, EOperationType::MoveToPending, bIsInRangeQuery ? InRangeIndex : OutOfRangeIndex)); + } + else + { + UE_CLOG(VisibilityResult != UAISense_Sight::EVisibilityResult::Visible && VisibilityResult != UAISense_Sight::EVisibilityResult::NotVisible, LogAIPerception, Error, TEXT("UAISense_Sight::Update received invalid Visibility result [%d] for query between Listener %s and Target %s. We'll consider it as NotVisible"), int(VisibilityResult), *GetNameSafe(ListenerBodyActor), *GetNameSafe(TargetActor)); + + const bool bIsVisible = VisibilityResult == UAISense_Sight::EVisibilityResult::Visible; + const bool bWasVisible = SightQuery->GetLastResult(); + + // Changed this up to support my VR Characters + const AVRBaseCharacter* VRChar = Cast(TargetActor); + const FVector TargetLocation = VRChar != nullptr ? VRChar->GetVRLocation_Inline() : TargetActor->GetActorLocation(); + + UpdateQueryVisibilityStatus(*SightQuery, Listener, bIsVisible, SeenLocation, StimulusStrength, *TargetActor, TargetLocation); + + const float SightRadiusSq = bWasVisible ? PropDigest.LoseSightRadiusSq : PropDigest.SightRadiusSq; + SightQuery->Importance = CalcQueryImportance(Listener, TargetLocation, SightRadiusSq); + const bool bShouldBeInRange = SightQuery->Importance > 0.0f; + if (bIsInRangeQuery != bShouldBeInRange) + { + QueryOperations.Add(FQueryOperation(bIsInRangeQuery, EOperationType::SwapList, bIsInRangeQuery ? InRangeIndex : OutOfRangeIndex)); + } + + // restart query + SightQuery->OnProcessed(); + } + + + + // restart query + SightQuery->OnProcessed(); + } + else + { + + // put this index to "to be removed" array + QueryOperations.Add(FQueryOperation(bIsInRangeQuery, EOperationType::Remove, bIsInRangeQuery ? InRangeIndex : OutOfRangeIndex)); + if (TargetActor == nullptr) + { + InvalidTargets.AddUnique(SightQuery->TargetId); + } + } + } + NextOutOfRangeIndex = SightQueriesOutOfRange.Num() > 0 ? (NextOutOfRangeIndex + OutOfRangeItr) % SightQueriesOutOfRange.Num() : 0; + +#if AISENSE_SIGHT_TIMESLICING_DEBUG + SlicingInfo.Stop(); + UE_LOG(LogAIPerception, VeryVerbose, TEXT("UAISense_Sight::Update processed %d sources %s [time slice limited? %d]"), NumQueriesProcessed, *SlicingInfo.ToString(), bHitTimeSliceLimit ? 1 : 0); +#else + UE_LOG(LogAIPerception, VeryVerbose, TEXT("UAISense_Sight::Update processed %d sources [time slice limited? %d]"), NumQueriesProcessed, bHitTimeSliceLimit ? 1 : 0); +#endif // AISENSE_SIGHT_TIMESLICING_DEBUG + + if (QueryOperations.Num() > 0) + { + SCOPE_CYCLE_COUNTER(STAT_AI_Sense_Sight_QueryOperations); + + // Sort by InRange and by descending Index + QueryOperations.Sort([](const FQueryOperation& LHS, const FQueryOperation& RHS)->bool + { + if (LHS.bInRange != RHS.bInRange) + return LHS.bInRange; + return LHS.Index > RHS.Index; + }); + // Do all the removes first and save the out of range swaps because we will insert them at the right location to prevent sorting + TArray SightQueriesOutOfRangeToInsert; + for (const FQueryOperation& Operation : QueryOperations) + { + switch (Operation.OpType) + { + case EOperationType::SwapList: + { + if (Operation.bInRange) + { + SightQueriesOutOfRangeToInsert.Push(SightQueriesInRange[Operation.Index]); + } + else + { + SightQueriesInRange.Add(SightQueriesOutOfRange[Operation.Index]); + } + }break; + + case EOperationType::MoveToPending: + { + SightQueriesPending.Add(Operation.bInRange ? SightQueriesInRange[Operation.Index] : SightQueriesOutOfRange[Operation.Index]); + }break; + + case EOperationType::Remove: + break; + + default: + check(false); + break; + } + + if (Operation.bInRange) + { + // In range queries are always sorted at the beginning of the update + SightQueriesInRange.RemoveAtSwap(Operation.Index, 1, EAllowShrinking::No); + } + else + { + // Preserve the list ordered + SightQueriesOutOfRange.RemoveAt(Operation.Index, 1, EAllowShrinking::No); + if (Operation.Index < NextOutOfRangeIndex) + { + NextOutOfRangeIndex--; + } + } + } + // Reinsert the saved out of range swaps + if (SightQueriesOutOfRangeToInsert.Num() > 0) + { + SightQueriesOutOfRange.Insert(SightQueriesOutOfRangeToInsert.GetData(), SightQueriesOutOfRangeToInsert.Num(), NextOutOfRangeIndex); + NextOutOfRangeIndex += SightQueriesOutOfRangeToInsert.Num(); + } + + if (InvalidTargets.Num() > 0) + { + // this should not be happening since UAIPerceptionSystem::OnPerceptionStimuliSourceEndPlay introduction + UE_VLOG(GetPerceptionSystem(), LogAIPerceptionVR, Error, TEXT("Invalid sight targets found during UAISense_Sight_VR::Update call")); + + for (const auto& TargetId : InvalidTargets) + { + // remove affected queries + RemoveAllQueriesToTarget_Internal(TargetId); + // remove target itself + ObservedTargets.Remove(TargetId); + } + + // remove holes + ObservedTargets.Compact(); + } + } + + //return SightQueryQueue.Num() > 0 ? 1.f/6 : FLT_MAX; + return 0.f; +} + +UAISense_Sight::EVisibilityResult UAISense_Sight_VR::ComputeVisibility(UWorld* World, FAISightQueryVR& SightQuery, FPerceptionListener& Listener, const AActor* ListenerActor, FAISightTargetVR& Target, AActor* TargetActor, const FDigestedSightProperties& PropDigest, float& OutStimulusStrength, FVector& OutSeenLocation, int32& OutNumberOfLoSChecksPerformed, int32& OutNumberOfAsyncLosCheckRequested) const +{ + SCOPE_CYCLE_COUNTER(STAT_AI_Sense_Sight_ComputeVisibility); + + // @Note that automagical "seeing" does not care about sight range nor vision cone + if (ShouldAutomaticallySeeTarget(PropDigest, &SightQuery, Listener, TargetActor, OutStimulusStrength)) + { + OutSeenLocation = FAISystem::InvalidLocation; + return UAISense_Sight::EVisibilityResult::Visible; + } + + // Changed this up to support my VR Characters + const AVRBaseCharacter* VRChar = Cast(TargetActor); + const FVector TargetLocation = VRChar != nullptr ? VRChar->GetVRLocation_Inline() : TargetActor->GetActorLocation(); + + const float SightRadiusSq = SightQuery.GetLastResult() ? PropDigest.LoseSightRadiusSq : PropDigest.SightRadiusSq; + if (!FAISystem::CheckIsTargetInSightCone(Listener.CachedLocation, Listener.CachedDirection, PropDigest.PeripheralVisionAngleCos, PropDigest.PointOfViewBackwardOffset, PropDigest.NearClippingRadiusSq, SightRadiusSq, TargetLocation)) + { + return UAISense_Sight::EVisibilityResult::NotVisible; + } + + if (Target.SightTargetInterface != nullptr) + { + const bool bWasVisible = SightQuery.GetLastResult(); + + FCanBeSeenFromContext Context; + + FAISightQuery NewQuery; + NewQuery.FrameInfo.bLastResult = SightQuery.FrameInfo.bLastResult; + NewQuery.FrameInfo.LastProcessedFrameNumber = SightQuery.FrameInfo.LastProcessedFrameNumber; + NewQuery.Importance = SightQuery.Importance; + NewQuery.LastSeenLocation = SightQuery.LastSeenLocation; + NewQuery.ObserverId = SightQuery.ObserverId; + NewQuery.UserData = SightQuery.UserData; + NewQuery.Score = SightQuery.Score; + + NewQuery.TraceInfo.bLastResult = SightQuery.TraceInfo.bLastResult; + NewQuery.TraceInfo.FrameNumber = SightQuery.TraceInfo.FrameNumber; + NewQuery.TraceInfo.Index = SightQuery.TraceInfo.Index; + + /*FAISightTarget NewTarget; + NewTarget.InvalidTargetId = SightQuery.TargetId.InvalidTargetId; + NewTarget.SightTargetInterface = SightQuery.TargetId.SightTargetInterface; + NewTarget.Target = SightQuery.TargetId.Target; + NewTarget.TargetId = SightQuery.TargetId.TargetId; + NewTarget.TeamId = SightQuery.TargetId.TeamId;*/ + + NewQuery.TargetId = SightQuery.TargetId; + + Context.SightQueryID = NewQuery;//FAISightQueryIDVR(SightQuery); + Context.ObserverLocation = Listener.CachedLocation; + Context.IgnoreActor = ListenerActor; + Context.bWasVisible = &bWasVisible; + + const UAISense_Sight::EVisibilityResult Result = Target.SightTargetInterface->CanBeSeenFrom(Context, OutSeenLocation, OutNumberOfLoSChecksPerformed, OutNumberOfAsyncLosCheckRequested, OutStimulusStrength, &SightQuery.UserData, &OnPendingCanBeSeenQueryProcessedDelegate); + if (Result == UAISense_Sight::EVisibilityResult::Pending) + { + // we need to clear the trace info value in order to avoid interfering with the engine processed asynchronous queries + SightQuery.SetTraceInfo(FTraceHandle()); + } + return Result; + } + else + { + // we need to do tests ourselves + + const FCollisionQueryParams QueryParams = FCollisionQueryParams(SCENE_QUERY_STAT(AILineOfSight), true, ListenerActor); + + if (bUseAsynchronousTraceForDefaultSightQueries) + { + const FTraceHandle TraceHandle = World->AsyncLineTraceByChannel(EAsyncTraceType::Single, Listener.CachedLocation, TargetLocation, DefaultSightCollisionChannel, QueryParams, FCollisionResponseParams::DefaultResponseParam, &OnPendingTraceQueryProcessedDelegate); + if (!TraceHandle.IsValid()) + { + return UAISense_Sight::EVisibilityResult::NotVisible; + } + + ++OutNumberOfAsyncLosCheckRequested; + + // store the trace handle information here so that we can identify the associated query when we'll receive the delegate callback + SightQuery.SetTraceInfo(TraceHandle); + return UAISense_Sight::EVisibilityResult::Pending; + } + else + { + FHitResult HitResult; + const bool bHit = World->LineTraceSingleByChannel(HitResult, Listener.CachedLocation, TargetLocation, DefaultSightCollisionChannel, QueryParams, FCollisionResponseParams::DefaultResponseParam); + + ++OutNumberOfLoSChecksPerformed; + + if (UE::AISense_SightVR::IsTraceConsideredVisible(bHit ? &HitResult : nullptr, TargetActor)) + { + OutSeenLocation = TargetLocation; + return UAISense_Sight::EVisibilityResult::Visible; + } + else + { + return UAISense_Sight::EVisibilityResult::NotVisible; + } + } + } +} + +void UAISense_Sight_VR::UpdateQueryVisibilityStatus(FAISightQueryVR& SightQuery, FPerceptionListener& Listener, const bool bIsVisible, const FVector& SeenLocation, const float StimulusStrength, AActor* TargetActor, const FVector& TargetLocation) const +{ + if (TargetActor) + { + UpdateQueryVisibilityStatus(SightQuery, Listener, bIsVisible, SeenLocation, StimulusStrength, *TargetActor, TargetLocation); + } +} + +void UAISense_Sight_VR::UpdateQueryVisibilityStatus(FAISightQueryVR& SightQuery, FPerceptionListener& Listener, const bool bIsVisible, const FVector& SeenLocation, const float StimulusStrength, AActor& TargetActor, const FVector& TargetLocation) const +{ + if (bIsVisible) + { + const bool bHasValidSeenLocation = SeenLocation != FAISystem::InvalidLocation; + Listener.RegisterStimulus(&TargetActor, FAIStimulus(*this, StimulusStrength, bHasValidSeenLocation ? SeenLocation : SightQuery.LastSeenLocation, Listener.CachedLocation)); + SightQuery.SetLastResult(true); + if (bHasValidSeenLocation) + { + SightQuery.LastSeenLocation = SeenLocation; + } + } + // communicate failure only if we've seen given actor before + else if (SightQuery.GetLastResult()) + { + Listener.RegisterStimulus(&TargetActor, FAIStimulus(*this, 0.f, TargetLocation, Listener.CachedLocation, FAIStimulus::SensingFailed)); + SightQuery.SetLastResult(false); + SightQuery.LastSeenLocation = FAISystem::InvalidLocation; + } + + // SIGHT_LOG_SEGMENT(Listener.GetBodyActor(), Listener.CachedLocation, TargetLocation, bIsVisible ? FColor::Green : FColor::Red, TEXT("Target: %s"), *TargetActor.GetName()); +} + +void UAISense_Sight_VR::OnPendingCanBeSeenQueryProcessed(const FAISightQueryID& QueryID, const bool bIsVisible, const float StimulusStrength, const FVector& SeenLocation, const TOptional& UserData) +{ + SCOPE_CYCLE_COUNTER(STAT_AI_Sense_Sight_ProcessPendingQuery); + + UE_MT_SCOPED_WRITE_ACCESS(QueriesListAccessDetector); + + + FAISightQueryIDVR NewID; + NewID.ObserverId = QueryID.ObserverId; + NewID.TargetId = QueryID.TargetId; + + + const int32 QueryIdx = SightQueriesPending.IndexOfByPredicate([&NewID](const FAISightQueryVR& Element) + { + return Element.ObserverId == NewID.ObserverId + && Element.TargetId == NewID.TargetId; + }); + + if (QueryIdx == INDEX_NONE) + { + // the query is not pending. It must have been removed because the source or the target have been removed + return; + } + + OnPendingQueryProcessed(QueryIdx, bIsVisible, StimulusStrength, SeenLocation, UserData); +} + +void UAISense_Sight_VR::OnPendingTraceQueryProcessed(const FTraceHandle& TraceHandle, FTraceDatum& TraceDatum) +{ + SCOPE_CYCLE_COUNTER(STAT_AI_Sense_Sight_ProcessPendingQuery); + UE_MT_SCOPED_WRITE_ACCESS(QueriesListAccessDetector); + + const int32 QueryIdx = SightQueriesPending.IndexOfByPredicate([&TraceHandle](const FAISightQueryVR& Element) + { + return Element.TraceInfo.FrameNumber == TraceHandle._Data.FrameNumber + && Element.TraceInfo.Index == TraceHandle._Data.Index; + }); + + if (QueryIdx == INDEX_NONE) + { + // the query is not pending. It must have been removed because the source or the target have been removed + return; + } + + AActor* TargetActor = nullptr; + if (const FAISightTargetVR* Target = ObservedTargets.Find(SightQueriesPending[QueryIdx].TargetId)) + { + TargetActor = Target->Target.Get(); + } + const bool bIsVisible = UE::AISense_SightVR::IsTraceConsideredVisible(TraceDatum.OutHits.Num() > 0 ? &TraceDatum.OutHits[0] : nullptr, TargetActor); + + OnPendingQueryProcessed(QueryIdx, bIsVisible, DefaultStimulusStrength, TraceDatum.End, NullOpt, TargetActor); +} + +void UAISense_Sight_VR::OnPendingQueryProcessed(const int32 SightQueryIndex, const bool bIsVisible, const float StimulusStrength, const FVector& SeenLocation, const TOptional& UserData, const TOptional InTargetActor) +{ + FAISightQueryVR SightQuery = SightQueriesPending[SightQueryIndex]; + SightQueriesPending.RemoveAtSwap(SightQueryIndex, 1, EAllowShrinking::No); + + AIPerception::FListenerMap& ListenersMap = *GetListeners(); + FPerceptionListener* Listener = ListenersMap.Find(SightQuery.ObserverId); + if (Listener == nullptr) + { + return; + } + + AActor* TargetActor = nullptr; + if (InTargetActor.IsSet()) + { + TargetActor = InTargetActor.GetValue(); + } + else + { + const FAISightTargetVR* Target = ObservedTargets.Find(SightQuery.TargetId); + TargetActor = Target ? Target->Target.Get() : nullptr; + } + + if (TargetActor == nullptr) + { + return; + } + + const bool bWasVisible = SightQuery.GetLastResult(); + + // Changed this up to support my VR Characters + const AVRBaseCharacter* VRChar = Cast(TargetActor); + const FVector TargetLocation = VRChar != nullptr ? VRChar->GetVRLocation_Inline() : TargetActor->GetActorLocation(); + + UpdateQueryVisibilityStatus(SightQuery, *Listener, bIsVisible, SeenLocation, StimulusStrength, *TargetActor, TargetLocation); + + if (UserData.IsSet()) + { + SightQuery.UserData = UserData.GetValue(); + } + + // Call this to be able to have an accurate tick time + SightQuery.OnProcessed(); + + const FDigestedSightProperties& PropDigest = DigestedProperties[SightQuery.ObserverId]; + const float SightRadiusSq = bWasVisible ? PropDigest.LoseSightRadiusSq : PropDigest.SightRadiusSq; + SightQuery.Importance = CalcQueryImportance(*Listener, TargetLocation, SightRadiusSq); + const bool bShouldBeInRange = SightQuery.Importance > 0.0f; + if (bShouldBeInRange) + { + SightQueriesInRange.Add(SightQuery); + } + else + { + if (bSightQueriesOutOfRangeDirty) + { + SightQueriesOutOfRange.Add(SightQuery); + } + else + { + SightQueriesOutOfRange.Insert(SightQuery, NextOutOfRangeIndex); + ++NextOutOfRangeIndex; + } + } +} + +void UAISense_Sight_VR::RegisterEvent(const FAISightEventVR& Event) +{ + +} + +void UAISense_Sight_VR::RegisterSource(AActor& SourceActor) +{ + RegisterTarget(SourceActor); +} + +void UAISense_Sight_VR::UnregisterSource(AActor& SourceActor) +{ + UE_MT_SCOPED_WRITE_ACCESS(QueriesListAccessDetector); + + const FAISightTargetVR::FTargetId AsTargetId = SourceActor.GetUniqueID(); + FAISightTargetVR AsTarget; + + + if (ObservedTargets.RemoveAndCopyValue(AsTargetId, AsTarget) + && (SightQueriesInRange.Num() + SightQueriesOutOfRange.Num() + SightQueriesPending.Num()) > 0) + { + AActor* TargetActor = AsTarget.Target.Get(); + + if (TargetActor) + { + // notify all interested observers that this source is no longer + // visible + AIPerception::FListenerMap& ListenersMap = *GetListeners(); + auto RemoveQuery = [this, &ListenersMap, &AsTargetId, &TargetActor](TArray& SightQueries, const int32 QueryIndex)->EReverseForEachResult + { + FAISightQueryVR* SightQuery = &SightQueries[QueryIndex]; + if (SightQuery->TargetId == AsTargetId) + { + if (SightQuery->GetLastResult()) + { + FPerceptionListener& Listener = ListenersMap[SightQuery->ObserverId]; + ensure(Listener.Listener.IsValid()); + + Listener.RegisterStimulus(TargetActor, FAIStimulus(*this, 0.f, SightQuery->LastSeenLocation, Listener.CachedLocation, FAIStimulus::SensingFailed)); + } + + SightQueries.RemoveAtSwap(QueryIndex, 1, EAllowShrinking::No); + return EReverseForEachResult::Modified; + } + + return EReverseForEachResult::UnTouched; + }; + + ReverseForEach(SightQueriesInRange, RemoveQuery); + if (ReverseForEach(SightQueriesOutOfRange, RemoveQuery) == EReverseForEachResult::Modified) + { + bSightQueriesOutOfRangeDirty = true; + } + ReverseForEach(SightQueriesPending, RemoveQuery); + } + } +} + +bool UAISense_Sight_VR::RegisterTarget(AActor& TargetActor, const TFunction& OnAddedFunc /*= nullptr*/) +{ + SCOPE_CYCLE_COUNTER(STAT_AI_Sense_Sight_RegisterTarget); + + FAISightTargetVR* SightTarget = ObservedTargets.Find(TargetActor.GetUniqueID()); + + if (SightTarget != nullptr && SightTarget->GetTargetActor() != &TargetActor) + { + // this means given unique ID has already been recycled. + FAISightTargetVR NewSightTarget(&TargetActor); + + SightTarget = &(ObservedTargets.Add(NewSightTarget.TargetId, NewSightTarget)); + SightTarget->SightTargetInterface = Cast(&TargetActor); + } + else if (SightTarget == nullptr) + { + FAISightTargetVR NewSightTarget(&TargetActor); + + SightTarget = &(ObservedTargets.Add(NewSightTarget.TargetId, NewSightTarget)); + SightTarget->SightTargetInterface = Cast(&TargetActor); + } + + // set/update data + SightTarget->TeamId = FGenericTeamId::GetTeamIdentifier(&TargetActor); + + + // generate all pairs and add them to current Sight Queries + bool bNewQueriesAdded = false; + AIPerception::FListenerMap& ListenersMap = *GetListeners(); + + // Changed this up to support my VR Characters + const AVRBaseCharacter * VRChar = Cast(&TargetActor); + const FVector TargetLocation = VRChar != nullptr ? VRChar->GetVRLocation_Inline() : TargetActor.GetActorLocation(); + + for (AIPerception::FListenerMap::TConstIterator ItListener(ListenersMap); ItListener; ++ItListener) + { + const FPerceptionListener& Listener = ItListener->Value; + + if (!Listener.HasSense(GetSenseID()) || Listener.GetBodyActor() == &TargetActor) + { + continue; + } + + const FDigestedSightProperties& PropDigest = DigestedProperties[Listener.GetListenerID()]; + const IGenericTeamAgentInterface* ListenersTeamAgent = Listener.GetTeamAgent(); + if (RegisterNewQuery(Listener, ListenersTeamAgent, TargetActor, SightTarget->TargetId, TargetLocation, PropDigest, OnAddedFunc)) + { + bNewQueriesAdded = true; + } + } + + // sort Sight Queries + if (bNewQueriesAdded) + { + RequestImmediateUpdate(); + } + + return bNewQueriesAdded; +} + +void UAISense_Sight_VR::OnNewListenerImpl(const FPerceptionListener& NewListener) +{ + UAIPerceptionComponent* NewListenerPtr = NewListener.Listener.Get(); + check(NewListenerPtr); + const UAISenseConfig_Sight_VR* SenseConfig = Cast(NewListenerPtr->GetSenseConfig(GetSenseID())); + + check(SenseConfig); + const FDigestedSightProperties PropertyDigest(*SenseConfig); + DigestedProperties.Add(NewListener.GetListenerID(), PropertyDigest); + + GenerateQueriesForListener(NewListener, PropertyDigest); +} + +void UAISense_Sight_VR::GenerateQueriesForListener(const FPerceptionListener& Listener, const FDigestedSightProperties& PropertyDigest, const TFunction& OnAddedFunc/*= nullptr */) +{ + bool bNewQueriesAdded = false; + const IGenericTeamAgentInterface* ListenersTeamAgent = Listener.GetTeamAgent(); + const AActor* Avatar = Listener.GetBodyActor(); + + // create sight queries with all legal targets + for (FTargetsContainer::TConstIterator ItTarget(ObservedTargets); ItTarget; ++ItTarget) + { + const AActor* TargetActor = ItTarget->Value.GetTargetActor(); + if (TargetActor == nullptr || TargetActor == Avatar) + { + continue; + } + + // Changed this up to support my VR Characters + const AVRBaseCharacter* VRChar = Cast(TargetActor); + const FVector TargetLocation = VRChar != nullptr ? VRChar->GetVRLocation_Inline() : TargetActor->GetActorLocation(); + if (RegisterNewQuery(Listener, ListenersTeamAgent, *TargetActor, ItTarget->Key, TargetLocation, PropertyDigest, OnAddedFunc)) + { + bNewQueriesAdded = true; + } + } + + // sort Sight Queries + if (bNewQueriesAdded) + { + RequestImmediateUpdate(); + } +} + +bool UAISense_Sight_VR::RegisterNewQuery(const FPerceptionListener& Listener, const IGenericTeamAgentInterface* ListenersTeamAgent, const AActor& TargetActor, const FAISightTargetVR::FTargetId& TargetId, const FVector& TargetLocation, const FDigestedSightProperties& PropDigest, const TFunction& OnAddedFunc) +{ + if (!FAISenseAffiliationFilter::ShouldSenseTeam(ListenersTeamAgent, TargetActor, PropDigest.AffiliationFlags)) + { + return false; + } + + // create a sight query + const float Importance = CalcQueryImportance(Listener, TargetLocation, PropDigest.SightRadiusSq); + const bool bInRange = Importance > 0.0f; + if (!bInRange) + { + bSightQueriesOutOfRangeDirty = true; + } + + FAISightQueryVR& AddedQuery = bInRange ? SightQueriesInRange.AddDefaulted_GetRef() : SightQueriesOutOfRange.AddDefaulted_GetRef(); + AddedQuery.ObserverId = Listener.GetListenerID(); + AddedQuery.TargetId = TargetId; + AddedQuery.Importance = Importance; + + if (OnAddedFunc) + { + OnAddedFunc(AddedQuery); + } + + return true; +} + +void UAISense_Sight_VR::OnListenerUpdateImpl(const FPerceptionListener& UpdatedListener) +{ + SCOPE_CYCLE_COUNTER(STAT_AI_Sense_Sight_ListenerUpdate); + + // first, naive implementation: + // 1. remove all queries by this listener + // 2. proceed as if it was a new listener + + // see if this listener is a Target as well + const FAISightTargetVR::FTargetId AsTargetId = UpdatedListener.GetBodyActorUniqueID(); + FAISightTargetVR* AsTarget = ObservedTargets.Find(AsTargetId); + if (AsTarget != nullptr) + { + if (AsTarget->Target.IsValid()) + { + // if still a valid target then backup list of observers for which the listener was visible to restore in the newly created queries + TSet LastVisibleObservers; + RemoveAllQueriesToTarget(AsTargetId, [&LastVisibleObservers](const FAISightQueryVR& Query) + { + if (Query.GetLastResult()) + { + LastVisibleObservers.Add(Query.ObserverId); + } + }); + + RegisterTarget(*(AsTarget->Target.Get()), [&LastVisibleObservers](FAISightQueryVR& Query) + { + Query.SetLastResult(LastVisibleObservers.Contains(Query.ObserverId)); + }); + } + else + { + RemoveAllQueriesToTarget(AsTargetId); + } + } + + const FPerceptionListenerID ListenerID = UpdatedListener.GetListenerID(); + + if (UpdatedListener.HasSense(GetSenseID())) + { + // if still a valid sense then backup list of targets that were visible by the listener to restore in the newly created queries + TSet LastVisibleTargets; + RemoveAllQueriesByListener(UpdatedListener, [&LastVisibleTargets](const FAISightQueryVR& Query) + { + if (Query.GetLastResult()) + { + LastVisibleTargets.Add(Query.TargetId); + } + }); + + const UAISenseConfig_Sight_VR* SenseConfig = Cast(UpdatedListener.Listener->GetSenseConfig(GetSenseID())); + check(SenseConfig); + + FDigestedSightProperties& PropertiesDigest = DigestedProperties.FindOrAdd(ListenerID); + PropertiesDigest = FDigestedSightProperties(*SenseConfig); + + GenerateQueriesForListener(UpdatedListener, PropertiesDigest, [&LastVisibleTargets](FAISightQueryVR & Query) + { + Query.SetLastResult(LastVisibleTargets.Contains(Query.TargetId)); + }); + } + else + { + // remove all queries + RemoveAllQueriesByListener(UpdatedListener); + DigestedProperties.Remove(ListenerID); + } +} + +void UAISense_Sight_VR::OnListenerConfigUpdated(const FPerceptionListener& UpdatedListener) +{ + + bool bSkipListenerUpdate = false; + const FPerceptionListenerID ListenerID = UpdatedListener.GetListenerID(); + + + FDigestedSightProperties* PropertiesDigest = DigestedProperties.Find(ListenerID); + if (PropertiesDigest) + { + // The only parameter we need to rebuild all the queries for this listener is if the affiliation mask changed, otherwise there is nothing to update. + const UAISenseConfig_Sight_VR* SenseConfig = CastChecked(UpdatedListener.Listener->GetSenseConfig(GetSenseID())); + FDigestedSightProperties NewPropertiesDigest(*SenseConfig); + bSkipListenerUpdate = NewPropertiesDigest.AffiliationFlags == PropertiesDigest->AffiliationFlags; + *PropertiesDigest = NewPropertiesDigest; + } + + if (!bSkipListenerUpdate) + { + Super::OnListenerConfigUpdated(UpdatedListener); + } +} + +void UAISense_Sight_VR::OnListenerRemovedImpl(const FPerceptionListener& RemovedListener) +{ + + RemoveAllQueriesByListener(RemovedListener); + + DigestedProperties.FindAndRemoveChecked(RemovedListener.GetListenerID()); + + // note: there use to be code to remove all queries _to_ listener here as well + // but that was wrong - the fact that a listener gets unregistered doesn't have to + // mean it's being removed from the game altogether. +} + + +void UAISense_Sight_VR::RemoveAllQueriesByListener(const FPerceptionListener& Listener, const TFunction& OnRemoveFunc/*= nullptr */) +{ + SCOPE_CYCLE_COUNTER(STAT_AI_Sense_Sight_RemoveByListener); + UE_MT_SCOPED_WRITE_ACCESS(QueriesListAccessDetector); + + const uint32 ListenerId = Listener.GetListenerID(); + + auto RemoveQuery = [&ListenerId, &OnRemoveFunc](TArray& SightQueries, const int32 QueryIndex)->EReverseForEachResult + { + const FAISightQueryVR& SightQuery = SightQueries[QueryIndex]; + + if (SightQuery.ObserverId == ListenerId) + { + if (OnRemoveFunc) + { + OnRemoveFunc(SightQuery); + } + SightQueries.RemoveAtSwap(QueryIndex, 1, EAllowShrinking::No); + + return EReverseForEachResult::Modified; + } + + return EReverseForEachResult::UnTouched; + }; + ReverseForEach(SightQueriesInRange, RemoveQuery); + if (ReverseForEach(SightQueriesOutOfRange, RemoveQuery) == EReverseForEachResult::Modified) + { + + bSightQueriesOutOfRangeDirty = true; + } + ReverseForEach(SightQueriesPending, RemoveQuery); +} + +void UAISense_Sight_VR::RemoveAllQueriesToTarget(const FAISightTargetVR::FTargetId& TargetId, const TFunction& OnRemoveFunc/*= nullptr */) +{ + SCOPE_CYCLE_COUNTER(STAT_AI_Sense_Sight_RemoveToTarget); + UE_MT_SCOPED_WRITE_ACCESS(QueriesListAccessDetector); + RemoveAllQueriesToTarget_Internal(TargetId, OnRemoveFunc); +} + +void UAISense_Sight_VR::RemoveAllQueriesToTarget_Internal(const FAISightTargetVR::FTargetId& TargetId, const TFunction& OnRemoveFunc/*= nullptr */) +{ + SCOPE_CYCLE_COUNTER(STAT_AI_Sense_Sight_RemoveToTarget); + + auto RemoveQuery = [&TargetId, &OnRemoveFunc](TArray& SightQueries, const int32 QueryIndex)->EReverseForEachResult + { + const FAISightQueryVR& SightQuery = SightQueries[QueryIndex]; + + if (SightQuery.TargetId == TargetId) + { + if (OnRemoveFunc) + { + OnRemoveFunc(SightQuery); + } + SightQueries.RemoveAtSwap(QueryIndex, 1, EAllowShrinking::No); + + return EReverseForEachResult::Modified; + } + + return EReverseForEachResult::UnTouched; + }; + ReverseForEach(SightQueriesInRange, RemoveQuery); + if (ReverseForEach(SightQueriesOutOfRange, RemoveQuery) == EReverseForEachResult::Modified) + { + + bSightQueriesOutOfRangeDirty = true; + } + ReverseForEach(SightQueriesPending, RemoveQuery); +} + + +void UAISense_Sight_VR::OnListenerForgetsActor(const FPerceptionListener& Listener, AActor& ActorToForget) +{ + const uint32 ListenerId = Listener.GetListenerID(); + const uint32 TargetId = ActorToForget.GetUniqueID(); + + auto ForgetPreviousResult = [&ListenerId, &TargetId](FAISightQueryVR& SightQuery)->EForEachResult + { + if (SightQuery.ObserverId == ListenerId && SightQuery.TargetId == TargetId) + { + // assuming one query per observer-target pair + SightQuery.ForgetPreviousResult(); + return EForEachResult::Break; + } + return EForEachResult::Continue; + }; + + if (ForEach(SightQueriesInRange, ForgetPreviousResult) == EForEachResult::Continue) + { + if (ForEach(SightQueriesOutOfRange, ForgetPreviousResult) == EForEachResult::Continue) + { + ForEach(SightQueriesPending, ForgetPreviousResult); + } + } +} + +void UAISense_Sight_VR::OnListenerForgetsAll(const FPerceptionListener& Listener) +{ + UE_MT_SCOPED_WRITE_ACCESS(QueriesListAccessDetector); + + const uint32 ListenerId = Listener.GetListenerID(); + + auto ForgetPreviousResult = [&ListenerId](FAISightQueryVR& SightQuery)->EForEachResult + { + if (SightQuery.ObserverId == ListenerId) + { + SightQuery.ForgetPreviousResult(); + } + + return EForEachResult::Continue; + }; + + ForEach(SightQueriesInRange, ForgetPreviousResult); + ForEach(SightQueriesOutOfRange, ForgetPreviousResult); + ForEach(SightQueriesPending, ForgetPreviousResult); +} + + +//----------------------------------------------------------------------// +// +//----------------------------------------------------------------------// +UAISenseConfig_Sight_VR::UAISenseConfig_Sight_VR(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) +{ + DebugColor = FColor::Green; + AutoSuccessRangeFromLastSeenLocation = -1.0; + SightRadius = 3000.f; + LoseSightRadius = 3500.f; + PeripheralVisionAngleDegrees = 90; + DetectionByAffiliation.bDetectEnemies = true; + Implementation = UAISense_Sight_VR::StaticClass(); +} + +TSubclassOf UAISenseConfig_Sight_VR::GetSenseImplementation() const +{ + return *Implementation; +} + +#if WITH_GAMEPLAY_DEBUGGER +static FString DescribeColorHelper(const FColor& Color) +{ + int32 MaxColors = GColorList.GetColorsNum(); + for (int32 Idx = 0; Idx < MaxColors; Idx++) + { + if (Color == GColorList.GetFColorByIndex(Idx)) + { + return GColorList.GetColorNameByIndex(Idx); + } + } + + return FString(TEXT("color")); +} + +void UAISenseConfig_Sight_VR::DescribeSelfToGameplayDebugger(const UAIPerceptionComponent* PerceptionComponent, FGameplayDebuggerCategory* DebuggerCategory) const +{ + if (PerceptionComponent == nullptr || DebuggerCategory == nullptr) + { + return; + } + + FColor SightRangeColor = FColor::Green; + FColor LoseSightRangeColor = FColorList::NeonPink; + + // don't call Super implementation on purpose, replace color description line + DebuggerCategory->AddTextLine( + FString::Printf(TEXT("%s: {%s}%s {white}rangeIN:{%s}%s {white} rangeOUT:{%s}%s"), *GetSenseName(), + *GetDebugColor().ToString(), *DescribeColorHelper(GetDebugColor()), + *SightRangeColor.ToString(), *DescribeColorHelper(SightRangeColor), + *LoseSightRangeColor.ToString(), *DescribeColorHelper(LoseSightRangeColor)) + ); + + const AActor* BodyActor = PerceptionComponent->GetBodyActor(); + if (BodyActor != nullptr) + { + FVector BodyLocation, BodyFacing; + PerceptionComponent->GetLocationAndDirection(BodyLocation, BodyFacing); + + DebuggerCategory->AddShape(FGameplayDebuggerShape::MakeCylinder(BodyLocation, LoseSightRadius, 25.0f, LoseSightRangeColor)); + DebuggerCategory->AddShape(FGameplayDebuggerShape::MakeCylinder(BodyLocation, SightRadius, 25.0f, SightRangeColor)); + + const float SightPieLength = FMath::Max(LoseSightRadius, SightRadius); + DebuggerCategory->AddShape(FGameplayDebuggerShape::MakeSegment(BodyLocation, BodyLocation + (BodyFacing * SightPieLength), SightRangeColor)); + DebuggerCategory->AddShape(FGameplayDebuggerShape::MakeSegment(BodyLocation, BodyLocation + (BodyFacing.RotateAngleAxis(PeripheralVisionAngleDegrees, FVector::UpVector) * SightPieLength), SightRangeColor)); + DebuggerCategory->AddShape(FGameplayDebuggerShape::MakeSegment(BodyLocation, BodyLocation + (BodyFacing.RotateAngleAxis(-PeripheralVisionAngleDegrees, FVector::UpVector) * SightPieLength), SightRangeColor)); + } +} + +#if WITH_GAMEPLAY_DEBUGGER_MENU +void UAISense_Sight_VR::DescribeSelfToGameplayDebugger(const UAIPerceptionSystem& PerceptionSystem, FGameplayDebuggerCategory& DebuggerCategory) const +{ + const int32 TotalQueriesCount = SightQueriesInRange.Num() + SightQueriesOutOfRange.Num() + SightQueriesPending.Num(); + DebuggerCategory.AddTextLine( + FString::Printf(TEXT("%s: %d Targets, %d Queries (InRange:%d, OutOfRange:%d, Pending:%d)"), + *GetSenseID().Name.ToString(), + ObservedTargets.Num(), + TotalQueriesCount, + SightQueriesInRange.Num(), + SightQueriesOutOfRange.Num(), + SightQueriesPending.Num()) + ); +} +#endif // WITH_GAMEPLAY_DEBUGGER_MENU + +#endif // WITH_GAMEPLAY_DEBUGGER \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VREPhysicalAnimationComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VREPhysicalAnimationComponent.cpp new file mode 100644 index 0000000..f109a22 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VREPhysicalAnimationComponent.cpp @@ -0,0 +1,389 @@ +#include "Misc/VREPhysicalAnimationComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VREPhysicalAnimationComponent) + +#include "SceneManagement.h" +#include "Components/SkeletalMeshComponent.h" +#include "PhysicsEngine/PhysicsAsset.h" +#include "PhysicsEngine/ConstraintInstance.h" +#include "ReferenceSkeleton.h" +#include "DrawDebugHelpers.h" + +#if UE_ENABLE_DEBUG_DRAWING +#include "Chaos/ImplicitObject.h" +#include "Chaos/TriangleMeshImplicitObject.h" +#include "Chaos/ShapeInstance.h" +#include "Chaos/DebugDrawQueue.h" +#endif + +#include "Physics/PhysicsInterfaceCore.h" +#include "Physics/PhysicsInterfaceTypes.h" + +UVREPhysicalAnimationComponent::UVREPhysicalAnimationComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + bAutoSetPhysicsSleepSensitivity = true; + SleepThresholdMultiplier = 0.0f; +} + +/*void UVREPhysicalAnimationComponent::CustomPhysics(float DeltaTime, FBodyInstance* BodyInstance) +{ + //UpdateWeldedBoneDriver(DeltaTime); +}*/ + +/*void UVREPhysicalAnimationComponent::OnWeldedMassUpdated(FBodyInstance* BodyInstance) +{ + // If our mass changed then our body was altered, lets re-init + SetupWeldedBoneDriver(true); +}*/ + +void UVREPhysicalAnimationComponent::SetWeldedBoneDriverPaused(bool bPaused) +{ + bIsPaused = bPaused; +} + +bool UVREPhysicalAnimationComponent::IsWeldedBoneDriverPaused() +{ + return bIsPaused; +} + +void UVREPhysicalAnimationComponent::RefreshWeldedBoneDriver() +{ + SetupWeldedBoneDriver_Implementation(true); +} + +void UVREPhysicalAnimationComponent::SetupWeldedBoneDriver(TArray BaseBoneNames) +{ + if (BaseBoneNames.Num()) + BaseWeldedBoneDriverNames = BaseBoneNames; + + SetupWeldedBoneDriver_Implementation(false); +} + +FTransform UVREPhysicalAnimationComponent::GetWorldSpaceRefBoneTransform(FReferenceSkeleton& RefSkel, int32 BoneIndex, int32 ParentBoneIndex) +{ + FTransform BoneTransform; + + if (BoneIndex > 0 && BoneIndex != ParentBoneIndex) + { + BoneTransform = RefSkel.GetRefBonePose()[BoneIndex]; + + FMeshBoneInfo BoneInfo = RefSkel.GetRefBoneInfo()[BoneIndex]; + if (BoneInfo.ParentIndex != 0 && BoneInfo.ParentIndex != ParentBoneIndex) + { + BoneTransform *= GetWorldSpaceRefBoneTransform(RefSkel, BoneInfo.ParentIndex, ParentBoneIndex); + } + } + + return BoneTransform; +} + +// #TODO: support off scaling +FTransform UVREPhysicalAnimationComponent::GetRefPoseBoneRelativeTransform(USkeletalMeshComponent* SkeleMesh, FName BoneName, FName ParentBoneName) +{ + FTransform BoneTransform; + + if (SkeleMesh && !BoneName.IsNone() && !ParentBoneName.IsNone()) + { + //SkelMesh->ClearRefPoseOverride(); + FReferenceSkeleton RefSkel; + RefSkel = SkeleMesh->GetSkinnedAsset()->GetRefSkeleton(); + + BoneTransform = GetWorldSpaceRefBoneTransform(RefSkel, RefSkel.FindBoneIndex(BoneName), RefSkel.FindBoneIndex(ParentBoneName)); + } + + return BoneTransform; +} + +void UVREPhysicalAnimationComponent::SetupWeldedBoneDriver_Implementation(bool bReInit) +{ + TArray OriginalData; + if (bReInit) + { + OriginalData = BoneDriverMap; + } + + BoneDriverMap.Empty(); + + USkeletalMeshComponent* SkeleMesh = GetSkeletalMesh(); + + if (!SkeleMesh || !SkeleMesh->Bodies.Num()) + return; + + // Get ref pose position and walk up the tree to the welded root to get our relative base pose. + //SkeleMesh->GetRefPosePosition() + + UPhysicsAsset* PhysAsset = SkeleMesh ? SkeleMesh->GetPhysicsAsset() : nullptr; + if (PhysAsset && SkeleMesh->GetSkinnedAsset()) + { + + for (FName BaseWeldedBoneDriverName : BaseWeldedBoneDriverNames) + { + int32 ParentBodyIdx = PhysAsset->FindBodyIndex(BaseWeldedBoneDriverName); + + if (FBodyInstance* ParentBody = (ParentBodyIdx == INDEX_NONE ? nullptr : SkeleMesh->Bodies[ParentBodyIdx])) + { + // Build map of bodies that we want to control. + FPhysicsActorHandle& ActorHandle = ParentBody->WeldParent ? ParentBody->WeldParent->GetPhysicsActorHandle() : ParentBody->GetPhysicsActorHandle(); + + if (FPhysicsInterface::IsValid(ActorHandle) /*&& FPhysicsInterface::IsRigidBody(ActorHandle)*/) + { + FPhysicsCommand::ExecuteWrite(ActorHandle, [&](FPhysicsActorHandle& Actor) + { + //TArray Shapes; + PhysicsInterfaceTypes::FInlineShapeArray Shapes; + FPhysicsInterface::GetAllShapes_AssumedLocked(Actor, Shapes); + + for (FPhysicsShapeHandle& Shape : Shapes) + { + if (ParentBody->WeldParent) + { + const FBodyInstance* OriginalBI = ParentBody->WeldParent->GetOriginalBodyInstance(Shape); + + if (OriginalBI != ParentBody) + { + // Not originally our shape + continue; + } + } + + FKShapeElem* ShapeElem = FChaosUserData::Get(FPhysicsInterface::GetUserData(Shape)); + if (ShapeElem) + { + FName TargetBoneName = ShapeElem->GetName(); + int32 BoneIdx = SkeleMesh->GetBoneIndex(TargetBoneName); + + if (BoneIdx != INDEX_NONE) + { + FWeldedBoneDriverData DriverData; + DriverData.BoneName = TargetBoneName; + //DriverData.ShapeHandle = Shape; + + if (bReInit && OriginalData.Num() - 1 >= BoneDriverMap.Num()) + { + DriverData.RelativeTransform = OriginalData[BoneDriverMap.Num()].RelativeTransform; + } + else + { + FTransform BoneTransform = FTransform::Identity; + if (SkeleMesh->GetBoneIndex(TargetBoneName) != INDEX_NONE) + BoneTransform = GetRefPoseBoneRelativeTransform(SkeleMesh, TargetBoneName, BaseWeldedBoneDriverName).Inverse(); + + //FTransform BoneTransform = SkeleMesh->GetSocketTransform(TargetBoneName, ERelativeTransformSpace::RTS_World); + + // Calc shape global pose + //FTransform RelativeTM = FPhysicsInterface::GetLocalTransform(Shape) * FPhysicsInterface::GetGlobalPose_AssumesLocked(ActorHandle); + + //RelativeTM = RelativeTM * BoneTransform.Inverse(); + //BoneTransform.SetScale3D(FVector(1.0f)); + DriverData.RelativeTransform = FPhysicsInterface::GetLocalTransform(Shape) * BoneTransform; + } + + BoneDriverMap.Add(DriverData); + } + } + } + + if (bAutoSetPhysicsSleepSensitivity && !ParentBody->WeldParent && BoneDriverMap.Num() > 0) + { + ParentBody->SleepFamily = ESleepFamily::Custom; + ParentBody->CustomSleepThresholdMultiplier = SleepThresholdMultiplier; + float SleepEnergyThresh = FPhysicsInterface::GetSleepEnergyThreshold_AssumesLocked(Actor); + SleepEnergyThresh *= ParentBody->GetSleepThresholdMultiplier(); + FPhysicsInterface::SetSleepEnergyThreshold_AssumesLocked(Actor, SleepEnergyThresh); + } + }); + } + } + } + } +} + +void UVREPhysicalAnimationComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) +{ + // Make sure base physical animation component runs its logic + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + UpdateWeldedBoneDriver(DeltaTime); +} + +void UVREPhysicalAnimationComponent::UpdateWeldedBoneDriver(float DeltaTime) +{ + if (!BoneDriverMap.Num()) + return; + + USkeletalMeshComponent* SkeleMesh = GetSkeletalMesh(); + + if (!SkeleMesh || !SkeleMesh->Bodies.Num())// || (!SkeleMesh->IsSimulatingPhysics(BaseWeldedBoneDriverNames) && !SkeleMesh->IsWelded())) + return; + + UPhysicsAsset* PhysAsset = SkeleMesh ? SkeleMesh->GetPhysicsAsset() : nullptr; + if(PhysAsset && SkeleMesh->GetSkinnedAsset()) + { + for (FName BaseWeldedBoneDriverName : BaseWeldedBoneDriverNames) + { + int32 ParentBodyIdx = PhysAsset->FindBodyIndex(BaseWeldedBoneDriverName); + + if (FBodyInstance* ParentBody = (ParentBodyIdx == INDEX_NONE ? nullptr : SkeleMesh->Bodies[ParentBodyIdx])) + { + // Allow it to run even when not simulating physics, if we have a welded root then it needs to animate anyway + //if (!ParentBody->IsInstanceSimulatingPhysics() && !ParentBody->WeldParent) + // return; + + FPhysicsActorHandle& ActorHandle = ParentBody->WeldParent ? ParentBody->WeldParent->GetPhysicsActorHandle() : ParentBody->GetPhysicsActorHandle(); + + if (FPhysicsInterface::IsValid(ActorHandle) /*&& FPhysicsInterface::IsRigidBody(ActorHandle)*/) + { + +#if UE_ENABLE_DEBUG_DRAWING + if (false)//bDebugDrawCollision) + { + Chaos::FDebugDrawQueue::GetInstance().SetConsumerActive(this, true); // Need to deactivate this later as well + Chaos::FDebugDrawQueue::GetInstance().SetMaxCost(20000); + //Chaos::FDebugDrawQueue::GetInstance().SetRegionOfInterest(SkeleMesh->GetComponentLocation(), 1000.0f); + Chaos::FDebugDrawQueue::GetInstance().SetEnabled(true); + } +#endif + + bool bModifiedBody = false; + FPhysicsCommand::ExecuteWrite(ActorHandle, [&](FPhysicsActorHandle& Actor) + { + PhysicsInterfaceTypes::FInlineShapeArray Shapes; + FPhysicsInterface::GetAllShapes_AssumedLocked(Actor, Shapes); + + FTransform GlobalPose = FPhysicsInterface::GetGlobalPose_AssumesLocked(ActorHandle); + FTransform GlobalPoseInv = GlobalPose.Inverse(); + + +#if UE_ENABLE_DEBUG_DRAWING + if (false)//bDebugDrawCollision) + { + Chaos::FDebugDrawQueue::GetInstance().SetRegionOfInterest(GlobalPose.GetLocation(), 100.0f); + } + +#endif + + for (FPhysicsShapeHandle& Shape : Shapes) + { + if (ParentBody->WeldParent) + { + const FBodyInstance* OriginalBI = ParentBody->WeldParent->GetOriginalBodyInstance(Shape); + + if (OriginalBI != ParentBody) + { + // Not originally our shape + continue; + } + } + + // Log the shapes name to match to the bone + FName TargetBoneName = NAME_None; + if (FKShapeElem* ShapeElem = FChaosUserData::Get(FPhysicsInterface::GetUserData(Shape))) + { + TargetBoneName = ShapeElem->GetName(); + } + else + { + // Cant find the matching shape + continue; + } + + if (FWeldedBoneDriverData* WeldedData = BoneDriverMap.FindByKey(TargetBoneName/*Shape*/)) + { + bModifiedBody = true; + + FTransform Trans = SkeleMesh->GetSocketTransform(WeldedData->BoneName, ERelativeTransformSpace::RTS_World); + + // This fixes a bug with simulating inverse scaled meshes + //Trans.SetScale3D(FVector(1.f) * Trans.GetScale3D().GetSignVector()); + FTransform GlobalTransform = WeldedData->RelativeTransform * Trans; + FTransform RelativeTM = GlobalTransform * GlobalPoseInv; + + // Fix chaos ensure + RelativeTM.RemoveScaling(); + + if (!WeldedData->LastLocal.Equals(RelativeTM)) + { + FPhysicsInterface::SetLocalTransform(Shape, RelativeTM); + WeldedData->LastLocal = RelativeTM; + } + } + +#if UE_ENABLE_DEBUG_DRAWING + if (false)//bDebugDrawCollision) + { + /*const Chaos::FImplicitObject& ShapeImplicit = Shape.GetGeometry(); + Chaos::EImplicitObjectType Type = ShapeImplicit.GetType(); + + FTransform shapeTransform = FPhysicsInterface::GetLocalTransform(Shape); + FTransform FinalTransform = shapeTransform * GlobalPose; + Chaos::FRigidTransform3 RigTransform(FinalTransform); + Chaos::DebugDraw::DrawShape(RigTransform, &ShapeImplicit, Shape.Shape, FColor::White);*/ + } +#endif + } + }); + +#if UE_ENABLE_DEBUG_DRAWING + if (false)//bDebugDrawCollision) + { + // Get the latest commands + /*TArray DrawCommands; + Chaos::FDebugDrawQueue::GetInstance().ExtractAllElements(DrawCommands); + if (DrawCommands.Num()) + { + DebugDrawMesh(DrawCommands); + } + Chaos::FDebugDrawQueue::GetInstance().SetConsumerActive(this, false); // Need to deactivate this later as well + Chaos::FDebugDrawQueue::GetInstance().SetEnabled(false);*/ + } +#endif + } + + } + } + } +} + +#if UE_ENABLE_DEBUG_DRAWING +/* +void UVREPhysicalAnimationComponent::DebugDrawMesh(const TArray& DrawCommands) +{ + UWorld* World = this->GetWorld(); + + // Draw all the captured elements in the viewport + for (const Chaos::FLatentDrawCommand& Command : DrawCommands) + { + switch (Command.Type) + { + case Chaos::FLatentDrawCommand::EDrawType::Point: + DrawDebugPoint(World, Command.LineStart, Command.Thickness, Command.Color, Command.bPersistentLines, -1.f, Command.DepthPriority); + break; + case Chaos::FLatentDrawCommand::EDrawType::Line: + DrawDebugLine(World, Command.LineStart, Command.LineEnd, Command.Color, Command.bPersistentLines, -1.0f, 0.f, 0.f); + break; + case Chaos::FLatentDrawCommand::EDrawType::DirectionalArrow: + DrawDebugDirectionalArrow(World, Command.LineStart, Command.LineEnd, Command.ArrowSize, Command.Color, Command.bPersistentLines, -1.f, Command.DepthPriority, Command.Thickness); + break; + case Chaos::FLatentDrawCommand::EDrawType::Sphere: + DrawDebugSphere(World, Command.LineStart, Command.Radius, Command.Segments, Command.Color, Command.bPersistentLines, -1.f, Command.DepthPriority, Command.Thickness); + break; + case Chaos::FLatentDrawCommand::EDrawType::Box: + DrawDebugBox(World, Command.Center, Command.Extent, Command.Rotation, Command.Color, Command.bPersistentLines, -1.f, Command.DepthPriority, Command.Thickness); + break; + case Chaos::FLatentDrawCommand::EDrawType::String: + DrawDebugString(World, Command.TextLocation, Command.Text, Command.TestBaseActor, Command.Color, -1.f, Command.bDrawShadow, Command.FontScale); + break; + case Chaos::FLatentDrawCommand::EDrawType::Circle: + { + FMatrix M = FRotationMatrix::MakeFromYZ(Command.YAxis, Command.ZAxis); + M.SetOrigin(Command.Center); + DrawDebugCircle(World, M, Command.Radius, Command.Segments, Command.Color, Command.bPersistentLines, -1.f, Command.DepthPriority, Command.Thickness, Command.bDrawAxis); + break; + } + case Chaos::FLatentDrawCommand::EDrawType::Capsule: + DrawDebugCapsule(World, Command.Center, Command.HalfHeight, Command.Radius, Command.Rotation, Command.Color, Command.bPersistentLines, -1.f, Command.DepthPriority, Command.Thickness); + default: + break; + } + } +}*/ +#endif \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRFullScreenUserWidget.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRFullScreenUserWidget.cpp new file mode 100644 index 0000000..b9592a2 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRFullScreenUserWidget.cpp @@ -0,0 +1,1251 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "Misc/VRFullScreenUserWidget.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRFullScreenUserWidget) + +//#include "Components/PostProcessComponent.h" +#include "Engine/Engine.h" +#include "Engine/GameInstance.h" +#include "Engine/GameViewportClient.h" +#include "Engine/TextureRenderTarget2D.h" +#include "Engine/UserInterfaceSettings.h" +#include "GameFramework/WorldSettings.h" +#include "Materials/MaterialInstanceDynamic.h" +#include "RenderingThread.h" +#include "RHI.h" +#include "UObject/ConstructorHelpers.h" +#include "UObject/Package.h" +#include "HAL/PlatformApplicationMisc.h" + +#include "Framework/Application/SlateApplication.h" +#include "Input/HittestGrid.h" +#include "Layout/Visibility.h" +#include "Slate/SceneViewport.h" +#include "Slate/WidgetRenderer.h" +#include "Widgets/Layout/SConstraintCanvas.h" +#include "Widgets/Layout/SDPIScaler.h" +#include "Widgets/SViewport.h" + +#include "IXRTrackingSystem.h" +#include "IHeadMountedDisplay.h" + +#if WITH_EDITOR +#include "LevelEditor.h" +#include "Modules/ModuleManager.h" +#include "SLevelViewport.h" +#endif + +#define LOCTEXT_NAMESPACE "VRFullScreenUserWidget" + +///////////////////////////////////////////////////// +// Internal helper +namespace +{ + const FName NAME_LevelEditorName = "LevelEditor"; + //const FName NAME_SlateUI = "SlateUI"; + //const FName NAME_TintColorAndOpacity = "TintColorAndOpacity"; + //const FName NAME_OpacityFromTexture = "OpacityFromTexture"; + + EVisibility ConvertWindowVisibilityToVisibility(EWindowVisibility visibility) + { + switch (visibility) + { + case EWindowVisibility::Visible: + return EVisibility::Visible; + case EWindowVisibility::SelfHitTestInvisible: + return EVisibility::SelfHitTestInvisible; + default: + checkNoEntry(); + return EVisibility::SelfHitTestInvisible; + } + } + + namespace VPVRFullScreenUserWidgetPrivate + { + /** + * Class made to handle world cleanup and hide/cleanup active UserWidget to avoid touching public headers + */ + class FWorldCleanupListener + { + public: + + static FWorldCleanupListener* Get() + { + static FWorldCleanupListener Instance; + return &Instance; + } + + /** Disallow Copying / Moving */ + UE_NONCOPYABLE(FWorldCleanupListener); + + ~FWorldCleanupListener() + { + FWorldDelegates::OnWorldCleanup.RemoveAll(this); + } + + void AddWidget(UVRFullScreenUserWidget* InWidget) + { + WidgetsToHide.AddUnique(InWidget); + } + + void RemoveWidget(UVRFullScreenUserWidget* InWidget) + { + WidgetsToHide.RemoveSingleSwap(InWidget, false); + } + + private: + + FWorldCleanupListener() + { + FWorldDelegates::OnWorldCleanup.AddRaw(this, &FWorldCleanupListener::OnWorldCleanup); + } + + void OnWorldCleanup(UWorld* InWorld, bool bSessionEnded, bool bCleanupResources) + { + for (auto WeakWidgetIter = WidgetsToHide.CreateIterator(); WeakWidgetIter; ++WeakWidgetIter) + { + TWeakObjectPtr& WeakWidget = *WeakWidgetIter; + if (UVRFullScreenUserWidget* Widget = WeakWidget.Get()) + { + if (Widget->IsDisplayed() + && Widget->GetWidget() + && (Widget->GetWidget()->GetWorld() == InWorld)) + { + //Remove first since Hide removes object from the list + WeakWidgetIter.RemoveCurrent(); + Widget->Hide(); + } + } + else + { + WeakWidgetIter.RemoveCurrent(); + } + } + } + + private: + + TArray> WidgetsToHide; + }; + } +} + + +///////////////////////////////////////////////////// +// FVRWidgetPostProcessHitTester +class FVRWidgetPostProcessHitTester : public ICustomHitTestPath +{ +public: + FVRWidgetPostProcessHitTester(UWorld* InWorld, TSharedPtr InSlateWindow, TAttribute GetDPIAttribute) + : World(InWorld) + , VirtualSlateWindow(InSlateWindow) + , GetDPIAttribute(MoveTemp(GetDPIAttribute)) + , WidgetDrawSize(FIntPoint::ZeroValue) + , LastLocalHitLocation(FVector2D::ZeroVector) + {} + + virtual TArray GetBubblePathAndVirtualCursors(const FGeometry& InGeometry, FVector2D DesktopSpaceCoordinate, bool bIgnoreEnabledStatus) const override + { + // Get the list of widget at the requested location. + TArray ArrangedWidgets; + if (TSharedPtr SlateWindowPin = VirtualSlateWindow.Pin()) + { + // For some reason the DPI is not applied correctly so we need to multiply the window's native DPI ourselves. + // This is the setting you'd find in Windows Settings > Display > Scale and layout + // If this bit is skipped, then hovering widgets towards the bottom right will not work + // if system scale is > 100% AND the viewport size is not fixed (default). + const float DPI = GetDPIAttribute.Get(); + const FVector2D LocalMouseCoordinate = DPI * InGeometry.AbsoluteToLocal(DesktopSpaceCoordinate); + + constexpr float CursorRadius = 0.f; + ArrangedWidgets = SlateWindowPin->GetHittestGrid().GetBubblePath(LocalMouseCoordinate, CursorRadius, bIgnoreEnabledStatus); + + const FVirtualPointerPosition VirtualMouseCoordinate(LocalMouseCoordinate, LastLocalHitLocation); + LastLocalHitLocation = LocalMouseCoordinate; + + for (FWidgetAndPointer& ArrangedWidget : ArrangedWidgets) + { + ArrangedWidget.SetPointerPosition(VirtualMouseCoordinate); + } + } + + return ArrangedWidgets; + } + + virtual void ArrangeCustomHitTestChildren(FArrangedChildren& ArrangedChildren) const override + { + // Add the displayed slate to the list of widgets. + if (TSharedPtr SlateWindowPin = VirtualSlateWindow.Pin()) + { + FGeometry WidgetGeom; + ArrangedChildren.AddWidget(FArrangedWidget(SlateWindowPin.ToSharedRef(), WidgetGeom.MakeChild(WidgetDrawSize, FSlateLayoutTransform()))); + } + } + + virtual TOptional TranslateMouseCoordinateForCustomHitTestChild(const SWidget& ChildWidget, const FGeometry& MyGeometry, const FVector2D ScreenSpaceMouseCoordinate, const FVector2D LastScreenSpaceMouseCoordinate) const override + { + return TOptional(); + } + + void SetWidgetDrawSize(FIntPoint NewWidgetDrawSize) + { + WidgetDrawSize = NewWidgetDrawSize; + } + +private: + TWeakObjectPtr World; + TWeakPtr VirtualSlateWindow; + TAttribute GetDPIAttribute; + FIntPoint WidgetDrawSize; + mutable FVector2D LastLocalHitLocation; +}; + +///////////////////////////////////////////////////// +// FVRFullScreenUserWidget_Viewport + +bool FVRFullScreenUserWidget_Viewport::Display(UWorld* World, UUserWidget* Widget, TAttribute InDPIScale) +{ + const TSharedPtr FullScreenWidgetPinned = FullScreenCanvasWidget.Pin(); + if (Widget == nullptr || World == nullptr || FullScreenWidgetPinned.IsValid()) + { + return false; + } + + const TSharedRef FullScreenCanvas = SNew(SConstraintCanvas); + FullScreenCanvas->AddSlot() + .Offset(FMargin(0, 0, 0, 0)) + .Anchors(FAnchors(0, 0, 1, 1)) + .Alignment(FVector2D(0, 0)) + [ + SNew(SDPIScaler) + .DPIScale(MoveTemp(InDPIScale)) + [ + Widget->TakeWidget() + ] + ]; + + UGameViewportClient* ViewportClient = World->GetGameViewport(); + const bool bCanUseGameViewport = ViewportClient && World->IsGameWorld(); + if (bCanUseGameViewport) + { + FullScreenCanvasWidget = FullScreenCanvas; + ViewportClient->AddViewportWidgetContent(FullScreenCanvas); + return true; + } + +#if WITH_EDITOR + + const TSharedPtr PinnedTargetViewport = EditorTargetViewport.Pin(); + for (FLevelEditorViewportClient* Client : GEditor->GetLevelViewportClients()) + { + const TSharedPtr LevelViewport = StaticCastSharedPtr(Client->GetEditorViewportWidget()); + if (LevelViewport.IsValid() && LevelViewport->GetSceneViewport() == PinnedTargetViewport) + { + + LevelViewport->AddOverlayWidget(FullScreenCanvas); + FullScreenCanvasWidget = FullScreenCanvas; + OverlayWidgetLevelViewport = LevelViewport; + return true; + } + + } +#endif + return false; +} + +void FVRFullScreenUserWidget_Viewport::Hide(UWorld* World) +{ + TSharedPtr FullScreenWidgetPinned = FullScreenCanvasWidget.Pin(); + if (FullScreenWidgetPinned.IsValid()) + { + // Remove from Viewport and Fullscreen, in case the settings changed before we had the chance to hide. + UGameViewportClient* ViewportClient = World ? World->GetGameViewport() : nullptr; + if (ViewportClient) + { + ViewportClient->RemoveViewportWidgetContent(FullScreenWidgetPinned.ToSharedRef()); + } + +#if WITH_EDITOR + if (const TSharedPtr OverlayWidgetLevelViewportPinned = OverlayWidgetLevelViewport.Pin()) + { + OverlayWidgetLevelViewportPinned->RemoveOverlayWidget(FullScreenWidgetPinned.ToSharedRef()); + } + OverlayWidgetLevelViewport.Reset(); +#endif + + FullScreenCanvasWidget.Reset(); + } +} + +///////////////////////////////////////////////////// +// FVRFullScreenUserWidget_PostProcess + +FVRFullScreenUserWidget_PostProcess::FVRFullScreenUserWidget_PostProcess() + :// PostProcessMaterial(nullptr) + //, PostProcessTintColorAndOpacity(FLinearColor::White) + //, PostProcessOpacityFromTexture(1.0f) + bWidgetDrawSize(false) + , WidgetDrawSize(FIntPoint(640, 360)) + , bWindowFocusable(true) + , WindowVisibility(EWindowVisibility::SelfHitTestInvisible) + , bReceiveHardwareInput(true) + , RenderTargetBackgroundColor(FLinearColor(0.0f, 0.0f, 0.0f, 1.0f)) + , RenderTargetBlendMode(EWidgetBlendMode::Masked) + , WidgetRenderTarget(nullptr) + //, PostProcessComponent(nullptr) + //, PostProcessMaterialInstance(nullptr) + , WidgetRenderer(nullptr) + , CurrentWidgetDrawSize(FIntPoint::ZeroValue) +{ + bRenderToTextureOnly = true; + bDrawToVRPreview = true; + VRDisplayType = ESpectatorScreenMode::TexturePlusEye; + PostVRDisplayType = ESpectatorScreenMode::SingleEye; +} + +bool FVRFullScreenUserWidget_PostProcess::Display(UWorld* World, UUserWidget* Widget, bool bInRenderToTextureOnly, TAttribute InDPIScale) +{ + TAttribute PostProcessDPIScale = 1.0f; + bool bOk = CreateRenderer(World, Widget, MoveTemp(PostProcessDPIScale)); + + if (bRenderToTextureOnly && IsValid(WidgetRenderTarget) && bDrawToVRPreview) + { + IHeadMountedDisplay* HMD = GEngine->XRSystem.IsValid() ? GEngine->XRSystem->GetHMDDevice() : nullptr; + ISpectatorScreenController* Controller = nullptr; + if (HMD) + { + Controller = HMD->GetSpectatorScreenController(); + } + + if (Controller) + { + if (VRDisplayType == ESpectatorScreenMode::TexturePlusEye) + { + if (Controller->GetSpectatorScreenMode() != ESpectatorScreenMode::TexturePlusEye) + { + Controller->SetSpectatorScreenMode(ESpectatorScreenMode::TexturePlusEye); + } + + FSpectatorScreenModeTexturePlusEyeLayout Layout; + Layout.bClearBlack = true; + Layout.bDrawEyeFirst = true; + Layout.bUseAlpha = true; + Layout.EyeRectMin = FVector2D(0.f, 0.f); + Layout.EyeRectMax = FVector2D(1.f, 1.f); + Layout.TextureRectMin = FVector2D(0.f, 0.f); + Layout.TextureRectMax = FVector2D(1.f, 1.f); + Controller->SetSpectatorScreenModeTexturePlusEyeLayout(Layout); + Controller->SetSpectatorScreenTexture(WidgetRenderTarget); + } + else if (VRDisplayType == ESpectatorScreenMode::Texture) + { + if (Controller->GetSpectatorScreenMode() != ESpectatorScreenMode::TexturePlusEye) + { + Controller->SetSpectatorScreenMode(ESpectatorScreenMode::Texture); + } + + Controller->SetSpectatorScreenTexture(WidgetRenderTarget); + } + } + } + + if (!bRenderToTextureOnly) + { + //bOk &= CreatePostProcessComponent(World); + } + + return bOk; +} + +void FVRFullScreenUserWidget_PostProcess::Hide(UWorld* World) +{ + if (!bRenderToTextureOnly) + { + //ReleasePostProcessComponent(); + } + + if (bRenderToTextureOnly && bDrawToVRPreview) + { + IHeadMountedDisplay* HMD = GEngine->XRSystem.IsValid() ? GEngine->XRSystem->GetHMDDevice() : nullptr; + ISpectatorScreenController* Controller = nullptr; + if (HMD) + { + Controller = HMD->GetSpectatorScreenController(); + } + + if (Controller) + { + if (Controller->GetSpectatorScreenMode() == ESpectatorScreenMode::TexturePlusEye || Controller->GetSpectatorScreenMode() == ESpectatorScreenMode::Texture) + { + Controller->SetSpectatorScreenMode(PostVRDisplayType); + Controller->SetSpectatorScreenTexture(nullptr); + } + } + } + + ReleaseRenderer(); +} + +void FVRFullScreenUserWidget_PostProcess::Tick(UWorld* World, float DeltaSeconds) +{ + TickRenderer(World, DeltaSeconds); +} + +TSharedPtr FVRFullScreenUserWidget_PostProcess::GetSlateWindow() const +{ + return SlateWindow; +} + +/*bool FVRFullScreenUserWidget_PostProcess::CreatePostProcessComponent(UWorld* World) +{ + ReleasePostProcessComponent(); + if (World && PostProcessMaterial) + { + AWorldSettings* WorldSetting = World->GetWorldSettings(); + PostProcessComponent = NewObject(WorldSetting, NAME_None, RF_Transient); + PostProcessComponent->bEnabled = true; + PostProcessComponent->bUnbound = true; + PostProcessComponent->RegisterComponent(); + + PostProcessMaterialInstance = UMaterialInstanceDynamic::Create(PostProcessMaterial, World); + + // set the parameter immediately + PostProcessMaterialInstance->SetTextureParameterValue(NAME_SlateUI, WidgetRenderTarget); + PostProcessMaterialInstance->SetVectorParameterValue(NAME_TintColorAndOpacity, PostProcessTintColorAndOpacity); + PostProcessMaterialInstance->SetScalarParameterValue(NAME_OpacityFromTexture, PostProcessOpacityFromTexture); + + PostProcessComponent->Settings.WeightedBlendables.Array.SetNumZeroed(1); + PostProcessComponent->Settings.WeightedBlendables.Array[0].Weight = 1.f; + PostProcessComponent->Settings.WeightedBlendables.Array[0].Object = PostProcessMaterialInstance; + } + + return PostProcessComponent && PostProcessMaterialInstance; +}*/ + +/*void FVRFullScreenUserWidget_PostProcess::ReleasePostProcessComponent() +{ + if (PostProcessComponent) + { + PostProcessComponent->UnregisterComponent(); + } + PostProcessComponent = nullptr; + PostProcessMaterialInstance = nullptr; +}*/ + +bool FVRFullScreenUserWidget_PostProcess::CreateRenderer(UWorld* World, UUserWidget* Widget, TAttribute InDPIScale) +{ + ReleaseRenderer(); + + if (World && Widget) + { + constexpr bool bApplyGammaCorrection = true; + WidgetRenderer = new FWidgetRenderer(bApplyGammaCorrection); + WidgetRenderer->SetIsPrepassNeeded(true); + + // CalculateWidgetDrawSize may sometimes return {0,0}, e.g. right after engine startup when viewport not yet initialized. + // TickRenderer will call Resize automatically once CurrentWidgetDrawSize is updated to be non-zero. + checkf(CurrentWidgetDrawSize == FIntPoint::ZeroValue, TEXT("Expected ReleaseRenderer to reset CurrentWidgetDrawSize.")); + SlateWindow = SNew(SVirtualWindow).Size(CurrentWidgetDrawSize); + SlateWindow->SetIsFocusable(bWindowFocusable); + SlateWindow->SetVisibility(ConvertWindowVisibilityToVisibility(WindowVisibility)); + SlateWindow->SetContent( + + SNew(SDPIScaler) + .DPIScale(InDPIScale) + [ + Widget->TakeWidget() + ] + ); + + RegisterHitTesterWithViewport(World); + + if (!Widget->IsDesignTime() && World->IsGameWorld()) + { + UGameInstance* GameInstance = World->GetGameInstance(); + UGameViewportClient* GameViewportClient = GameInstance ? GameInstance->GetGameViewportClient() : nullptr; + if (GameViewportClient) + { + SlateWindow->AssignParentWidget(GameViewportClient->GetGameViewportWidget()); + } + } + + FLinearColor ActualBackgroundColor = RenderTargetBackgroundColor; + switch (RenderTargetBlendMode) + { + case EWidgetBlendMode::Opaque: + ActualBackgroundColor.A = 1.0f; + break; + case EWidgetBlendMode::Masked: + ActualBackgroundColor.A = 0.0f; + break; + } + + // Skip InitCustomFormat call because CalculateWidgetDrawSize may sometimes return {0,0}, e.g. right after engine startup when viewport not yet initialized + // TickRenderer will call InitCustomFormat automatically once CurrentWidgetDrawSize is updated to be non-zero. + checkf(CurrentWidgetDrawSize == FIntPoint::ZeroValue, TEXT("Expected ReleaseRenderer to reset CurrentWidgetDrawSize.")); + // Outer needs to be transient package: otherwise we cause a world memory leak using "Save Current Level As" due to reference not getting replaced correctly + WidgetRenderTarget = NewObject(GetTransientPackage(), NAME_None, RF_Transient); + WidgetRenderTarget->ClearColor = ActualBackgroundColor; + } + + return WidgetRenderer && WidgetRenderTarget; +} + +void FVRFullScreenUserWidget_PostProcess::ReleaseRenderer() +{ + if (WidgetRenderer) + { + BeginCleanup(WidgetRenderer); + WidgetRenderer = nullptr; + } + UnRegisterHitTesterWithViewport(); + + SlateWindow.Reset(); + WidgetRenderTarget = nullptr; + CurrentWidgetDrawSize = FIntPoint::ZeroValue; +} + +void FVRFullScreenUserWidget_PostProcess::TickRenderer(UWorld* World, float DeltaSeconds) +{ + check(World); + if (IsValid(WidgetRenderTarget)) + { + + if (bRenderToTextureOnly && bDrawToVRPreview) + { + IHeadMountedDisplay* HMD = GEngine->XRSystem.IsValid() ? GEngine->XRSystem->GetHMDDevice() : nullptr; + ISpectatorScreenController* Controller = nullptr; + if (HMD) + { + Controller = HMD->GetSpectatorScreenController(); + } + + if (Controller) + { + if (Controller->GetSpectatorScreenMode() != ESpectatorScreenMode::TexturePlusEye) + { + Controller->SetSpectatorScreenMode(ESpectatorScreenMode::TexturePlusEye); + FSpectatorScreenModeTexturePlusEyeLayout Layout; + Layout.bClearBlack = true; + Layout.bDrawEyeFirst = true; + Layout.bUseAlpha = true; + Layout.EyeRectMin = FVector2D(0.f, 0.f); + Layout.EyeRectMax = FVector2D(1.f, 1.f); + Layout.TextureRectMin = FVector2D(0.f, 0.f); + Layout.TextureRectMax = FVector2D(1.f, 1.f); + Controller->SetSpectatorScreenModeTexturePlusEyeLayout(Layout); + Controller->SetSpectatorScreenTexture(WidgetRenderTarget); + } + } + } + + const float DrawScale = 1.0f; + + const FIntPoint NewCalculatedWidgetSize = CalculateWidgetDrawSize(World); + if (NewCalculatedWidgetSize != CurrentWidgetDrawSize) + { + if (IsTextureSizeValid(NewCalculatedWidgetSize)) + { + CurrentWidgetDrawSize = NewCalculatedWidgetSize; + WidgetRenderTarget->InitCustomFormat(CurrentWidgetDrawSize.X, CurrentWidgetDrawSize.Y, PF_B8G8R8A8, false); + WidgetRenderTarget->UpdateResourceImmediate(); + SlateWindow->Resize(CurrentWidgetDrawSize); + if (CustomHitTestPath) + { + CustomHitTestPath->SetWidgetDrawSize(CurrentWidgetDrawSize); + } + } + else + { + Hide(World); + } + } + + if (WidgetRenderer && CurrentWidgetDrawSize != FIntPoint::ZeroValue) + { + WidgetRenderer->DrawWindow( + WidgetRenderTarget, + SlateWindow->GetHittestGrid(), + SlateWindow.ToSharedRef(), + DrawScale, + CurrentWidgetDrawSize, + DeltaSeconds); + } + } +} + +FIntPoint FVRFullScreenUserWidget_PostProcess::CalculateWidgetDrawSize(UWorld* World) +{ + if (bWidgetDrawSize) + { + return WidgetDrawSize; + } + + if (World->WorldType == EWorldType::Game || World->WorldType == EWorldType::PIE) + { + if (UGameViewportClient* ViewportClient = World->GetGameViewport()) + { + // The viewport maybe resizing or not yet initialized. + // See TickRenderer(), it will be resize on the next tick to the proper size. + // We initialized all the rendering with an small size. + + const float SmallWidgetSize = 16.f; + FVector2D OutSize = FVector2D(SmallWidgetSize, SmallWidgetSize); + OutSize = ViewportClient->GetWindow()->GetSizeInScreen(); //ViewportClient->GetViewportSize(OutSize); + if (OutSize.X < UE_SMALL_NUMBER) + { + OutSize = FVector2D(SmallWidgetSize, SmallWidgetSize); + } + return OutSize.IntPoint(); + } + + return FIntPoint::ZeroValue; + } +#if WITH_EDITOR + + if (const TSharedPtr SharedActiveViewport = EditorTargetViewport.Pin()) + { + return SharedActiveViewport->GetSize(); + } + //UE_LOG(LogVPUtilities, Warning, TEXT("CalculateWidgetDrawSize failed for editor world.")); +#endif + + return FIntPoint::ZeroValue; +} + +bool FVRFullScreenUserWidget_PostProcess::IsTextureSizeValid(FIntPoint Size) const +{ + const int32 MaxAllowedDrawSize = GetMax2DTextureDimension(); + return Size.X > 0 && Size.Y > 0 && Size.X <= MaxAllowedDrawSize && Size.Y <= MaxAllowedDrawSize; +} + +void FVRFullScreenUserWidget_PostProcess::RegisterHitTesterWithViewport(UWorld* World) +{ + if (!bReceiveHardwareInput && FSlateApplication::IsInitialized()) + { + FSlateApplication::Get().RegisterVirtualWindow(SlateWindow.ToSharedRef()); + } + const TSharedPtr EngineViewportWidget = GetViewport(World); + if (EngineViewportWidget && bReceiveHardwareInput) + { + if (EngineViewportWidget->GetCustomHitTestPath()) + { + //UE_LOG(LogVPUtilities, Warning, TEXT("Can't register a hit tester for FullScreenUserWidget. There is already one defined.")); + } + else + { + ViewportWidget = EngineViewportWidget; + CustomHitTestPath = MakeShared(World, SlateWindow, TAttribute::CreateRaw(this, &FVRFullScreenUserWidget_PostProcess::GetDPIScaleForPostProcessHitTester, TWeakObjectPtr(World))); + CustomHitTestPath->SetWidgetDrawSize(CurrentWidgetDrawSize); + EngineViewportWidget->SetCustomHitTestPath(CustomHitTestPath); + } + } +} + +void FVRFullScreenUserWidget_PostProcess::UnRegisterHitTesterWithViewport() +{ + if (SlateWindow.IsValid() && FSlateApplication::IsInitialized()) + { + FSlateApplication::Get().UnregisterVirtualWindow(SlateWindow.ToSharedRef()); + } + + if (TSharedPtr ViewportWidgetPin = ViewportWidget.Pin()) + { + if (ViewportWidgetPin->GetCustomHitTestPath() == CustomHitTestPath) + { + ViewportWidgetPin->SetCustomHitTestPath(nullptr); + } + } + + ViewportWidget.Reset(); + CustomHitTestPath.Reset(); +} + +TSharedPtr FVRFullScreenUserWidget_PostProcess::GetViewport(UWorld* World) const +{ + if (World->WorldType == EWorldType::Game || World->WorldType == EWorldType::PIE) + { + return GEngine->GetGameViewportWidget(); + } + +#if WITH_EDITOR + if (const TSharedPtr TargetViewportPin = EditorTargetViewport.Pin()) + { + return TargetViewportPin->GetViewportWidget().Pin(); + } +#endif + + return nullptr; +} + +float FVRFullScreenUserWidget_PostProcess::GetDPIScaleForPostProcessHitTester(TWeakObjectPtr World) const +{ + FSceneViewport* Viewport = nullptr; + if (ensure(World.IsValid()) && World->IsGameWorld()) + { + UGameViewportClient* ViewportClient = World->GetGameViewport(); + Viewport = ensure(ViewportClient) ? ViewportClient->GetGameViewport() : nullptr; + } + +#if WITH_EDITOR + const TSharedPtr ViewportPin = EditorTargetViewport.Pin(); + Viewport = Viewport ? Viewport : ViewportPin.Get(); +#endif + + const bool bCanScale = Viewport && !Viewport->HasFixedSize(); + if (!bCanScale) + { + return 1.f; + } + + // For some reason the DPI is not applied correctly when the viewport has a fixed size and the system scale is > 100%. + // This is the setting you'd find in Windows Settings > Display > Scale and layout + // If this bit is skipped, then hovering widgets towards the bottom right will not work + // if system scale is > 100% AND the viewport size is not fixed (default). + const TSharedPtr ViewportWindow = Viewport->FindWindow(); + return ViewportWindow ? ViewportWindow->GetDPIScaleFactor() : 1.f; +} + + +///////////////////////////////////////////////////// +// UVRFullScreenUserWidget + +UVRFullScreenUserWidget::UVRFullScreenUserWidget(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , CurrentDisplayType(EVRWidgetDisplayType::Inactive) + , bDisplayRequested(false) +{ + //Material'/VRExpansionPlugin/Materials/VRWidgetPostProcessMaterial.WidgetPostProcessMaterial' + //static ConstructorHelpers::FObjectFinder PostProcessMaterial_Finder(TEXT("/VRExpansionPlugin/Materials/VRWidgetPostProcessMaterial")); + //PostProcessDisplayType.PostProcessMaterial = PostProcessMaterial_Finder.Object; +} + +void UVRFullScreenUserWidget::BeginDestroy() +{ + Hide(); + Super::BeginDestroy(); +} + +bool UVRFullScreenUserWidget::ShouldDisplay(UWorld* InWorld) const +{ +#if UE_SERVER + return false; +#else + if (GUsingNullRHI || HasAnyFlags(RF_ArchetypeObject | RF_ClassDefaultObject) || IsRunningDedicatedServer()) + { + return false; + } + + return GetDisplayType(InWorld) != EVRWidgetDisplayType::Inactive; +#endif //!UE_SERVER +} + +EVRWidgetDisplayType UVRFullScreenUserWidget::GetDisplayType(UWorld* InWorld) const +{ + if (InWorld) + { + if (InWorld->WorldType == EWorldType::Game) + { + return GameDisplayType; + } +#if WITH_EDITOR + else if (InWorld->WorldType == EWorldType::PIE) + { + return PIEDisplayType; + } + else if (InWorld->WorldType == EWorldType::Editor) + { + return EditorDisplayType; + } +#endif // WITH_EDITOR + } + return EVRWidgetDisplayType::Inactive; +} + +bool UVRFullScreenUserWidget::IsDisplayed() const +{ + return CurrentDisplayType != EVRWidgetDisplayType::Inactive; +} + +bool UVRFullScreenUserWidget::Display(UWorld* InWorld) +{ + bDisplayRequested = true; + World = InWorld; + +#if WITH_EDITOR + if (!EditorTargetViewport.IsValid() && !World->IsGameWorld()) + { + //UE_LOG(LogVPUtilities, Log, TEXT("No TargetViewport set. Defaulting to FLevelEditorModule::GetFirstActiveLevelViewport.")) + if (FModuleManager::Get().IsModuleLoaded(NAME_LevelEditorName)) + { + FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked(NAME_LevelEditorName); + const TSharedPtr ActiveLevelViewport = LevelEditorModule.GetFirstActiveLevelViewport(); + EditorTargetViewport = ActiveLevelViewport ? ActiveLevelViewport->GetSharedActiveViewport() : nullptr; + } + + if (!EditorTargetViewport.IsValid()) + { + //UE_LOG(LogVPUtilities, Error, TEXT("FLevelEditorModule::GetFirstActiveLevelViewport found no level viewport. UVPFullScreenUserWidget will not display.")) + return false; + } + } + + // Make sure that each display type has also received the EditorTargetViewport + SetEditorTargetViewport(EditorTargetViewport); +#endif + + bool bWasAdded = false; + if (InWorld && WidgetClass && ShouldDisplay(InWorld) && CurrentDisplayType == EVRWidgetDisplayType::Inactive) + { + const bool bCreatedWidget = InitWidget(); + if (!bCreatedWidget) + { + //UE_LOG(LogVPUtilities, Error, TEXT("Failed to create subwidget for UVPFullScreenUserWidget.")); + return false; + } + + CurrentDisplayType = GetDisplayType(InWorld); + + TAttribute GetDpiScaleAttribute = TAttribute::CreateLambda([WeakThis = TWeakObjectPtr(this)]() + { + return WeakThis.IsValid() ? WeakThis->GetViewportDPIScale() : 1.f; + + }); + + if (CurrentDisplayType == EVRWidgetDisplayType::Viewport) + { + bWasAdded = ViewportDisplayType.Display(InWorld, Widget, MoveTemp(GetDpiScaleAttribute)); + } + else if (CurrentDisplayType == EVRWidgetDisplayType::PostProcess /*|| (CurrentDisplayType == EVRWidgetDisplayType::Composure)*/) + { + bWasAdded = PostProcessDisplayType.Display(InWorld, Widget, /*(CurrentDisplayType == EVPWidgetDisplayType::Composure)*/true, MoveTemp(GetDpiScaleAttribute)); + } + + if (bWasAdded) + { + FWorldDelegates::LevelRemovedFromWorld.AddUObject(this, &UVRFullScreenUserWidget::OnLevelRemovedFromWorld); + FWorldDelegates::OnWorldCleanup.AddUObject(this, &UVRFullScreenUserWidget::OnWorldCleanup); + VPVRFullScreenUserWidgetPrivate::FWorldCleanupListener::Get()->AddWidget(this); + + // If we are using Composure as our output, then send the WidgetRenderTarget to each one + /*if (CurrentDisplayType == EVRWidgetDisplayType::Composure) + { + static const FString TextureCompClassName("BP_TextureRTCompElement_C"); + static const FName TextureInputPropertyName("TextureRTInput"); + + for (ACompositingElement* Layer : PostProcessDisplayType.ComposureLayerTargets) + { + if (Layer && (Layer->GetClass()->GetName() == TextureCompClassName)) + { + FProperty* TextureInputProperty = Layer->GetClass()->FindPropertyByName(TextureInputPropertyName); + if (TextureInputProperty) + { + FObjectProperty* TextureInputObjectProperty = CastField(TextureInputProperty); + if (TextureInputObjectProperty) + { + UTextureRenderTarget2D** DestTextureRT2D = TextureInputProperty->ContainerPtrToValuePtr(Layer); + if (DestTextureRT2D) + { + TextureInputObjectProperty->SetObjectPropertyValue(DestTextureRT2D, PostProcessDisplayType.WidgetRenderTarget); + Layer->RerunConstructionScripts(); + } + } + } + } + else if (Layer) + { + UE_LOG(LogVPUtilities, Warning, TEXT("VRFullScreenUserWidget - ComposureLayerTarget entry '%s' is not the correct class '%s'"), *Layer->GetName(), *TextureCompClassName); + } + } + }*/ + } + } + + return bWasAdded; +} + +void UVRFullScreenUserWidget::Hide() +{ + bDisplayRequested = false; + + if (CurrentDisplayType != EVRWidgetDisplayType::Inactive) + { + ReleaseWidget(); + + if (CurrentDisplayType == EVRWidgetDisplayType::Viewport) + { + ViewportDisplayType.Hide(World.Get()); + } + else if (CurrentDisplayType == EVRWidgetDisplayType::PostProcess /*|| (CurrentDisplayType == EVRWidgetDisplayType::Composure)*/) + { + PostProcessDisplayType.Hide(World.Get()); + } + CurrentDisplayType = EVRWidgetDisplayType::Inactive; + } + + FWorldDelegates::LevelRemovedFromWorld.RemoveAll(this); + FWorldDelegates::OnWorldCleanup.RemoveAll(this); + VPVRFullScreenUserWidgetPrivate::FWorldCleanupListener::Get()->RemoveWidget(this); + World.Reset(); +} + +void UVRFullScreenUserWidget::Tick(float DeltaSeconds) +{ + if (CurrentDisplayType != EVRWidgetDisplayType::Inactive) + { + UWorld* CurrentWorld = World.Get(); + if (CurrentWorld == nullptr) + { + Hide(); + } + else if (CurrentDisplayType == EVRWidgetDisplayType::PostProcess /* || (CurrentDisplayType == EVPWidgetDisplayType::Composure)*/) + { + PostProcessDisplayType.Tick(CurrentWorld, DeltaSeconds); + } + } +} + +void UVRFullScreenUserWidget::SetDisplayTypes(EVRWidgetDisplayType InEditorDisplayType, EVRWidgetDisplayType InGameDisplayType, EVRWidgetDisplayType InPIEDisplayType) +{ + EditorDisplayType = InEditorDisplayType; + GameDisplayType = InGameDisplayType; + PIEDisplayType = InPIEDisplayType; +} + +void UVRFullScreenUserWidget::SetOverrideWidget(UUserWidget* InWidget) +{ + if (ensureMsgf(!IsDisplayed(), TEXT("For simplicity of API you can only override the widget before displaying."))) + { + Widget = InWidget; + } +} + +#if WITH_EDITOR +void UVRFullScreenUserWidget::SetEditorTargetViewport(TWeakPtr InTargetViewport) +{ + EditorTargetViewport = InTargetViewport; + ViewportDisplayType.EditorTargetViewport = InTargetViewport; + PostProcessDisplayType.EditorTargetViewport = InTargetViewport; +} + +void UVRFullScreenUserWidget::ResetEditorTargetViewport() +{ + EditorTargetViewport.Reset(); + ViewportDisplayType.EditorTargetViewport.Reset(); + PostProcessDisplayType.EditorTargetViewport.Reset(); +} +#endif + +bool UVRFullScreenUserWidget::InitWidget() +{ + const bool bCanCreate = !Widget && WidgetClass && ensure(World.Get()) && FSlateApplication::IsInitialized(); + if (!bCanCreate) + { + return false; + } + + // Could fail e.g. if the class has been marked deprecated or abstract. + Widget = CreateWidget(World.Get(), WidgetClass); + //UE_CLOG(!Widget, LogVPUtilities, Warning, TEXT("Failed to create widget with class %s. Review the log for more info."), *WidgetClass->GetPathName()) + if (Widget) + { + Widget->SetFlags(RF_Transient); + } + + return Widget != nullptr; +} + +void UVRFullScreenUserWidget::ReleaseWidget() +{ + Widget = nullptr; +} + +void UVRFullScreenUserWidget::OnLevelRemovedFromWorld(ULevel* InLevel, UWorld* InWorld) +{ + // If the InLevel is invalid, then the entire world is about to disappear. + //Hide the widget to clear the memory and reference to the world it may hold. + if (InLevel == nullptr && InWorld && InWorld == World.Get()) + { + Hide(); + } +} + +void UVRFullScreenUserWidget::OnWorldCleanup(UWorld* InWorld, bool bSessionEnded, bool bCleanupResources) +{ + + if (IsDisplayed() && World == InWorld) + { + Hide(); + } +} + +FVector2D UVRFullScreenUserWidget::FindSceneViewportSize() +{ + ensure(World.IsValid()); + + const UWorld* CurrentWorld = World.Get(); + const bool bIsPlayWorld = CurrentWorld && (CurrentWorld->WorldType == EWorldType::Game || CurrentWorld->WorldType == EWorldType::PIE); + if (bIsPlayWorld) + { + if (UGameViewportClient* ViewportClient = World->GetGameViewport()) + { + FVector2D OutSize; + ViewportClient->GetViewportSize(OutSize); + return OutSize; + } + } + +#if WITH_EDITOR + + if (const TSharedPtr TargetViewportPin = EditorTargetViewport.Pin()) + { + return TargetViewportPin->GetSize(); + } +#endif + + ensureMsgf(false, TEXT( + "FindSceneViewportSize failed. Likely Hide() was called (making World = nullptr) or EditorTargetViewport " + "reset externally (possibly as part of Hide()). After Hide() is called all widget code should stop calling " + "FindSceneViewportSize. Investigate whether something was not cleaned up correctly!" + ) + ); + return FVector2d::ZeroVector; +} + +float UVRFullScreenUserWidget::GetViewportDPIScale() +{ + float UIScale = 1.0f; + float PlatformScale = FPlatformApplicationMisc::GetDPIScaleFactorAtPoint(10.0f, 10.0f); + + UWorld* CurrentWorld = World.Get(); + if ((CurrentDisplayType == EVRWidgetDisplayType::Viewport) && CurrentWorld && (CurrentWorld->WorldType == EWorldType::Game || CurrentWorld->WorldType == EWorldType::PIE)) + { + // If we are in Game or PIE in Viewport display mode, the GameLayerManager will scale correctly so just return the Platform Scale + UIScale = PlatformScale; + } + else + { + // Otherwise when in Editor mode, the editor automatically scales to the platform size, so we only care about the UI scale + const FIntPoint ViewportSize = FindSceneViewportSize().IntPoint(); + UIScale = GetDefault()->GetDPIScaleBasedOnSize(ViewportSize); + } + + return UIScale; +} + + +#if WITH_EDITOR + +void UVRFullScreenUserWidget::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) +{ + FProperty* Property = PropertyChangedEvent.MemberProperty; + + if (Property && PropertyChangedEvent.ChangeType != EPropertyChangeType::Interactive) + { + static FName NAME_WidgetClass = GET_MEMBER_NAME_CHECKED(UVRFullScreenUserWidget, WidgetClass); + static FName NAME_EditorDisplayType = GET_MEMBER_NAME_CHECKED(UVRFullScreenUserWidget, EditorDisplayType); + //static FName NAME_PostProcessMaterial = GET_MEMBER_NAME_CHECKED(FVRFullScreenUserWidget_PostProcess, PostProcessMaterial); + static FName NAME_WidgetDrawSize = GET_MEMBER_NAME_CHECKED(FVRFullScreenUserWidget_PostProcess, WidgetDrawSize); + static FName NAME_WindowFocusable = GET_MEMBER_NAME_CHECKED(FVRFullScreenUserWidget_PostProcess, bWindowFocusable); + static FName NAME_WindowVisibility = GET_MEMBER_NAME_CHECKED(FVRFullScreenUserWidget_PostProcess, WindowVisibility); + static FName NAME_ReceiveHardwareInput = GET_MEMBER_NAME_CHECKED(FVRFullScreenUserWidget_PostProcess, bReceiveHardwareInput); + static FName NAME_RenderTargetBackgroundColor = GET_MEMBER_NAME_CHECKED(FVRFullScreenUserWidget_PostProcess, RenderTargetBackgroundColor); + static FName NAME_RenderTargetBlendMode = GET_MEMBER_NAME_CHECKED(FVRFullScreenUserWidget_PostProcess, RenderTargetBlendMode); + //static FName NAME_PostProcessTintColorAndOpacity = GET_MEMBER_NAME_CHECKED(FVRFullScreenUserWidget_PostProcess, PostProcessTintColorAndOpacity); + //static FName NAME_PostProcessOpacityFromTexture = GET_MEMBER_NAME_CHECKED(FVRFullScreenUserWidget_PostProcess, PostProcessOpacityFromTexture); + static FName NAME_DrawToVRPreview = GET_MEMBER_NAME_CHECKED(FVRFullScreenUserWidget_PostProcess, bDrawToVRPreview); + static FName NAME_VRDisplayType = GET_MEMBER_NAME_CHECKED(FVRFullScreenUserWidget_PostProcess, VRDisplayType); + static FName NAME_PostVRDisplayType = GET_MEMBER_NAME_CHECKED(FVRFullScreenUserWidget_PostProcess, PostVRDisplayType); + + if (Property->GetFName() == NAME_WidgetClass + || Property->GetFName() == NAME_EditorDisplayType + //|| Property->GetFName() == NAME_PostProcessMaterial + || Property->GetFName() == NAME_WidgetDrawSize + || Property->GetFName() == NAME_WindowFocusable + || Property->GetFName() == NAME_WindowVisibility + || Property->GetFName() == NAME_ReceiveHardwareInput + || Property->GetFName() == NAME_RenderTargetBackgroundColor + || Property->GetFName() == NAME_RenderTargetBlendMode + || Property->GetFName() == NAME_DrawToVRPreview + || Property->GetFName() == NAME_VRDisplayType + || Property->GetFName() == NAME_PostVRDisplayType) + //|| Property->GetFName() == NAME_PostProcessTintColorAndOpacity + //|| Property->GetFName() == NAME_PostProcessOpacityFromTexture) + { + bool bWasRequestedDisplay = bDisplayRequested; + UWorld* CurrentWorld = World.Get(); + Hide(); + if (bWasRequestedDisplay && CurrentWorld) + { + Display(CurrentWorld); + } + } + } + + Super::PostEditChangeProperty(PropertyChangedEvent); +} +#endif + +///////////////////////////////////////////////////// +// AVRFullScreenUserWidgetActor + +AVRFullScreenUserWidgetActor::AVRFullScreenUserWidgetActor(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +#if WITH_EDITOR + , bEditorDisplayRequested(false) +#endif //WITH_EDITOR +{ + ScreenUserWidget = CreateDefaultSubobject(TEXT("ScreenUserWidget")); + + PrimaryActorTick.bCanEverTick = true; + PrimaryActorTick.bStartWithTickEnabled = false; + bAllowTickBeforeBeginPlay = false; + SetActorTickEnabled(false); + //SetHidden(false); + + bShowOnInit = false; +} + +void AVRFullScreenUserWidgetActor::PostInitializeComponents() +{ + Super::PostInitializeComponents(); + +#if WITH_EDITOR + bEditorDisplayRequested = true; +#endif //WITH_EDITOR +} + +void AVRFullScreenUserWidgetActor::PostLoad() +{ + Super::PostLoad(); + +#if WITH_EDITOR + bEditorDisplayRequested = true; +#endif //WITH_EDITOR +} + +void AVRFullScreenUserWidgetActor::PostActorCreated() +{ + Super::PostActorCreated(); + +#if WITH_EDITOR + bEditorDisplayRequested = true; +#endif //WITH_EDITOR +} + +void AVRFullScreenUserWidgetActor::Destroyed() +{ + if (ScreenUserWidget) + { + ScreenUserWidget->Hide(); + } + Super::Destroyed(); +} + +void AVRFullScreenUserWidgetActor::BeginPlay() +{ + if (ScreenUserWidget && bShowOnInit) + { + RequestGameDisplay(); + } + + Super::BeginPlay(); +} + +void AVRFullScreenUserWidgetActor::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + Super::EndPlay(EndPlayReason); + + if (ScreenUserWidget) + { + UWorld* ActorWorld = GetWorld(); + if (ActorWorld && (ActorWorld->WorldType == EWorldType::Game || ActorWorld->WorldType == EWorldType::PIE)) + { + ScreenUserWidget->Hide(); + } + } +} + +void AVRFullScreenUserWidgetActor::Tick(float DeltaSeconds) +{ + Super::Tick(DeltaSeconds); + +#if WITH_EDITOR + if (bEditorDisplayRequested) + { + bEditorDisplayRequested = false; + RequestEditorDisplay(); + } +#endif //WITH_EDITOR + + // Don't tick if not requested + if (ScreenUserWidget && ScreenUserWidget->IsDisplayRequested()) + { + ScreenUserWidget->Tick(DeltaSeconds); + } +} + +void AVRFullScreenUserWidgetActor::RequestEditorDisplay() +{ +#if WITH_EDITOR + UWorld* ActorWorld = GetWorld(); + if (ScreenUserWidget && ActorWorld && ActorWorld->WorldType == EWorldType::Editor) + { + ScreenUserWidget->Display(ActorWorld); + } +#endif //WITH_EDITOR +} + +void AVRFullScreenUserWidgetActor::RequestGameDisplay() +{ + UWorld* ActorWorld = GetWorld(); + if (ScreenUserWidget && ActorWorld && (ActorWorld->WorldType == EWorldType::Game || ActorWorld->WorldType == EWorldType::PIE)) + { + ScreenUserWidget->Display(ActorWorld); + SetActorTickEnabled(true); + } +} + +void AVRFullScreenUserWidgetActor::SetWidgetVisible(bool bIsVisible) +{ + if (ScreenUserWidget) + { + if (!bIsVisible) + { + ScreenUserWidget->Hide(); + SetActorTickEnabled(false); + } + else + { + RequestGameDisplay(); + } + } +} + +UVRFullScreenUserWidget* AVRFullScreenUserWidgetActor::GetPreviewWidgetComp() +{ + return ScreenUserWidget; +} + +UUserWidget* AVRFullScreenUserWidgetActor::GetWidget() +{ + if (ScreenUserWidget) + { + return ScreenUserWidget->GetWidget(); + } + + return nullptr; +} + +UTextureRenderTarget2D* AVRFullScreenUserWidgetActor::GetPostProcessRenderTarget() +{ + if (ScreenUserWidget) + { + return ScreenUserWidget->GetPostProcessRenderTarget(); + } + + return nullptr; +} + + +#undef LOCTEXT_NAMESPACE diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRGameViewportClient.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRGameViewportClient.cpp new file mode 100644 index 0000000..44d9e5a --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRGameViewportClient.cpp @@ -0,0 +1,143 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Misc/VRGameViewportClient.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRGameViewportClient) + +#include "CoreMinimal.h" + + +UVRGameViewportClient::UVRGameViewportClient(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + GameInputMethod = EVRGameInputMethod::GameInput_Default; + bAlsoChangeGamepPadInput = false; +} + +bool UVRGameViewportClient::IsValidGamePadKey(const FKey & InputKey) +{ + if (!bAlsoChangeGamepPadInput) + return false; + + FName KeyCategory = InputKey.GetMenuCategory(); + + return GamepadInputCategories.Contains(KeyCategory); +} + +bool UVRGameViewportClient::EventWindowClosing() +{ + if (BPOnWindowCloseRequested.IsBound()) + { + BPOnWindowCloseRequested.Broadcast(); + } + + if (bIgnoreWindowCloseCommands) + { + return false; + } + + return true; +} + +void UVRGameViewportClient::PostInitProperties() +{ + Super::PostInitProperties(); + + if (GamepadInputCategories.Num() < 1) + { + GamepadInputCategories.Add(FName(TEXT("Gamepad"))); + GamepadInputCategories.Add(FName(TEXT("PS4"))); + GamepadInputCategories.Add(FName(TEXT("XBox One"))); + GamepadInputCategories.Add(FName(TEXT("Touch"))); + GamepadInputCategories.Add(FName(TEXT("Gesture"))); + } + + OnWindowCloseRequested().BindUObject(this, &UVRGameViewportClient::EventWindowClosing); +} + + +bool UVRGameViewportClient::InputKey(const FInputKeyEventArgs& EventArgs) +{ + // Remap the old int32 ControllerId value to the new InputDeviceId + IPlatformInputDeviceMapper& DeviceMapper = IPlatformInputDeviceMapper::Get(); + + // Early out if a gamepad event or ignoring input or is default setup / no GEngine + if(GameInputMethod == EVRGameInputMethod::GameInput_Default || IgnoreInput() || (EventArgs.IsGamepad() && !IsValidGamePadKey(EventArgs.Key))) + return Super::InputKey(EventArgs); + + const int32 NumLocalPlayers = World->GetGameInstance()->GetNumLocalPlayers(); + + // Also early out if number of players is less than 2 + if (NumLocalPlayers < 2) + return Super::InputKey(EventArgs); + + + // Its const so have to copy and send a new one in now that the function signature has changed + FInputKeyEventArgs NewStruct = EventArgs; + + if (GameInputMethod == EVRGameInputMethod::GameInput_KeyboardAndMouseToPlayer2) + { + // keyboard / mouse always go to player 0, so + 1 will be player 2 + NewStruct.ControllerId++; + + FPlatformUserId UserId = PLATFORMUSERID_NONE; + FInputDeviceId DeviceId = INPUTDEVICEID_NONE; + DeviceMapper.RemapControllerIdToPlatformUserAndDevice(NewStruct.ControllerId, UserId, NewStruct.InputDevice); + + return Super::InputKey(NewStruct); + } + else // Shared keyboard and mouse + { + bool bRetVal = false; + for (int32 i = 0; i < NumLocalPlayers; i++) + { + NewStruct.ControllerId = i; + + FPlatformUserId UserId = PLATFORMUSERID_NONE; + FInputDeviceId DeviceId = INPUTDEVICEID_NONE; + DeviceMapper.RemapControllerIdToPlatformUserAndDevice(NewStruct.ControllerId, UserId, NewStruct.InputDevice); + + bRetVal = Super::InputKey(NewStruct) || bRetVal; + } + + return bRetVal; + } +} + +bool UVRGameViewportClient::InputAxis(FViewport* tViewport, FInputDeviceId InputDevice, FKey Key, float Delta, float DeltaTime, int32 NumSamples, bool bGamepad) +{ + // Remap the old int32 ControllerId value to the new InputDeviceId + IPlatformInputDeviceMapper& DeviceMapper = IPlatformInputDeviceMapper::Get(); + + const int32 NumLocalPlayers = World->GetGameInstance()->GetNumLocalPlayers(); + + // Early out if a gamepad or not a mouse event (vr controller) or ignoring input or is default setup / no GEngine + if (((!Key.IsMouseButton() && !bGamepad) || (bGamepad && !IsValidGamePadKey(Key))) || NumLocalPlayers < 2 || GameInputMethod == EVRGameInputMethod::GameInput_Default || IgnoreInput()) + return Super::InputAxis(tViewport, InputDevice, Key, Delta, DeltaTime, NumSamples, bGamepad); + + if (GameInputMethod == EVRGameInputMethod::GameInput_KeyboardAndMouseToPlayer2) + { + // keyboard / mouse always go to player 0, so + 1 will be player 2 + int32 ControllerId = 1; + + FPlatformUserId UserId = PLATFORMUSERID_NONE; + FInputDeviceId DeviceId = INPUTDEVICEID_NONE; + DeviceMapper.RemapControllerIdToPlatformUserAndDevice(ControllerId, UserId, DeviceId); + + return Super::InputAxis(tViewport, DeviceId, Key, Delta, DeltaTime, NumSamples, bGamepad); + } + else // Shared keyboard and mouse + { + bool bRetVal = false; + for (int32 i = 0; i < NumLocalPlayers; i++) + { + FPlatformUserId UserId = PLATFORMUSERID_NONE; + FInputDeviceId DeviceId = INPUTDEVICEID_NONE; + DeviceMapper.RemapControllerIdToPlatformUserAndDevice(i, UserId, DeviceId); + + bRetVal = Super::InputAxis(tViewport, DeviceId, Key, Delta, DeltaTime, NumSamples, bGamepad) || bRetVal; + } + + return bRetVal; + } + +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRLogComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRLogComponent.cpp new file mode 100644 index 0000000..bae8fd7 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRLogComponent.cpp @@ -0,0 +1,205 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Misc/VRLogComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRLogComponent) + +#include "Engine/Engine.h" +#include "GenericPlatform/GenericPlatformInputDeviceMapper.h" +#include "Engine/GameViewportClient.h" +#include "GlobalRenderResources.h" + +//#include "Engine/Engine.h" + +/* Top of File */ +#define LOCTEXT_NAMESPACE "VRLogComponent" + + //============================================================================= +UVRLogComponent::UVRLogComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + PrimaryComponentTick.bCanEverTick = false; + MaxLineLength = 130; + MaxStoredMessages = 10000; +} + +//============================================================================= +UVRLogComponent::~UVRLogComponent() +{ + +} + + +void UVRLogComponent::SetConsoleText(FString Text) +{ + UConsole* ViewportConsole = (GEngine->GameViewport != nullptr) ? GEngine->GameViewport->ViewportConsole : nullptr; + + if (!ViewportConsole) + return; + + // Using append because UpdatePrecompletedInputLine is private and append calls it + ViewportConsole->SetInputText(""); + ViewportConsole->AppendInputText(Text); +} + +void UVRLogComponent::SendKeyEventToConsole(FKey Key, EInputEvent KeyEvent) +{ + UConsole* ViewportConsole = (GEngine->GameViewport != nullptr) ? GEngine->GameViewport->ViewportConsole : nullptr; + + if (!ViewportConsole) + return; + + ViewportConsole->FakeGotoState(FName(TEXT("Typing"))); + ViewportConsole->InputKey(IPlatformInputDeviceMapper::Get().GetDefaultInputDevice(), Key, KeyEvent); + ViewportConsole->FakeGotoState(NAME_None); +} + +void UVRLogComponent::AppendTextToConsole(FString Text, bool bReturnAtEnd) +{ + UConsole* ViewportConsole = (GEngine->GameViewport != nullptr) ? GEngine->GameViewport->ViewportConsole : nullptr; + + if (!ViewportConsole) + return; + + ViewportConsole->AppendInputText(Text); + + if (bReturnAtEnd) + { + ViewportConsole->FakeGotoState(FName(TEXT("Typing"))); + ViewportConsole->InputKey(IPlatformInputDeviceMapper::Get().GetDefaultInputDevice(), EKeys::Enter, EInputEvent::IE_Released); + ViewportConsole->FakeGotoState(NAME_None); + } + +} + +bool UVRLogComponent::DrawConsoleToRenderTarget2D(EBPVRConsoleDrawType DrawType, UTextureRenderTarget2D * Texture, float ScrollOffset, bool bForceDraw) +{ + if (!bForceDraw && DrawType == EBPVRConsoleDrawType::VRConsole_Draw_OutputLogOnly && !OutputLogHistory.bIsDirty) + { + return false; + } + //LastRenderedOutputLogSize + +// check(WorldContextObject); + UWorld* World = GetWorld();//GEngine->GetWorldFromContextObject(WorldContextObject, false); + + if (!World) + return false; + + // Create or find the canvas object to use to render onto the texture. Multiple canvas render target textures can share the same canvas. + UCanvas* Canvas = World->GetCanvasForRenderingToTarget(); + + if (!Canvas) + return false; + + // Create the FCanvas which does the actual rendering. + //const ERHIFeatureLevel::Type FeatureLevel = World != nullptr ? World->FeatureLevel : GMaxRHIFeatureLevel; + FCanvas * RenderCanvas = new FCanvas( + (FRenderTarget*)Texture->GameThread_GetRenderTargetResource(), + nullptr, + World, + World->GetFeatureLevel(), + // Draw immediately so that interleaved SetVectorParameter (etc) function calls work as expected + FCanvas::CDM_ImmediateDrawing); + + Canvas->Init(Texture->GetSurfaceWidth(), Texture->GetSurfaceHeight(), nullptr, RenderCanvas); + Canvas->Update(); + + switch (DrawType) + { + //case EBPVRConsoleDrawType::VRConsole_Draw_ConsoleAndOutputLog: DrawConsole(true, Canvas); DrawOutputLog(true, Canvas); break; + case EBPVRConsoleDrawType::VRConsole_Draw_ConsoleOnly: DrawConsole(false, Canvas); break; + case EBPVRConsoleDrawType::VRConsole_Draw_OutputLogOnly: DrawOutputLog(false, Canvas, ScrollOffset); break; + default: break; + } + + // Clean up and flush the rendering canvas. + Canvas->Canvas = nullptr; + RenderCanvas->Flush_GameThread(); + delete RenderCanvas; + RenderCanvas = nullptr; + + // It renders without this, is it actually required? + // Enqueue the rendering command to copy the freshly rendering texture resource back to the render target RHI + // so that the texture is updated and available for rendering. + /*ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER + ( + CanvasRenderTargetResolveCommand, + FTextureRenderTargetResource*, + RenderTargetResource, + Texture->GameThread_GetRenderTargetResource(), + { + RHICmdList.CopyToResolveTarget(RenderTargetResource->GetRenderTargetTexture(), RenderTargetResource->TextureRHI, true, FResolveParams()); + } + );*/ + + return true; +} + + + +void UVRLogComponent::DrawConsole(bool bLowerHalf, UCanvas* Canvas) +{ + UConsole* ViewportConsole = (GEngine->GameViewport != nullptr) ? GEngine->GameViewport->ViewportConsole : nullptr; + if (!ViewportConsole) + return; + + ViewportConsole->PostRender_Console_Open(Canvas); + +} + +void UVRLogComponent::DrawOutputLog(bool bUpperHalf, UCanvas* Canvas, float ScrollOffset) +{ + UFont* Font = GEngine->GetSmallFont();// GEngine->GetTinyFont();//GEngine->GetSmallFont(); + + // determine the height of the text + float xl, yl; + Canvas->StrLen(Font, TEXT("M"), xl, yl); + float Height = FMath::FloorToFloat(Canvas->ClipY);// *0.75f); + + + // Background + FLinearColor BackgroundColor = FColor::Black.ReinterpretAsLinear(); + BackgroundColor.A = 1.0f; + FCanvasTileItem ConsoleTile(FVector2D(0, 0.0f), GBlackTexture, FVector2D(Canvas->ClipX, Canvas->ClipY), FVector2D(0.0f, 0.0f), FVector2D(1.0f, 1.0f), BackgroundColor); + + // Preserve alpha to allow single-pass composite + ConsoleTile.BlendMode = SE_BLEND_AlphaBlend; + + Canvas->DrawItem(ConsoleTile); + + FCanvasTextItem ConsoleText(FVector2D(0, 0 + Height - 5 - yl), FText::FromString(TEXT("")), Font, FColor::Emerald); + + const TArray< TSharedPtr > LoggedMessages = OutputLogHistory.GetMessages(); + + int32 ScrollPos = 0; + + if(ScrollOffset > 0 && LoggedMessages.Num() > 1) + ScrollPos = FMath::Clamp(FMath::RoundToInt(LoggedMessages.Num() * ScrollOffset ) , 0, LoggedMessages.Num() - 1); + + float Xpos = 0.0f; + float Ypos = 0.0f; + for (int i = LoggedMessages.Num() - (1 + ScrollPos); i >= 0 && Ypos <= Height - yl; i--)//auto &Message : LoggedMessages) + { + switch (LoggedMessages[i]->Verbosity) + { + + case ELogVerbosity::Error: + case ELogVerbosity::Fatal: ConsoleText.SetColor(FLinearColor(0.7f,0.1f,0.1f)); break; + case ELogVerbosity::Warning: ConsoleText.SetColor(FLinearColor(0.5f,0.5f,0.0f)); break; + + case ELogVerbosity::Log: + default: ConsoleText.SetColor(FLinearColor(0.8f,0.8f,0.8f)); + } + + Ypos += yl; + ConsoleText.Text = FText::Format(NSLOCTEXT("VRLogComponent", "ConsoleFormat", "{0}"), FText::FromString(*LoggedMessages[i]->Message)); + Canvas->DrawItem(ConsoleText, 0, Height - Ypos); + } + + OutputLogHistory.bIsDirty = false; +} + + + +#undef LOCTEXT_NAMESPACE +/* Bottom of File */ \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRPlayerStart.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRPlayerStart.cpp new file mode 100644 index 0000000..a4fbddf --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRPlayerStart.cpp @@ -0,0 +1,126 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Misc/VRPlayerStart.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRPlayerStart) + +#include "CoreMinimal.h" +#include "Engine/World.h" +#include "Components/CapsuleComponent.h" +#include "Components/BillboardComponent.h" + + +AVRPlayerStart::AVRPlayerStart(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + VRRootComp = CreateDefaultSubobject(TEXT("VRRootComp")); + VRRootComp->Mobility = EComponentMobility::Static; + RootComponent = VRRootComp; + + UCapsuleComponent * CapsuleComp = GetCapsuleComponent(); + if (CapsuleComp && VRRootComp) + { + CapsuleComp->SetupAttachment(VRRootComp); + CapsuleComp->SetRelativeLocation(FVector(0.f,0.f,CapsuleComp->GetScaledCapsuleHalfHeight())); + } +} + +void AVRPlayerStart::GetSimpleCollisionCylinder(float& CollisionRadius, float& CollisionHalfHeight) const +{ + UCapsuleComponent * CapsuleComp = GetCapsuleComponent(); + if (CapsuleComp != nullptr && CapsuleComp->IsRegistered() && CapsuleComp->IsCollisionEnabled()) + { + // Note: assuming vertical orientation + CapsuleComp->GetScaledCapsuleSize(CollisionRadius, CollisionHalfHeight); + } + else + { + Super::GetSimpleCollisionCylinder(CollisionRadius, CollisionHalfHeight); + } +} +void AVRPlayerStart::FindBase() +{ + if (GetWorld()->HasBegunPlay()) + { + return; + } + if (ShouldBeBased()) + { + UCapsuleComponent * CapsuleComp = GetCapsuleComponent(); + if (!CapsuleComp) + return; + // not using find base, because don't want to fail if LD has navigationpoint slightly interpenetrating floor + FHitResult Hit(1.f); + const float Radius = CapsuleComp->GetScaledCapsuleRadius(); + FVector const CollisionSlice(Radius, Radius, 1.f); + // check for placement + float ScaledHalfHeight = CapsuleComp->GetScaledCapsuleHalfHeight(); + const FVector TraceStart = GetActorLocation() + FVector(0.f, 0.f, ScaledHalfHeight); + const FVector TraceEnd = GetActorLocation() - FVector(0.f, 0.f, 2.f * ScaledHalfHeight); + GetWorld()->SweepSingleByObjectType(Hit, TraceStart, TraceEnd, FQuat::Identity, FCollisionObjectQueryParams(ECC_WorldStatic), FCollisionShape::MakeBox(CollisionSlice), FCollisionQueryParams(SCENE_QUERY_STAT(NavFindBase), false)); + // @fixme, ensure object is on the navmesh? + // if( Hit.Actor != NULL ) + // { + // if (Hit.Normal.Z > Scout->WalkableFloorZ) + // { + // const FVector HitLocation = TraceStart + (TraceEnd - TraceStart) * Hit.Time; + // TeleportTo(HitLocation + FVector(0.f,0.f,CapsuleComponent->GetScaledCapsuleHalfHeight()-2.f), GetActorRotation(), false, true); + // } + // else + // { + // Hit.Actor = NULL; + // } + // } + if (GetGoodSprite()) + { + GetGoodSprite()->SetVisibility(true); + } + if (GetBadSprite()) + { + GetBadSprite()->SetVisibility(false); + } + } +} +void AVRPlayerStart::Validate() +{ + if (ShouldBeBased() && (GetGoodSprite() || GetBadSprite())) + { + UCapsuleComponent * CapsuleComp = GetCapsuleComponent(); + if (!CapsuleComp) + return; + FVector OrigLocation = GetActorLocation(); + const float Radius = CapsuleComp->GetScaledCapsuleRadius(); + FVector const Slice(Radius, Radius, 1.f); + bool bResult = true; + // Check for adjustment + FHitResult Hit(ForceInit); + float ScaledHalfHeight = CapsuleComp->GetScaledCapsuleHalfHeight(); + const FVector TraceStart = GetActorLocation() + FVector(0.f, 0.f, ScaledHalfHeight); + const FVector TraceEnd = GetActorLocation() - FVector(0.f, 0.f, 4.f * ScaledHalfHeight); + GetWorld()->SweepSingleByChannel(Hit, TraceStart, TraceEnd, FQuat::Identity, ECC_Pawn, FCollisionShape::MakeBox(Slice), FCollisionQueryParams(SCENE_QUERY_STAT(NavObjectBase_Validate), false, this)); + if (Hit.bBlockingHit) + { + const FVector HitLocation = TraceStart + (TraceEnd - TraceStart) * Hit.Time; + FVector Dest = HitLocation - FVector(0.f, 0.f, /*CapsuleComponent->GetScaledCapsuleHalfHeight() -*/ 2.f); + // Move actor (TEST ONLY) to see if navigation point moves + TeleportTo(Dest, GetActorRotation(), false, true); + // If only adjustment was down towards the floor, then it is a valid placement + FVector NewLocation = GetActorLocation(); + bResult = (NewLocation.X == OrigLocation.X && + NewLocation.Y == OrigLocation.Y && + NewLocation.Z <= OrigLocation.Z); + // Move actor back to original position + TeleportTo(OrigLocation, GetActorRotation(), false, true); + } + // Update sprites by result + if (GetGoodSprite()) + { + GetGoodSprite()->SetVisibility(bResult); + } + if (GetBadSprite()) + { + GetBadSprite()->SetVisibility(!bResult); + } + } + // Force update of icon + MarkComponentsRenderStateDirty(); +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRRenderTargetManager.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRRenderTargetManager.cpp new file mode 100644 index 0000000..901c0f0 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Misc/VRRenderTargetManager.cpp @@ -0,0 +1,1815 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Misc/VRRenderTargetManager.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRRenderTargetManager) + +#include "Engine/World.h" +#include "GlobalRenderResources.h" +#include "Components/ActorComponent.h" +#include "Kismet/GameplayStatics.h" +#include "GameFramework/Pawn.h" +#include "GameFramework/PlayerState.h" +#include "GameFramework/PlayerController.h" +#include "Engine/TextureRenderTarget2D.h" +#include "Engine/Texture2D.h" +#include "TextureResource.h" +#include "PixelFormat.h" +#include "CanvasTypes.h" +#include "Kismet/KismetMathLibrary.h" +#include "Kismet/KismetRenderingLibrary.h" +#include "Engine/CanvasRenderTarget2D.h" +#include "Engine/Canvas.h" +#include "GeomTools.h" +#include "Serialization/ArchiveSaveCompressedProxy.h" +#include "Serialization/ArchiveLoadCompressedProxy.h" +#include "Materials/Material.h" +#include "Net/UnrealNetwork.h" + +namespace RLE_Funcs +{ + enum RLE_Flags + { + RLE_CompressedByte = 1, + RLE_CompressedShort = 2, + RLE_Compressed24 = 3, + RLE_NotCompressedByte = 4, + RLE_NotCompressedShort = 5, + RLE_NotCompressed24 = 6, + //RLE_Empty = 3, + //RLE_AllSame = 4, + RLE_ContinueRunByte = 7, + RLE_ContinueRunShort = 8, + RLE_ContinueRun24 = 9 + }; + + template + static bool RLEEncodeLine(TArray* LineToEncode, TArray* EncodedLine); + + template + static bool RLEEncodeBuffer(DataType* BufferToEncode, uint32 EncodeLength, TArray* EncodedLine); + + template + static void RLEDecodeLine(TArray* LineToDecode, TArray* DecodedLine, bool bCompressed); + + template + static void RLEDecodeLine(const uint8* LineToDecode, uint32 Num, TArray* DecodedLine, bool bCompressed); + + static inline void RLEWriteContinueFlag(uint32 Count, uint8** loc); + + template + static inline void RLEWriteRunFlag(uint32 Count, uint8** loc, TArray& Data, bool bCompressed); +} + +UVRRenderTargetManager::UVRRenderTargetManager(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + + PrimaryComponentTick.bCanEverTick = true; + PrimaryComponentTick.bStartWithTickEnabled = true; + + PollRelevancyTime = 0.1f; + DrawRate = 0.0333; + + bIsStoringImage = false; + RenderTarget = nullptr; + RenderTargetWidth = 100; + RenderTargetHeight = 100; + ClearColor = FColor::White; + + TextureBlobSize = 512; + MaxBytesPerSecondRate = 5000; + + bInitiallyReplicateTexture = false; + bIsLoadingTextureBuffer = false; + + OwnerIDCounter = 0; +} + +bool UVRRenderTargetManager::SendDrawOperations_Validate(const TArray& RenderOperationStoreList) +{ + return true; +} + +void UVRRenderTargetManager::SendDrawOperations_Implementation(const TArray& RenderOperationStoreList) +{ + if (GetNetMode() == ENetMode::NM_Client) + { + RenderOperationStore.Append(RenderOperationStoreList); + } + + DrawOperations(); +} + + +void UVRRenderTargetManager::AddLineDrawOperation(FVector2D Point1, FVector2D Point2, FColor Color, int32 Thickness) +{ + FRenderManagerOperation NewOperation; + NewOperation.OperationType = ERenderManagerOperationType::Op_LineDraw; + NewOperation.Color = Color; + NewOperation.P1 = Point1; + NewOperation.P2 = Point2; + NewOperation.Thickness = (uint32)Thickness; + + if (GetNetMode() < ENetMode::NM_Client) + RenderOperationStore.Add(NewOperation); + else + LocalRenderOperationStore.Add(NewOperation); + + if (!DrawHandle.IsValid()) + GetWorld()->GetTimerManager().SetTimer(DrawHandle, this, &UVRRenderTargetManager::DrawPoll, DrawRate, true); + + // Send to server now +} + +void UVRRenderTargetManager::AddTextureDrawOperation(FVector2D Position, UTexture2D* TextureToDisplay) +{ + + if (!TextureToDisplay) + return; + + FRenderManagerOperation NewOperation; + NewOperation.OperationType = ERenderManagerOperationType::Op_TexDraw; + NewOperation.P1 = Position; + NewOperation.Texture = TextureToDisplay; + + if (GetNetMode() < ENetMode::NM_Client) + RenderOperationStore.Add(NewOperation); + else + LocalRenderOperationStore.Add(NewOperation); + + if (!DrawHandle.IsValid()) + GetWorld()->GetTimerManager().SetTimer(DrawHandle, this, &UVRRenderTargetManager::DrawPoll, DrawRate, true); + + // Send to server now +} + +void UVRRenderTargetManager::AddMaterialTrianglesDrawOperation(TArray Tris, UMaterial* Material) +{ + + if (!Tris.Num()) + return; + + FRenderManagerOperation NewOperation; + NewOperation.OperationType = ERenderManagerOperationType::Op_TriDraw; + NewOperation.Color = Tris[0].V0_Color.ToFColor(true); + + NewOperation.Tris.AddUninitialized(Tris.Num()); + int Counter = 0; + FRenderManagerTri RenderTri; + for (FCanvasUVTri Tri : Tris) + { + RenderTri.P1 = Tri.V0_Pos; + RenderTri.P2 = Tri.V1_Pos; + RenderTri.P3 = Tri.V2_Pos; + NewOperation.Tris[Counter++] = RenderTri; + } + + NewOperation.Material = Material; + + if (GetNetMode() < ENetMode::NM_Client) + RenderOperationStore.Add(NewOperation); + else + LocalRenderOperationStore.Add(NewOperation); + + if (!DrawHandle.IsValid()) + GetWorld()->GetTimerManager().SetTimer(DrawHandle, this, &UVRRenderTargetManager::DrawPoll, DrawRate, true); + + // Send to server now +} + +void UVRRenderTargetManager::DrawOperation(UCanvas* Canvas, const FRenderManagerOperation& Operation) +{ + if (IsValid(LocalProxy) && LocalProxy->OwnersID == Operation.OwnerID) + { + return; + } + + switch (Operation.OperationType) + { + case ERenderManagerOperationType::Op_LineDraw: + { + FCanvasLineItem LineItem; + LineItem.Origin = FVector(Operation.P1.X, Operation.P1.Y, 0.f); + LineItem.EndPos = FVector(Operation.P2.X, Operation.P2.Y, 0.f); + LineItem.LineThickness = (float)Operation.Thickness; + LineItem.SetColor(Operation.Color.ReinterpretAsLinear()); + Canvas->DrawItem(LineItem); + }break; + case ERenderManagerOperationType::Op_TexDraw: + { + if (Operation.Texture && Operation.Texture->GetResource()) + { + //FTexture* RenderTextureResource = (RenderBase) ? RenderBase->Resource : GWhiteTexture; + FCanvasTileItem TileItem(Operation.P1, Operation.Texture->GetResource(), FVector2D(Operation.Texture->GetSizeX(), Operation.Texture->GetSizeY()), FVector2D(0, 0), FVector2D(1.f, 1.f), ClearColor); + TileItem.BlendMode = FCanvas::BlendToSimpleElementBlend(EBlendMode::BLEND_Translucent); + Canvas->DrawItem(TileItem); + } + }break; + case ERenderManagerOperationType::Op_TriDraw: + { + if (Operation.Tris.Num() && Operation.Material) + { + FCanvasTriangleItem TriangleItem(FVector2D::ZeroVector, FVector2D::ZeroVector, FVector2D::ZeroVector, NULL); + TriangleItem.MaterialRenderProxy = Operation.Material->GetRenderProxy(); + + FCanvasUVTri triStore; + triStore.V0_Color = Operation.Color; + triStore.V1_Color = Operation.Color; + triStore.V2_Color = Operation.Color; + + TriangleItem.TriangleList.Reset(Operation.Tris.Num()); + TriangleItem.TriangleList.AddUninitialized(Operation.Tris.Num()); + uint32 Counter = 0; + for (FRenderManagerTri Tri : Operation.Tris) + { + triStore.V0_Pos = Tri.P1; + triStore.V1_Pos = Tri.P2; + triStore.V2_Pos = Tri.P3; + TriangleItem.TriangleList[Counter++] = triStore; + } + + Canvas->DrawItem(TriangleItem); + } + }break; + } + +} + +void UVRRenderTargetManager::DrawPoll() +{ + if (!RenderOperationStore.Num() && !LocalRenderOperationStore.Num()) + { + GetWorld()->GetTimerManager().ClearTimer(DrawHandle); + return; + } + + if (GetNetMode() < ENetMode::NM_Client) + { + SendDrawOperations(RenderOperationStore); + } + else + { + if (LocalRenderOperationStore.Num()) + { + // Send operations to server + if (IsValid(LocalProxy)) + { + LocalProxy->SendLocalDrawOperations(LocalRenderOperationStore); + } + + RenderOperationStore.Append(LocalRenderOperationStore); + LocalRenderOperationStore.Empty(); + } + + DrawOperations(); + } +} + +void UVRRenderTargetManager::DrawOperations() +{ + + if (bIsLoadingTextureBuffer) + { + if (!DrawHandle.IsValid()) + GetWorld()->GetTimerManager().SetTimer(DrawHandle, this, &UVRRenderTargetManager::DrawPoll, DrawRate, true); + + return; + } + + if (GetNetMode() == ENetMode::NM_DedicatedServer) + { + RenderOperationStore.Empty(); + return; + } + + UWorld* World = GetWorld(); + + if (!World || !World->GetBegunPlay()) + return; + + // Reference to the Render Target resource + FTextureRenderTargetResource* RenderTargetResource = RenderTarget->GameThread_GetRenderTargetResource(); + + if (!RenderTargetResource) + { + RenderOperationStore.Empty(); + return; + } + + // Retrieve a UCanvas form the world to avoid creating a new one each time + UCanvas* CanvasToUse = World->GetCanvasForDrawMaterialToRenderTarget(); + + // Creates a new FCanvas for rendering + FCanvas RenderCanvas( + RenderTargetResource, + nullptr, + World, + World->GetFeatureLevel()); + + // Setup the canvas with the FCanvas reference + CanvasToUse->Init(RenderTarget->SizeX, RenderTarget->SizeY, nullptr, &RenderCanvas); + CanvasToUse->Update(); + + if (CanvasToUse) + { + for (const FRenderManagerOperation& opt : RenderOperationStore) + { + DrawOperation(CanvasToUse, opt); + } + + RenderOperationStore.Empty(); + + // Perform the drawing + RenderCanvas.Flush_GameThread(); + + // Cleanup the FCanvas reference, to delete it + CanvasToUse->Canvas = NULL; + } +} + + +ARenderTargetReplicationProxy::ARenderTargetReplicationProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + bOnlyRelevantToOwner = true; + bNetUseOwnerRelevancy = true; + bReplicates = true; + PrimaryActorTick.bCanEverTick = false; + SetReplicateMovement(false); + bWaitingForManager = false; +} + +void ARenderTargetReplicationProxy::OnRep_Manager() +{ + // If our manager is valid, save off a reference to ourselves to the local copy. + if (IsValid(OwningManager)) + { + OwningManager->LocalProxy = this; + + // If we loaded a texture before the manager loaded + if (bWaitingForManager) + { + OwningManager->bIsLoadingTextureBuffer = false; + OwningManager->RenderTargetStore = TextureStore; + TextureStore.Reset(); + TextureStore.PackedData.Empty(); + TextureStore.UnpackedData.Empty(); + //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Orange, FString::Printf(TEXT("Recieved Texture, total byte count: %i"), OwningManager->RenderTargetStore.PackedData.Num())); + OwningManager->DeCompressRenderTarget2D(); + bWaitingForManager = false; + } + } +} + +bool ARenderTargetReplicationProxy::SendLocalDrawOperations_Validate(const TArray& LocalRenderOperationStoreList) +{ + return true; +} + +void ARenderTargetReplicationProxy::SendLocalDrawOperations_Implementation(const TArray& LocalRenderOperationStoreList) +{ + if (IsValid(OwningManager)) + { + OwningManager->RenderOperationStore.Append(LocalRenderOperationStoreList); + + // ID the render operations to the player that sent them in + if (APlayerController* OwningPlayer = Cast(GetOwner())) + { + for (int i = (OwningManager->RenderOperationStore.Num() - LocalRenderOperationStoreList.Num()); i < OwningManager->RenderOperationStore.Num(); i++) + { + OwningManager->RenderOperationStore[i].OwnerID = OwnersID; + } + } + + if (!OwningManager->DrawHandle.IsValid()) + GetWorld()->GetTimerManager().SetTimer(OwningManager->DrawHandle, OwningManager.Get(), &UVRRenderTargetManager::DrawPoll, OwningManager->DrawRate, true); + } +} + +void ARenderTargetReplicationProxy::ReceiveTexture_Implementation(const FBPVRReplicatedTextureStore& TextureData) +{ + if (IsValid(OwningManager)) + { + OwningManager->RenderTargetStore = TextureData; + //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Orange, FString::Printf(TEXT("Recieved Texture, byte count: %i"), TextureData.PackedData.Num())); + OwningManager->DeCompressRenderTarget2D(); + } +} + +void ARenderTargetReplicationProxy::InitTextureSend_Implementation(int32 Width, int32 Height, int32 TotalDataCount, int32 BlobCount, EPixelFormat PixelFormat, bool bIsZipped/*, bool bIsJPG*/) +{ + TextureStore.Reset(); + TextureStore.PixelFormat = PixelFormat; + TextureStore.bIsZipped = bIsZipped; + //TextureStore.bJPG = bIsJPG; + TextureStore.Width = Width; + TextureStore.Height = Height; + + TextureStore.PackedData.Reset(TotalDataCount); + TextureStore.PackedData.AddUninitialized(TotalDataCount); + + BlobNum = BlobCount; + + if (IsValid(OwningManager)) + { + OwningManager->bIsLoadingTextureBuffer = true; + } + + Ack_InitTextureSend(TotalDataCount); +} + +bool ARenderTargetReplicationProxy::Ack_InitTextureSend_Validate(int32 TotalDataCount) +{ + return true; +} + +void ARenderTargetReplicationProxy::Ack_InitTextureSend_Implementation(int32 TotalDataCount) +{ + if (TotalDataCount == TextureStore.PackedData.Num()) + { + BlobNum = 0; + + // Calculate time offset to achieve our max bytes per second with the given blob size + float SendRate = 1.f / (MaxBytesPerSecondRate / (float)TextureBlobSize); + + GetWorld()->GetTimerManager().SetTimer(SendTimer_Handle, this, &ARenderTargetReplicationProxy::SendNextDataBlob, SendRate, true); + + // Start sending data blobs + //SendNextDataBlob(); + } +} + +void ARenderTargetReplicationProxy::SendInitMessage() +{ + int32 TotalBlobs = TextureStore.PackedData.Num() / TextureBlobSize + (TextureStore.PackedData.Num() % TextureBlobSize > 0 ? 1 : 0); + + InitTextureSend(TextureStore.Width, TextureStore.Height, TextureStore.PackedData.Num(), TotalBlobs, TextureStore.PixelFormat, TextureStore.bIsZipped/*, TextureStore.bJPG*/); + +} + +void ARenderTargetReplicationProxy::SendNextDataBlob() +{ + if (!IsValid(this) || !this->GetOwner() || !IsValid(this->GetOwner())) + { + TextureStore.Reset(); + TextureStore.PackedData.Empty(); + TextureStore.UnpackedData.Empty(); + BlobNum = 0; + if (SendTimer_Handle.IsValid()) + GetWorld()->GetTimerManager().ClearTimer(SendTimer_Handle); + + return; + } + + BlobNum++; + int32 TotalBlobs = TextureStore.PackedData.Num() / TextureBlobSize + (TextureStore.PackedData.Num() % TextureBlobSize > 0 ? 1 : 0); + + if (BlobNum <= TotalBlobs) + { + TArray BlobStore; + int32 BlobLen = (BlobNum == TotalBlobs ? TextureStore.PackedData.Num() % TextureBlobSize : TextureBlobSize); + + + BlobStore.AddUninitialized(BlobLen); + uint8* MemLoc = TextureStore.PackedData.GetData(); + int32 MemCount = (BlobNum - 1) * TextureBlobSize; + MemLoc += MemCount; + + FMemory::Memcpy(BlobStore.GetData(), MemLoc, BlobLen); + + ReceiveTextureBlob(BlobStore, MemCount, BlobNum); + } + else + { + TextureStore.Reset(); + TextureStore.PackedData.Empty(); + TextureStore.UnpackedData.Empty(); + if (SendTimer_Handle.IsValid()) + GetWorld()->GetTimerManager().ClearTimer(SendTimer_Handle); + BlobNum = 0; + } +} + +void ARenderTargetReplicationProxy::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + if (SendTimer_Handle.IsValid()) + GetWorld()->GetTimerManager().ClearTimer(SendTimer_Handle); + + Super::EndPlay(EndPlayReason); +} + +//============================================================================= +void ARenderTargetReplicationProxy::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty >& OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_InitialOnly, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(ARenderTargetReplicationProxy, OwningManager, PushModelParamsWithCondition); + DOREPLIFETIME_WITH_PARAMS_FAST(ARenderTargetReplicationProxy, OwnersID, PushModelParamsWithCondition); +} + +void ARenderTargetReplicationProxy::ReceiveTextureBlob_Implementation(const TArray& TextureBlob, int32 LocationInData, int32 BlobNumber) +{ + if (LocationInData + TextureBlob.Num() <= TextureStore.PackedData.Num()) + { + uint8* MemLoc = TextureStore.PackedData.GetData(); + MemLoc += LocationInData; + FMemory::Memcpy(MemLoc, TextureBlob.GetData(), TextureBlob.Num()); + + //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Orange, FString::Printf(TEXT("Recieved Texture blob, byte count: %i"), TextureBlob.Num())); + } + + if (BlobNumber == BlobNum) + { + Ack_ReceiveTextureBlob(BlobNum); + + // We finished, unpack and display + if (IsValid(OwningManager)) + { + OwningManager->bIsLoadingTextureBuffer = false; + OwningManager->RenderTargetStore = TextureStore; + TextureStore.Reset(); + TextureStore.PackedData.Empty(); + TextureStore.UnpackedData.Empty(); + //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Orange, FString::Printf(TEXT("Recieved Texture, total byte count: %i"), OwningManager->RenderTargetStore.PackedData.Num())); + OwningManager->DeCompressRenderTarget2D(); + } + else + { + bWaitingForManager = true; + } + } + +} + +bool ARenderTargetReplicationProxy::Ack_ReceiveTextureBlob_Validate(int32 BlobCount) +{ + return true; +} + +void ARenderTargetReplicationProxy::Ack_ReceiveTextureBlob_Implementation(int32 BlobCount) +{ + // Send next data blob + //SendNextDataBlob(); + +} + +void UVRRenderTargetManager::UpdateRelevancyMap() +{ + AActor* myOwner = GetOwner(); + + for (int i = NetRelevancyLog.Num() - 1; i >= 0; i--) + { + if (!IsValid(NetRelevancyLog[i].PC) || NetRelevancyLog[i].PC->IsLocalController() || !NetRelevancyLog[i].PC->GetPawn()) + { + NetRelevancyLog[i].ReplicationProxy->Destroy(); + NetRelevancyLog.RemoveAt(i); + } + else + { + if (APawn* pawn = NetRelevancyLog[i].PC->GetPawn()) + { + if (!myOwner->IsNetRelevantFor(NetRelevancyLog[i].PC.Get(), pawn, pawn->GetActorLocation())) + { + NetRelevancyLog[i].bIsRelevant = false; + NetRelevancyLog[i].bIsDirty = false; + //NetRelevancyLog.RemoveAt(i); + } + } + } + } + + + bool bHadDirtyActors = false; + + for (FConstPlayerControllerIterator PCIt = GetWorld()->GetPlayerControllerIterator(); PCIt; ++PCIt) + { + if (APlayerController* PC = PCIt->Get()) + { + if (PC->IsLocalController()) + continue; + + if (!PC->HasClientLoadedCurrentWorld()) + continue; + + if (APawn* pawn = PC->GetPawn()) + { + + if (myOwner->IsNetRelevantFor(PC, pawn, pawn->GetActorLocation())) + { + FClientRepData* RepData = NetRelevancyLog.FindByPredicate([PC](const FClientRepData& Other) + { + return Other.PC == PC; + }); + + if (!RepData) + { + FClientRepData ClientRepData; + + FTransform NewTransform = this->GetOwner()->GetActorTransform(); + ARenderTargetReplicationProxy* RenderProxy = GetWorld()->SpawnActorDeferred(ARenderTargetReplicationProxy::StaticClass(), NewTransform, PC); + if (RenderProxy) + { + RenderProxy->OwnersID = ++OwnerIDCounter; + RenderProxy->OwningManager = this; + RenderProxy->MaxBytesPerSecondRate = MaxBytesPerSecondRate; + RenderProxy->TextureBlobSize = TextureBlobSize; + UGameplayStatics::FinishSpawningActor(RenderProxy, NewTransform); + } + + if (RenderProxy) + { + RenderProxy->AttachToActor(this->GetOwner(), FAttachmentTransformRules::SnapToTargetIncludingScale); + + + ClientRepData.PC = PC; + ClientRepData.ReplicationProxy = RenderProxy; + ClientRepData.bIsRelevant = true; + ClientRepData.bIsDirty = true; + bHadDirtyActors = true; + NetRelevancyLog.Add(ClientRepData); + } + // Update this client with the new data + } + else + { + if (!RepData->bIsRelevant) + { + RepData->bIsRelevant = true; + RepData->bIsDirty = true; + bHadDirtyActors = true; + } + } + } + } + + } + } + + if (bHadDirtyActors && bInitiallyReplicateTexture && GetNetMode() != ENetMode::NM_DedicatedServer) + { + QueueImageStore(); + } +} + +bool UVRRenderTargetManager::DeCompressRenderTarget2D() +{ + if (!RenderTarget) + return false; + + RenderTargetStore.UnPackData(); + + + int32 Width = RenderTargetStore.Width; + int32 Height = RenderTargetStore.Height; + EPixelFormat PixelFormat = RenderTargetStore.PixelFormat; + uint8 PixelFormat8 = 0; + + TArray FinalColorData; + FinalColorData.AddUninitialized(RenderTargetStore.UnpackedData.Num()); + + uint32 Counter = 0; + FColor ColorVal; + ColorVal.A = 0xFF; + for (uint16 CompColor : RenderTargetStore.UnpackedData) + { + //CompColor.FillTo(ColorVal); + ColorVal.R = CompColor << 3; + ColorVal.G = CompColor >> 5 << 2; + ColorVal.B = CompColor >> 11 << 3; + ColorVal.A = 0xFF; + FinalColorData[Counter++] = ColorVal; + } + + // Write this to a texture2d + UTexture2D* RenderBase = UTexture2D::CreateTransient(Width, Height, PF_R8G8B8A8);// RenderTargetStore.PixelFormat); + + // Switched to a Memcpy instead of byte by byte transer + uint8* MipData = (uint8*)RenderBase->GetPlatformData()->Mips[0].BulkData.Lock(LOCK_READ_WRITE); + FMemory::Memcpy(MipData, (void*)FinalColorData.GetData(), FinalColorData.Num() * sizeof(FColor)); + RenderBase->GetPlatformData()->Mips[0].BulkData.Unlock(); + + //Setting some Parameters for the Texture and finally returning it + RenderBase->GetPlatformData()->SetNumSlices(1); + RenderBase->NeverStream = true; + RenderBase->SRGB = true; + //Avatar->CompressionSettings = TC_EditorIcon; + + RenderBase->UpdateResource(); + + /*uint32 size = sizeof(FColor); + + uint8* pData = new uint8[FinalColorData.Num() * sizeof(FColor)]; + FMemory::Memcpy(pData, (void*)FinalColorData.GetData(), FinalColorData.Num() * sizeof(FColor)); + + UTexture2D* TexturePtr = RenderBase; + const uint8* TextureData = pData; + ENQUEUE_RENDER_COMMAND(VRRenderTargetManager_FillTexture)( + [TexturePtr, TextureData](FRHICommandList& RHICmdList) + { + FUpdateTextureRegion2D region; + region.SrcX = 0; + region.SrcY = 0; + region.DestX = 0; + region.DestY = 0; + region.Width = TexturePtr->GetSizeX();// TEX_WIDTH; + region.Height = TexturePtr->GetSizeY();//TEX_HEIGHT; + + FTexture2DResource* resource = (FTexture2DResource*)TexturePtr->Resource; + RHIUpdateTexture2D(resource->GetTexture2DRHI(), 0, region, region.Width * GPixelFormats[TexturePtr->GetPixelFormat()].BlockBytes, TextureData); + delete[] TextureData; + });*/ + + + // Using this as it saves custom implementation + + UWorld* World = GetWorld(); + + // Reference to the Render Target resource + FTextureRenderTargetResource* RenderTargetResource = RenderTarget->GameThread_GetRenderTargetResource(); + + // Retrieve a UCanvas form the world to avoid creating a new one each time + UCanvas* CanvasToUse = World->GetCanvasForDrawMaterialToRenderTarget(); + + // Creates a new FCanvas for rendering + FCanvas RenderCanvas( + RenderTargetResource, + nullptr, + World, + World->GetFeatureLevel()); + + // Setup the canvas with the FCanvas reference + CanvasToUse->Init(RenderTarget->SizeX, RenderTarget->SizeY, nullptr, &RenderCanvas); + CanvasToUse->Update(); + + if (CanvasToUse) + { + FTexture* RenderTextureResource = (RenderBase) ? RenderBase->GetResource() : GWhiteTexture; + FCanvasTileItem TileItem(FVector2D(0, 0), RenderTextureResource, FVector2D(RenderTarget->SizeX, RenderTarget->SizeY), FVector2D(0, 0), FVector2D(1.f, 1.f), FLinearColor::White); + TileItem.BlendMode = FCanvas::BlendToSimpleElementBlend(EBlendMode::BLEND_Opaque); + CanvasToUse->DrawItem(TileItem); + + + // Perform the drawing + RenderCanvas.Flush_GameThread(); + + // Cleanup the FCanvas reference, to delete it + CanvasToUse->Canvas = NULL; + } + + RenderBase->ReleaseResource(); + RenderBase->MarkAsGarbage(); + + return true; +} + +void UVRRenderTargetManager::QueueImageStore() +{ + + if (!bInitiallyReplicateTexture || !RenderTarget || bIsStoringImage || GetNetMode() == ENetMode::NM_DedicatedServer) + { + return; + } + + bIsStoringImage = true; + + // Init new RenderRequest + FRenderDataStore* renderData = new FRenderDataStore(); + + // Get RenderContext + FTextureRenderTargetResource* renderTargetResource = RenderTarget->GameThread_GetRenderTargetResource(); + + if (!renderTargetResource) + return; + + renderData->Size2D = renderTargetResource->GetSizeXY(); + renderData->PixelFormat = RenderTarget->GetFormat(); + + struct FReadSurfaceContext { + FRenderTarget* SrcRenderTarget; + TArray* OutData; + FIntRect Rect; + FReadSurfaceDataFlags Flags; + }; + + // Setup GPU command + FReadSurfaceContext readSurfaceContext = + { + renderTargetResource, + &(renderData->ColorData), + FIntRect(0,0,renderTargetResource->GetSizeXY().X, renderTargetResource->GetSizeXY().Y), + FReadSurfaceDataFlags(RCM_UNorm, CubeFace_MAX) + }; + + ENQUEUE_RENDER_COMMAND(SceneDrawCompletion)( + [readSurfaceContext](FRHICommandListImmediate& RHICmdList) { + RHICmdList.ReadSurfaceData( + readSurfaceContext.SrcRenderTarget->GetRenderTargetTexture(), + readSurfaceContext.Rect, + *readSurfaceContext.OutData, + readSurfaceContext.Flags + ); + }); + + // Notify new task in RenderQueue + RenderDataQueue.Enqueue(renderData); + + // Set RenderCommandFence + renderData->RenderFence.BeginFence(); + + this->SetComponentTickEnabled(true); +} + +void UVRRenderTargetManager::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) +{ + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + // Read pixels once RenderFence is completed + if (!bInitiallyReplicateTexture || RenderDataQueue.IsEmpty() || GetNetMode() == ENetMode::NM_DedicatedServer) + { + SetComponentTickEnabled(false); + } + else + { + // Peek the next RenderRequest from queue + FRenderDataStore* nextRenderData; + RenderDataQueue.Peek(nextRenderData); + + if (nextRenderData) + { + if (nextRenderData->RenderFence.IsFenceComplete()) + { + bIsStoringImage = false; + RenderTargetStore.Reset(); + uint32 SizeOfData = nextRenderData->ColorData.Num(); + + RenderTargetStore.UnpackedData.Reset(SizeOfData); + RenderTargetStore.UnpackedData.AddUninitialized(SizeOfData); + + uint16 ColorVal = 0; + uint32 Counter = 0; + + // Convert to 16bit color + for (FColor col : nextRenderData->ColorData) + { + ColorVal = (col.R >> 3) << 11 | (col.G >> 2) << 5 | (col.B >> 3); + RenderTargetStore.UnpackedData[Counter++] = ColorVal; + } + + FIntPoint Size2D = nextRenderData->Size2D; + RenderTargetStore.Width = Size2D.X; + RenderTargetStore.Height = Size2D.Y; + RenderTargetStore.PixelFormat = nextRenderData->PixelFormat; + RenderTargetStore.PackData(); + + +//#if WITH_PUSH_MODEL + //MARK_PROPERTY_DIRTY_FROM_NAME(UVRRenderTargetManager, RenderTargetStore, this); +//#endif + + + // Delete the first element from RenderQueue + RenderDataQueue.Pop(); + delete nextRenderData; + + for (int i = NetRelevancyLog.Num() - 1; i >= 0; i--) + { + if (NetRelevancyLog[i].bIsDirty && IsValid(NetRelevancyLog[i].PC) && !NetRelevancyLog[i].PC->IsLocalController()) + { + if (IsValid(NetRelevancyLog[i].ReplicationProxy)) + { + NetRelevancyLog[i].ReplicationProxy->TextureStore = RenderTargetStore; + NetRelevancyLog[i].ReplicationProxy->SendInitMessage(); + NetRelevancyLog[i].bIsDirty = false; + } + } + } + + + } + } + } + +} + +void UVRRenderTargetManager::BeginPlay() +{ + Super::BeginPlay(); + + InitRenderTarget(); + + if (/*bInitiallyReplicateTexture && */GetNetMode() < ENetMode::NM_Client) + GetWorld()->GetTimerManager().SetTimer(NetRelevancyTimer_Handle, this, &UVRRenderTargetManager::UpdateRelevancyMap, PollRelevancyTime, true); +} + +void UVRRenderTargetManager::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + Super::EndPlay(EndPlayReason); + + FRenderDataStore* Store = nullptr; + while (!RenderDataQueue.IsEmpty()) + { + RenderDataQueue.Dequeue(Store); + + if (Store) + { + delete Store; + } + } + + if (GetNetMode() < ENetMode::NM_Client) + GetWorld()->GetTimerManager().ClearTimer(NetRelevancyTimer_Handle); + + if(DrawHandle.IsValid()) + GetWorld()->GetTimerManager().ClearTimer(DrawHandle); + + if (RenderTarget) + { + RenderTarget->ReleaseResource(); + RenderTarget = nullptr; + } + + for (FClientRepData& RepData : NetRelevancyLog) + { + RepData.PC = nullptr; + if (IsValid(RepData.ReplicationProxy.Get())) + { + RepData.ReplicationProxy->Destroy(); + } + + RepData.ReplicationProxy = nullptr; + } + +} + +void UVRRenderTargetManager::InitRenderTarget() +{ + if (this->GetNetMode() == ENetMode::NM_DedicatedServer) + { + return; // Dedicated servers cannot handle render targets + } + + UWorld* World = GetWorld(); + + if (RenderTargetWidth > 0 && RenderTargetHeight > 0 && World) + { + RenderTarget = NewObject(this); + if (RenderTarget) + { + //NewCanvasRenderTarget->World = World; + RenderTarget->InitAutoFormat(RenderTargetWidth, RenderTargetHeight); + RenderTarget->ClearColor = ClearColor; + RenderTarget->bAutoGenerateMips = false; + RenderTarget->UpdateResourceImmediate(true); + } + else + { + RenderTarget = nullptr; + } + } + else + { + RenderTarget = nullptr; + } +} + + +bool UVRRenderTargetManager::GenerateTrisFromBoxPlaneIntersection(UPrimitiveComponent* PrimToBoxCheck, FTransform WorldTransformOfPlane, const FPlane& LocalProjectionPlane, FVector2D PlaneSize, FColor UVColor, TArray& OutTris) +{ + + if (!PrimToBoxCheck) + return false; + + OutTris.Reset(); + + FBoxSphereBounds LocalBounds = PrimToBoxCheck->CalcLocalBounds(); + FVector Center = LocalBounds.Origin; + FVector Extent = LocalBounds.BoxExtent; + + // Transform into plane local space from our localspace + FTransform LocalTrans = PrimToBoxCheck->GetComponentTransform() * WorldTransformOfPlane.Inverse(); + + FVector BoxMin = Center - Extent; + FVector BoxMax = Center + Extent; + + TArray PointList; + PointList.AddUninitialized(8); // 8 Is number of points on box + + PointList[0] = LocalTrans.TransformPosition(BoxMin); + PointList[1] = LocalTrans.TransformPosition(BoxMax); + PointList[2] = LocalTrans.TransformPosition(FVector(BoxMin.X, BoxMin.Y, BoxMax.Z)); + PointList[3] = LocalTrans.TransformPosition(FVector(BoxMin.X, BoxMax.Y, BoxMin.Z)); + PointList[4] = LocalTrans.TransformPosition(FVector(BoxMax.X, BoxMin.Y, BoxMin.Z)); + PointList[5] = LocalTrans.TransformPosition(FVector(BoxMin.X, BoxMax.Y, BoxMax.Z)); + PointList[6] = LocalTrans.TransformPosition(FVector(BoxMax.X, BoxMin.Y, BoxMax.Z)); + PointList[7] = LocalTrans.TransformPosition(FVector(BoxMax.X, BoxMax.Y, BoxMin.Z)); + + // List of edges to check, 12 total, 2 points per edge + int EdgeList[24] = + { + 0, 3, + 0, 4, + 0, 2, + 2, 5, + 2, 6, + 4, 7, + 4, 6, + 6, 1, + 1, 7, + 1, 5, + 5, 3, + 3, 7 + }; + + TArray IntersectionPoints; + + FVector Intersection; + float Time; + + FVector2D HalfPlane = PlaneSize / 2.f; + FVector2D PtCenter; + FVector2D NewPt; + FVector PlanePoint; + int CenterCount = 0; + for (int i = 0; i < 24; i += 2) + { + + if (UKismetMathLibrary::LinePlaneIntersection(PointList[EdgeList[i]], PointList[EdgeList[i + 1]], LocalProjectionPlane, Time, Intersection)) + { + //DrawDebugSphere(GetWorld(), WorldTransformOfPlane.TransformPosition(Intersection), 2.f, 32.f, FColor::Black); + PlanePoint = Intersection; + + if (IsValid(RenderTarget)) + { + NewPt.X = ((PlanePoint.X + HalfPlane.X) / PlaneSize.X) * RenderTarget->SizeX; + NewPt.Y = ((PlanePoint.Y + HalfPlane.Y) / PlaneSize.Y) * RenderTarget->SizeY; + } + else + { + NewPt.X = ((PlanePoint.X + HalfPlane.X) / PlaneSize.X) * RenderTargetWidth; + NewPt.Y = ((PlanePoint.Y + HalfPlane.Y) / PlaneSize.Y) * RenderTargetHeight; + } + + IntersectionPoints.Add(NewPt); + PtCenter += NewPt; + CenterCount++; + } + } + + if (IntersectionPoints.Num() <= 2) + { + return false; + } + + // Get our center value + PtCenter /= CenterCount; + + // Sort the points clockwise + struct FPointSortCompare + { + public: + FVector2D CenterPoint; + FPointSortCompare(const FVector2D& InCenterPoint) + : CenterPoint(InCenterPoint) + { + + } + + FORCEINLINE bool operator()(const FVector2D& A, const FVector2D& B) const + { + if (A.Y - CenterPoint.X >= 0 && B.X - CenterPoint.X < 0) + return true; + if (A.X - CenterPoint.X < 0 && B.X - CenterPoint.X >= 0) + return false; + if (A.X - CenterPoint.X == 0 && B.X - CenterPoint.X == 0) { + if (A.Y - CenterPoint.Y >= 0 || B.Y - CenterPoint.Y >= 0) + return A.Y > B.Y; + return B.Y > A.Y; + } + + // compute the cross product of vectors (center -> a) x (center -> b) + int det = (A.X - CenterPoint.X) * (B.Y - CenterPoint.Y) - (B.X - CenterPoint.X) * (A.Y - CenterPoint.Y); + if (det < 0) + return true; + if (det > 0) + return false; + + // points a and b are on the same line from the center + // check which point is closer to the center + int d1 = (A.X - CenterPoint.X) * (A.X - CenterPoint.X) + (A.Y - CenterPoint.Y) * (A.Y - CenterPoint.Y); + int d2 = (B.X - CenterPoint.X) * (B.X - CenterPoint.X) + (B.Y - CenterPoint.Y) * (B.Y - CenterPoint.Y); + return d1 > d2; + } + }; + + IntersectionPoints.Sort(FPointSortCompare(PtCenter)); + + FCanvasUVTri Tri; + Tri.V0_Color = UVColor; + Tri.V1_Color = UVColor; + Tri.V2_Color = UVColor; + + OutTris.Reserve(IntersectionPoints.Num() - 2); + + // Now that we have our sorted list, we can generate a tri map from it, just doing a Fan from first to last + for (int i = 1; i < IntersectionPoints.Num() - 1; i++) + { + Tri.V0_Pos = IntersectionPoints[0]; + Tri.V1_Pos = IntersectionPoints[i]; + Tri.V2_Pos = IntersectionPoints[i + 1]; + + OutTris.Add(Tri); + } + + return true; +} + +void FBPVRReplicatedTextureStore::PackData() +{ + if (UnpackedData.Num() > 0) + { + TArray TmpPacked; + RLE_Funcs::RLEEncodeBuffer(UnpackedData.GetData(), UnpackedData.Num(), &TmpPacked); + UnpackedData.Reset(); + + /*if (TmpPacked.Num() > 30000) + { + IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked(FName("ImageWrapper")); + TSharedPtr imageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG); + + imageWrapper->SetRaw(UnpackedData.GetData(), UnpackedData.Num(), Width, Height, ERGBFormat::RGBA, 8); + const TArray64& ImgData = imageWrapper->GetCompressed(1); + + + PackedData.Reset(ImgData.Num()); + PackedData.AddUninitialized(ImgData.Num()); + FMemory::Memcpy(PackedData.GetData(), ImgData.GetData(), ImgData.Num()); + bJPG = true; + bIsZipped = false; + } + else */if (TmpPacked.Num() > 512) + { + FArchiveSaveCompressedProxy Compressor(PackedData, NAME_Zlib, COMPRESS_BiasSpeed); + Compressor << TmpPacked; + Compressor.Flush(); + bIsZipped = true; + //bJPG = false; + } + else + { + PackedData = TmpPacked; + bIsZipped = false; + //bJPG = false; + } + } +} + + +void FBPVRReplicatedTextureStore::UnPackData() +{ + if (PackedData.Num() > 0) + { + + /*if (bJPG) + { + IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked(FName("ImageWrapper")); + TSharedPtr imageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG); + + + if (imageWrapper.IsValid() && (PackedData.Num() > 0) && imageWrapper->SetCompressed(PackedData.GetData(), PackedData.Num())) + { + Width = imageWrapper->GetWidth(); + Height = imageWrapper->GetHeight(); + + if (imageWrapper->GetRaw(ERGBFormat::BGRA, 8, UnpackedData)) + { + //bSucceeded = true; + } + } + } + else */if (bIsZipped) + { + TArray RLEEncodedData; + FArchiveLoadCompressedProxy DataArchive(PackedData, NAME_Zlib); + DataArchive << RLEEncodedData; + RLE_Funcs::RLEDecodeLine(&RLEEncodedData, &UnpackedData, true); + } + else + { + RLE_Funcs::RLEDecodeLine(&PackedData, &UnpackedData, true); + } + + PackedData.Reset(); + } +} + +/** Network serialization */ +// Doing a custom NetSerialize here because this is sent via RPCs and should change on every update +bool FBPVRReplicatedTextureStore::NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) +{ + bOutSuccess = true; + + //Ar.SerializeBits(&bIsJPG, 1); + Ar.SerializeBits(&bIsZipped, 1); + Ar.SerializeIntPacked(Width); + Ar.SerializeIntPacked(Height); + Ar.SerializeBits(&PixelFormat, 8); + + Ar << PackedData; + + //uint32 UncompressedBufferSize = PackedData.Num(); + + return bOutSuccess; +} + + +// BEGIN RLE FUNCTIONS /// + +// Followed by a count of the following voxels +template +void RLE_Funcs::RLEDecodeLine(TArray* LineToDecode, TArray* DecodedLine, bool bCompressed) +{ + if (!LineToDecode || !DecodedLine) + return; + + RLEDecodeLine(LineToDecode->GetData(), LineToDecode->Num(), DecodedLine, bCompressed); +} + +// Followed by a count of the following voxels +template +void RLE_Funcs::RLEDecodeLine(const uint8* LineToDecode, uint32 Num, TArray* DecodedLine, bool bCompressed) +{ + if (!bCompressed) + { + DecodedLine->Empty(Num / sizeof(DataType)); + DecodedLine->AddUninitialized(Num / sizeof(DataType)); + FMemory::Memcpy(DecodedLine->GetData(), LineToDecode, Num); + return; + } + + const uint8* StartLoc = LineToDecode; + const uint8* EndLoc = StartLoc + Num; + uint8 incr = sizeof(DataType); + + DataType ValToWrite = *((DataType*)LineToDecode); // This is just to prevent stupid compiler warnings without disabling them + + DecodedLine->Empty(); + + uint8 RLE_FLAG; + uint32 Length32; + uint32 Length8; + uint32 Length16; + int origLoc; + + for (const uint8* loc = StartLoc; loc < EndLoc;) + { + RLE_FLAG = *loc >> 4; // Get the RLE flag from the first 4 bits of the first byte + + switch (RLE_FLAG) + { + case RLE_Flags::RLE_CompressedByte: + { + Length8 = (*loc & ~0xF0) + 1; + loc++; + ValToWrite = *((DataType*)loc); + loc += incr; + + origLoc = DecodedLine->AddUninitialized(Length8); + + for (uint32 i = origLoc; i < origLoc + Length8; i++) + { + (*DecodedLine)[i] = ValToWrite; + } + + }break; + case RLE_Flags::RLE_CompressedShort: + { + Length16 = (((uint16)(*loc & ~0xF0)) << 8 | (*(loc + 1))) + 1; + loc += 2; + ValToWrite = *((DataType*)loc); + loc += incr; + + origLoc = DecodedLine->AddUninitialized(Length16); + + for (uint32 i = origLoc; i < origLoc + Length16; i++) + { + (*DecodedLine)[i] = ValToWrite; + } + + }break; + case RLE_Flags::RLE_Compressed24: + { + Length32 = (((uint32)(*loc & ~0xF0)) << 16 | ((uint32)(*(loc + 1))) << 8 | (uint32)(*(loc + 2))) + 1; + loc += 3; + ValToWrite = *((DataType*)loc); + loc += incr; + + origLoc = DecodedLine->AddUninitialized(Length32); + + for (uint32 i = origLoc; i < origLoc + Length32; i++) + { + (*DecodedLine)[i] = ValToWrite; + } + + }break; + + case RLE_Flags::RLE_NotCompressedByte: + { + Length8 = (*loc & ~0xF0) + 1; + loc++; + + origLoc = DecodedLine->AddUninitialized(Length8); + + for (uint32 i = origLoc; i < origLoc + Length8; i++) + { + (*DecodedLine)[i] = *((DataType*)loc); + loc += incr; + } + + }break; + case RLE_Flags::RLE_NotCompressedShort: + { + Length16 = (((uint16)(*loc & ~0xF0)) << 8 | (*(loc + 1))) + 1; + loc += 2; + + origLoc = DecodedLine->AddUninitialized(Length16); + + for (uint32 i = origLoc; i < origLoc + Length16; i++) + { + (*DecodedLine)[i] = *((DataType*)loc); + loc += incr; + } + + }break; + case RLE_Flags::RLE_NotCompressed24: + { + Length32 = (((uint32)(*loc & ~0xF0)) << 16 | ((uint32)(*(loc + 1))) << 8 | ((uint32)(*(loc + 2)))) + 1; + loc += 3; + + origLoc = DecodedLine->AddUninitialized(Length32); + + for (uint32 i = origLoc; i < origLoc + Length32; i++) + { + (*DecodedLine)[i] = *((DataType*)loc); + loc += incr; + } + + }break; + + case RLE_Flags::RLE_ContinueRunByte: + { + Length8 = (*loc & ~0xF0) + 1; + loc++; + + origLoc = DecodedLine->AddUninitialized(Length8); + + for (uint32 i = origLoc; i < origLoc + Length8; i++) + { + (*DecodedLine)[i] = ValToWrite; + } + + }break; + case RLE_Flags::RLE_ContinueRunShort: + { + Length16 = (((uint16)(*loc & ~0xF0)) << 8 | (*(loc + 1))) + 1; + loc += 2; + + origLoc = DecodedLine->AddUninitialized(Length16); + + for (uint32 i = origLoc; i < origLoc + Length16; i++) + { + (*DecodedLine)[i] = ValToWrite; + } + + }break; + case RLE_Flags::RLE_ContinueRun24: + { + Length32 = (((uint32)(*loc & ~0xF0)) << 16 | ((uint32)(*(loc + 1))) << 8 | (*(loc + 2))) + 1; + loc += 3; + + origLoc = DecodedLine->AddUninitialized(Length32); + + for (uint32 i = origLoc; i < origLoc + Length32; i++) + { + (*DecodedLine)[i] = ValToWrite; + } + + }break; + + } + } +} + +template +bool RLE_Funcs::RLEEncodeLine(TArray* LineToEncode, TArray* EncodedLine) +{ + return RLEEncodeBuffer(LineToEncode->GetData(), LineToEncode->Num(), EncodedLine); +} + +void RLE_Funcs::RLEWriteContinueFlag(uint32 count, uint8** loc) +{ + if (count <= 16) + { + **loc = (((uint8)RLE_Flags::RLE_ContinueRunByte << 4) | ((uint8)count - 1)); + (*loc)++; + } + else if (count <= 4096) + { + uint16 val = ((((uint16)RLE_Flags::RLE_ContinueRunShort) << 12) | ((uint16)count - 1)); + **loc = val >> 8; + (*loc)++; + **loc = (uint8)val; + (*loc)++; + } + else + { + uint32 val = ((((uint32)RLE_Flags::RLE_ContinueRun24) << 20) | ((uint32)count - 1)); + **loc = (uint8)(val >> 16); + (*loc)++; + **loc = (uint8)(val >> 8); + (*loc)++; + **loc = (uint8)val; + (*loc)++; + } +} + +template +void RLE_Funcs::RLEWriteRunFlag(uint32 count, uint8** loc, TArray& Data, bool bCompressed) +{ + + if (count <= 16) + { + uint8 val; + if (bCompressed) + val = ((((uint8)RLE_Flags::RLE_CompressedByte) << 4) | ((uint8)count - 1)); + else + val = ((((uint8)RLE_Flags::RLE_NotCompressedByte) << 4) | ((uint8)count - 1)); + + **loc = val; + (*loc)++; + } + else if (count <= 4096) + { + uint16 val; + if (bCompressed) + val = ((((uint16)RLE_Flags::RLE_CompressedShort) << 12) | ((uint16)count - 1)); + else + val = ((((uint16)RLE_Flags::RLE_NotCompressedShort) << 12) | ((uint16)count - 1)); + + **loc = (uint8)(val >> 8); + (*loc)++; + **loc = (uint8)val; + (*loc)++; + } + else + { + uint32 val; + if (bCompressed) + val = ((((uint32)RLE_Flags::RLE_Compressed24) << 20) | ((uint32)count - 1)); + else + val = ((((uint32)RLE_Flags::RLE_NotCompressed24) << 20) | ((uint32)count - 1)); + + **loc = (uint8)(val >> 16); + (*loc)++; + **loc = (uint8)(val >> 8); + (*loc)++; + **loc = (uint8)(val); + (*loc)++; + } + + FMemory::Memcpy(*loc, Data.GetData(), Data.Num() * sizeof(DataType)); + *loc += Data.Num() * sizeof(DataType); + Data.Empty(256); +} + + +template +bool RLE_Funcs::RLEEncodeBuffer(DataType* BufferToEncode, uint32 EncodeLength, TArray* EncodedLine) +{ + uint32 OrigNum = EncodeLength;//LineToEncode->Num(); + uint8 incr = sizeof(DataType); + uint32 MAX_COUNT = 1048576; // Max of 2.5 bytes as 0.5 bytes is used for control flags + + EncodedLine->Empty((OrigNum * sizeof(DataType)) + (OrigNum * (sizeof(short)))); + // Reserve enough memory to account for a perfectly bad situation (original size + 3 bytes per max array value) + // Remove the remaining later with RemoveAt() and a count + EncodedLine->AddUninitialized((OrigNum * sizeof(DataType)) + ((OrigNum / MAX_COUNT * 3))); + + DataType* First = BufferToEncode;// LineToEncode->GetData(); + DataType Last; + uint32 RunCount = 0; + + uint8* loc = EncodedLine->GetData(); + //uint8 * countLoc = NULL; + + bool bInRun = false; + bool bWroteStart = false; + bool bContinueRun = false; + + TArray TempBuffer; + TempBuffer.Reserve(256); + uint32 TempCount = 0; + + Last = *First; + First++; + + for (uint32 i = 0; i < OrigNum - 1; i++, First++) + { + if (Last == *First) + { + if (bWroteStart && !bInRun) + { + RLE_Funcs::RLEWriteRunFlag(TempCount, &loc, TempBuffer, false); + bWroteStart = false; + } + + if (bInRun && /**countLoc*/TempCount < MAX_COUNT) + { + TempCount++; + + if (TempCount == MAX_COUNT) + { + // Write run byte + if (bContinueRun) + { + RLE_Funcs::RLEWriteContinueFlag(TempCount, &loc); + } + else + RLE_Funcs::RLEWriteRunFlag(TempCount, &loc, TempBuffer, true); + + bContinueRun = true; + TempCount = 0; + } + } + else + { + bInRun = true; + bWroteStart = false; + bContinueRun = false; + + TempBuffer.Add(Last); + TempCount = 1; + } + + // Begin Run Here + } + else if (bInRun) + { + bInRun = false; + + if (bContinueRun) + { + TempCount++; + RLE_Funcs::RLEWriteContinueFlag(TempCount, &loc); + } + else + { + TempCount++; + RLE_Funcs::RLEWriteRunFlag(TempCount, &loc, TempBuffer, true); + } + + bContinueRun = false; + } + else + { + if (bWroteStart && TempCount/**countLoc*/ < MAX_COUNT) + { + TempCount++; + TempBuffer.Add(Last); + } + else if (bWroteStart && TempCount == MAX_COUNT) + { + RLE_Funcs::RLEWriteRunFlag(TempCount, &loc, TempBuffer, false); + + bWroteStart = true; + TempBuffer.Add(Last); + TempCount = 1; + } + else + { + TempBuffer.Add(Last); + TempCount = 1; + //*countLoc = 1; + + bWroteStart = true; + } + } + + Last = *First; + } + + // Finish last num + if (bInRun) + { + if (TempCount <= MAX_COUNT) + { + if (TempCount == MAX_COUNT) + { + // Write run byte + RLE_Funcs::RLEWriteRunFlag(TempCount, &loc, TempBuffer, true); + bContinueRun = true; + } + + if (bContinueRun) + { + TempCount++; + RLE_Funcs::RLEWriteContinueFlag(TempCount, &loc); + } + else + { + TempCount++; + RLE_Funcs::RLEWriteRunFlag(TempCount, &loc, TempBuffer, true); + } + } + + // Begin Run Here + } + else + { + if (bWroteStart && TempCount/**countLoc*/ <= MAX_COUNT) + { + if (TempCount/**countLoc*/ == MAX_COUNT) + { + // Write run byte + RLE_Funcs::RLEWriteRunFlag(TempCount, &loc, TempBuffer, false); + TempCount = 0; + } + + TempCount++; + TempBuffer.Add(Last); + RLE_Funcs::RLEWriteRunFlag(TempCount, &loc, TempBuffer, false); + } + } + + // Resize the out array to fit compressed contents + uint32 Wrote = loc - EncodedLine->GetData(); + EncodedLine->RemoveAt(Wrote, EncodedLine->Num() - Wrote, true); + + // If the compression performed worse than the original file size, throw the results array and use the original instead. + // This will almost never happen with voxels but can so should be accounted for. + + return true; + // Skipping non compressed for now, the overhead is so low that it isn't worth supporting since the last revision + /* + if (Wrote > OrigNum * incr) + { + EncodedLine->Empty(OrigNum * incr); + EncodedLine->AddUninitialized(OrigNum * incr); + FMemory::Memcpy(EncodedLine->GetData(), BufferToEncode, OrigNum * incr); + return false; // Return that there was no compression, so the decoder can receive it later + } + else + return true; + */ +} + +template +bool WritePackedVector2D(FVector2D Value, FArchive& Ar) // Note Value is intended to not be a reference since we are scaling it before serializing! +{ + check(Ar.IsSaving()); + + // Scale vector by quant factor first + Value *= ScaleFactor; + + // Nan Check + if (Value.ContainsNaN()) + { + logOrEnsureNanError(TEXT("WritePackedVector2D: Value contains NaN, clearing for safety.")); + FVector2D Dummy(0, 0); + WritePackedVector2D(Dummy, Ar); + return false; + } + + float MinV = -1073741824.0f; + float MaxV = 1073741760.0f; + + // Some platforms have RoundToInt implementations that essentially reduces the allowed inputs to 2^31. + const FVector2D ClampedValue = FVector2D(FMath::Clamp(Value.X, MinV, MaxV), FMath::Clamp(Value.Y, MinV, MaxV)); + bool bClamp = ClampedValue != Value; + + // Do basically FVector::SerializeCompressed + int32 IntX = FMath::RoundToInt(ClampedValue.X); + int32 IntY = FMath::RoundToInt(ClampedValue.Y); + + uint32 Bits = FMath::Clamp(FMath::CeilLogTwo(1 + FMath::Max(FMath::Abs(IntX), FMath::Abs(IntY))), 1, MaxBitsPerComponent) - 1; + + // Serialize how many bits each component will have + Ar.SerializeInt(Bits, MaxBitsPerComponent); + + int32 Bias = 1 << (Bits + 1); + uint32 Max = 1 << (Bits + 2); + uint32 DX = IntX + Bias; + uint32 DY = IntY + Bias; + + if (DX >= Max) { bClamp = true; DX = static_cast(DX) > 0 ? Max - 1 : 0; } + if (DY >= Max) { bClamp = true; DY = static_cast(DY) > 0 ? Max - 1 : 0; } + + Ar.SerializeInt(DX, Max); + Ar.SerializeInt(DY, Max); + + return !bClamp; +} + +template +bool ReadPackedVector2D(FVector2D& Value, FArchive& Ar) +{ + uint32 Bits = 0; + + // Serialize how many bits each component will have + Ar.SerializeInt(Bits, MaxBitsPerComponent); + + int32 Bias = 1 << (Bits + 1); + uint32 Max = 1 << (Bits + 2); + uint32 DX = 0; + uint32 DY = 0; + + Ar.SerializeInt(DX, Max); + Ar.SerializeInt(DY, Max); + + + float fact = (float)ScaleFactor; + + Value.X = (float)(static_cast(DX) - Bias) / fact; + Value.Y = (float)(static_cast(DY) - Bias) / fact; + + return true; +} + +bool FRenderManagerOperation::NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) +{ + bOutSuccess = true; + + + Ar.SerializeIntPacked(OwnerID); + Ar.SerializeBits(&OperationType, 3); + + switch (OperationType) + { + case ERenderManagerOperationType::Op_LineDraw: + { + Ar << Color; + Ar.SerializeIntPacked(Thickness); + + if (Ar.IsSaving()) + { + bOutSuccess &= WritePackedVector2D<1, 20>(P1, Ar); + bOutSuccess &= WritePackedVector2D<1, 20>(P2, Ar); + } + else + { + ReadPackedVector2D<1, 20>(P1, Ar); + ReadPackedVector2D<1, 20>(P2, Ar); + } + }break; + case ERenderManagerOperationType::Op_TexDraw: + { + Ar << Texture; + + if (Ar.IsSaving()) + { + bOutSuccess &= WritePackedVector2D<1, 20>(P1, Ar); + } + else + { + ReadPackedVector2D<1, 20>(P1, Ar); + } + }break; + case ERenderManagerOperationType::Op_TriDraw: + { + Ar << Color; + Ar << Material; + + uint32 ArrayCt = Tris.Num(); + Ar.SerializeIntPacked(ArrayCt); + + if (Ar.IsLoading()) + { + Tris.Reset(ArrayCt); + Tris.AddUninitialized(ArrayCt); + + FRenderManagerTri TriTemp; + for (uint32 i = 0; i < ArrayCt; ++i) + { + ReadPackedVector2D<1, 20>(TriTemp.P1, Ar); + ReadPackedVector2D<1, 20>(TriTemp.P2, Ar); + ReadPackedVector2D<1, 20>(TriTemp.P3, Ar); + Tris[i] = TriTemp; + } + } + else + { + for (uint32 i = 0; i < ArrayCt; ++i) + { + WritePackedVector2D<1, 20>(Tris[i].P1, Ar); + WritePackedVector2D<1, 20>(Tris[i].P2, Ar); + WritePackedVector2D<1, 20>(Tris[i].P3, Ar); + } + } + + }break; + } + + return bOutSuccess; +} diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Mover/VRMoverComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Mover/VRMoverComponent.cpp new file mode 100644 index 0000000..d9abaa8 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/Mover/VRMoverComponent.cpp @@ -0,0 +1,207 @@ + +#include "Mover/VRMoverComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRMoverComponent) + +#include "VRBPDatatypes.h" +#include "DefaultMovementSet/LayeredMoves/BasicLayeredMoves.h" +#include "Engine/BlueprintGeneratedClass.h" +#include "Curves/CurveFloat.h" // Delete after tests, only needed for cloning +#include "ReplicatedVRCameraComponent.h" + +DEFINE_LOG_CATEGORY(LogVRMoverComponent); + + +static const FName Name_CharacterMotionComponent(TEXT("MoverComponent")); + +/* + + Layered move to inject VR movement into the mover component + +*/ + + +FLayeredMove_VRMovement::FLayeredMove_VRMovement() + : Velocity(FVector::ZeroVector) + , MagnitudeOverTime(nullptr) + , SettingsFlags(0) +{ + // This should never end + DurationMs = -1.0f; +} + +bool FLayeredMove_VRMovement::IsFinished(float CurrentSimTimeMs) const +{ + // We never end the VR velocity injection + return false; +} + +bool FLayeredMove_VRMovement::GenerateMove(const FMoverTickStartData& SimState, const FMoverTimeStep& TimeStep, const UMoverComponent* MoverComp, UMoverBlackboard* SimBlackboard, FProposedMove& OutProposedMove) +{ + const FMoverDefaultSyncState* SyncState = SimState.SyncState.SyncStateCollection.FindDataByType(); + check(SyncState); + + const float DeltaSeconds = TimeStep.StepMs * 0.001f; + + // Convert starting velocity based on starting orientation, if settings call for it + if (SettingsFlags & (uint8)ELayeredMove_ConstantVelocitySettingsFlags::VelocityStartRelative && + StartSimTimeMs == TimeStep.BaseSimTimeMs) + { + SettingsFlags &= ~(uint8)ELayeredMove_ConstantVelocitySettingsFlags::VelocityStartRelative; + Velocity = SyncState->GetOrientation_WorldSpace().RotateVector(Velocity); + } + + FVector VelocityThisFrame = Velocity; + + // Put velocity into worldspace + if (SettingsFlags & (uint8)ELayeredMove_ConstantVelocitySettingsFlags::VelocityAlwaysRelative) + { + VelocityThisFrame = SyncState->GetOrientation_WorldSpace().RotateVector(Velocity); + } + + if (MagnitudeOverTime && DurationMs > 0) + { + const float TimeValue = DurationMs > 0.f ? FMath::Clamp((TimeStep.BaseSimTimeMs - StartSimTimeMs) / DurationMs, 0.f, 1.f) : TimeStep.BaseSimTimeMs; + const float TimeFactor = MagnitudeOverTime->GetFloatValue(TimeValue); + VelocityThisFrame *= TimeFactor; + } + + OutProposedMove.LinearVelocity = VelocityThisFrame; + + return true; +} + +FLayeredMoveBase* FLayeredMove_VRMovement::Clone() const +{ + FLayeredMove_VRMovement* CopyPtr = new FLayeredMove_VRMovement(*this); + return CopyPtr; +} + +void FLayeredMove_VRMovement::NetSerialize(FArchive& Ar) +{ + Super::NetSerialize(Ar); + + SerializePackedVector<10, 16>(Velocity, Ar); + Ar << SettingsFlags; + Ar << MagnitudeOverTime; +} + +UScriptStruct* FLayeredMove_VRMovement::GetScriptStruct() const +{ + return FLayeredMove_VRMovement::StaticStruct(); +} + +FString FLayeredMove_VRMovement::ToSimpleString() const +{ + return FString::Printf(TEXT("LinearVelocity")); +} + +void FLayeredMove_VRMovement::AddReferencedObjects(class FReferenceCollector& Collector) +{ + Super::AddReferencedObjects(Collector); +} + + +/* + + VR HMD Sync State to store the HMD velocities + Which should be pulled from input somehow +*/ + +FMoverDataStructBase* FVRMoverHMDSyncState::Clone() const +{ + // TODO: ensure that this memory allocation jives with deletion method + FVRMoverHMDSyncState* CopyPtr = new FVRMoverHMDSyncState(*this); + return CopyPtr; +} + +bool FVRMoverHMDSyncState::NetSerialize(FArchive& Ar, UPackageMap* Map, bool& bOutSuccess) +{ + Super::NetSerialize(Ar, Map, bOutSuccess); + + SerializeFixedVector<2, 8>(MoveDirectionIntent, Ar); + bOutSuccess = true; + return true; +} + + + +AVRMoverBasePawn::AVRMoverBasePawn(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + + CharacterMotionComponent = CreateDefaultSubobject(Name_CharacterMotionComponent); + ensure(CharacterMotionComponent); + + // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. + PrimaryActorTick.bCanEverTick = true; + + SetReplicatingMovement(false); // disable Actor-level movement replication, since our Mover component will handle it + + // Let the code know if blueprints have implemented input + auto IsImplementedInBlueprint = [](const UFunction* Func) -> bool + { + return Func && ensure(Func->GetOuter()) + && Func->GetOuter()->IsA(UBlueprintGeneratedClass::StaticClass()); + }; + + static FName ProduceInputBPFuncName = FName(TEXT("OnProduceInputInBlueprint")); + UFunction* ProduceInputFunction = GetClass()->FindFunctionByName(ProduceInputBPFuncName); + bHasProduceInputinBpFunc = IsImplementedInBlueprint(ProduceInputFunction); +} + +void AVRMoverBasePawn::BeginPlay() +{ + Super::BeginPlay(); + + // In constructor for the data instead of begin play? Might even be able to queue the layered move there too + if (IsValid(CharacterMotionComponent)) + { + // Add the sync data for our layered HMD movement injection + CharacterMotionComponent->PersistentSyncStateDataTypes.Add(FMoverDataPersistence(FVRMoverHMDSyncState::StaticStruct(), true)); + + // Needs to be handled off of possession instead? + if (HasLocalNetOwner()) + { + // Add the persistant HMDlayered move addition + TSharedPtr VRMoveLayer = MakeShared(); + CharacterMotionComponent->QueueLayeredMove(VRMoveLayer); + } + } +} + + +UPrimitiveComponent* AVRMoverBasePawn::GetMovementBase() const +{ + return CharacterMotionComponent ? CharacterMotionComponent->GetMovementBase() : nullptr; +} + + +void AVRMoverBasePawn::ProduceInput_Implementation(int32 SimTimeMs, FMoverInputCmdContext& InputCmdResult) +{ + OnProduceInput((float)SimTimeMs, InputCmdResult); + + if (bHasProduceInputinBpFunc) + { + InputCmdResult = OnProduceInputInBlueprint((float)SimTimeMs, InputCmdResult); + } +} + + +void AVRMoverBasePawn::OnProduceInput(float DeltaMs, FMoverInputCmdContext& OutInputCmd) +{ + + // Generate user commands. Called right before the Character movement simulation will tick (for a locally controlled pawn) + // This isn't meant to be the best way of doing a camera system. It is just meant to show a couple of ways it may be done + // and to make sure we can keep distinct the movement, rotation, and view angles. + // Styles 1-3 are really meant to be used with a gamepad. + // + // Its worth calling out: the code that happens here is happening *outside* of the Character movement simulation. All we are doing + // is generating the input being fed into that simulation. That said, this means that A) the code below does not run on the server + // (and non controlling clients) and B) the code is not rerun during reconcile/resimulates. Use this information guide any + // decisions about where something should go (such as aim assist, lock on targeting systems, etc): it is hard to give absolute + // answers and will depend on the game and its specific needs. In general, at this time, I'd recommend aim assist and lock on + // targeting systems to happen /outside/ of the system, i.e, here. But I can think of scenarios where that may not be ideal too. + + //FCharacterDefaultInputs& CharacterInputs = OutInputCmd.InputCollection.FindOrAddMutableDataByType(); + +} diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/ParentRelativeAttachmentComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/ParentRelativeAttachmentComponent.cpp new file mode 100644 index 0000000..741ed2f --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/ParentRelativeAttachmentComponent.cpp @@ -0,0 +1,257 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "ParentRelativeAttachmentComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(ParentRelativeAttachmentComponent) + +#include "Engine/Engine.h" +#include "VRBaseCharacter.h" +#include "VRCharacter.h" +#include "IXRTrackingSystem.h" +#include "VRRootComponent.h" +//#include "Runtime/Engine/Private/EnginePrivate.h" +//#include "VRSimpleCharacter.h" +//#include "VRCharacter.h" + + +UParentRelativeAttachmentComponent::UParentRelativeAttachmentComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + PrimaryComponentTick.bCanEverTick = true; + PrimaryComponentTick.bStartWithTickEnabled = true; + // Let it sit in DuringPhysics like is the default + //PrimaryComponentTick.TickGroup = TG_PrePhysics; + + bWantsInitializeComponent = true; + + SetRelativeScale3D(FVector(1.0f, 1.0f, 1.0f)); + SetRelativeLocation(FVector::ZeroVector); + YawTolerance = 0.0f; + //bOffsetByHMD = false; + + bLerpTransition = true; + LerpSpeed = 100.0f; + LastLerpVal = 0.0f; + LerpTarget = 0.0f; + bWasSetOnce = false; + + LeftControllerTrans = FTransform::Identity; + RightControllerTrans = FTransform::Identity; + + bIgnoreRotationFromParent = false; + bUpdateInCharacterMovement = true; + bIsPaused = false; + + CustomOffset = FVector::ZeroVector; + + //YawRotationMethod = EVR_PRC_RotationMethod::PRC_ROT_HMD; +} + +void UParentRelativeAttachmentComponent::InitializeComponent() +{ + Super::InitializeComponent(); + + // Update our tracking + if (!bUseFeetLocation && IsValid(AttachChar) && IsValid(AttachChar->VRReplicatedCamera)) // New case to early out and with less calculations + { + SetRelativeTransform(AttachChar->VRReplicatedCamera->GetRelativeTransform()); + } + +} + +void UParentRelativeAttachmentComponent::OnAttachmentChanged() +{ + if (AVRCharacter* CharacterOwner = Cast(this->GetOwner())) + { + AttachChar = CharacterOwner; + } + else + { + AttachChar = nullptr; + } + + if (AVRBaseCharacter * BaseCharacterOwner = Cast(this->GetOwner())) + { + AttachBaseChar = BaseCharacterOwner; + } + else + { + AttachBaseChar = nullptr; + } + + Super::OnAttachmentChanged(); +} + +void UParentRelativeAttachmentComponent::SetPaused(bool bNewPaused, bool bZeroOutRotation, bool bZeroOutLocation) +{ + if (bNewPaused != bIsPaused) + { + bIsPaused = bNewPaused; + + if (bIsPaused && (bZeroOutLocation || bZeroOutRotation)) + { + FVector NewLoc = this->GetRelativeLocation(); + FRotator NewRot = this->GetRelativeRotation(); + + if (bZeroOutLocation) + { + NewLoc = FVector::ZeroVector; + } + + if (bZeroOutRotation) + { + NewRot = FRotator::ZeroRotator; + } + + SetRelativeLocationAndRotation(NewLoc, NewRot); + } + } +} + +void UParentRelativeAttachmentComponent::SetRelativeRotAndLoc(FVector NewRelativeLocation, FRotator NewRelativeRotation, float DeltaTime) +{ + + RunSampling(NewRelativeRotation, NewRelativeLocation); + + if (bUseFeetLocation) + { + FVector TotalOffset = CustomOffset; + if (bUseCenterAsFeetLocation && AttachChar && AttachChar->VRRootReference) + { + TotalOffset.Z += AttachChar->VRRootReference->GetUnscaledCapsuleHalfHeight(); + } + + if (!bIgnoreRotationFromParent) + { + SetRelativeLocationAndRotation( + FVector(NewRelativeLocation.X, NewRelativeLocation.Y, 0.0f) + TotalOffset, + GetCalculatedRotation(NewRelativeRotation, DeltaTime) + ); + } + else + { + SetRelativeLocation(FVector(NewRelativeLocation.X, NewRelativeLocation.Y, 0.0f) + TotalOffset); + } + } + else + { + if (!bIgnoreRotationFromParent) + { + SetRelativeLocationAndRotation( + NewRelativeLocation + CustomOffset, + GetCalculatedRotation(NewRelativeRotation, DeltaTime) + ); // Use the HMD height instead + } + else + { + SetRelativeLocation(NewRelativeLocation + CustomOffset); // Use the HMD height instead + } + } +} + +void UParentRelativeAttachmentComponent::UpdateTracking(float DeltaTime) +{ + // We are paused, do not update tracking anymore + if (bIsPaused) + return; + + if (OptionalWaistTrackingParent.IsValid()) + { + //#TODO: bOffsetByHMD not supported with this currently, fix it, need to check for both camera and HMD + FTransform TrackedParentWaist = IVRTrackedParentInterface::Default_GetWaistOrientationAndPosition(OptionalWaistTrackingParent); + + if (bUseFeetLocation) + { + TrackedParentWaist.SetTranslation(TrackedParentWaist.GetTranslation() * FVector(1.0f, 1.0f, 0.0f)); + + if (!bIgnoreRotationFromParent) + { + FRotator InverseRot = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(TrackedParentWaist.Rotator()); + + TrackedParentWaist.SetRotation(GetCalculatedRotation(InverseRot, DeltaTime)); + } + } + + TrackedParentWaist.AddToTranslation(CustomOffset); + SetRelativeTransform(TrackedParentWaist); + + } + else if (IsValid(AttachChar)) // New case to early out and with less calculations + { + if (AttachChar->bRetainRoomscale) + { + SetRelativeRotAndLoc(AttachChar->VRRootReference->curCameraLoc, AttachChar->VRRootReference->StoredCameraRotOffset, DeltaTime); + } + else + { + FVector CameraLoc = FVector(0.0f, 0.0f, AttachChar->VRRootReference->curCameraLoc.Z); + CameraLoc += AttachChar->VRRootReference->StoredCameraRotOffset.RotateVector(FVector(-AttachChar->VRRootReference->VRCapsuleOffset.X, -AttachChar->VRRootReference->VRCapsuleOffset.Y, 0.0f)); + SetRelativeRotAndLoc(CameraLoc, AttachChar->VRRootReference->StoredCameraRotOffset, DeltaTime); + } + } + else if (IsLocallyControlled() && GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowed()) + { + FQuat curRot; + FVector curCameraLoc; + if (GEngine->XRSystem->GetCurrentPose(IXRTrackingSystem::HMDDeviceId, curRot, curCameraLoc)) + { + /*if (bOffsetByHMD) + { + curCameraLoc.X = 0; + curCameraLoc.Y = 0; + }*/ + + if (!bIgnoreRotationFromParent) + { + FRotator InverseRot = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(curRot.Rotator()); + SetRelativeRotAndLoc(curCameraLoc, InverseRot, DeltaTime); + } + else + SetRelativeRotAndLoc(curCameraLoc, FRotator::ZeroRotator, DeltaTime); + } + } + else if (IsValid(AttachBaseChar)) + { + if (AttachBaseChar->VRReplicatedCamera) + { + if (!bIgnoreRotationFromParent) + { + FRotator InverseRot = UVRExpansionFunctionLibrary::GetHMDPureYaw(AttachBaseChar->VRReplicatedCamera->GetRelativeRotation()); + SetRelativeRotAndLoc(AttachBaseChar->VRReplicatedCamera->GetRelativeLocation(), InverseRot, DeltaTime); + } + else + SetRelativeRotAndLoc(AttachBaseChar->VRReplicatedCamera->GetRelativeLocation(), FRotator::ZeroRotator, DeltaTime); + } + } + else if (AActor* owner = this->GetOwner()) + { + if (UCameraComponent* CameraOwner = owner->FindComponentByClass()) + { + if (!bIgnoreRotationFromParent) + { + FRotator InverseRot = UVRExpansionFunctionLibrary::GetHMDPureYaw(CameraOwner->GetRelativeRotation()); + SetRelativeRotAndLoc(CameraOwner->GetRelativeLocation(), InverseRot, DeltaTime); + } + else + SetRelativeRotAndLoc(CameraOwner->GetRelativeLocation(), FRotator::ZeroRotator, DeltaTime); + } + } +} + +void UParentRelativeAttachmentComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) +{ + if (!bUpdateInCharacterMovement || !IsValid(AttachChar)) + { + UpdateTracking(DeltaTime); + } + else + { + UCharacterMovementComponent * CharMove = AttachChar->GetCharacterMovement(); + if (!CharMove || !CharMove->IsComponentTickEnabled() || !CharMove->IsActive()) + { + // Our character movement isn't handling our updates, lets do it ourself. + UpdateTracking(DeltaTime); + } + } + + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/ReplicatedVRCameraComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/ReplicatedVRCameraComponent.cpp new file mode 100644 index 0000000..c592ee2 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/ReplicatedVRCameraComponent.cpp @@ -0,0 +1,601 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "ReplicatedVRCameraComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(ReplicatedVRCameraComponent) + +#include "CoreMinimal.h" +#include "Engine/Engine.h" +#include "Engine/World.h" +#include "Net/UnrealNetwork.h" +#include "VRBaseCharacter.h" +#include "VRCharacter.h" +#include "VRRootComponent.h" +#include "IXRTrackingSystem.h" +#include "IXRCamera.h" +#include "Rendering/MotionVectorSimulation.h" + +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + +UReplicatedVRCameraComponent::UReplicatedVRCameraComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + PrimaryComponentTick.bCanEverTick = true; + PrimaryComponentTick.bStartWithTickEnabled = true; + //PrimaryComponentTick.TickGroup = TG_PrePhysics; + + SetIsReplicatedByDefault(true); + SetRelativeScale3D(FVector(1.0f, 1.0f, 1.0f)); + + // Default 100 htz update rate, same as the 100htz update rate of rep_notify, will be capped to 90/45 though because of vsync on HMD + //bReplicateTransform = true; + NetUpdateRate = 100.0f; // 100 htz is default + NetUpdateCount = 0.0f; + + bUsePawnControlRotation = false; + bAutoSetLockToHmd = true; + bScaleTracking = false; + TrackingScaler = FVector(1.0f); + //bOffsetByHMD = false; + bLimitMinHeight = false; + MinimumHeightAllowed = 0.0f; + bLimitMaxHeight = false; + MaxHeightAllowed = 300.f; + bLimitBounds = false; + // Just shy of 20' distance from the center of tracked space + MaximumTrackedBounds = 1028; + + bSetPositionDuringTick = false; + bLerpingPosition = false; + bReppedOnce = false; + + OverrideSendTransform = nullptr; + + LastRelativePosition = FTransform::Identity; + bSampleVelocityInWorldSpace = false; + bHadValidFirstVelocity = false; + + //bUseVRNeckOffset = true; + //VRNeckOffset = FTransform(FRotator::ZeroRotator, FVector(15.0f,0,0), FVector(1.0f)); + +} + + +//============================================================================= +void UReplicatedVRCameraComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + + // I am skipping the Scene component replication here + // Generally components aren't set to replicate anyway and I need it to NOT pass the Relative position through the network + // There isn't much in the scene component to replicate anyway + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + DISABLE_REPLICATED_PRIVATE_PROPERTY(USceneComponent, RelativeLocation); + DISABLE_REPLICATED_PRIVATE_PROPERTY(USceneComponent, RelativeRotation); + DISABLE_REPLICATED_PRIVATE_PROPERTY(USceneComponent, RelativeScale3D); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_SkipOwner, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + // Skipping the owner with this as the owner will use the location directly + DOREPLIFETIME_WITH_PARAMS_FAST(UReplicatedVRCameraComponent, ReplicatedCameraTransform, PushModelParamsWithCondition); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(UReplicatedVRCameraComponent, NetUpdateRate, PushModelParams); + //DOREPLIFETIME(UReplicatedVRCameraComponent, bSmoothReplicatedMotion); // This doesn't need to be replicated + //DOREPLIFETIME(UReplicatedVRCameraComponent, bReplicateTransform); +} + +void UReplicatedVRCameraComponent::Server_SendCameraTransform_Implementation(FBPVRComponentPosRep NewTransform) +{ + // Store new transform and trigger OnRep_Function + ReplicatedCameraTransform = NewTransform; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UReplicatedVRCameraComponent, ReplicatedCameraTransform, this); +#endif + + // Don't call on rep on the server if the server controls this controller + if (!bHasAuthority) + { + OnRep_ReplicatedCameraTransform(); + } +} + +bool UReplicatedVRCameraComponent::Server_SendCameraTransform_Validate(FBPVRComponentPosRep NewTransform) +{ + return true; + // Optionally check to make sure that player is inside of their bounds and deny it if they aren't? +} + +/*bool UReplicatedVRCameraComponent::IsServer() +{ + if (GEngine != nullptr && GWorld != nullptr) + { + switch (GEngine->GetNetMode(GWorld)) + { + case NM_Client: + {return false; } break; + case NM_DedicatedServer: + case NM_ListenServer: + default: + {return true; } break; + } + } + + return false; +}*/ + +void UReplicatedVRCameraComponent::OnAttachmentChanged() +{ + if (AVRCharacter* CharacterOwner = Cast(this->GetOwner())) + { + AttachChar = CharacterOwner; + } + else + { + AttachChar = nullptr; + } + + Super::OnAttachmentChanged(); +} + +bool UReplicatedVRCameraComponent::HasTrackingParameters() +{ + return /*bOffsetByHMD ||*/ bScaleTracking || bLimitMaxHeight || bLimitMinHeight || bLimitBounds || (AttachChar && !AttachChar->bRetainRoomscale); +} + +void UReplicatedVRCameraComponent::ApplyTrackingParameters(FVector &OriginalPosition, bool bSkipLocZero) +{ + // I'm keeping the original values here as it lets me send them out for seated mode + if (!bSkipLocZero && (AttachChar && !AttachChar->bRetainRoomscale)) + { + OriginalPosition.X = 0; + OriginalPosition.Y = 0; + } + + if (bLimitBounds) + { + OriginalPosition.X = FMath::Clamp(OriginalPosition.X, -MaximumTrackedBounds, MaximumTrackedBounds); + OriginalPosition.Y = FMath::Clamp(OriginalPosition.Y, -MaximumTrackedBounds, MaximumTrackedBounds); + } + + if (bScaleTracking) + { + OriginalPosition *= TrackingScaler; + } + + if (bLimitMaxHeight) + { + OriginalPosition.Z = FMath::Min(MaxHeightAllowed, OriginalPosition.Z); + } + + if (bLimitMinHeight) + { + OriginalPosition.Z = FMath::Max(MinimumHeightAllowed, OriginalPosition.Z); + } +} + +void UReplicatedVRCameraComponent::UpdateTracking(float DeltaTime) +{ + bHasAuthority = IsLocallyControlled(); + + // Don't do any of the below if we aren't the authority + if (bHasAuthority) + { + // For non view target positional updates (third party and the like) + if (bSetPositionDuringTick && bLockToHmd && GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowedForWorld(*GetWorld())) + { + //ResetRelativeTransform(); + FQuat Orientation; + FVector Position; + if (GEngine->XRSystem->GetCurrentPose(IXRTrackingSystem::HMDDeviceId, Orientation, Position)) + { + if (HasTrackingParameters()) + { + ApplyTrackingParameters(Position, true); + } + + ReplicatedCameraTransform.Position = Position; + ReplicatedCameraTransform.Rotation = Orientation.Rotator(); + + if (IsValid(AttachChar) && !AttachChar->bRetainRoomscale) + { + // Zero out camera posiiton + Position.X = 0.0f; + Position.Y = 0.0f; + + FRotator StoredCameraRotOffset = FRotator::ZeroRotator; + if (AttachChar->VRMovementReference && AttachChar->VRMovementReference->GetReplicatedMovementMode() == EVRConjoinedMovementModes::C_VRMOVE_Seated) + { + AttachChar->SeatInformation.InitialRelCameraTransform.Rotator(); + } + else + { + StoredCameraRotOffset = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(Orientation.Rotator()); + } + + Position += StoredCameraRotOffset.RotateVector(FVector(-AttachChar->VRRootReference->VRCapsuleOffset.X, -AttachChar->VRRootReference->VRCapsuleOffset.Y, 0.0f)); + + } + + SetRelativeTransform(FTransform(Orientation, Position)); + } + } + } + else + { + // Run any networked smoothing + RunNetworkedSmoothing(DeltaTime); + } + + // Save out the component velocity from this and last frame + if(bHadValidFirstVelocity || !LastRelativePosition.Equals(FTransform::Identity)) + { + bHadValidFirstVelocity = true; + ComponentVelocity = ((bSampleVelocityInWorldSpace ? GetComponentLocation() : GetRelativeLocation()) - LastRelativePosition.GetTranslation()) / DeltaTime; + } + + LastRelativePosition = bSampleVelocityInWorldSpace ? this->GetComponentTransform() : this->GetRelativeTransform(); +} + +void UReplicatedVRCameraComponent::RunNetworkedSmoothing(float DeltaTime) +{ + FVector RetainPositionOffset(0.0f, 0.0f, ReplicatedCameraTransform.Position.Z); + + if (AttachChar && !AttachChar->bRetainRoomscale) + { + FRotator StoredCameraRotOffset = FRotator::ZeroRotator; + if (AttachChar->VRMovementReference && AttachChar->VRMovementReference->GetReplicatedMovementMode() == EVRConjoinedMovementModes::C_VRMOVE_Seated) + { + AttachChar->SeatInformation.InitialRelCameraTransform.Rotator(); + } + else + { + StoredCameraRotOffset = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(ReplicatedCameraTransform.Rotation); + } + + RetainPositionOffset += StoredCameraRotOffset.RotateVector(FVector(-AttachChar->VRRootReference->VRCapsuleOffset.X, -AttachChar->VRRootReference->VRCapsuleOffset.Y, 0.0f)); + } + + if (bLerpingPosition) + { + if (!bUseExponentialSmoothing) + { + NetUpdateCount += DeltaTime; + float LerpVal = FMath::Clamp(NetUpdateCount / (1.0f / NetUpdateRate), 0.0f, 1.0f); + + if (LerpVal >= 1.0f) + { + if (AttachChar && !AttachChar->bRetainRoomscale) + { + SetRelativeLocationAndRotation(RetainPositionOffset, ReplicatedCameraTransform.Rotation); + } + else + { + SetRelativeLocationAndRotation(ReplicatedCameraTransform.Position, ReplicatedCameraTransform.Rotation); + } + + // Stop lerping, wait for next update if it is delayed or lost then it will hitch here + // Actual prediction might be something to consider in the future, but rough to do in VR + // considering the speed and accuracy of movements + // would like to consider sub stepping but since there is no server rollback...not sure how useful it would be + // and might be perf taxing enough to not make it worth it. + bLerpingPosition = false; + NetUpdateCount = 0.0f; + } + else + { + + if (AttachChar && !AttachChar->bRetainRoomscale) + { + // Removed variables to speed this up a bit + SetRelativeLocationAndRotation( + FMath::Lerp(LastUpdatesRelativePosition, RetainPositionOffset, LerpVal), + FMath::Lerp(LastUpdatesRelativeRotation, ReplicatedCameraTransform.Rotation, LerpVal) + ); + } + else + { + // Removed variables to speed this up a bit + SetRelativeLocationAndRotation( + FMath::Lerp(LastUpdatesRelativePosition, (FVector)ReplicatedCameraTransform.Position, LerpVal), + FMath::Lerp(LastUpdatesRelativeRotation, ReplicatedCameraTransform.Rotation, LerpVal) + ); + } + } + } + else // Exponential Smoothing + { + if (InterpolationSpeed <= 0.f) + { + if (AttachChar && !AttachChar->bRetainRoomscale) + { + SetRelativeLocationAndRotation(RetainPositionOffset, ReplicatedCameraTransform.Rotation); + } + else + { + SetRelativeLocationAndRotation((FVector)ReplicatedCameraTransform.Position, ReplicatedCameraTransform.Rotation); + } + + bLerpingPosition = false; + return; + } + + const float Alpha = FMath::Clamp(DeltaTime * InterpolationSpeed, 0.f, 1.f); + + FTransform NA = FTransform(GetRelativeRotation(), GetRelativeLocation(), FVector(1.0f)); + FTransform NB = FTransform::Identity; + + if (AttachChar && !AttachChar->bRetainRoomscale) + { + NB = FTransform(ReplicatedCameraTransform.Rotation, RetainPositionOffset, FVector(1.0f)); + } + else + { + NB = FTransform(ReplicatedCameraTransform.Rotation, (FVector)ReplicatedCameraTransform.Position, FVector(1.0f)); + } + + NA.NormalizeRotation(); + NB.NormalizeRotation(); + + NA.Blend(NA, NB, Alpha); + + // If we are nearly equal then snap to final position + if (NA.EqualsNoScale(NB)) + { + if (AttachChar && !AttachChar->bRetainRoomscale) + { + SetRelativeLocationAndRotation(RetainPositionOffset, ReplicatedCameraTransform.Rotation); + } + else + { + SetRelativeLocationAndRotation(ReplicatedCameraTransform.Position, ReplicatedCameraTransform.Rotation); + } + } + else // Else just keep going + { + SetRelativeLocationAndRotation(NA.GetTranslation(), NA.Rotator()); + } + } + } +} + + +void UReplicatedVRCameraComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) +{ + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + + if (!bUpdateInCharacterMovement || !IsValid(AttachChar)) + { + UpdateTracking(DeltaTime); + } + else + { + UCharacterMovementComponent* CharMove = AttachChar->GetCharacterMovement(); + if (!CharMove || !CharMove->IsComponentTickEnabled() || !CharMove->IsActive() || (!CharMove->PrimaryComponentTick.bTickEvenWhenPaused && GetWorld()->IsPaused())) + { + // Our character movement isn't handling our updates, lets do it ourself. + UpdateTracking(DeltaTime); + } + } + + if (bHasAuthority) + { + // Send changes + if (this->GetIsReplicated()) + { + FRotator RelativeRot = GetRelativeRotation(); + FVector RelativeLoc = GetRelativeLocation(); + + // Don't rep if no changes + if (!RelativeLoc.Equals(LastUpdatesRelativePosition) || !RelativeRot.Equals(LastUpdatesRelativeRotation)) + { + NetUpdateCount += DeltaTime; + + if (NetUpdateCount >= (1.0f / NetUpdateRate)) + { + NetUpdateCount = 0.0f; + + // Already stored out now, only do this for FPS debug characters + if (bFPSDebugMode) + { + ReplicatedCameraTransform.Position = RelativeLoc; + ReplicatedCameraTransform.Rotation = RelativeRot; + } + +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UReplicatedVRCameraComponent, ReplicatedCameraTransform, this); +#endif + + if (GetNetMode() == NM_Client) + { + AVRBaseCharacter* OwningChar = Cast(GetOwner()); + if (OverrideSendTransform != nullptr && OwningChar != nullptr) + { + (OwningChar->* (OverrideSendTransform))(ReplicatedCameraTransform); + } + else + { + // Don't bother with any of this if not replicating transform + //if (bHasAuthority && bReplicateTransform) + Server_SendCameraTransform(ReplicatedCameraTransform); + } + } + + LastUpdatesRelativeRotation = RelativeRot; + LastUpdatesRelativePosition = RelativeLoc; + } + } + } + } +} + +void UReplicatedVRCameraComponent::HandleXRCamera() +{ + bool bIsLocallyControlled = IsLocallyControlled(); + + if (bAutoSetLockToHmd) + { + if (bIsLocallyControlled) + bLockToHmd = true; + else + bLockToHmd = false; + } + + if (bIsLocallyControlled && GEngine && GEngine->XRSystem.IsValid() && GetWorld() && GetWorld()->WorldType != EWorldType::Editor) + { + IXRTrackingSystem* XRSystem = GEngine->XRSystem.Get(); + auto XRCamera = XRSystem->GetXRCamera(); + + if (XRCamera.IsValid()) + { + if (XRSystem->IsHeadTrackingAllowedForWorld(*GetWorld())) + { + const FTransform ParentWorld = CalcNewComponentToWorld(FTransform()); + XRCamera->SetupLateUpdate(ParentWorld, this, bLockToHmd == 0); + + if (bLockToHmd) + { + FQuat Orientation; + FVector Position; + if (XRCamera->UpdatePlayerCamera(Orientation, Position)) + { + if (HasTrackingParameters()) + { + ApplyTrackingParameters(Position, true); + } + + ReplicatedCameraTransform.Position = Position; + ReplicatedCameraTransform.Rotation = Orientation.Rotator(); + + if (IsValid(AttachChar) && !AttachChar->bRetainRoomscale) + { + // Zero out XY for non retained + Position.X = 0.0f; + Position.Y = 0.0f; + //FRotator OffsetRotator = + if (AttachChar->VRMovementReference && AttachChar->VRMovementReference->GetReplicatedMovementMode() != EVRConjoinedMovementModes::C_VRMOVE_Seated) + { + AttachChar->SeatInformation.InitialRelCameraTransform.Rotator(); + + FRotator StoredCameraRotOffset = FRotator::ZeroRotator; + if (AttachChar->VRMovementReference->GetReplicatedMovementMode() == EVRConjoinedMovementModes::C_VRMOVE_Seated) + { + AttachChar->SeatInformation.InitialRelCameraTransform.Rotator(); + } + else + { + StoredCameraRotOffset = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(Orientation.Rotator()); + } + + Position += StoredCameraRotOffset.RotateVector(FVector(-AttachChar->VRRootReference->VRCapsuleOffset.X, -AttachChar->VRRootReference->VRCapsuleOffset.Y, 0.0f)); + } + } + + SetRelativeTransform(FTransform(Orientation, Position)); + } + else + { + SetRelativeScale3D(FVector(1.0f)); + //ResetRelativeTransform(); stop doing this, it is problematic + // Let the camera freeze in the last position instead + // Setting scale by itself makes sure we don't get camera scaling but keeps the last location and rotation alive + } + } + + // #TODO: Check back on this, was moved here in 4.20 but shouldn't it be inside of bLockToHMD? + XRCamera->OverrideFOV(this->FieldOfView); + } + } + } +} + +FTransform UReplicatedVRCameraComponent::GetHMDTrackingTransform() +{ + return FTransform(ReplicatedCameraTransform.Rotation, ReplicatedCameraTransform.Position); +} + +void UReplicatedVRCameraComponent::OnRep_ReplicatedCameraTransform() +{ + if (GetNetMode() < ENetMode::NM_Client && HasTrackingParameters()) + { + // Ensure that we clamp to the expected values from the client + ApplyTrackingParameters(ReplicatedCameraTransform.Position, true); + } + + FVector CameraPosition = ReplicatedCameraTransform.Position; + if (AttachChar && !AttachChar->bRetainRoomscale) + { + CameraPosition.X = 0; + CameraPosition.Y = 0; + + FRotator StoredCameraRotOffset = FRotator::ZeroRotator; + if (AttachChar->VRMovementReference && AttachChar->VRMovementReference->GetReplicatedMovementMode() == EVRConjoinedMovementModes::C_VRMOVE_Seated) + { + AttachChar->SeatInformation.InitialRelCameraTransform.Rotator(); + } + else + { + StoredCameraRotOffset = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(ReplicatedCameraTransform.Rotation); + } + + CameraPosition += StoredCameraRotOffset.RotateVector(FVector(-AttachChar->VRRootReference->VRCapsuleOffset.X, -AttachChar->VRRootReference->VRCapsuleOffset.Y, 0.0f)); + + } + + if (bSmoothReplicatedMotion) + { + if (bReppedOnce) + { + bLerpingPosition = true; + NetUpdateCount = 0.0f; + LastUpdatesRelativePosition = this->GetRelativeLocation(); + LastUpdatesRelativeRotation = this->GetRelativeRotation(); + + if (bUseExponentialSmoothing) + { + FVector OldToNewVector = CameraPosition - LastUpdatesRelativePosition; + float NewDistance = OldToNewVector.SizeSquared(); + + // Too far, snap to the new value + if (NewDistance >= FMath::Square(NetworkNoSmoothUpdateDistance)) + { + SetRelativeLocationAndRotation(CameraPosition, ReplicatedCameraTransform.Rotation); + bLerpingPosition = false; + } + // Outside of the buffer distance, snap within buffer and keep smoothing from there + else if (NewDistance >= FMath::Square(NetworkMaxSmoothUpdateDistance)) + { + FVector Offset = (OldToNewVector.Size() - NetworkMaxSmoothUpdateDistance) * OldToNewVector.GetSafeNormal(); + SetRelativeLocation(LastUpdatesRelativePosition + Offset); + } + } + } + else + { + SetRelativeLocationAndRotation(CameraPosition, ReplicatedCameraTransform.Rotation); + bReppedOnce = true; + } + } + else + SetRelativeLocationAndRotation(CameraPosition, ReplicatedCameraTransform.Rotation); +} + +void UReplicatedVRCameraComponent::SetNetUpdateRate(float NewNetUpdateRate) +{ + NetUpdateRate = NewNetUpdateRate; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(UReplicatedVRCameraComponent, NetUpdateRate, this); +#endif +} + +bool UReplicatedVRCameraComponent::IsLocallyControlled() const +{ + // I like epics new authority check more than my own + const AActor* MyOwner = GetOwner(); + return MyOwner->HasLocalNetOwner(); +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRAIController.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRAIController.cpp new file mode 100644 index 0000000..dc6fc4c --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRAIController.cpp @@ -0,0 +1,144 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "VRAIController.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRAIController) + +//#include "VRBPDatatypes.h" +#include "CoreMinimal.h" +#include "Engine/World.h" +#include "VRBaseCharacter.h" +#include "Components/CapsuleComponent.h" +#include "NetworkingDistanceConstants.h" // Needed for the LinOfSightTo function override to work +#include "Navigation/CrowdFollowingComponent.h" +//#include "Runtime/Engine/Private/EnginePrivate.h" + + +FVector AVRAIController::GetFocalPointOnActor(const AActor *Actor) const +{ + if (const AVRBaseCharacter * VRChar = Cast(Actor)) + { + return VRChar->GetVRLocation_Inline(); + } + else + return Super::GetFocalPointOnActor(Actor); // Actor != nullptr ? Actor->GetActorLocation() : FAISystem::InvalidLocation; +} + +bool AVRAIController::LineOfSightTo(const AActor* Other, FVector ViewPoint, bool bAlternateChecks) const +{ + if (Other == nullptr) + { + return false; + } + + if (ViewPoint.IsZero()) + { + FRotator ViewRotation; + GetActorEyesViewPoint(ViewPoint, ViewRotation); + + // if we still don't have a view point we simply fail + if (ViewPoint.IsZero()) + { + return false; + } + } + + static FName NAME_LineOfSight = FName(TEXT("LineOfSight")); + FVector TargetLocation = Other->GetTargetLocation(GetPawn()); + + FCollisionQueryParams CollisionParams(NAME_LineOfSight, true, this->GetPawn()); + CollisionParams.AddIgnoredActor(Other); + + bool bHit = GetWorld()->LineTraceTestByChannel(ViewPoint, TargetLocation, ECC_Visibility, CollisionParams); + if (!bHit) + { + return true; + } + + // if other isn't using a cylinder for collision and isn't a Pawn (which already requires an accurate cylinder for AI) + // then don't go any further as it likely will not be tracing to the correct location + const APawn * OtherPawn = Cast(Other); + if (!OtherPawn && Cast(Other->GetRootComponent()) == NULL) + { + return false; + } + + // Changed this up to support my VR Characters + const AVRBaseCharacter * VRChar = Cast(Other); + const FVector OtherActorLocation = VRChar != nullptr ? VRChar->GetVRLocation_Inline() : Other->GetActorLocation(); + + const FVector::FReal DistSq = (OtherActorLocation - ViewPoint).SizeSquared(); + if (DistSq > FARSIGHTTHRESHOLDSQUARED) + { + return false; + } + + if (!OtherPawn && (DistSq > NEARSIGHTTHRESHOLDSQUARED)) + { + return false; + } + + float OtherRadius, OtherHeight; + Other->GetSimpleCollisionCylinder(OtherRadius, OtherHeight); + + if (!bAlternateChecks || !bLOSflag) + { + //try viewpoint to head + bHit = GetWorld()->LineTraceTestByChannel(ViewPoint, OtherActorLocation + FVector(0.f, 0.f, OtherHeight), ECC_Visibility, CollisionParams); + if (!bHit) + { + return true; + } + } + + if (!bSkipExtraLOSChecks && (!bAlternateChecks || bLOSflag)) + { + // only check sides if width of other is significant compared to distance + if (OtherRadius * OtherRadius / (OtherActorLocation - ViewPoint).SizeSquared() < 0.0001f) + { + return false; + } + //try checking sides - look at dist to four side points, and cull furthest and closest + FVector Points[4]; + Points[0] = OtherActorLocation - FVector(OtherRadius, -1 * OtherRadius, 0); + Points[1] = OtherActorLocation + FVector(OtherRadius, OtherRadius, 0); + Points[2] = OtherActorLocation - FVector(OtherRadius, OtherRadius, 0); + Points[3] = OtherActorLocation + FVector(OtherRadius, -1 * OtherRadius, 0); + int32 IndexMin = 0; + int32 IndexMax = 0; + FVector::FReal CurrentMax = (Points[0] - ViewPoint).SizeSquared(); + FVector::FReal CurrentMin = CurrentMax; + for (int32 PointIndex = 1; PointIndex < 4; PointIndex++) + { + const FVector::FReal NextSize = (Points[PointIndex] - ViewPoint).SizeSquared(); + if (NextSize > CurrentMin) + { + CurrentMin = NextSize; + IndexMax = PointIndex; + } + else if (NextSize < CurrentMax) + { + CurrentMax = NextSize; + IndexMin = PointIndex; + } + } + + for (int32 PointIndex = 0; PointIndex < 4; PointIndex++) + { + if ((PointIndex != IndexMin) && (PointIndex != IndexMax)) + { + bHit = GetWorld()->LineTraceTestByChannel(ViewPoint, Points[PointIndex], ECC_Visibility, CollisionParams); + if (!bHit) + { + return true; + } + } + } + } + return false; +} + +AVRDetourCrowdAIController::AVRDetourCrowdAIController(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer.SetDefaultSubobjectClass(TEXT("PathFollowingComponent"))) +{ + +} diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRBPDatatypes.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRBPDatatypes.cpp new file mode 100644 index 0000000..82cbd35 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRBPDatatypes.cpp @@ -0,0 +1,292 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#include "VRBPDatatypes.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRBPDatatypes) + +#include "CoreMinimal.h" +#include "VRGlobalSettings.h" +#include "Components/PrimitiveComponent.h" +#include "HAL/IConsoleManager.h" +#include "Chaos/ChaosEngineInterface.h" + +namespace VRDataTypeCVARs +{ + // Doing it this way because I want as little rep and perf impact as possible and sampling a static var is that. + // This is to specifically help out very rare cases, DON'T USE THIS UNLESS YOU HAVE NO CHOICE + static int32 RepHighPrecisionTransforms = 0; + FAutoConsoleVariableRef CVarRepHighPrecisionTransforms( + TEXT("vrexp.RepHighPrecisionTransforms"), + RepHighPrecisionTransforms, + TEXT("When on, will rep Quantized transforms at full precision, WARNING use at own risk, if this isn't the same setting client & server then it will crash.\n") + TEXT("0: Disable, 1: Enable"), + ECVF_Default); +} + +bool FTransform_NetQuantize::NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) +{ + bOutSuccess = true; + + FVector rTranslation; + FVector rScale3D; + //FQuat rRotation; + FRotator rRotation; + + uint16 ShortPitch = 0; + uint16 ShortYaw = 0; + uint16 ShortRoll = 0; + + bool bUseHighPrecision = VRDataTypeCVARs::RepHighPrecisionTransforms > 0; + + if (Ar.IsSaving()) + { + // Because transforms can be vectorized or not, need to use the inline retrievers + rTranslation = this->GetTranslation(); + rScale3D = this->GetScale3D(); + rRotation = this->Rotator();//this->GetRotation(); + + if (bUseHighPrecision) + { + Ar << rTranslation; + Ar << rScale3D; + Ar << rRotation; + } + else + { + // Translation set to 2 decimal precision + bOutSuccess &= SerializePackedVector<100, 30>(rTranslation, Ar); + + // Scale set to 2 decimal precision, had it 1 but realized that I used two already even + bOutSuccess &= SerializePackedVector<100, 30>(rScale3D, Ar); + + // Rotation converted to FRotator and short compressed, see below for conversion reason + // FRotator already serializes compressed short by default but I can save a func call here + rRotation.SerializeCompressedShort(Ar); + } + + + //Ar << rRotation; + + // If I converted it to a rotator and serialized as shorts I would save 6 bytes. + // I am unsure about a safe method of compressed serializing a quat, though I read through smallest three + // Epic already drops W from the Quat and reconstructs it after the send. + // Converting to rotator first may have conversion issues and has a perf cost....needs testing, epic attempts to handle + // Singularities in their conversion but I haven't tested it in all circumstances + //rRotation.SerializeCompressedShort(Ar); + } + else // If loading + { + + if (bUseHighPrecision) + { + Ar << rTranslation; + Ar << rScale3D; + Ar << rRotation; + } + else + { + bOutSuccess &= SerializePackedVector<100, 30>(rTranslation, Ar); + bOutSuccess &= SerializePackedVector<100, 30>(rScale3D, Ar); + rRotation.SerializeCompressedShort(Ar); + } + + //Ar << rRotation; + + // Set it + this->SetComponents(rRotation.Quaternion(), rTranslation, rScale3D); + this->NormalizeRotation(); + } + + return bOutSuccess; +} + +// ** Euro Low Pass Filter ** // + +void FBPEuroLowPassFilter::ResetSmoothingFilter() +{ + RawFilter.bFirstTime = true; + DeltaFilter.bFirstTime = true; +} + +FVector FBPEuroLowPassFilter::RunFilterSmoothing(const FVector& InRawValue, const float& InDeltaTime) +{ + if (InDeltaTime <= 0.0f) + { + // Invalid delta time, return the in value + return InRawValue; + } + + // Calculate the delta, if this is the first time then there is no delta + const FVector Delta = RawFilter.bFirstTime == true ? FVector::ZeroVector : (InRawValue - RawFilter.PreviousRaw) * 1.0 / InDeltaTime; + + // Filter the delta to get the estimated + const FVector Estimated = DeltaFilter.Filter(Delta, FVector(DeltaFilter.CalculateAlphaTau(DeltaCutoff, InDeltaTime))); + + // Use the estimated to calculate the cutoff + const FVector Cutoff = DeltaFilter.CalculateCutoff(Estimated, MinCutoff, CutoffSlope); + + // Filter passed value + return RawFilter.Filter(InRawValue, RawFilter.CalculateAlpha(Cutoff, InDeltaTime)); +} + +void FBPEuroLowPassFilterQuat::ResetSmoothingFilter() +{ + RawFilter.bFirstTime = true; + DeltaFilter.bFirstTime = true; +} + +FQuat FBPEuroLowPassFilterQuat::RunFilterSmoothing(const FQuat& InRawValue, const float& InDeltaTime) +{ + if (InDeltaTime <= 0.0f) + { + // Invalid delta time, return the in value + return InRawValue; + } + + FQuat NewInVal = InRawValue; + if (!RawFilter.bFirstTime) + { + // fix axial flipping, from unity open 1 Euro implementation + FVector4 PrevQuatAsVector(RawFilter.Previous.X, RawFilter.Previous.Y, RawFilter.Previous.Z, RawFilter.Previous.W); + FVector4 CurrQuatAsVector(InRawValue.X, InRawValue.Y, InRawValue.Z, InRawValue.W); + if ((PrevQuatAsVector - CurrQuatAsVector).SizeSquared() > 2) + NewInVal = FQuat(-InRawValue.X, -InRawValue.Y, -InRawValue.Z, -InRawValue.W); + } + + // Calculate the delta, if this is the first time then there is no delta + FQuat Delta = FQuat::Identity; + + if (!RawFilter.bFirstTime) + { + Delta = (NewInVal - RawFilter.PreviousRaw) * (1.0 / InDeltaTime); + } + + + double AlphaTau = DeltaFilter.CalculateAlphaTau(DeltaCutoff, InDeltaTime); + FQuat AlphaTauQ(AlphaTau, AlphaTau, AlphaTau, AlphaTau); + const FQuat Estimated = DeltaFilter.Filter(Delta, AlphaTauQ); + + // Use the estimated to calculate the cutoff + const FQuat Cutoff = DeltaFilter.CalculateCutoff(Estimated, MinCutoff, CutoffSlope); + + // Filter passed value + return RawFilter.Filter(NewInVal, RawFilter.CalculateAlpha(Cutoff, InDeltaTime)).GetNormalized();// .GetNormalized(); +} + +void FBPEuroLowPassFilterTrans::ResetSmoothingFilter() +{ + RawFilter.bFirstTime = true; + DeltaFilter.bFirstTime = true; +} + +FTransform FBPEuroLowPassFilterTrans::RunFilterSmoothing(const FTransform& InRawValue, const float& InDeltaTime) +{ + if (InDeltaTime <= 0.0f) + { + // Invalid delta time, return the in value + return InRawValue; + } + + FTransform NewInVal = InRawValue; + if (!RawFilter.bFirstTime) + { + FQuat TransQ = NewInVal.GetRotation(); + FQuat PrevQ = RawFilter.Previous.GetRotation(); + // fix axial flipping, from unity open 1 Euro implementation + FVector4 PrevQuatAsVector(PrevQ.X, PrevQ.Y, PrevQ.Z, PrevQ.W); + FVector4 CurrQuatAsVector(TransQ.X, TransQ.Y, TransQ.Z, TransQ.W); + if ((PrevQuatAsVector - CurrQuatAsVector).SizeSquared() > 2) + NewInVal.SetRotation(FQuat(-TransQ.X, -TransQ.Y, -TransQ.Z, -TransQ.W)); + } + + // Calculate the delta, if this is the first time then there is no delta + FTransform Delta = FTransform::Identity; + + double Frequency = 1.0 / InDeltaTime; + if (!RawFilter.bFirstTime) + { + Delta.SetLocation((NewInVal.GetLocation() - RawFilter.PreviousRaw.GetLocation()) * Frequency); + Delta.SetRotation((NewInVal.GetRotation() - RawFilter.PreviousRaw.GetRotation()) * Frequency); + Delta.SetScale3D((NewInVal.GetScale3D() - RawFilter.PreviousRaw.GetScale3D()) * Frequency); + } + + + double AlphaTau = DeltaFilter.CalculateAlphaTau(DeltaCutoff, InDeltaTime); + FTransform AlphaTauQ(FQuat(AlphaTau, AlphaTau, AlphaTau, AlphaTau), FVector(AlphaTau), FVector(AlphaTau)); + const FTransform Estimated = DeltaFilter.Filter(Delta, AlphaTauQ); + + // Use the estimated to calculate the cutoff + const FTransform Cutoff = DeltaFilter.CalculateCutoff(Estimated, MinCutoff, CutoffSlope); + + FTransform NewTrans = RawFilter.Filter(NewInVal, RawFilter.CalculateAlpha(Cutoff, InDeltaTime)); + NewTrans.NormalizeRotation(); + // Filter passed value + return NewTrans; +} + +bool FBPAdvancedPhysicsHandleSettings::FillTo(FBPActorPhysicsHandleInformation* HandleInfo, bool bModifyWithScalers) const +{ + if (!HandleInfo) + return false; + + float DampingMod = 0.0f; + float StiffnessMod = 0.0f; + float ADampingMod = 0.0f; + float AStiffnessMod = 0.0f; + const UVRGlobalSettings& VRSettings = *GetDefault(); + + if (VRSettings.bUseChaosTranslationScalers) + { + StiffnessMod = VRSettings.LinearDriveStiffnessScale; + DampingMod = VRSettings.LinearDriveDampingScale; + AStiffnessMod = VRSettings.AngularDriveStiffnessScale; + ADampingMod = VRSettings.AngularDriveDampingScale; + } + else + { + auto CVarLinearDriveStiffnessScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.LinearDriveStiffnessScale")); + auto CVarLinearDriveDampingScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.LinaearDriveDampingScale")); + auto CVarAngularDriveStiffnessScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.AngularDriveStiffnessScale")); + auto CVarAngularDriveDampingScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.AngularDriveDampingScale")); + + StiffnessMod = CVarLinearDriveStiffnessScale->GetFloat(); + DampingMod = CVarLinearDriveDampingScale->GetFloat(); + AStiffnessMod = CVarAngularDriveStiffnessScale->GetFloat(); + ADampingMod = CVarAngularDriveDampingScale->GetFloat(); + } + + XAxisSettings.FillTo(HandleInfo->LinConstraint.XDrive, DampingMod, StiffnessMod); + YAxisSettings.FillTo(HandleInfo->LinConstraint.YDrive, DampingMod, StiffnessMod); + ZAxisSettings.FillTo(HandleInfo->LinConstraint.ZDrive, DampingMod, StiffnessMod); + + if ((SlerpSettings.bEnablePositionDrive || SlerpSettings.bEnableVelocityDrive)) + { + HandleInfo->AngConstraint.AngularDriveMode = EAngularDriveMode::SLERP; + SlerpSettings.FillTo(HandleInfo->AngConstraint.SlerpDrive, ADampingMod, AStiffnessMod); + } + else + { + HandleInfo->AngConstraint.AngularDriveMode = EAngularDriveMode::TwistAndSwing; + TwistSettings.FillTo(HandleInfo->AngConstraint.TwistDrive, ADampingMod, AStiffnessMod); + SwingSettings.FillTo(HandleInfo->AngConstraint.SwingDrive, ADampingMod, AStiffnessMod); + } + + return true; +} + +AActor* FBPActorGripInformation::GetGrippedActor() const +{ + return Cast(GrippedObject); +} + +UPrimitiveComponent* FBPActorGripInformation::GetGrippedComponent() const +{ + return Cast(GrippedObject); +} + +bool FBPActorGripInformation::operator==(const UPrimitiveComponent* Other) const +{ + if (Other && GrippedObject && GrippedObject == (const UObject*)Other) + return true; + + return false; +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRBaseCharacter.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRBaseCharacter.cpp new file mode 100644 index 0000000..43efdf8 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRBaseCharacter.cpp @@ -0,0 +1,1246 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "VRBaseCharacter.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRBaseCharacter) + +#include "VRPlayerController.h" +#include "NavigationSystem.h" +#include "GameFramework/Controller.h" +#include "Components/CapsuleComponent.h" +#include "ParentRelativeAttachmentComponent.h" +#include "GripMotionControllerComponent.h" +#include "IMotionController.h" +#include "VRRootComponent.h" +#include "VRPathFollowingComponent.h" +#include "Net/UnrealNetwork.h" +#include "XRMotionControllerBase.h" +#include "NavFilters/NavigationQueryFilter.h" +//#include "Runtime/Engine/Private/EnginePrivate.h" + +#if WITH_PUSH_MODEL +#include "Net/Core/PushModel/PushModel.h" +#endif + +DEFINE_LOG_CATEGORY(LogBaseVRCharacter); + +FName AVRBaseCharacter::LeftMotionControllerComponentName(TEXT("Left Grip Motion Controller")); +FName AVRBaseCharacter::RightMotionControllerComponentName(TEXT("Right Grip Motion Controller")); +FName AVRBaseCharacter::ReplicatedCameraComponentName(TEXT("VR Replicated Camera")); +FName AVRBaseCharacter::ParentRelativeAttachmentComponentName(TEXT("Parent Relative Attachment")); +FName AVRBaseCharacter::SmoothingSceneParentComponentName(TEXT("NetSmoother")); +FName AVRBaseCharacter::VRProxyComponentName(TEXT("VRProxy")); + + +FRepMovementVRCharacter::FRepMovementVRCharacter() +: Super() +{ + bJustTeleported = false; + bJustTeleportedGrips = false; + bPausedTracking = false; + PausedTrackingLoc = FVector::ZeroVector; + PausedTrackingRot = 0.f; + Owner = nullptr; +} + +AVRBaseCharacter::AVRBaseCharacter(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer/*.DoNotCreateDefaultSubobject(ACharacter::MeshComponentName)*/.SetDefaultSubobjectClass(ACharacter::CharacterMovementComponentName)) + +{ + + FRepMovement& MovementRep = GetReplicatedMovement_Mutable(); + + // Remove the movement jitter with slow speeds + MovementRep.LocationQuantizationLevel = EVectorQuantization::RoundTwoDecimals; + + if (UCapsuleComponent * cap = GetCapsuleComponent()) + { + cap->SetCapsuleSize(16.0f, 96.0f); + cap->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore); + cap->SetCollisionResponseToChannel(ECollisionChannel::ECC_WorldStatic, ECollisionResponse::ECR_Block); + } + + NetSmoother = CreateOptionalDefaultSubobject(AVRBaseCharacter::SmoothingSceneParentComponentName); + if (NetSmoother) + { + NetSmoother->SetupAttachment(RootComponent); + + if (!bRetainRoomscale) + { + if (UVRRootComponent* MyRoot = Cast(RootComponent)) + { + NetSmoother->SetRelativeLocation(MyRoot->GetTargetHeightOffset()); + //VRProxyComponent->SetRelativeLocation(MyRoot->GetTargetHeightOffset()); + } + } + } + + VRProxyComponent = CreateOptionalDefaultSubobject(AVRBaseCharacter::VRProxyComponentName); + if (NetSmoother && VRProxyComponent) + { + VRProxyComponent->SetupAttachment(NetSmoother); + } + + VRReplicatedCamera = CreateOptionalDefaultSubobject(AVRBaseCharacter::ReplicatedCameraComponentName); + if (VRReplicatedCamera) + { + //VRReplicatedCamera->bOffsetByHMD = false; + VRReplicatedCamera->SetupAttachment(VRProxyComponent ? VRProxyComponent : NetSmoother ? NetSmoother : RootComponent); + VRReplicatedCamera->OverrideSendTransform = &AVRBaseCharacter::Server_SendTransformCamera; + } + + VRMovementReference = NULL; + if (GetMovementComponent()) + { + VRMovementReference = Cast(GetMovementComponent()); + //AddTickPrerequisiteComponent(this->GetCharacterMovement()); + } + + ParentRelativeAttachment = CreateOptionalDefaultSubobject(AVRBaseCharacter::ParentRelativeAttachmentComponentName); + if (ParentRelativeAttachment && VRReplicatedCamera) + { + // Moved this to be root relative as the camera late updates were killing how it worked + ParentRelativeAttachment->SetupAttachment(VRProxyComponent ? VRProxyComponent : NetSmoother ? NetSmoother : RootComponent); + //ParentRelativeAttachment->bOffsetByHMD = false; + ParentRelativeAttachment->AddTickPrerequisiteComponent(VRReplicatedCamera); + + if (USkeletalMeshComponent * SKMesh = GetMesh()) + { + SKMesh->SetupAttachment(ParentRelativeAttachment); + } + } + + LeftMotionController = CreateOptionalDefaultSubobject(AVRBaseCharacter::LeftMotionControllerComponentName); + if (IsValid(LeftMotionController)) + { + LeftMotionController->SetupAttachment(VRProxyComponent ? VRProxyComponent : NetSmoother ? NetSmoother : RootComponent); + //LeftMotionController->MotionSource = FXRMotionControllerBase::LeftHandSourceId; + LeftMotionController->SetTrackingMotionSource(IMotionController::LeftHandSourceId); + //LeftMotionController->Hand = EControllerHand::Left; + //LeftMotionController->bOffsetByHMD = false; + //LeftMotionController->bUpdateInCharacterMovement = true; + // Keep the controllers ticking after movement + LeftMotionController->AddTickPrerequisiteComponent(GetCharacterMovement()); + LeftMotionController->OverrideSendTransform = &AVRBaseCharacter::Server_SendTransformLeftController; + } + + RightMotionController = CreateOptionalDefaultSubobject(AVRBaseCharacter::RightMotionControllerComponentName); + if (IsValid(RightMotionController)) + { + RightMotionController->SetupAttachment(VRProxyComponent ? VRProxyComponent : NetSmoother ? NetSmoother : RootComponent); + //RightMotionController->MotionSource = FXRMotionControllerBase::RightHandSourceId; + RightMotionController->SetTrackingMotionSource(IMotionController::RightHandSourceId); + //RightMotionController->Hand = EControllerHand::Right; + //RightMotionController->bOffsetByHMD = false; + //RightMotionController->bUpdateInCharacterMovement = true; + // Keep the controllers ticking after movement + RightMotionController->AddTickPrerequisiteComponent(GetCharacterMovement()); + RightMotionController->OverrideSendTransform = &AVRBaseCharacter::Server_SendTransformRightController; + } + + OffsetComponentToWorld = FTransform(FQuat(0.0f, 0.0f, 0.0f, 1.0f), FVector::ZeroVector, FVector(1.0f)); + + + // Setting a minimum of every frame for replication consideration (UT uses this value for characters and projectiles). + // Otherwise we will get some massive slow downs if the replication is allowed to hit the 2 per second minimum default + MinNetUpdateFrequency = 100.0f; + + // This is for smooth turning, we have more of a use for this than FPS characters do + // Due to roll/pitch almost never being off 0 for VR the cost is just one byte so i'm fine defaulting it here + // End users can reset to byte components if they ever want too. + MovementRep.RotationQuantizationLevel = ERotatorQuantization::ShortComponents; + + VRReplicateCapsuleHeight = false; + + bUseExperimentalUnseatModeFix = true; + + ReplicatedMovementVR.Owner = this; + bFlagTeleported = false; + bTrackingPaused = false; + PausedTrackingLoc = FVector::ZeroVector; + PausedTrackingRot = 0.f; +} + + void AVRBaseCharacter::PossessedBy(AController* NewController) + { + Super::PossessedBy(NewController); + OwningVRPlayerController = Cast(Controller); + } + +void AVRBaseCharacter::OnRep_Controller() +{ + Super::OnRep_Controller(); + OwningVRPlayerController = Cast(Controller); +} + +void AVRBaseCharacter::OnRep_PlayerState() +{ + OnPlayerStateReplicated_Bind.Broadcast(GetPlayerState()); + Super::OnRep_PlayerState(); +} + +void AVRBaseCharacter::PostInitializeComponents() +{ + QUICK_SCOPE_CYCLE_COUNTER(STAT_Character_PostInitComponents); + + Super::PostInitializeComponents(); + + if (IsValid(this)) + { + if (NetSmoother) + { + CacheInitialMeshOffset(NetSmoother->GetRelativeLocation(), NetSmoother->GetRelativeRotation()); + } + + if (USkeletalMeshComponent * myMesh = GetMesh()) + { + // force animation tick after movement component updates + if (myMesh->PrimaryComponentTick.bCanEverTick && GetMovementComponent()) + { + myMesh->PrimaryComponentTick.AddPrerequisite(GetMovementComponent(), GetMovementComponent()->PrimaryComponentTick); + } + } + + if (GetCharacterMovement() && GetCapsuleComponent()) + { + GetCharacterMovement()->UpdateNavAgent(*GetCapsuleComponent()); + } + + if (Controller == nullptr && GetNetMode() != NM_Client) + { + if (GetCharacterMovement() && GetCharacterMovement()->bRunPhysicsWithNoController) + { + GetCharacterMovement()->SetDefaultMovementMode(); + } + } + } +} + +/*void AVRBaseCharacter::CacheInitialMeshOffset(FVector MeshRelativeLocation, FRotator MeshRelativeRotation) +{ + BaseTranslationOffset = MeshRelativeLocation; + BaseRotationOffset = MeshRelativeRotation.Quaternion(); + +#if ENABLE_NAN_DIAGNOSTIC + if (BaseRotationOffset.ContainsNaN()) + { + logOrEnsureNanError(TEXT("ACharacter::PostInitializeComponents detected NaN in BaseRotationOffset! (%s)"), *BaseRotationOffset.ToString()); + } + + if (GetMesh()) + { + const FRotator LocalRotation = GetMesh()->GetRelativeRotation(); + if (LocalRotation.ContainsNaN()) + { + logOrEnsureNanError(TEXT("ACharacter::PostInitializeComponents detected NaN in Mesh->RelativeRotation! (%s)"), *LocalRotation.ToString()); + } + } +#endif +}*/ + +void AVRBaseCharacter::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + // For std properties + FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(AVRBaseCharacter, SeatInformation, PushModelParams); + DOREPLIFETIME_WITH_PARAMS_FAST(AVRBaseCharacter, VRReplicateCapsuleHeight, PushModelParams); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsWithCondition{ COND_SimulatedOnly, REPNOTIFY_OnChanged, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(AVRBaseCharacter, ReplicatedCapsuleHeight, PushModelParamsWithCondition); + + DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, ReplicatedMovement); + + // For properties with special conditions + FDoRepLifetimeParams PushModelParamsReplicatedMovement{ COND_SimulatedOrPhysics, REPNOTIFY_Always, /*bIsPushBased=*/true }; + + DOREPLIFETIME_WITH_PARAMS_FAST(AVRBaseCharacter, ReplicatedMovementVR, PushModelParamsReplicatedMovement); +} + +void AVRBaseCharacter::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) +{ + Super::PreReplication(ChangedPropertyTracker); + + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AVRBaseCharacter, ReplicatedCapsuleHeight, VRReplicateCapsuleHeight); + DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AVRBaseCharacter, ReplicatedMovementVR, IsReplicatingMovement()); +} + +/*USkeletalMeshComponent* AVRBaseCharacter::GetIKMesh_Implementation() const +{ + return GetMesh(); +// return nullptr; +}*/ + +bool AVRBaseCharacter::Server_SetSeatedMode_Validate(USceneComponent * SeatParent, bool bSetSeatedMode, FTransform_NetQuantize TargetTransform, FTransform_NetQuantize InitialRelCameraTransform, float AllowedRadius, float AllowedRadiusThreshold, bool bZeroToHead, EVRConjoinedMovementModes PostSeatedMovementMode) +{ + return true; +} + +void AVRBaseCharacter::Server_SetSeatedMode_Implementation(USceneComponent * SeatParent, bool bSetSeatedMode, FTransform_NetQuantize TargetTransform, FTransform_NetQuantize InitialRelCameraTransform, float AllowedRadius, float AllowedRadiusThreshold, bool bZeroToHead, EVRConjoinedMovementModes PostSeatedMovementMode) +{ + SetSeatedMode(SeatParent, bSetSeatedMode, TargetTransform, InitialRelCameraTransform, AllowedRadius, AllowedRadiusThreshold, bZeroToHead, PostSeatedMovementMode); +} + +void AVRBaseCharacter::Server_ReZeroSeating_Implementation(FTransform_NetQuantize NewTargetTransform, FTransform_NetQuantize NewInitialRelCameraTransform, bool bZeroToHead) +{ + SeatInformation.StoredTargetTransform = NewTargetTransform; + SeatInformation.InitialRelCameraTransform = NewInitialRelCameraTransform; + + // Purify the yaw of the initial rotation + SeatInformation.InitialRelCameraTransform.SetRotation(UVRExpansionFunctionLibrary::GetHMDPureYaw_I(NewInitialRelCameraTransform.Rotator()).Quaternion()); + + // #TODO: Need to handle non 1 scaled values here eventually + if (bZeroToHead) + { + FVector newLocation = SeatInformation.InitialRelCameraTransform.GetTranslation(); + SeatInformation.StoredTargetTransform.AddToTranslation(FVector(0, 0, -newLocation.Z)); + } + +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(AVRBaseCharacter, SeatInformation, this); +#endif + + OnRep_SeatedCharInfo(); +} + +bool AVRBaseCharacter::Server_ReZeroSeating_Validate(FTransform_NetQuantize NewTargetTransform, FTransform_NetQuantize NewInitialRelCameraTransform, bool bZeroToHead) +{ + return true; +} + +void AVRBaseCharacter::Server_SeatedSnapTurn_Implementation(float Yaw) +{ + if(VRMovementReference && SeatInformation.bSitting) + { + FVRMoveActionContainer MoveActionTmp; + MoveActionTmp.MoveAction = EVRMoveAction::VRMOVEACTION_SnapTurn; + MoveActionTmp.MoveActionRot.Yaw = Yaw; + MoveActionTmp.VelRetentionSetting = EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_None; + VRMovementReference->MoveActionArray.MoveActions.Add(MoveActionTmp); + VRMovementReference->CheckForMoveAction(); + VRMovementReference->MoveActionArray.Clear(); + } +} + +bool AVRBaseCharacter::Server_SeatedSnapTurn_Validate(float Yaw) +{ + return true; +} + +void AVRBaseCharacter::OnCustomMoveActionPerformed_Implementation(EVRMoveAction MoveActionType, FVector MoveActionVector, FRotator MoveActionRotator, uint8 MoveActionFlags) +{ + +} + +void AVRBaseCharacter::OnBeginWallPushback_Implementation(FHitResult HitResultOfImpact, bool bHadLocomotionInput, FVector HmdInput) +{ + +} + +void AVRBaseCharacter::OnEndWallPushback_Implementation() +{ + +} + +void AVRBaseCharacter::OnClimbingSteppedUp_Implementation() +{ + +} + +void AVRBaseCharacter::Server_SendTransformCamera_Implementation(FBPVRComponentPosRep NewTransform) +{ + if(VRReplicatedCamera) + VRReplicatedCamera->Server_SendCameraTransform_Implementation(NewTransform); +} + +bool AVRBaseCharacter::Server_SendTransformCamera_Validate(FBPVRComponentPosRep NewTransform) +{ + return true; + // Optionally check to make sure that player is inside of their bounds and deny it if they aren't? +} + +void AVRBaseCharacter::Server_SendTransformLeftController_Implementation(FBPVRComponentPosRep NewTransform) +{ + if (IsValid(LeftMotionController)) + LeftMotionController->Server_SendControllerTransform_Implementation(NewTransform); +} + +bool AVRBaseCharacter::Server_SendTransformLeftController_Validate(FBPVRComponentPosRep NewTransform) +{ + return true; + // Optionally check to make sure that player is inside of their bounds and deny it if they aren't? +} + +void AVRBaseCharacter::Server_SendTransformRightController_Implementation(FBPVRComponentPosRep NewTransform) +{ + if(IsValid(RightMotionController)) + RightMotionController->Server_SendControllerTransform_Implementation(NewTransform); +} + +bool AVRBaseCharacter::Server_SendTransformRightController_Validate(FBPVRComponentPosRep NewTransform) +{ + return true; + // Optionally check to make sure that player is inside of their bounds and deny it if they aren't? +} +FVector AVRBaseCharacter::GetTeleportLocation(FVector OriginalLocation) +{ + return OriginalLocation; +} + + +void AVRBaseCharacter::NotifyOfTeleport(bool bRegisterAsTeleport) +{ + if (bRegisterAsTeleport) + { + if (GetNetMode() < ENetMode::NM_Client) + bFlagTeleported = true; + + if (VRMovementReference) + { + VRMovementReference->bNotifyTeleported = true; + } + } + + if (GetNetMode() < ENetMode::NM_Client) + { + if (bRegisterAsTeleport) + { + bFlagTeleported = true; + } + else + { + bFlagTeleportedGrips = true; + } + } + + if (IsValid(LeftMotionController)) + LeftMotionController->bIsPostTeleport = true; + + if (IsValid(RightMotionController)) + RightMotionController->bIsPostTeleport = true; +} + +void AVRBaseCharacter::OnRep_ReplicatedMovement() +{ + FRepMovement& ReppedMovement = GetReplicatedMovement_Mutable(); + + ReppedMovement.AngularVelocity = ReplicatedMovementVR.AngularVelocity; + ReppedMovement.bRepPhysics = ReplicatedMovementVR.bRepPhysics; + ReppedMovement.bSimulatedPhysicSleep = ReplicatedMovementVR.bSimulatedPhysicSleep; + ReppedMovement.LinearVelocity = ReplicatedMovementVR.LinearVelocity; + ReppedMovement.Location = ReplicatedMovementVR.Location; + ReppedMovement.Rotation = ReplicatedMovementVR.Rotation; + + Super::OnRep_ReplicatedMovement(); + + if (!IsLocallyControlled()) + { + if (ReplicatedMovementVR.bJustTeleported) + { + // Server should never get this value so it shouldn't be double throwing for them + NotifyOfTeleport(); + } + else if (ReplicatedMovementVR.bJustTeleportedGrips) + { + NotifyOfTeleport(false); + } + + bTrackingPaused = ReplicatedMovementVR.bPausedTracking; + if (bTrackingPaused) + { + PausedTrackingLoc = ReplicatedMovementVR.PausedTrackingLoc; + PausedTrackingRot = ReplicatedMovementVR.PausedTrackingRot; + } + } +} + +void AVRBaseCharacter::GatherCurrentMovement() +{ + Super::GatherCurrentMovement(); + + FRepMovement ReppedMovement = this->GetReplicatedMovement(); + + ReplicatedMovementVR.AngularVelocity = ReppedMovement.AngularVelocity; + ReplicatedMovementVR.bRepPhysics = ReppedMovement.bRepPhysics; + ReplicatedMovementVR.bSimulatedPhysicSleep = ReppedMovement.bSimulatedPhysicSleep; + ReplicatedMovementVR.LinearVelocity = ReppedMovement.LinearVelocity; + ReplicatedMovementVR.Location = ReppedMovement.Location; + ReplicatedMovementVR.Rotation = ReppedMovement.Rotation; + ReplicatedMovementVR.bJustTeleported = bFlagTeleported; + ReplicatedMovementVR.bJustTeleportedGrips = bFlagTeleportedGrips; + bFlagTeleported = false; + bFlagTeleportedGrips = false; + ReplicatedMovementVR.bPausedTracking = bTrackingPaused; + ReplicatedMovementVR.PausedTrackingLoc = PausedTrackingLoc; + ReplicatedMovementVR.PausedTrackingRot = PausedTrackingRot; + +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(AVRBaseCharacter, ReplicatedMovementVR, this); +#endif + +} + + +void AVRBaseCharacter::OnRep_SeatedCharInfo() +{ + // Handle setting up the player here + + if (UPrimitiveComponent * root = Cast(GetRootComponent())) + { + if (SeatInformation.bSitting /*&& !SeatInformation.bWasSeated*/) // Removing WasSeated check because we may be switching seats + { + if (SeatInformation.bWasSeated) + { + if (SeatInformation.SeatParent != this->GetRootComponent()->GetAttachParent()) + { + InitSeatedModeTransition(); + } + else // Is just a reposition + { + //if (this->Role != ROLE_SimulatedProxy) + ZeroToSeatInformation(); + } + + } + else + { + if (this->GetLocalRole() == ROLE_SimulatedProxy) + { + /*if (UVRBaseCharacterMovementComponent * charMovement = Cast(GetMovementComponent())) + { + charMovement->SetMovementMode(MOVE_Custom, (uint8)EVRCustomMovementMode::VRMOVE_Seated); + }*/ + } + else + { + if (VRMovementReference) + { + VRMovementReference->SetMovementMode(MOVE_Custom, (uint8)EVRCustomMovementMode::VRMOVE_Seated); + } + } + } + } + else if (!SeatInformation.bSitting && SeatInformation.bWasSeated) + { + if (this->GetLocalRole() == ROLE_SimulatedProxy) + { + + /*if (UVRBaseCharacterMovementComponent * charMovement = Cast(GetMovementComponent())) + { + charMovement->ApplyReplicatedMovementMode(SeatInformation.PostSeatedMovementMode); + //charMovement->SetComponentTickEnabled(true); + }*/ + + } + else + { + if (VRMovementReference) + { + VRMovementReference->ApplyReplicatedMovementMode(SeatInformation.PostSeatedMovementMode); + } + } + } + } +} + +void AVRBaseCharacter::InitSeatedModeTransition() +{ + if (UPrimitiveComponent * root = Cast(GetRootComponent())) + { + if (SeatInformation.bSitting /*&& !SeatInformation.bWasSeated*/) // Removing WasSeated check because we may be switching seats + { + + if (SeatInformation.SeatParent /*&& !root->IsAttachedTo(SeatInformation.SeatParent)*/) + { + FAttachmentTransformRules TransformRule = FAttachmentTransformRules::SnapToTargetNotIncludingScale; + TransformRule.bWeldSimulatedBodies = true; + AttachToComponent(SeatInformation.SeatParent, TransformRule); + } + + if (this->GetLocalRole() == ROLE_SimulatedProxy) + { + if (VRMovementReference) + { + //charMovement->DisableMovement(); + //charMovement->SetComponentTickEnabled(false); + //charMovement->SetMovementMode(MOVE_Custom, (uint8)EVRCustomMovementMode::VRMOVE_Seated); + } + + root->SetCollisionEnabled(ECollisionEnabled::NoCollision); + + // Set it before it is set below + if (!SeatInformation.bWasSeated) + SeatInformation.bOriginalControlRotation = bUseControllerRotationYaw; + + SeatInformation.bWasSeated = true; + bUseControllerRotationYaw = false; // This forces rotation in world space, something that we don't want + ZeroToSeatInformation(); + OnSeatedModeChanged(SeatInformation.bSitting, SeatInformation.bWasSeated); + } + else + { + if (VRMovementReference) + { + //charMovement->DisableMovement(); + //charMovement->SetComponentTickEnabled(false); + //charMovement->SetMovementMode(MOVE_Custom, (uint8)EVRCustomMovementMode::VRMOVE_Seated); + //charMovement->bIgnoreClientMovementErrorChecksAndCorrection = true; + + if (this->GetLocalRole() == ROLE_AutonomousProxy) + { + FNetworkPredictionData_Client_Character* ClientData = VRMovementReference->GetPredictionData_Client_Character(); + check(ClientData); + + if (ClientData->SavedMoves.Num()) + { + // Ack our most recent move, we don't want to start sending old moves after un seating. + ClientData->AckMove(ClientData->SavedMoves.Num() - 1, *VRMovementReference); + } + } + + } + + root->SetCollisionEnabled(ECollisionEnabled::NoCollision); + + // Set it before it is set below + if (!SeatInformation.bWasSeated) + { + SeatInformation.bOriginalControlRotation = bUseControllerRotationYaw; + } + + SeatInformation.bWasSeated = true; + bUseControllerRotationYaw = false; // This forces rotation in world space, something that we don't want + + ZeroToSeatInformation(); + OnSeatedModeChanged(SeatInformation.bSitting, SeatInformation.bWasSeated); + } + } + else if (!SeatInformation.bSitting && SeatInformation.bWasSeated) + { + DetachFromActor(FDetachmentTransformRules::KeepWorldTransform); + + if (this->GetLocalRole() == ROLE_SimulatedProxy) + { + root->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); + + + bUseControllerRotationYaw = SeatInformation.bOriginalControlRotation; + + SetActorLocationAndRotationVR(SeatInformation.StoredTargetTransform.GetTranslation(), SeatInformation.StoredTargetTransform.Rotator(), true, true, true); + + if (IsValid(LeftMotionController)) + { + LeftMotionController->PostTeleportMoveGrippedObjects(); + } + + if (IsValid(RightMotionController)) + { + RightMotionController->PostTeleportMoveGrippedObjects(); + } + + /*if (UVRBaseCharacterMovementComponent * charMovement = Cast(GetMovementComponent())) + { + charMovement->ApplyReplicatedMovementMode(SeatInformation.PostSeatedMovementMode); + //charMovement->SetComponentTickEnabled(true); + }*/ + + OnSeatedModeChanged(SeatInformation.bSitting, SeatInformation.bWasSeated); + } + else + { + if (VRMovementReference) + { + //charMovement->ApplyReplicatedMovementMode(SeatInformation.PostSeatedMovementMode); + //charMovement->bIgnoreClientMovementErrorChecksAndCorrection = false; + //charMovement->SetComponentTickEnabled(true); + + if (this->GetLocalRole() == ROLE_Authority) + { + if (bUseExperimentalUnseatModeFix) + { + VRMovementReference->bJustUnseated = true; + FNetworkPredictionData_Server_Character * ServerData = VRMovementReference->GetPredictionData_Server_Character(); + check(ServerData); + ServerData->CurrentClientTimeStamp = 0.0f; + ServerData->PendingAdjustment = FClientAdjustment(); + //ServerData->CurrentClientTimeStamp = 0.f; + //ServerData->ServerAccumulatedClientTimeStamp = 0.0f; + //ServerData->LastUpdateTime = 0.f; + ServerData->ServerTimeStampLastServerMove = 0.f; + ServerData->bForceClientUpdate = false; + ServerData->TimeDiscrepancy = 0.f; + ServerData->bResolvingTimeDiscrepancy = false; + ServerData->TimeDiscrepancyResolutionMoveDeltaOverride = 0.f; + ServerData->TimeDiscrepancyAccumulatedClientDeltasSinceLastServerTick = 0.f; + } + //charMovement->ForceReplicationUpdate(); + //FNetworkPredictionData_Server_Character * ServerData = charMovement->GetPredictionData_Server_Character(); + //check(ServerData); + + // Reset client timestamp check so that there isn't a delay on ending seated mode before we accept movement packets + //ServerData->CurrentClientTimeStamp = 1.f; + } + } + + bUseControllerRotationYaw = SeatInformation.bOriginalControlRotation; + + // Re-purposing them for the new location and rotations + SetActorLocationAndRotationVR(SeatInformation.StoredTargetTransform.GetTranslation(), SeatInformation.StoredTargetTransform.Rotator(), true, true, true); + LeftMotionController->PostTeleportMoveGrippedObjects(); + RightMotionController->PostTeleportMoveGrippedObjects(); + + // Enable collision now + root->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); + + OnSeatedModeChanged(SeatInformation.bSitting, SeatInformation.bWasSeated); + SeatInformation.ClearTempVals(); + } + } + } +} + +void AVRBaseCharacter::TickSeatInformation(float DeltaTime) +{ + if (!VRReplicatedCamera) + return; + + float LastThresholdScaler = SeatInformation.CurrentThresholdScaler; + bool bLastOverThreshold = SeatInformation.bIsOverThreshold; + + FVector NewLoc = VRReplicatedCamera->ReplicatedCameraTransform.Position;//GetRelativeLocation(); + FVector OrigLocation = SeatInformation.InitialRelCameraTransform.GetTranslation(); + + if (!SeatInformation.bZeroToHead) + { + NewLoc.Z = 0.0f; + OrigLocation.Z = 0.0f; + } + + if (FMath::IsNearlyZero(SeatInformation.AllowedRadius)) + { + // Nothing to process here, seated mode isn't sticking to a set radius + if (SeatInformation.bIsOverThreshold) + { + SeatInformation.bIsOverThreshold = false; + bLastOverThreshold = false; + } + return; + } + + float AbsDistance = FMath::Abs(FVector::Dist(OrigLocation, NewLoc)); + + //FTransform newTrans = SeatInformation.StoredTargetTransform * SeatInformation.SeatParent->GetComponentTransform(); + + // If over the allowed distance + if (AbsDistance > SeatInformation.AllowedRadius) + { + // Force them back into range + FVector diff = NewLoc - OrigLocation; + diff.Normalize(); + + if (bRetainRoomscale) + { + diff = (-diff * (AbsDistance - SeatInformation.AllowedRadius)); + SetSeatRelativeLocationAndRotationVR(diff); + } + else + { + diff = (diff * (SeatInformation.AllowedRadius)); + diff.Z = 0.0f; + SetSeatRelativeLocationAndRotationVR(diff); + } + + SeatInformation.bWasOverLimit = true; + } + else if (SeatInformation.bWasOverLimit) // Make sure we are in the zero point otherwise + { + if (bRetainRoomscale) + { + SetSeatRelativeLocationAndRotationVR(FVector::ZeroVector); + } + else + { + FVector diff = NewLoc - OrigLocation; + diff.Z = 0.0f; + SetSeatRelativeLocationAndRotationVR(diff); + } + + SeatInformation.bWasOverLimit = false; + } + else + { + if (!bRetainRoomscale) + { + FVector diff = NewLoc - OrigLocation; + diff.Z = 0.0f; + SetSeatRelativeLocationAndRotationVR(diff); + } + } + + if (AbsDistance > SeatInformation.AllowedRadius - SeatInformation.AllowedRadiusThreshold) + SeatInformation.bIsOverThreshold = true; + else + SeatInformation.bIsOverThreshold = false; + + SeatInformation.CurrentThresholdScaler = FMath::Clamp((AbsDistance - (SeatInformation.AllowedRadius - SeatInformation.AllowedRadiusThreshold)) / SeatInformation.AllowedRadiusThreshold, 0.0f, 1.0f); + + if (bLastOverThreshold != SeatInformation.bIsOverThreshold || !FMath::IsNearlyEqual(LastThresholdScaler, SeatInformation.CurrentThresholdScaler)) + { + OnSeatThreshholdChanged(!SeatInformation.bIsOverThreshold, SeatInformation.CurrentThresholdScaler); + OnSeatThreshholdChanged_Bind.Broadcast(!SeatInformation.bIsOverThreshold, SeatInformation.CurrentThresholdScaler); + } +} + +bool AVRBaseCharacter::SetSeatedMode(USceneComponent * SeatParent, bool bSetSeatedMode, FTransform TargetTransform, FTransform InitialRelCameraTransform, float AllowedRadius, float AllowedRadiusThreshold, bool bZeroToHead, EVRConjoinedMovementModes PostSeatedMovementMode) +{ + if (!this->HasAuthority()) + return false; + + if (bSetSeatedMode) + { + if (!SeatParent) + return false; + + // Automate the intial relative camera transform for this mode + // I think we can remove the initial value alltogether eventually right? + if (!bRetainRoomscale && VRReplicatedCamera) + { + InitialRelCameraTransform = VRReplicatedCamera->GetHMDTrackingTransform(); + } + + SeatInformation.SeatParent = SeatParent; + SeatInformation.bSitting = true; + SeatInformation.bZeroToHead = bZeroToHead; + SeatInformation.StoredTargetTransform = TargetTransform; + SeatInformation.InitialRelCameraTransform = InitialRelCameraTransform; + + // Purify the yaw of the initial rotation + SeatInformation.InitialRelCameraTransform.SetRotation(UVRExpansionFunctionLibrary::GetHMDPureYaw_I(InitialRelCameraTransform.Rotator()).Quaternion()); + SeatInformation.AllowedRadius = AllowedRadius; + SeatInformation.AllowedRadiusThreshold = AllowedRadiusThreshold; + + // #TODO: Need to handle non 1 scaled values here eventually + if (bZeroToHead) + { + FVector newLocation = SeatInformation.InitialRelCameraTransform.GetTranslation(); + SeatInformation.StoredTargetTransform.AddToTranslation(FVector(0, 0, -newLocation.Z)); + } + +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(AVRBaseCharacter, SeatInformation, this); +#endif + + //SetReplicateMovement(false);/ / No longer doing this, allowing it to replicate down to simulated clients now instead + } + else + { + SeatInformation.SeatParent = nullptr; + SeatInformation.StoredTargetTransform = TargetTransform; + SeatInformation.PostSeatedMovementMode = PostSeatedMovementMode; + //SetReplicateMovement(true); // No longer doing this, allowing it to replicate down to simulated clients now instead + SeatInformation.bSitting = false; + } +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(AVRBaseCharacter, SeatInformation, this); +#endif + + OnRep_SeatedCharInfo(); // Call this on server side because it won't call itself + NotifyOfTeleport(); // Teleport the controllers + + return true; +} + +void AVRBaseCharacter::SetSeatRelativeLocationAndRotationVR(FVector DeltaLoc) +{ + /*if (bUseYawOnly) + { + NewRot.Pitch = 0.0f; + NewRot.Roll = 0.0f; + } + + NewLoc = NewLoc + Pivot; + NewLoc -= NewRot.RotateVector(Pivot); + + SetActorRelativeTransform(FTransform(NewRot, NewLoc, GetCapsuleComponent()->RelativeScale3D));*/ + + FVector ZOffset = -GetTargetHeightOffset() * GetCapsuleComponent()->GetRelativeScale3D(); + + FTransform NewTrans = SeatInformation.StoredTargetTransform;// *SeatInformation.SeatParent->GetComponentTransform(); + + if (!bRetainRoomscale) + { + NewTrans.SetTranslation(FVector(0.0f, 0.0f, NewTrans.GetTranslation().Z)); + } + + + FVector NewLocation; + FRotator NewRotation; + FVector PivotPoint = bRetainRoomscale ? SeatInformation.InitialRelCameraTransform.GetTranslation() : FVector::ZeroVector; + PivotPoint.Z = 0.0f; + + NewRotation = SeatInformation.InitialRelCameraTransform.Rotator(); + NewRotation = (NewRotation.Quaternion().Inverse() * NewTrans.GetRotation()).Rotator(); + NewLocation = NewTrans.GetTranslation(); + NewLocation -= NewRotation.RotateVector(PivotPoint + (-DeltaLoc)); + + // Also setting actor rot because the control rot transfers to it anyway eventually + SetActorRelativeTransform(FTransform(NewRotation, NewLocation + ZOffset, GetCapsuleComponent()->GetRelativeScale3D())); +} + +FVector AVRBaseCharacter::GetProjectedVRLocation() const +{ + return GetVRLocation_Inline(); +} + +FVector AVRBaseCharacter::AddActorWorldRotationVR(FRotator DeltaRot, bool bUseYawOnly, bool bRotateAroundCapsule) +{ + AController* OwningController = GetController(); + + FVector NewLocation; + FRotator NewRotation; + FVector OrigLocation = GetActorLocation(); + FVector PivotPoint = GetActorTransform().InverseTransformPosition(bRotateAroundCapsule ? GetVRLocation_Inline() : GetProjectedVRLocation()); + PivotPoint.Z = 0.0f; + + NewRotation = bUseControllerRotationYaw && OwningController ? OwningController->GetControlRotation() : GetActorRotation(); + + if (bUseYawOnly) + { + NewRotation.Pitch = 0.0f; + NewRotation.Roll = 0.0f; + } + + NewLocation = OrigLocation + NewRotation.RotateVector(PivotPoint); + NewRotation = (NewRotation.Quaternion() * DeltaRot.Quaternion()).Rotator(); + NewLocation -= NewRotation.RotateVector(PivotPoint); + + if (bUseControllerRotationYaw && OwningController /*&& IsLocallyControlled()*/) + OwningController->SetControlRotation(NewRotation); + + // Also setting actor rot because the control rot transfers to it anyway eventually + SetActorLocationAndRotation(NewLocation, NewRotation); + return NewLocation - OrigLocation; +} + +FVector AVRBaseCharacter::SetActorRotationVR(FRotator NewRot, bool bUseYawOnly, bool bAccountForHMDRotation, bool bRotateAroundCapsule) +{ + AController* OwningController = GetController(); + + FVector NewLocation; + FRotator NewRotation; + FVector OrigLocation = GetActorLocation(); + FVector PivotPoint = GetActorTransform().InverseTransformPosition(bRotateAroundCapsule ? GetVRLocation_Inline() : GetProjectedVRLocation()); + PivotPoint.Z = 0.0f; + + FRotator OrigRotation = bUseControllerRotationYaw && OwningController ? OwningController->GetControlRotation() : GetActorRotation(); + + if (bUseYawOnly) + { + NewRot.Pitch = 0.0f; + NewRot.Roll = 0.0f; + } + + if (bAccountForHMDRotation && VRReplicatedCamera) + { + NewRotation = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(VRReplicatedCamera->GetRelativeRotation()); + NewRotation = (NewRot.Quaternion() * NewRotation.Quaternion().Inverse()).Rotator(); + } + else + NewRotation = NewRot; + + NewLocation = OrigLocation + OrigRotation.RotateVector(PivotPoint); + //NewRotation = NewRot; + NewLocation -= NewRotation.RotateVector(PivotPoint); + + if (bUseControllerRotationYaw && OwningController /*&& IsLocallyControlled()*/) + OwningController->SetControlRotation(NewRotation); + + // Also setting actor rot because the control rot transfers to it anyway eventually + SetActorLocationAndRotation(NewLocation, NewRotation); + return NewLocation - OrigLocation; +} + +FVector AVRBaseCharacter::SetActorLocationAndRotationVR(FVector NewLoc, FRotator NewRot, bool bUseYawOnly, bool bAccountForHMDRotation, bool bTeleport, bool bRotateAroundCapsule) +{ + AController* OwningController = GetController(); + + FVector NewLocation; + FRotator NewRotation; + FVector PivotPoint = GetActorTransform().InverseTransformPosition(bRotateAroundCapsule ? GetVRLocation_Inline() : GetProjectedVRLocation()); + PivotPoint.Z = 0.0f; + + if (bUseYawOnly) + { + NewRot.Pitch = 0.0f; + NewRot.Roll = 0.0f; + } + + if (bAccountForHMDRotation && VRReplicatedCamera) + { + NewRotation = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(VRReplicatedCamera->GetRelativeRotation());//bUseControllerRotationYaw && OwningController ? OwningController->GetControlRotation() : GetActorRotation(); + NewRotation = (NewRot.Quaternion() * NewRotation.Quaternion().Inverse()).Rotator(); + } + else + NewRotation = NewRot; + + NewLocation = NewLoc;// +PivotPoint;// NewRotation.RotateVector(PivotPoint); + //NewRotation = NewRot; + NewLocation -= NewRotation.RotateVector(PivotPoint); + + if (bUseControllerRotationYaw && OwningController /*&& IsLocallyControlled()*/) + OwningController->SetControlRotation(NewRotation); + + // Also setting actor rot because the control rot transfers to it anyway eventually + SetActorLocationAndRotation(NewLocation, NewRotation, false, nullptr, bTeleport ? ETeleportType::TeleportPhysics : ETeleportType::None); + return NewLocation - NewLoc; +} + +FVector AVRBaseCharacter::SetActorLocationVR(FVector NewLoc, bool bTeleport, bool bSetCapsuleLocation) +{ + FVector NewLocation; + FRotator NewRotation; + FVector PivotOffsetVal = (bSetCapsuleLocation ? GetVRLocation_Inline() : GetProjectedVRLocation()) - GetActorLocation(); + PivotOffsetVal.Z = 0.0f; + + + NewLocation = NewLoc - PivotOffsetVal;// +PivotPoint;// NewRotation.RotateVector(PivotPoint); + //NewRotation = NewRot; + + + // Also setting actor rot because the control rot transfers to it anyway eventually + SetActorLocation(NewLocation, false, nullptr, bTeleport ? ETeleportType::TeleportPhysics : ETeleportType::None); + return NewLocation - NewLoc; +} + +void AVRBaseCharacter::OnRep_CapsuleHeight() +{ + if (!VRReplicateCapsuleHeight) + return; + + if (UCapsuleComponent* Capsule = Cast(GetRootComponent())) + { + if (ReplicatedCapsuleHeight.CapsuleHeight > 0.0f && !FMath::IsNearlyEqual(ReplicatedCapsuleHeight.CapsuleHeight, Capsule->GetUnscaledCapsuleHalfHeight())) + { + SetCharacterHalfHeightVR(ReplicatedCapsuleHeight.CapsuleHeight, false); + } + } +} + +void AVRBaseCharacter::SetCharacterSizeVR(float NewRadius, float NewHalfHeight, bool bUpdateOverlaps) +{ + if (UCapsuleComponent * Capsule = Cast(this->RootComponent)) + { + if (!FMath::IsNearlyEqual(NewRadius, Capsule->GetUnscaledCapsuleRadius()) || !FMath::IsNearlyEqual(NewHalfHeight, Capsule->GetUnscaledCapsuleHalfHeight())) + Capsule->SetCapsuleSize(NewRadius, NewHalfHeight, bUpdateOverlaps); + + if (GetNetMode() < ENetMode::NM_Client && VRReplicateCapsuleHeight) + ReplicatedCapsuleHeight.CapsuleHeight = Capsule->GetUnscaledCapsuleHalfHeight(); + } +} + +void AVRBaseCharacter::SetCharacterHalfHeightVR(float HalfHeight, bool bUpdateOverlaps) +{ + if (UCapsuleComponent * Capsule = Cast(this->RootComponent)) + { + if (!FMath::IsNearlyEqual(HalfHeight, Capsule->GetUnscaledCapsuleHalfHeight())) + Capsule->SetCapsuleHalfHeight(HalfHeight, bUpdateOverlaps); + + if (GetNetMode() < ENetMode::NM_Client && VRReplicateCapsuleHeight) + ReplicatedCapsuleHeight.CapsuleHeight = Capsule->GetUnscaledCapsuleHalfHeight(); + } +} + +void AVRBaseCharacter::ExtendedSimpleMoveToLocation(const FVector& GoalLocation, float AcceptanceRadius, bool bStopOnOverlap, bool bUsePathfinding, bool bProjectDestinationToNavigation, bool bCanStrafe, TSubclassOf FilterClass, bool bAllowPartialPaths) +{ + UNavigationSystemV1* NavSys = Controller ? FNavigationSystem::GetCurrent(Controller->GetWorld()) : nullptr; + if (NavSys == nullptr || Controller == nullptr ) + { + UE_LOG(LogBaseVRCharacter, Warning, TEXT("UVRSimpleCharacter::ExtendedSimpleMoveToLocation called for NavSys:%s Controller:%s (if any of these is None then there's your problem"), + *GetNameSafe(NavSys), *GetNameSafe(Controller)); + return; + } + + UPathFollowingComponent* PFollowComp = nullptr; + //Controller->InitNavigationControl(PFollowComp); + if (Controller) + { + // New for 4.20, spawning the missing path following component here if there isn't already one + PFollowComp = Controller->FindComponentByClass(); + if (PFollowComp == nullptr) + { + PFollowComp = NewObject(Controller); + PFollowComp->RegisterComponentWithWorld(Controller->GetWorld()); + PFollowComp->Initialize(); + } + } + + if (PFollowComp == nullptr) + { + UE_LOG(LogBaseVRCharacter, Warning, TEXT("ExtendedSimpleMoveToLocation - No PathFollowingComponent Found")); + return; + } + + if (!PFollowComp->IsPathFollowingAllowed()) + { + UE_LOG(LogBaseVRCharacter, Warning, TEXT("ExtendedSimpleMoveToLocation - Path Following Movement Is Not Set To Allowed")); + return; + } + + EPathFollowingReachMode ReachMode; + if (bStopOnOverlap) + ReachMode = EPathFollowingReachMode::OverlapAgent; + else + ReachMode = EPathFollowingReachMode::ExactLocation; + + bool bAlreadyAtGoal = false; + + if(UVRPathFollowingComponent * pathcomp = Cast(PFollowComp)) + bAlreadyAtGoal = pathcomp->HasReached(GoalLocation, /*EPathFollowingReachMode::OverlapAgent*/ReachMode); + else + bAlreadyAtGoal = PFollowComp->HasReached(GoalLocation, /*EPathFollowingReachMode::OverlapAgent*/ReachMode); + + // script source, keep only one move request at time + if (PFollowComp->GetStatus() != EPathFollowingStatus::Idle) + { + if (GetNetMode() == ENetMode::NM_Client) + { + // Stop the movement here, not keeping the velocity because it bugs out for clients, might be able to fix. + PFollowComp->AbortMove(*NavSys, FPathFollowingResultFlags::ForcedScript | FPathFollowingResultFlags::NewRequest + , FAIRequestID::AnyRequest, /*bAlreadyAtGoal ? */EPathFollowingVelocityMode::Reset /*: EPathFollowingVelocityMode::Keep*/); + } + else + { + PFollowComp->AbortMove(*NavSys, FPathFollowingResultFlags::ForcedScript | FPathFollowingResultFlags::NewRequest + , FAIRequestID::AnyRequest, bAlreadyAtGoal ? EPathFollowingVelocityMode::Reset : EPathFollowingVelocityMode::Keep); + } + } + + if (bAlreadyAtGoal) + { + PFollowComp->RequestMoveWithImmediateFinish(EPathFollowingResult::Success); + } + else + { + const ANavigationData* NavData = NavSys->GetNavDataForProps(Controller->GetNavAgentPropertiesRef()); + if (NavData) + { + FPathFindingQuery Query(Controller, *NavData, Controller->GetNavAgentLocation(), GoalLocation); + FPathFindingResult Result = NavSys->FindPathSync(Query); + if (Result.IsSuccessful()) + { + FAIMoveRequest MoveReq(GoalLocation); + MoveReq.SetUsePathfinding(bUsePathfinding); + MoveReq.SetAllowPartialPath(bAllowPartialPaths); + MoveReq.SetProjectGoalLocation(bProjectDestinationToNavigation); + MoveReq.SetNavigationFilter(*FilterClass ? FilterClass : DefaultNavigationFilterClass); + MoveReq.SetAcceptanceRadius(AcceptanceRadius); + MoveReq.SetReachTestIncludesAgentRadius(bStopOnOverlap); + MoveReq.SetCanStrafe(bCanStrafe); + MoveReq.SetReachTestIncludesGoalRadius(true); + + PFollowComp->RequestMove(/*FAIMoveRequest(GoalLocation)*/MoveReq, Result.Path); + } + else if (PFollowComp->GetStatus() != EPathFollowingStatus::Idle) + { + PFollowComp->RequestMoveWithImmediateFinish(EPathFollowingResult::Invalid); + } + } + } +} + +bool AVRBaseCharacter::GetCurrentNavigationPathPoints(TArray& NavigationPointList) +{ + UPathFollowingComponent* PFollowComp = nullptr; + if (Controller) + { + // New for 4.20, spawning the missing path following component here if there isn't already one + PFollowComp = Controller->FindComponentByClass(); + if (PFollowComp) + { + FNavPathSharedPtr NavPtr = PFollowComp->GetPath(); + if (NavPtr.IsValid()) + { + TArray& NavPoints = NavPtr->GetPathPoints(); + if (NavPoints.Num()) + { + FTransform BaseTransform = FTransform::Identity; + if (AActor* BaseActor = NavPtr->GetBaseActor()) + { + BaseTransform = BaseActor->GetActorTransform(); + } + + NavigationPointList.Empty(NavPoints.Num()); + NavigationPointList.AddUninitialized(NavPoints.Num()); + + int counter = 0; + for (FNavPathPoint& pt : NavPoints) + { + NavigationPointList[counter++] = BaseTransform.TransformPosition(pt.Location); + } + + return true; + } + } + + return false; + } + } + + return false; +} + +void AVRBaseCharacter::NavigationMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult& Result) +{ + this->Controller->StopMovement(); + ReceiveNavigationMoveCompleted(Result.Code); +} + +EPathFollowingStatus::Type AVRBaseCharacter::GetMoveStatus() const +{ + if (!Controller) + return EPathFollowingStatus::Idle; + + if (UPathFollowingComponent* pathComp = Controller->FindComponentByClass()) + { + pathComp->GetStatus(); + } + + return EPathFollowingStatus::Idle; +} + +bool AVRBaseCharacter::HasPartialPath() const +{ + if (!Controller) + return false; + + if (UPathFollowingComponent* pathComp = Controller->FindComponentByClass()) + { + return pathComp->HasPartialPath(); + } + + return false; +} + +void AVRBaseCharacter::StopNavigationMovement() +{ + if (!Controller) + return; + + if (UPathFollowingComponent* pathComp = Controller->FindComponentByClass()) + { + // @note FPathFollowingResultFlags::ForcedScript added to make AITask_MoveTo instances + // not ignore OnRequestFinished notify that's going to be sent out due to this call + pathComp->AbortMove(*this, FPathFollowingResultFlags::MovementStop | FPathFollowingResultFlags::ForcedScript); + } +} + +void AVRBaseCharacter::SetVRReplicateCapsuleHeight(bool bNewVRReplicateCapsuleHeight) +{ + VRReplicateCapsuleHeight = bNewVRReplicateCapsuleHeight; +#if WITH_PUSH_MODEL + MARK_PROPERTY_DIRTY_FROM_NAME(AVRBaseCharacter, VRReplicateCapsuleHeight, this); +#endif +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRBaseCharacterMovementComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRBaseCharacterMovementComponent.cpp new file mode 100644 index 0000000..db3bddd --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRBaseCharacterMovementComponent.cpp @@ -0,0 +1,2412 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +/*============================================================================= + Movement.cpp: Character movement implementation + +=============================================================================*/ + +#include "VRBaseCharacterMovementComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRBaseCharacterMovementComponent) + +#include "VRBPDatatypes.h" +#include "ParentRelativeAttachmentComponent.h" +#include "VRBaseCharacter.h" +#include "VRCharacter.h" +#include "VRRootComponent.h" +#include "AITypes.h" +#include "GripMotionControllerComponent.h" +#include "AI/Navigation/NavigationTypes.h" +#include "Navigation/PathFollowingComponent.h" +#include "VRPlayerController.h" +#include "GameFramework/PhysicsVolume.h" +#include "Animation/AnimInstance.h" + + +DEFINE_LOG_CATEGORY(LogVRBaseCharacterMovement); + +UVRBaseCharacterMovementComponent::UVRBaseCharacterMovementComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + PrimaryComponentTick.TickGroup = TG_PrePhysics; + + + //#TODO: Might not be ready to make this change globally yet.... + + // Set Acceleration and braking deceleration walking to high values to avoid ramp up on speed + // Realized that I wasn't doing this here for people to default to no acceleration. + /*this->bRequestedMoveUseAcceleration = false; + this->MaxAcceleration = 200048.0f; + this->BrakingDecelerationWalking = 200048.0f; + */ + + AdditionalVRInputVector = FVector::ZeroVector; + CustomVRInputVector = FVector::ZeroVector; + TrackingLossThreshold = 6000.f; + bApplyAdditionalVRInputVectorAsNegative = true; + bHadExtremeInput = false; + bHoldPositionOnTrackingLossThresholdHit = false; + + VRClimbingStepHeight = 96.0f; + VRClimbingEdgeRejectDistance = 5.0f; + VRClimbingStepUpMultiplier = 1.0f; + bClampClimbingStepUp = false; + VRClimbingStepUpMaxSize = 20.0f; + + VRClimbingMaxReleaseVelocitySize = 800.0f; + SetDefaultPostClimbMovementOnStepUp = true; + DefaultPostClimbMovement = EVRConjoinedMovementModes::C_MOVE_Falling; + + bIgnoreSimulatingComponentsInFloorCheck = true; + + VRWallSlideScaler = 1.0f; + VRLowGravWallFrictionScaler = 1.0f; + VRLowGravIgnoresDefaultFluidFriction = true; + + VREdgeRejectDistance = 0.01f; // Rounded minimum of root movement + + VRReplicatedMovementMode = EVRConjoinedMovementModes::C_MOVE_MAX; + + NetworkSmoothingMode = ENetworkSmoothingMode::Exponential; + + bWasInPushBack = false; + bIsInPushBack = false; + + bRunControlRotationInMovementComponent = true; + + // Allow merging dual movements, generally this is wanted for the perf increase + bEnableServerDualMoveScopedMovementUpdates = true; + + bNotifyTeleported = false; + + bJustUnseated = false; + + bUseClientControlRotation = true; + bDisableSimulatedTickWhenSmoothingMovement = true; + bCapHMDMovementToMaxMovementSpeed = false; + + SetNetworkMoveDataContainer(VRNetworkMoveDataContainer); + SetMoveResponseDataContainer(VRMoveResponseDataContainer); +} + +// Rewind the relative movement that we had with the HMD +void UVRBaseCharacterMovementComponent::RewindVRRelativeMovement() +{ + if (bApplyAdditionalVRInputVectorAsNegative && (BaseVRCharacterOwner && BaseVRCharacterOwner->bRetainRoomscale)) + { + //FHitResult AHit; + MoveUpdatedComponent(-AdditionalVRInputVector, UpdatedComponent->GetComponentQuat(), false); + //SafeMoveUpdatedComponent(-AdditionalVRInputVector, UpdatedComponent->GetComponentQuat(), false, AHit); + } +} + +void UVRBaseCharacterMovementComponent::OnMovementModeChanged(EMovementMode PreviousMovementMode, uint8 PreviousCustomMode) +{ + if (!HasValidData()) + { + return; + } + + // Clear out the old custom input vector, it will pollute the pool now that all modes allow it. + CustomVRInputVector = FVector::ZeroVector; + + if (PreviousMovementMode == EMovementMode::MOVE_Custom && PreviousCustomMode == (uint8)EVRCustomMovementMode::VRMOVE_Seated) + { + if (MovementMode != EMovementMode::MOVE_Custom || CustomMovementMode != (uint8)EVRCustomMovementMode::VRMOVE_Seated) + { + if (AVRBaseCharacter * BaseOwner = Cast(CharacterOwner)) + { + BaseOwner->InitSeatedModeTransition(); + } + } + } + + if (MovementMode == EMovementMode::MOVE_Custom) + { + if (CustomMovementMode == (uint8)EVRCustomMovementMode::VRMOVE_Climbing || CustomMovementMode == (uint8)EVRCustomMovementMode::VRMOVE_Seated) + { + // Kill velocity and clear queued up events + StopMovementKeepPathing(); + CharacterOwner->ResetJumpState(); + ClearAccumulatedForces(); + + if (CustomMovementMode == (uint8)EVRCustomMovementMode::VRMOVE_Seated) + { + if (AVRBaseCharacter * BaseOwner = Cast(CharacterOwner)) + { + BaseOwner->InitSeatedModeTransition(); + } + } + } + } + + Super::OnMovementModeChanged(PreviousMovementMode, PreviousCustomMode); +} + +bool UVRBaseCharacterMovementComponent::ForcePositionUpdate(float DeltaTime) +{ + // Skip force updating position if we are seated. + if ((MovementMode == EMovementMode::MOVE_Custom && CustomMovementMode == (uint8)EVRCustomMovementMode::VRMOVE_Seated)) + { + return false; + } + + return Super::ForcePositionUpdate(DeltaTime); +} + +bool UVRBaseCharacterMovementComponent::ClientUpdatePositionAfterServerUpdate() +{ + //SCOPE_CYCLE_COUNTER(STAT_CharacterMovementClientUpdatePositionAfterServerUpdate); + if (!HasValidData()) + { + return false; + } + + FNetworkPredictionData_Client_Character* ClientData = GetPredictionData_Client_Character(); + check(ClientData); + + if (!ClientData->bUpdatePosition) + { + return false; + } + + ClientData->bUpdatePosition = false; + + // Don't do any network position updates on things running PHYS_RigidBody + if (CharacterOwner->GetRootComponent() && CharacterOwner->GetRootComponent()->IsSimulatingPhysics()) + { + return false; + } + + if (ClientData->SavedMoves.Num() == 0) + { + UE_LOG(LogNetPlayerMovement, Verbose, TEXT("ClientUpdatePositionAfterServerUpdate No saved moves to replay"), ClientData->SavedMoves.Num()); + + // With no saved moves to resimulate, the move the server updated us with is the last move we've done, no resimulation needed. + CharacterOwner->bClientResimulateRootMotion = false; + if (CharacterOwner->bClientResimulateRootMotionSources) + { + // With no resimulation, we just update our current root motion to what the server sent us + UE_LOG(LogRootMotion, VeryVerbose, TEXT("CurrentRootMotion getting updated to ServerUpdate state: %s"), *CharacterOwner->GetName()); + CurrentRootMotion.UpdateStateFrom(CharacterOwner->SavedRootMotion); + CharacterOwner->bClientResimulateRootMotionSources = false; + } + CharacterOwner->SavedRootMotion.Clear(); + + return false; + } + + // Save important values that might get affected by the replay. + const float SavedAnalogInputModifier = AnalogInputModifier; + const FRootMotionMovementParams BackupRootMotionParams = RootMotionParams; // For animation root motion + const FRootMotionSourceGroup BackupRootMotion = CurrentRootMotion; + const bool bRealPressedJump = CharacterOwner->bPressedJump; + const float RealJumpMaxHoldTime = CharacterOwner->JumpMaxHoldTime; + const int32 RealJumpMaxCount = CharacterOwner->JumpMaxCount; + const bool bRealCrouch = bWantsToCrouch; + const bool bRealForceMaxAccel = bForceMaxAccel; + CharacterOwner->bClientWasFalling = (MovementMode == MOVE_Falling); + CharacterOwner->bClientUpdating = true; + bForceNextFloorCheck = true; + + // Store out our custom properties to restore after replaying + const FVRMoveActionArray Orig_MoveActions = MoveActionArray; + const FVector Orig_CustomInput = CustomVRInputVector; + const EVRConjoinedMovementModes Orig_VRReplicatedMovementMode = VRReplicatedMovementMode; + const FVector Orig_RequestedVelocity = RequestedVelocity; + const bool Orig_HasRequestedVelocity = HasRequestedVelocity(); + + // Replay moves that have not yet been acked. + UE_LOG(LogNetPlayerMovement, Verbose, TEXT("ClientUpdatePositionAfterServerUpdate Replaying %d Moves, starting at Timestamp %f"), ClientData->SavedMoves.Num(), ClientData->SavedMoves[0]->TimeStamp); + for (int32 i = 0; i < ClientData->SavedMoves.Num(); i++) + { + FSavedMove_Character* const CurrentMove = ClientData->SavedMoves[i].Get(); + checkSlow(CurrentMove != nullptr); + + // Make current SavedMove accessible to any functions that might need it. + SetCurrentReplayedSavedMove(CurrentMove); + + CurrentMove->PrepMoveFor(CharacterOwner); + + if (ShouldUsePackedMovementRPCs()) + { + // Make current move data accessible to MoveAutonomous or any other functions that might need it. + if (FCharacterNetworkMoveData* NewMove = GetNetworkMoveDataContainer().GetNewMoveData()) + { + SetCurrentNetworkMoveData(NewMove); + NewMove->ClientFillNetworkMoveData(*CurrentMove, FCharacterNetworkMoveData::ENetworkMoveType::NewMove); + } + } + + MoveAutonomous(CurrentMove->TimeStamp, CurrentMove->DeltaTime, CurrentMove->GetCompressedFlags(), CurrentMove->Acceleration); + + CurrentMove->PostUpdate(CharacterOwner, FSavedMove_Character::PostUpdate_Replay); + SetCurrentNetworkMoveData(nullptr); + SetCurrentReplayedSavedMove(nullptr); + } + const bool bPostReplayPressedJump = CharacterOwner->bPressedJump; + + if (FSavedMove_Character* const PendingMove = ClientData->PendingMove.Get()) + { + PendingMove->bForceNoCombine = true; + } + + // Restore saved values. + AnalogInputModifier = SavedAnalogInputModifier; + RootMotionParams = BackupRootMotionParams; + CurrentRootMotion = BackupRootMotion; + if (CharacterOwner->bClientResimulateRootMotionSources) + { + // If we were resimulating root motion sources, it's because we had mismatched state + // with the server - we just resimulated our SavedMoves and now need to restore + // CurrentRootMotion with the latest "good state" + UE_LOG(LogRootMotion, VeryVerbose, TEXT("CurrentRootMotion getting updated after ServerUpdate replays: %s"), *CharacterOwner->GetName()); + CurrentRootMotion.UpdateStateFrom(CharacterOwner->SavedRootMotion); + CharacterOwner->bClientResimulateRootMotionSources = false; + } + CharacterOwner->SavedRootMotion.Clear(); + CharacterOwner->bClientResimulateRootMotion = false; + CharacterOwner->bClientUpdating = false; + CharacterOwner->bPressedJump = bRealPressedJump || bPostReplayPressedJump; + CharacterOwner->JumpMaxHoldTime = RealJumpMaxHoldTime; + CharacterOwner->JumpMaxCount = RealJumpMaxCount; + bWantsToCrouch = bRealCrouch; + bForceMaxAccel = bRealForceMaxAccel; + bForceNextFloorCheck = true; + + // Restore our move actions + MoveActionArray = Orig_MoveActions; + CustomVRInputVector = Orig_CustomInput; + VRReplicatedMovementMode = Orig_VRReplicatedMovementMode; + RequestedVelocity = Orig_RequestedVelocity; + SetHasRequestedVelocity(Orig_HasRequestedVelocity); + + return (ClientData->SavedMoves.Num() > 0); +} + +void UVRBaseCharacterMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) +{ + + // Skip calling into BP if we aren't locally controlled + if (CharacterOwner->IsLocallyControlled() && GetReplicatedMovementMode() == EVRConjoinedMovementModes::C_VRMOVE_Climbing) + { + // Allow the player to run updates on the climb logic for CustomVRInputVector + if (BaseVRCharacterOwner) + { + BaseVRCharacterOwner->UpdateClimbingMovement(DeltaTime); + } + } + + // Scope all of the movements, including PRC + { + UParentRelativeAttachmentComponent* OuterScopePRC = nullptr; + if (BaseVRCharacterOwner && BaseVRCharacterOwner->ParentRelativeAttachment && BaseVRCharacterOwner->ParentRelativeAttachment->bUpdateInCharacterMovement) + { + OuterScopePRC = BaseVRCharacterOwner->ParentRelativeAttachment; + } + + FScopedMovementUpdate ScopedPRCMovementUpdate(OuterScopePRC, EScopedUpdate::DeferredUpdates); + + { + UReplicatedVRCameraComponent* OuterScopeCamera = nullptr; + if (BaseVRCharacterOwner && BaseVRCharacterOwner->VRReplicatedCamera) + { + OuterScopeCamera = BaseVRCharacterOwner->VRReplicatedCamera; + } + + FScopedMovementUpdate ScopedCameraMovementUpdate(OuterScopeCamera, EScopedUpdate::DeferredUpdates); + + // Scope in the character movements first + { + // Scope these, they nest with Outer references so it should work fine + FVRCharacterScopedMovementUpdate ScopedMovementUpdate(UpdatedComponent, bEnableScopedMovementUpdates ? EScopedUpdate::DeferredUpdates : EScopedUpdate::ImmediateUpdates); + + if (MovementMode == MOVE_Custom && CustomMovementMode == (uint8)EVRCustomMovementMode::VRMOVE_Seated) + { + + //#TODO 5.0: Handle this? + /*FVector InputVector = FVector::ZeroVector; + bool bUsingAsyncTick = (CharacterMovementCVars::AsyncCharacterMovement == 1) && IsAsyncCallbackRegistered(); + if (!bUsingAsyncTick) + { + // Do not consume input if simulating asynchronously, we will consume input when filling out async inputs. + InputVector = ConsumeInputVector(); + }*/ + + + const FVector InputVector = ConsumeInputVector(); + if (!HasValidData() || ShouldSkipUpdate(DeltaTime)) + { + return; + } + + // Skip the perform movement logic, run the re-seat logic instead - running base movement component tick instead + Super::Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + // See if we fell out of the world. + const bool bIsSimulatingPhysics = UpdatedComponent->IsSimulatingPhysics(); + if (CharacterOwner->GetLocalRole() == ROLE_Authority && (!bCheatFlying || bIsSimulatingPhysics) && !CharacterOwner->CheckStillInWorld()) + { + return; + } + + // If we are the owning client or the server then run the re-basing + if (CharacterOwner->GetLocalRole() > ROLE_SimulatedProxy) + { + // Run offset logic here, the server will update simulated proxies with the movement replication + if (AVRBaseCharacter* BaseChar = Cast(CharacterOwner)) + { + BaseChar->TickSeatInformation(DeltaTime); + } + + // Handle move actions here - Should be scoped + CheckForMoveAction(); + MoveActionArray.Clear(); + + if (CharacterOwner && !CharacterOwner->IsLocallyControlled() && DeltaTime > 0.0f) + { + // If not playing root motion, tick animations after physics. We do this here to keep events, notifies, states and transitions in sync with client updates. + if (!CharacterOwner->bClientUpdating && !CharacterOwner->IsPlayingRootMotion() && CharacterOwner->GetMesh()) + { + TickCharacterPose(DeltaTime); + // TODO: SaveBaseLocation() in case tick moves us? + + // Trigger Events right away, as we could be receiving multiple ServerMoves per frame. + CharacterOwner->GetMesh()->ConditionallyDispatchQueuedAnimEvents(); + } + } + + } + else + { + if (bNetworkUpdateReceived) + { + if (bNetworkMovementModeChanged) + { + ApplyNetworkMovementMode(CharacterOwner->GetReplicatedMovementMode()); + bNetworkMovementModeChanged = false; + } + } + } + } + else + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + + // This should be valid for both Simulated and owning clients as well as the server + // Better here than in perform movement + if (UVRRootComponent* VRRoot = Cast(CharacterOwner->GetCapsuleComponent())) + { + // If we didn't move the capsule, have it update itself here so the visual and physics representation is correct + // We do this specifically to avoid double calling into the render / physics threads. + if (!VRRoot->bCalledUpdateTransform) + VRRoot->OnUpdateTransform_Public(EUpdateTransformFlags::None, ETeleportType::None); + } + + // Make sure these are cleaned out for the next frame + AdditionalVRInputVector = FVector::ZeroVector; + CustomVRInputVector = FVector::ZeroVector; + } + + if (bRunControlRotationInMovementComponent && CharacterOwner->IsLocallyControlled()) + { + if (BaseVRCharacterOwner) + { + if (BaseVRCharacterOwner->VRReplicatedCamera && BaseVRCharacterOwner->VRReplicatedCamera->bUsePawnControlRotation) + { + const AController* OwningController = BaseVRCharacterOwner->GetController(); + if (OwningController) + { + const FRotator PawnViewRotation = BaseVRCharacterOwner->GetViewRotation(); + if (!PawnViewRotation.Equals(BaseVRCharacterOwner->VRReplicatedCamera->GetComponentRotation())) + { + BaseVRCharacterOwner->VRReplicatedCamera->SetWorldRotation(PawnViewRotation); + } + } + } + } + } + + // If some of our important components run inside the cmc updates then lets update them now + if (OuterScopeCamera) + { + OuterScopeCamera->UpdateTracking(DeltaTime); + } + + if (OuterScopePRC) + { + OuterScopePRC->UpdateTracking(DeltaTime); + } + } + } + + if (bNotifyTeleported) + { + if (BaseVRCharacterOwner) + { + BaseVRCharacterOwner->OnCharacterTeleported_Bind.Broadcast(); + bNotifyTeleported = false; + } + } +} + +bool UVRBaseCharacterMovementComponent::VerifyClientTimeStamp(float TimeStamp, FNetworkPredictionData_Server_Character & ServerData) +{ + // Server is auth on seated mode and we want to ignore incoming pending movements after we have decided to set the client to seated mode + if (MovementMode == MOVE_Custom && CustomMovementMode == (uint8)EVRCustomMovementMode::VRMOVE_Seated) + return false; + + return Super::VerifyClientTimeStamp(TimeStamp, ServerData); +} + +void UVRBaseCharacterMovementComponent::StartPushBackNotification(FHitResult HitResult) +{ + bIsInPushBack = true; + + if (bWasInPushBack) + return; + + bWasInPushBack = true; + + if (AVRBaseCharacter * OwningCharacter = Cast(GetCharacterOwner())) + { + OwningCharacter->OnBeginWallPushback(HitResult, !Acceleration.Equals(FVector::ZeroVector), AdditionalVRInputVector); + } +} + +void UVRBaseCharacterMovementComponent::EndPushBackNotification() +{ + if (bIsInPushBack || !bWasInPushBack) + return; + + bIsInPushBack = false; + bWasInPushBack = false; + + if (AVRBaseCharacter * OwningCharacter = Cast(GetCharacterOwner())) + { + OwningCharacter->OnEndWallPushback(); + } +} + +FVector UVRBaseCharacterMovementComponent::GetActorFeetLocationVR() const +{ + if (AVRBaseCharacter * BaseCharacter = Cast(GetCharacterOwner())) + { + return UpdatedComponent ? (BaseCharacter->OffsetComponentToWorld.GetLocation() - FVector(0, 0, UpdatedComponent->Bounds.BoxExtent.Z)) : FNavigationSystem::InvalidLocation; + } + else + { + return UpdatedComponent ? (UpdatedComponent->GetComponentLocation() - FVector(0, 0, UpdatedComponent->Bounds.BoxExtent.Z)) : FNavigationSystem::InvalidLocation; + } +} + +void UVRBaseCharacterMovementComponent::OnMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult& Result) +{ + if (AVRBaseCharacter* vrOwner = Cast(GetCharacterOwner())) + { + vrOwner->NavigationMoveCompleted(RequestID, Result); + } +} + +bool UVRBaseCharacterMovementComponent::FloorSweepTest( + FHitResult& OutHit, + const FVector& Start, + const FVector& End, + ECollisionChannel TraceChannel, + const struct FCollisionShape& CollisionShape, + const struct FCollisionQueryParams& Params, + const struct FCollisionResponseParams& ResponseParam +) const +{ + bool bBlockingHit = false; + + // #TODO: Report to epic that their FloorSweepTest was not using the gravity rotation so it didn't work when the capsule was out of range + + if (!bUseFlatBaseForFloorChecks) + { + bBlockingHit = GetWorld()->SweepSingleByChannel(OutHit, Start, End, GetWorldToGravityTransform(), TraceChannel, CollisionShape, Params, ResponseParam); + } + else + { + // Test with a box that is enclosed by the capsule. + const float CapsuleRadius = CollisionShape.GetCapsuleRadius(); + const float CapsuleHeight = CollisionShape.GetCapsuleHalfHeight(); + const FCollisionShape BoxShape = FCollisionShape::MakeBox(FVector(CapsuleRadius * 0.707f, CapsuleRadius * 0.707f, CapsuleHeight)); + + // First test with the box rotated so the corners are along the major axes (ie rotated 45 degrees). + bBlockingHit = GetWorld()->SweepSingleByChannel(OutHit, Start, End, FQuat(RotateGravityToWorld(FVector(0.f, 0.f, -1.f)), UE_PI * 0.25f), TraceChannel, BoxShape, Params, ResponseParam); + + if (!bBlockingHit) + { + // Test again with the same box, not rotated. + OutHit.Reset(1.f, false); + bBlockingHit = GetWorld()->SweepSingleByChannel(OutHit, Start, End, GetWorldToGravityTransform(), TraceChannel, BoxShape, Params, ResponseParam); + } + } + + return bBlockingHit; +} + +void UVRBaseCharacterMovementComponent::ComputeFloorDist(const FVector& CapsuleLocation, float LineDistance, float SweepDistance, FFindFloorResult& OutFloorResult, float SweepRadius, const FHitResult* DownwardSweepResult) const +{ + UE_LOG(LogVRBaseCharacterMovement, VeryVerbose, TEXT("[Role:%d] ComputeFloorDist: %s at location %s"), (int32)CharacterOwner->GetLocalRole(), *GetNameSafe(CharacterOwner), *CapsuleLocation.ToString()); + OutFloorResult.Clear(); + + float PawnRadius, PawnHalfHeight; + CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleSize(PawnRadius, PawnHalfHeight); + + bool bSkipSweep = false; + if (DownwardSweepResult != NULL && DownwardSweepResult->IsValidBlockingHit()) + { + // Only if the supplied sweep was vertical and downward. + const bool bIsDownward = RotateWorldToGravity(DownwardSweepResult->TraceStart - DownwardSweepResult->TraceEnd).Z > 0; + const bool bIsVertical = RotateWorldToGravity(DownwardSweepResult->TraceStart - DownwardSweepResult->TraceEnd).SizeSquared2D() <= UE_KINDA_SMALL_NUMBER; + if (bIsDownward && bIsVertical) + { + // Reject hits that are barely on the cusp of the radius of the capsule + if (IsWithinEdgeTolerance(DownwardSweepResult->Location, DownwardSweepResult->ImpactPoint, PawnRadius)) + { + // Don't try a redundant sweep, regardless of whether this sweep is usable. + bSkipSweep = true; + + const bool bIsWalkable = IsWalkable(*DownwardSweepResult); + const float FloorDist = RotateWorldToGravity(CapsuleLocation - DownwardSweepResult->Location).Z; + OutFloorResult.SetFromSweep(*DownwardSweepResult, FloorDist, bIsWalkable); + + if (bIsWalkable) + { + // Use the supplied downward sweep as the floor hit result. + return; + } + } + } + } + + // We require the sweep distance to be >= the line distance, otherwise the HitResult can't be interpreted as the sweep result. + if (SweepDistance < LineDistance) + { + ensure(SweepDistance >= LineDistance); + return; + } + + bool bBlockingHit = false; + FCollisionQueryParams QueryParams(SCENE_QUERY_STAT(ComputeFloorDist), false, CharacterOwner); + FCollisionResponseParams ResponseParam; + InitCollisionParams(QueryParams, ResponseParam); + const ECollisionChannel CollisionChannel = UpdatedComponent->GetCollisionObjectType(); + + // Skip physics bodies for floor check if we are skipping simulated objects + if (bIgnoreSimulatingComponentsInFloorCheck) + ResponseParam.CollisionResponse.PhysicsBody = ECollisionResponse::ECR_Ignore; + + // Sweep test + if (!bSkipSweep && SweepDistance > 0.f && SweepRadius > 0.f) + { + // Use a shorter height to avoid sweeps giving weird results if we start on a surface. + // This also allows us to adjust out of penetrations. + const float ShrinkScale = 0.9f; + const float ShrinkScaleOverlap = 0.1f; + float ShrinkHeight = (PawnHalfHeight - PawnRadius) * (1.f - ShrinkScale); + float TraceDist = SweepDistance + ShrinkHeight; + FCollisionShape CapsuleShape = FCollisionShape::MakeCapsule(SweepRadius, PawnHalfHeight - ShrinkHeight); + + FHitResult Hit(1.f); + bBlockingHit = FloorSweepTest(Hit, CapsuleLocation, CapsuleLocation + RotateGravityToWorld(FVector(0.f, 0.f, -TraceDist)), CollisionChannel, CapsuleShape, QueryParams, ResponseParam); + + if (bBlockingHit) + { + // Reject hits adjacent to us, we only care about hits on the bottom portion of our capsule. + // Check 2D distance to impact point, reject if within a tolerance from radius. + if (Hit.bStartPenetrating || !IsWithinEdgeTolerance(CapsuleLocation, Hit.ImpactPoint, CapsuleShape.Capsule.Radius)) + { + // Use a capsule with a slightly smaller radius and shorter height to avoid the adjacent object. + // Capsule must not be nearly zero or the trace will fall back to a line trace from the start point and have the wrong length. + CapsuleShape.Capsule.Radius = FMath::Max(0.f, CapsuleShape.Capsule.Radius - SWEEP_EDGE_REJECT_DISTANCE - UE_KINDA_SMALL_NUMBER); + if (!CapsuleShape.IsNearlyZero()) + { + ShrinkHeight = (PawnHalfHeight - PawnRadius) * (1.f - ShrinkScaleOverlap); + TraceDist = SweepDistance + ShrinkHeight; + CapsuleShape.Capsule.HalfHeight = FMath::Max(PawnHalfHeight - ShrinkHeight, CapsuleShape.Capsule.Radius); + Hit.Reset(1.f, false); + + bBlockingHit = FloorSweepTest(Hit, CapsuleLocation, CapsuleLocation + RotateGravityToWorld(FVector(0.f, 0.f, -TraceDist)), CollisionChannel, CapsuleShape, QueryParams, ResponseParam); + } + } + + // Reduce hit distance by ShrinkHeight because we shrank the capsule for the trace. + // We allow negative distances here, because this allows us to pull out of penetrations. + const float MaxPenetrationAdjust = FMath::Max(MAX_FLOOR_DIST, PawnRadius); + const float SweepResult = FMath::Max(-MaxPenetrationAdjust, Hit.Time * TraceDist - ShrinkHeight); + + OutFloorResult.SetFromSweep(Hit, SweepResult, false); + if (Hit.IsValidBlockingHit() && IsWalkable(Hit)) + { + if (SweepResult <= SweepDistance) + { + // Hit within test distance. + OutFloorResult.bWalkableFloor = true; + return; + } + } + } + } + + // Since we require a longer sweep than line trace, we don't want to run the line trace if the sweep missed everything. + // We do however want to try a line trace if the sweep was stuck in penetration. + if (!OutFloorResult.bBlockingHit && !OutFloorResult.HitResult.bStartPenetrating) + { + OutFloorResult.FloorDist = SweepDistance; + return; + } + + // Line trace + if (LineDistance > 0.f) + { + const float ShrinkHeight = PawnHalfHeight; + const FVector LineTraceStart = CapsuleLocation; + const float TraceDist = LineDistance + ShrinkHeight; + const FVector Down = RotateGravityToWorld(FVector(0.f, 0.f, -TraceDist)); + QueryParams.TraceTag = SCENE_QUERY_STAT_NAME_ONLY(FloorLineTrace); + + FHitResult Hit(1.f); + bBlockingHit = GetWorld()->LineTraceSingleByChannel(Hit, LineTraceStart, LineTraceStart + Down, CollisionChannel, QueryParams, ResponseParam); + + if (bBlockingHit) + { + if (Hit.Time > 0.f) + { + // Reduce hit distance by ShrinkHeight because we started the trace higher than the base. + // We allow negative distances here, because this allows us to pull out of penetrations. + const float MaxPenetrationAdjust = FMath::Max(MAX_FLOOR_DIST, PawnRadius); + const float LineResult = FMath::Max(-MaxPenetrationAdjust, Hit.Time * TraceDist - ShrinkHeight); + + OutFloorResult.bBlockingHit = true; + if (LineResult <= LineDistance && IsWalkable(Hit)) + { + OutFloorResult.SetFromLineTrace(Hit, OutFloorResult.FloorDist, LineResult, true); + return; + } + } + } + } + + // No hits were acceptable. + OutFloorResult.bWalkableFloor = false; +} + + +float UVRBaseCharacterMovementComponent::SlideAlongSurface(const FVector& Delta, float Time, const FVector& InNormal, FHitResult& Hit, bool bHandleImpact) +{ + // Am running the CharacterMovementComponents calculations manually here now prior to scaling down the delta + + if (!Hit.bBlockingHit) + { + return 0.f; + } + + FVector Normal(RotateWorldToGravity(InNormal)); + if (IsMovingOnGround()) + { + // We don't want to be pushed up an unwalkable surface. + if (Normal.Z > 0.f) + { + if (!IsWalkable(Hit)) + { + Normal = Normal.GetSafeNormal2D(); + } + } + else if (Normal.Z < -UE_KINDA_SMALL_NUMBER) + { + // Don't push down into the floor when the impact is on the upper portion of the capsule. + if (CurrentFloor.FloorDist < MIN_FLOOR_DIST && CurrentFloor.bBlockingHit) + { + const FVector FloorNormal = RotateWorldToGravity(CurrentFloor.HitResult.Normal); + const bool bFloorOpposedToMovement = (RotateWorldToGravity(Delta) | FloorNormal) < 0.f && (FloorNormal.Z < 1.f - UE_DELTA); + + if (bFloorOpposedToMovement) + { + Normal = FloorNormal; + } + + Normal = Normal.GetSafeNormal2D(); + } + } + } + + + /*if ((Delta | InNormal) <= -0.2) + { + + }*/ + + StartPushBackNotification(Hit); + + // If the movement mode is one where sliding is an issue in VR, scale the delta by the custom scaler now + // that we have already validated the floor normal. + // Otherwise just pass in as normal, either way skip the parents implementation as we are doing it now. + if (IsMovingOnGround() || (MovementMode == MOVE_Custom && CustomMovementMode == (uint8)EVRCustomMovementMode::VRMOVE_Climbing)) + return Super::Super::SlideAlongSurface(Delta * VRWallSlideScaler, Time, RotateGravityToWorld(Normal), Hit, bHandleImpact); + else + return Super::Super::SlideAlongSurface(Delta, Time, RotateGravityToWorld(Normal), Hit, bHandleImpact); +} + +/*void UVRBaseCharacterMovementComponent::SetCrouchedHalfHeight(float NewCrouchedHalfHeight) +{ + this->CrouchedHalfHeight = NewCrouchedHalfHeight; +}*/ + +void UVRBaseCharacterMovementComponent::AddCustomReplicatedMovement(FVector Movement) +{ + // if we are a client then lets round this to match what it will be after net Replication + if (GetNetMode() == NM_Client) + CustomVRInputVector += RoundDirectMovement(Movement); + else + CustomVRInputVector += Movement; // If not a client, don't bother to round this down. +} + +void UVRBaseCharacterMovementComponent::ClearCustomReplicatedMovement() +{ + CustomVRInputVector = FVector::ZeroVector; +} + +void UVRBaseCharacterMovementComponent::CheckServerAuthedMoveAction() +{ + // If we are calling this on the server on a non owned character, there is no reason to wait around, just do the action now + // If we ARE locally controlled, keep the action inline with the movement component to maintain consistency + if (GetNetMode() < NM_Client) + { + ACharacter* OwningChar = GetCharacterOwner(); + if (OwningChar && !OwningChar->IsLocallyControlled()) + { + CheckForMoveAction(); + MoveActionArray.Clear(); + } + } +} + +void UVRBaseCharacterMovementComponent::PerformMoveAction_SetTrackingPaused(bool bNewTrackingPaused) +{ + StoreSetTrackingPaused(bNewTrackingPaused); +} + +void UVRBaseCharacterMovementComponent::StoreSetTrackingPaused(bool bNewTrackingPaused) +{ + FVRMoveActionContainer MoveAction; + MoveAction.MoveAction = EVRMoveAction::VRMOVEACTION_PauseTracking; + MoveAction.MoveActionFlags = bNewTrackingPaused; + MoveActionArray.MoveActions.Add(MoveAction); + CheckServerAuthedMoveAction(); +} + +void UVRBaseCharacterMovementComponent::PerformMoveAction_SnapTurn(float DeltaYawAngle, EVRMoveActionVelocityRetention VelocityRetention, bool bFlagGripTeleport, bool bFlagCharacterTeleport, bool bRotateAroundCapsule ) +{ + FVRMoveActionContainer MoveAction; + MoveAction.MoveAction = EVRMoveAction::VRMOVEACTION_SnapTurn; + + // Removed 2 decimal precision rounding in favor of matching the actual replicated short fidelity instead. + // MoveAction.MoveActionRot = FRotator(0.0f, FMath::RoundToFloat(((FRotator(0.f,DeltaYawAngle, 0.f).Quaternion() * UpdatedComponent->GetComponentQuat()).Rotator().Yaw) * 100.f) / 100.f, 0.0f); + + // Setting to the exact same fidelity as the replicated value ends up being, losing some precision + FRotator TargetRotation = (UpdatedComponent->GetComponentQuat() * FRotator(0.f, DeltaYawAngle, 0.f).Quaternion()).Rotator(); + TargetRotation.Yaw = FRotator::DecompressAxisFromShort(FRotator::CompressAxisToShort(TargetRotation.Yaw)); + TargetRotation.Pitch = FRotator::DecompressAxisFromShort(FRotator::CompressAxisToShort(TargetRotation.Pitch)); + TargetRotation.Roll = FRotator::DecompressAxisFromShort(FRotator::CompressAxisToShort(TargetRotation.Roll)); + MoveAction.MoveActionRot = TargetRotation; + //MoveAction.MoveActionRot = FRotator( 0.0f, FRotator::DecompressAxisFromShort(FRotator::CompressAxisToShort(DeltaYawAngle)), 0.0f); + //FRotator(0.0f, FRotator::DecompressAxisFromShort(FRotator::CompressAxisToShort((FRotator(0.f, DeltaYawAngle, 0.f).Quaternion() * UpdatedComponent->GetComponentQuat()).Rotator().Yaw)), 0.0f); + + if (bFlagCharacterTeleport) + MoveAction.MoveActionFlags = 0x02;// .MoveActionRot.Roll = 2.0f; + else if(bFlagGripTeleport) + MoveAction.MoveActionFlags = 0x01;//MoveActionRot.Roll = bFlagGripTeleport ? 1.0f : 0.0f; + + if (bRotateAroundCapsule) + { + MoveAction.MoveActionFlags |= 0x08; + } + + if (VelocityRetention == EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_Turn) + { + //MoveAction.MoveActionRot.Pitch = FMath::RoundToFloat(DeltaYawAngle * 100.f) / 100.f; + //MoveAction.MoveActionRot.Pitch = DeltaYawAngle; + MoveAction.MoveActionDeltaYaw = FRotator::DecompressAxisFromShort(FRotator::CompressAxisToShort(DeltaYawAngle)); + } + + MoveAction.VelRetentionSetting = VelocityRetention; + + MoveActionArray.MoveActions.Add(MoveAction); + CheckServerAuthedMoveAction(); +} + +void UVRBaseCharacterMovementComponent::PerformMoveAction_SetRotation(float NewYaw, EVRMoveActionVelocityRetention VelocityRetention, bool bFlagGripTeleport, bool bFlagCharacterTeleport, bool bRotateAroundCapsule) +{ + FVRMoveActionContainer MoveAction; + MoveAction.MoveAction = EVRMoveAction::VRMOVEACTION_SetRotation; + MoveAction.MoveActionRot = FRotator(0.0f, FMath::RoundToFloat(NewYaw * 100.f) / 100.f, 0.0f); + + if (bFlagCharacterTeleport) + MoveAction.MoveActionFlags = 0x02;// .MoveActionRot.Roll = 2.0f; + else if (bFlagGripTeleport) + MoveAction.MoveActionFlags = 0x01;//MoveActionRot.Roll = bFlagGripTeleport ? 1.0f : 0.0f; + + if (bRotateAroundCapsule) + { + MoveAction.MoveActionFlags |= 0x08; + } + + if (VelocityRetention == EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_Turn) + { + float DeltaYawAngle = FMath::FindDeltaAngleDegrees(UpdatedComponent->GetComponentRotation().Yaw, NewYaw); + //MoveAction.MoveActionRot.Pitch = FMath::RoundToFloat(DeltaYawAngle * 100.f) / 100.f; + MoveAction.MoveActionRot.Pitch = DeltaYawAngle; + } + + MoveAction.VelRetentionSetting = VelocityRetention; + + MoveActionArray.MoveActions.Add(MoveAction); + CheckServerAuthedMoveAction(); +} + +void UVRBaseCharacterMovementComponent::PerformMoveAction_Teleport(FVector TeleportLocation, FRotator TeleportRotation, EVRMoveActionVelocityRetention VelocityRetention, bool bSkipEncroachmentCheck) +{ + FVRMoveActionContainer MoveAction; + MoveAction.MoveAction = EVRMoveAction::VRMOVEACTION_Teleport; + MoveAction.MoveActionLoc = RoundDirectMovement(TeleportLocation); + MoveAction.MoveActionRot.Yaw = FMath::RoundToFloat(TeleportRotation.Yaw * 100.f) / 100.f; + MoveAction.MoveActionFlags |= (uint8)bSkipEncroachmentCheck;//.MoveActionRot.Roll = bSkipEncroachmentCheck ? 1.0f : 0.0f; + + if (VelocityRetention == EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_Turn) + { + float DeltaYawAngle = FMath::FindDeltaAngleDegrees(UpdatedComponent->GetComponentRotation().Yaw, TeleportRotation.Yaw); + //MoveAction.MoveActionRot.Pitch = FMath::RoundToFloat(DeltaYawAngle * 100.f) / 100.f; + MoveAction.MoveActionRot.Pitch = DeltaYawAngle; + } + + MoveAction.VelRetentionSetting = VelocityRetention; + + MoveActionArray.MoveActions.Add(MoveAction); + CheckServerAuthedMoveAction(); +} + +void UVRBaseCharacterMovementComponent::PerformMoveAction_StopAllMovement() +{ + FVRMoveActionContainer MoveAction; + MoveAction.MoveAction = EVRMoveAction::VRMOVEACTION_StopAllMovement; + MoveActionArray.MoveActions.Add(MoveAction); + + CheckServerAuthedMoveAction(); +} + +void UVRBaseCharacterMovementComponent::PerformMoveAction_SetGravityDirection(FVector NewGravityDirection, bool bOrientToNewGravity) +{ + if (NewGravityDirection.IsNearlyZero()) + { + return; + } + + FVRMoveActionContainer MoveAction; + MoveAction.MoveAction = EVRMoveAction::VRMOVEACTION_SetGravityDirection; + MoveAction.MoveActionVel = NewGravityDirection.GetSafeNormal(); + MoveAction.MoveActionFlags |= (uint8)bOrientToNewGravity; + MoveActionArray.MoveActions.Add(MoveAction); + + CheckServerAuthedMoveAction(); +} + +void UVRBaseCharacterMovementComponent::PerformMoveAction_Custom(EVRMoveAction MoveActionToPerform, EVRMoveActionDataReq DataRequirementsForMoveAction, FVector MoveActionVector, FRotator MoveActionRotator, uint8 MoveActionFlags) +{ + FVRMoveActionContainer MoveAction; + MoveAction.MoveAction = MoveActionToPerform; + + // Round the vector to 2 decimal precision + MoveAction.MoveActionLoc = RoundDirectMovement(MoveActionVector); + MoveAction.MoveActionRot = MoveActionRotator; + MoveAction.MoveActionDataReq = DataRequirementsForMoveAction; + MoveAction.MoveActionFlags = MoveActionFlags; + MoveActionArray.MoveActions.Add(MoveAction); + + CheckServerAuthedMoveAction(); +} + +bool UVRBaseCharacterMovementComponent::CheckForMoveAction() +{ + if (!BaseVRCharacterOwner) + return true; + + for (FVRMoveActionContainer& MoveAction : MoveActionArray.MoveActions) + { + switch (MoveAction.MoveAction) + { + case EVRMoveAction::VRMOVEACTION_SnapTurn: + { + /*return */DoMASnapTurn(MoveAction); + }break; + case EVRMoveAction::VRMOVEACTION_Teleport: + { + if (!BaseVRCharacterOwner->SeatInformation.bSitting) + { + /*return */DoMATeleport(MoveAction); + } + }break; + case EVRMoveAction::VRMOVEACTION_StopAllMovement: + { + /*return */DoMAStopAllMovement(MoveAction); + }break; + case EVRMoveAction::VRMOVEACTION_SetGravityDirection: + { + if (!BaseVRCharacterOwner->SeatInformation.bSitting) + { + /*return */DoMASetGravityDirection(MoveAction); + } + }break; + case EVRMoveAction::VRMOVEACTION_SetRotation: + { + if (!BaseVRCharacterOwner->SeatInformation.bSitting) + { + /*return */DoMASetRotation(MoveAction); + } + }break; + case EVRMoveAction::VRMOVEACTION_PauseTracking: + { + /*return */DoMAPauseTracking(MoveAction); + }break; + case EVRMoveAction::VRMOVEACTION_None: + {}break; + default: // All other move actions (CUSTOM) + { + if (BaseVRCharacterOwner) + { + BaseVRCharacterOwner->OnCustomMoveActionPerformed(MoveAction.MoveAction, MoveAction.MoveActionLoc, MoveAction.MoveActionRot, MoveAction.MoveActionFlags); + } + }break; + } + } + + return true; +} + +bool UVRBaseCharacterMovementComponent::DoMASnapTurn(FVRMoveActionContainer& MoveAction) +{ + if (BaseVRCharacterOwner) + { + FRotator TargetRot = MoveAction.MoveActionRot; + FQuat OrigRot = BaseVRCharacterOwner->GetActorQuat(); + + if (BaseVRCharacterOwner->SeatInformation.bSitting) + { + FRotator DeltaRot(0.f, MoveAction.MoveActionDeltaYaw, 0.f); + TargetRot = ( OrigRot * DeltaRot.Quaternion() ).Rotator(); + } + + FTransform OriginalRelativeTrans = BaseVRCharacterOwner->GetRootComponent()->GetRelativeTransform(); + + bool bRotateAroundCapsule = MoveAction.MoveActionFlags & 0x08; + + // Clamp to 2 decimal precision + /*TargetRot = TargetRot.Clamp(); + TargetRot.Pitch = (TargetRot.Pitch * 100.f) / 100.f; + TargetRot.Yaw = (TargetRot.Yaw * 100.f) / 100.f; + TargetRot.Roll = (TargetRot.Roll * 100.f) / 100.f; + TargetRot.Normalize();*/ + bIsBlendingOrientation = true; + + if (this->BaseVRCharacterOwner && this->BaseVRCharacterOwner->IsLocallyControlled()) + { + if (this->bUseClientControlRotation) + { + MoveAction.MoveActionLoc = BaseVRCharacterOwner->SetActorRotationVR(TargetRot, false, false, bRotateAroundCapsule); + MoveAction.MoveActionFlags |= 0x04; // Flag that we are using loc only + } + else + { + BaseVRCharacterOwner->SetActorRotationVR(TargetRot, false, false, bRotateAroundCapsule); + } + } + else + { + if (MoveAction.MoveActionFlags & 0x04) + { + BaseVRCharacterOwner->SetActorLocation(BaseVRCharacterOwner->GetActorLocation() + MoveAction.MoveActionLoc); + } + else + { + BaseVRCharacterOwner->SetActorRotationVR(TargetRot, false, false, bRotateAroundCapsule); + } + } + + switch (MoveAction.VelRetentionSetting) + { + case EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_None: + { + + }break; + case EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_Clear: + { + this->Velocity = FVector::ZeroVector; + }break; + case EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_Turn: + { + if (BaseVRCharacterOwner->IsLocallyControlled()) + { + MoveAction.MoveActionVel = RoundDirectMovement((TargetRot.Quaternion() * OrigRot.Inverse()).RotateVector(this->Velocity)); + this->Velocity = MoveAction.MoveActionVel; + } + else + { + this->Velocity = MoveAction.MoveActionVel; + } + }break; + } + + // If we are flagged to teleport the grips + if (MoveAction.MoveActionFlags & 0x01 || MoveAction.MoveActionFlags & 0x02) + { + BaseVRCharacterOwner->NotifyOfTeleport(MoveAction.MoveActionFlags & 0x02); + } + + if (BaseVRCharacterOwner->SeatInformation.bSitting) + { + BaseVRCharacterOwner->SeatInformation.StoredTargetTransform = (OriginalRelativeTrans.Inverse() * BaseVRCharacterOwner->GetRootComponent()->GetRelativeTransform()) * BaseVRCharacterOwner->SeatInformation.StoredTargetTransform; + if (BaseVRCharacterOwner->IsLocallyControlled() && GetNetMode() == ENetMode::NM_Client) + { + BaseVRCharacterOwner->Server_SeatedSnapTurn(MoveAction.MoveActionDeltaYaw); + } + } + } + + return false; +} + +bool UVRBaseCharacterMovementComponent::DoMASetRotation(FVRMoveActionContainer& MoveAction) +{ + bool bRotateAroundCapsule = MoveAction.MoveActionFlags & 0x08; + + if (BaseVRCharacterOwner) + { + FTransform OriginalRelativeTrans = BaseVRCharacterOwner->GetRootComponent()->GetRelativeTransform(); + + FRotator TargetRot(0.f, MoveAction.MoveActionRot.Yaw, 0.f); + + // Clamp to 2 decimal precision + /*TargetRot = TargetRot.Clamp(); + TargetRot.Pitch = (TargetRot.Pitch * 100.f) / 100.f; + TargetRot.Yaw = (TargetRot.Yaw * 100.f) / 100.f; + TargetRot.Roll = (TargetRot.Roll * 100.f) / 100.f; + TargetRot.Normalize();*/ + bIsBlendingOrientation = true; + + if (this->BaseVRCharacterOwner && this->BaseVRCharacterOwner->IsLocallyControlled()) + { + if (this->bUseClientControlRotation) + { + MoveAction.MoveActionLoc = BaseVRCharacterOwner->SetActorRotationVR(TargetRot, true); + MoveAction.MoveActionFlags |= 0x04; // Flag that we are using loc only + } + else + { + BaseVRCharacterOwner->SetActorRotationVR(TargetRot, true, true, bRotateAroundCapsule); + } + } + else + { + if (MoveAction.MoveActionFlags & 0x04) + { + BaseVRCharacterOwner->SetActorLocation(BaseVRCharacterOwner->GetActorLocation() + MoveAction.MoveActionLoc); + } + else + { + BaseVRCharacterOwner->SetActorRotationVR(TargetRot, true, true, bRotateAroundCapsule); + } + } + + switch (MoveAction.VelRetentionSetting) + { + case EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_None: + { + + }break; + case EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_Clear: + { + this->Velocity = FVector::ZeroVector; + }break; + case EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_Turn: + { + if (BaseVRCharacterOwner->IsLocallyControlled()) + { + MoveAction.MoveActionVel = RoundDirectMovement(FRotator(0.f, MoveAction.MoveActionRot.Pitch, 0.f).RotateVector(this->Velocity)); + this->Velocity = MoveAction.MoveActionVel; + } + else + { + this->Velocity = MoveAction.MoveActionVel; + } + }break; + } + + // If we are flagged to teleport the grips + if (MoveAction.MoveActionFlags & 0x01 || MoveAction.MoveActionFlags & 0x02) + { + BaseVRCharacterOwner->NotifyOfTeleport(MoveAction.MoveActionFlags & 0x02); + } + } + + return false; +} + +bool UVRBaseCharacterMovementComponent::DoMATeleport(FVRMoveActionContainer& MoveAction) +{ + if (BaseVRCharacterOwner) + { + AController* OwningController = BaseVRCharacterOwner->GetController(); + + if (!OwningController) + { + MoveAction.MoveAction = EVRMoveAction::VRMOVEACTION_None; + return false; + } + + bool bSkipEncroachmentCheck = MoveAction.MoveActionFlags & 0x01; //MoveAction.MoveActionRot.Roll > 0.0f; + FRotator TargetRot(0.f, MoveAction.MoveActionRot.Yaw, 0.f); + BaseVRCharacterOwner->TeleportTo(MoveAction.MoveActionLoc, TargetRot, false, bSkipEncroachmentCheck); + + switch (MoveAction.VelRetentionSetting) + { + case EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_None: + { + + }break; + case EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_Clear: + { + this->Velocity = FVector::ZeroVector; + }break; + case EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_Turn: + { + if (BaseVRCharacterOwner->IsLocallyControlled()) + { + MoveAction.MoveActionVel = RoundDirectMovement(FRotator(0.f, MoveAction.MoveActionRot.Pitch, 0.f).RotateVector(this->Velocity)); + this->Velocity = MoveAction.MoveActionVel; + } + else + { + this->Velocity = MoveAction.MoveActionVel; + } + }break; + } + + if (BaseVRCharacterOwner->bUseControllerRotationYaw) + OwningController->SetControlRotation(TargetRot); + + return true; + } + + return false; +} + +bool UVRBaseCharacterMovementComponent::DoMAStopAllMovement(FVRMoveActionContainer& MoveAction) +{ + if (AVRBaseCharacter * OwningCharacter = Cast(GetCharacterOwner())) + { + this->StopMovementImmediately(); + return true; + } + + return false; +} + +bool UVRBaseCharacterMovementComponent::DoMASetGravityDirection(FVRMoveActionContainer& MoveAction) +{ + bool bOrientToNewGravity = MoveAction.MoveActionFlags > 0; + return SetCharacterToNewGravity(MoveAction.MoveActionVel, bOrientToNewGravity); +} + +bool UVRBaseCharacterMovementComponent::DoMAPauseTracking(FVRMoveActionContainer& MoveAction) +{ + if (BaseVRCharacterOwner) + { + BaseVRCharacterOwner->bTrackingPaused = MoveAction.MoveActionFlags > 0; + BaseVRCharacterOwner->PausedTrackingLoc = MoveAction.MoveActionLoc; + BaseVRCharacterOwner->PausedTrackingRot = MoveAction.MoveActionRot.Yaw; + return true; + } + return false; +} + +void UVRBaseCharacterMovementComponent::PhysCustom(float deltaTime, int32 Iterations) +{ + switch (static_cast(CustomMovementMode)) + { + case EVRCustomMovementMode::VRMOVE_Climbing: + PhysCustom_Climbing(deltaTime, Iterations); + break; + case EVRCustomMovementMode::VRMOVE_LowGrav: + PhysCustom_LowGrav(deltaTime, Iterations); + break; + case EVRCustomMovementMode::VRMOVE_Seated: + break; + default: + Super::PhysCustom(deltaTime, Iterations); + break; + } +} + +bool UVRBaseCharacterMovementComponent::VRClimbStepUp(const FVector& GravDir, const FVector& Delta, const FHitResult &InHit, FStepDownResult* OutStepDownResult) +{ + return StepUp(GravDir, Delta, InHit, OutStepDownResult); +} + +void UVRBaseCharacterMovementComponent::PhysCustom_Climbing(float deltaTime, int32 Iterations) +{ + if (deltaTime < MIN_TICK_TIME) + { + return; + } + + // Skip calling into BP if we aren't locally controlled - *EDIT* MOVED TO TICKCOMPONENT to avoid batched movement issues + /*if (CharacterOwner->IsLocallyControlled()) + { + // Allow the player to run updates on the climb logic for CustomVRInputVector + if (AVRBaseCharacter * characterOwner = Cast(CharacterOwner)) + { + characterOwner->UpdateClimbingMovement(deltaTime); + } + }*/ + + + // I am forcing this to 0 to avoid some legacy velocity coming out of other movement modes, climbing should only be direct movement anyway. + Velocity = FVector::ZeroVector; + + // Rewind the players position by the new capsule location + RewindVRRelativeMovement(); + + Iterations++; + bJustTeleported = false; + + FVector OldLocation = UpdatedComponent->GetComponentLocation(); + const FVector Adjusted = /*(Velocity * deltaTime) + */CustomVRInputVector; + FVector Delta = Adjusted + AdditionalVRInputVector; + bool bZeroDelta = Delta.IsNearlyZero(); + + FStepDownResult StepDownResult; + + // Instead of remaking the step up function, temp assign a custom step height and then fall back to the old one afterward + // This isn't the "proper" way to do it, but it saves on re-making stepup() for both vr characters seperatly (due to different hmd injection) + float OldMaxStepHeight = MaxStepHeight; + MaxStepHeight = VRClimbingStepHeight; + bool bSteppedUp = false; + + if (!bZeroDelta) + { + FHitResult Hit(1.f); + SafeMoveUpdatedComponent(Delta, UpdatedComponent->GetComponentQuat(), true, Hit); + + if (Hit.Time < 1.f) + { + const FVector GravDir = FVector(0.f, 0.f, -1.f); + const FVector VelDir = (CustomVRInputVector).GetSafeNormal();//Velocity.GetSafeNormal(); + const float UpDown = GravDir | VelDir; + + //bool bSteppedUp = false; + if ((FMath::Abs(Hit.ImpactNormal.Z) < 0.2f) && (UpDown < 0.5f) && (UpDown > -0.2f) && CanStepUp(Hit)) + { + // Scope our movement updates, and do not apply them until all intermediate moves are completed. + FVRCharacterScopedMovementUpdate ScopedStepUpMovement(UpdatedComponent, EScopedUpdate::DeferredUpdates); + + float stepZ = UpdatedComponent->GetComponentLocation().Z; + + // Making it easier to step up here with the multiplier, helps avoid falling back off + if(bClampClimbingStepUp) + bSteppedUp = VRClimbStepUp(GravDir, ((Adjusted.GetClampedToMaxSize2D(VRClimbingStepUpMaxSize) * VRClimbingStepUpMultiplier) + AdditionalVRInputVector) * (1.f - Hit.Time), Hit, &StepDownResult); + else + bSteppedUp = VRClimbStepUp(GravDir, ((Adjusted * VRClimbingStepUpMultiplier) + AdditionalVRInputVector) * (1.f - Hit.Time), Hit, &StepDownResult); + + if (bSteppedUp && OnPerformClimbingStepUp.IsBound()) + { + FVector finalLoc = UpdatedComponent->GetComponentLocation(); + + // Rewind the step up, the end user wants to handle it instead + ScopedStepUpMovement.RevertMove(); + + // Revert to old max step height + MaxStepHeight = OldMaxStepHeight; + + OnPerformClimbingStepUp.Broadcast(finalLoc); + return; + } + + if (bSteppedUp) + { + OldLocation.Z = UpdatedComponent->GetComponentLocation().Z + (OldLocation.Z - stepZ); + } + + } + + if (!bSteppedUp) + { + //adjust and try again + HandleImpact(Hit, deltaTime, Adjusted); + SlideAlongSurface(Adjusted, (1.f - Hit.Time), Hit.Normal, Hit, true); + } + } + } + + // Revert to old max step height + MaxStepHeight = OldMaxStepHeight; + + if (bSteppedUp) + { + if (AVRBaseCharacter * ownerCharacter = Cast(CharacterOwner)) + { + if (SetDefaultPostClimbMovementOnStepUp) + { + // Takes effect next frame, this allows server rollback to correctly handle auto step up + SetReplicatedMovementMode(DefaultPostClimbMovement); + // Before doing this the server could rollback the client from a bad step up and leave it hanging in climb mode + // This way the rollback replay correctly sets the movement mode from the step up request + + Velocity = FVector::ZeroVector; + } + + // Notify the end user that they probably want to stop gripping now + ownerCharacter->OnClimbingSteppedUp(); + } + } + + // Update floor. + // StepUp might have already done it for us. + if (StepDownResult.bComputedFloor) + { + CurrentFloor = StepDownResult.FloorResult; + } + else + { + FindFloor(UpdatedComponent->GetComponentLocation(), CurrentFloor, bZeroDelta, NULL); + } + + if (CurrentFloor.IsWalkableFloor()) + { + if(CurrentFloor.GetDistanceToFloor() < (MIN_FLOOR_DIST + MAX_FLOOR_DIST) / 2) + AdjustFloorHeight(); + + // This was causing based movement to apply to climbing + //SetBase(CurrentFloor.HitResult.Component.Get(), CurrentFloor.HitResult.BoneName); + } + else if (CurrentFloor.HitResult.bStartPenetrating) + { + // The floor check failed because it started in penetration + // We do not want to try to move downward because the downward sweep failed, rather we'd like to try to pop out of the floor. + FHitResult Hit(CurrentFloor.HitResult); + Hit.TraceEnd = Hit.TraceStart + FVector(0.f, 0.f, MAX_FLOOR_DIST); + const FVector RequestedAdjustment = GetPenetrationAdjustment(Hit); + ResolvePenetration(RequestedAdjustment, Hit, UpdatedComponent->GetComponentQuat()); + bForceNextFloorCheck = true; + } + + if (bAutoOrientToFloorNormal && CurrentFloor.IsWalkableFloor()) + { + // Auto Align to the new floor normal + // Set gravity direction to the new floor normal + AutoTraceAndSetCharacterToNewGravity(CurrentFloor.HitResult, deltaTime); + } + + if(!bSteppedUp || !SetDefaultPostClimbMovementOnStepUp) + { + if (!bJustTeleported && !HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity()) + { + Velocity = (((UpdatedComponent->GetComponentLocation() - OldLocation) - AdditionalVRInputVector) / deltaTime).GetClampedToMaxSize(VRClimbingMaxReleaseVelocitySize); + } + } +} + +void UVRBaseCharacterMovementComponent::PhysCustom_LowGrav(float deltaTime, int32 Iterations) +{ + + if (deltaTime < MIN_TICK_TIME) + { + return; + } + + // Skip calling into BP if we aren't locally controlled + if (CharacterOwner->IsLocallyControlled()) + { + // Allow the player to run updates on the push logic for CustomVRInputVector + if (AVRBaseCharacter * characterOwner = Cast(CharacterOwner)) + { + characterOwner->UpdateLowGravMovement(deltaTime); + } + } + + float Friction = 0.0f; + // Rewind the players position by the new capsule location + RewindVRRelativeMovement(); + + //RestorePreAdditiveVRMotionVelocity(); + + // If we are not in the default physics volume then accept the custom fluid friction setting + // I set this by default to be ignored as many will not alter the default fluid friction + if(!VRLowGravIgnoresDefaultFluidFriction || GetWorld()->GetDefaultPhysicsVolume() != GetPhysicsVolume()) + Friction = 0.5f * GetPhysicsVolume()->FluidFriction; + + CalcVelocity(deltaTime, Friction, true, 0.0f); + + // Adding in custom VR input vector here, can be used for custom movement during it + // AddImpulse is not multiplayer compatible client side + //Velocity += CustomVRInputVector; + + ApplyVRMotionToVelocity(deltaTime); + + Iterations++; + bJustTeleported = false; + + FVector OldLocation = UpdatedComponent->GetComponentLocation(); + const FVector Adjusted = (Velocity * deltaTime); + FHitResult Hit(1.f); + SafeMoveUpdatedComponent(Adjusted/* + AdditionalVRInputVector*/, UpdatedComponent->GetComponentQuat(), true, Hit); + + if (Hit.Time < 1.f) + { + // Still running step up with grav dir + const FVector GravDir = FVector(0.f, 0.f, -1.f); + const FVector VelDir = Velocity.GetSafeNormal(); + const float UpDown = GravDir | VelDir; + + bool bSteppedUp = false; + if ((FMath::Abs(Hit.ImpactNormal.Z) < 0.2f) && (UpDown < 0.5f) && (UpDown > -0.2f) && CanStepUp(Hit)) + { + float stepZ = UpdatedComponent->GetComponentLocation().Z; + bSteppedUp = StepUp(GravDir, Adjusted * (1.f - Hit.Time), Hit); + if (bSteppedUp) + { + OldLocation.Z = UpdatedComponent->GetComponentLocation().Z + (OldLocation.Z - stepZ); + } + } + + if (!bSteppedUp) + { + //adjust and try again + HandleImpact(Hit, deltaTime, Adjusted); + SlideAlongSurface(Adjusted, (1.f - Hit.Time), Hit.Normal, Hit, true); + } + + if (!bJustTeleported && !HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity()) + { + Velocity = (((UpdatedComponent->GetComponentLocation() - OldLocation) /* - AdditionalVRInputVector*/) / deltaTime) * VRLowGravWallFrictionScaler; + } + } + else + { + if (!bJustTeleported && !HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity()) + { + Velocity = (((UpdatedComponent->GetComponentLocation() - OldLocation) /* - AdditionalVRInputVector*/) / deltaTime); + } + } + + RestorePreAdditiveVRMotionVelocity(); +} + + +void UVRBaseCharacterMovementComponent::SetClimbingMode(bool bIsClimbing) +{ + if (bIsClimbing) + VRReplicatedMovementMode = EVRConjoinedMovementModes::C_VRMOVE_Climbing; + else + VRReplicatedMovementMode = DefaultPostClimbMovement; +} + +void UVRBaseCharacterMovementComponent::SetReplicatedMovementMode(EVRConjoinedMovementModes NewMovementMode) +{ + // Only have up to 15 that it can go up to, the previous 7 index's are used up for std movement modes + VRReplicatedMovementMode = NewMovementMode; +} + +EVRConjoinedMovementModes UVRBaseCharacterMovementComponent::GetReplicatedMovementMode() +{ + if (MovementMode == EMovementMode::MOVE_Custom) + { + return (EVRConjoinedMovementModes)((int8)CustomMovementMode + (int8)EVRConjoinedMovementModes::C_VRMOVE_Climbing); + } + else + return (EVRConjoinedMovementModes)MovementMode.GetValue(); +} + +void UVRBaseCharacterMovementComponent::ApplyNetworkMovementMode(const uint8 ReceivedMode) +{ + if (CharacterOwner->GetLocalRole() != ENetRole::ROLE_SimulatedProxy) + { + const uint8 CurrentPackedMovementMode = PackNetworkMovementMode(); + if (CurrentPackedMovementMode != ReceivedMode) + { + TEnumAsByte NetMovementMode(MOVE_None); + TEnumAsByte NetGroundMode(MOVE_None); + uint8 NetCustomMode(0); + UnpackNetworkMovementMode(ReceivedMode, NetMovementMode, NetCustomMode, NetGroundMode); + + // Custom movement modes aren't going to be rolled back as they are client authed for our pawns + if (NetMovementMode == EMovementMode::MOVE_Custom || MovementMode == EMovementMode::MOVE_Custom) + { + if (NetCustomMode == (uint8)EVRCustomMovementMode::VRMOVE_Climbing || CustomMovementMode == (uint8)EVRCustomMovementMode::VRMOVE_Climbing) + return; // Don't rollback custom movement modes, we set the server to trust the client on them now so the server should get corrected + } + } + } + + Super::ApplyNetworkMovementMode(ReceivedMode); +} + +void UVRBaseCharacterMovementComponent::SetUpdatedComponent(USceneComponent* NewUpdatedComponent) +{ + Super::SetUpdatedComponent(NewUpdatedComponent); + + BaseVRCharacterOwner = Cast(CharacterOwner); +} + + +void UVRBaseCharacterMovementComponent::PerformMovement(float DeltaSeconds) +{ + // Scope these, they nest with Outer references so it should work fine + FVRCharacterScopedMovementUpdate ScopedMovementUpdate(UpdatedComponent, bEnableScopedMovementUpdates ? EScopedUpdate::DeferredUpdates : EScopedUpdate::ImmediateUpdates); + + // This moves it into update scope + if (bRunControlRotationInMovementComponent && CharacterOwner->IsLocallyControlled()) + { + if (BaseVRCharacterOwner && BaseVRCharacterOwner->OwningVRPlayerController) + { + BaseVRCharacterOwner->OwningVRPlayerController->RotationInput = BaseVRCharacterOwner->OwningVRPlayerController->LastRotationInput; + BaseVRCharacterOwner->OwningVRPlayerController->UpdateRotation(DeltaSeconds); + BaseVRCharacterOwner->OwningVRPlayerController->LastRotationInput = FRotator::ZeroRotator; + BaseVRCharacterOwner->OwningVRPlayerController->RotationInput = FRotator::ZeroRotator; + } + } + + // Apply any replicated movement modes that are pending + ApplyReplicatedMovementMode(VRReplicatedMovementMode, true); + + // Handle move actions here - Should be scoped + CheckForMoveAction(); + + // Clear out this flag prior to movement so we can see if it gets changed + bIsInPushBack = false; + + + // Handle collision swapping if we aren't doing locomotion based movement + if (BaseVRCharacterOwner->VRRootReference->bUseWalkingCollisionOverride && !BaseVRCharacterOwner->bRetainRoomscale) + { + bool bAllowWalkingCollision = false; + if (MovementMode == EMovementMode::MOVE_Walking || MovementMode == EMovementMode::MOVE_NavWalking) + bAllowWalkingCollision = true; + + BaseVRCharacterOwner->VRRootReference->SetCollisionOverride(bAllowWalkingCollision && GetCurrentAcceleration().IsNearlyZero()); + } + + Super::PerformMovement(DeltaSeconds); + + EndPushBackNotification(); // Check if we need to notify of ending pushback + + // Make sure these are cleaned out for the next frame + //AdditionalVRInputVector = FVector::ZeroVector; + //CustomVRInputVector = FVector::ZeroVector; + + // Only clear it here if we are the server, the client clears it later + if (CharacterOwner->GetLocalRole() == ROLE_Authority) + { + MoveActionArray.Clear(); + } +} + +void UVRBaseCharacterMovementComponent::OnClientCorrectionReceived(class FNetworkPredictionData_Client_Character& ClientData, float TimeStamp, FVector NewLocation, FVector NewVelocity, UPrimitiveComponent* NewBase, FName NewBaseBoneName, bool bHasBase, bool bBaseRelativePosition, uint8 ServerMovementMode, FVector ServerGravityDirection) +{ + Super::OnClientCorrectionReceived(ClientData, TimeStamp, NewLocation, NewVelocity, NewBase, NewBaseBoneName, bHasBase, bBaseRelativePosition, ServerMovementMode, ServerGravityDirection); + + + // If we got corrected then lets teleport our grips, this means that we were out of sync with the server or the server moved us + if (BaseVRCharacterOwner) + { + BaseVRCharacterOwner->OnCharacterNetworkCorrected_Bind.Broadcast(); + + if (IsValid(BaseVRCharacterOwner->LeftMotionController)) + { + BaseVRCharacterOwner->LeftMotionController->TeleportMoveGrips(false, false); + BaseVRCharacterOwner->LeftMotionController->PostTeleportMoveGrippedObjects(); + } + + if (IsValid(BaseVRCharacterOwner->RightMotionController)) + { + BaseVRCharacterOwner->RightMotionController->TeleportMoveGrips(false, false); + BaseVRCharacterOwner->RightMotionController->PostTeleportMoveGrippedObjects(); + } + //BaseVRCharacterOwner->NotifyOfTeleport(false); + } +} + +void UVRBaseCharacterMovementComponent::SimulatedTick(float DeltaSeconds) +{ + //return Super::SimulatedTick(DeltaSeconds); + + QUICK_SCOPE_CYCLE_COUNTER(STAT_Character_CharacterMovementSimulated); + checkSlow(CharacterOwner != nullptr); + + // If we are playing a RootMotion AnimMontage. + if (CharacterOwner->IsPlayingNetworkedRootMotionMontage()) + { + bWasSimulatingRootMotion = true; + UE_LOG(LogRootMotion, Verbose, TEXT("UCharacterMovementComponent::SimulatedTick")); + + // Tick animations before physics. + if (CharacterOwner && CharacterOwner->GetMesh()) + { + TickCharacterPose(DeltaSeconds); + + // Make sure animation didn't trigger an event that destroyed us + if (!HasValidData()) + { + return; + } + } + + const FQuat OldRotationQuat = UpdatedComponent->GetComponentQuat(); + const FVector OldLocation = UpdatedComponent->GetComponentLocation(); + + USkeletalMeshComponent* Mesh = CharacterOwner->GetMesh(); + const FVector SavedMeshRelativeLocation = Mesh ? Mesh->GetRelativeLocation() : FVector::ZeroVector; + + + if (RootMotionParams.bHasRootMotion) + { + SimulateRootMotion(DeltaSeconds, RootMotionParams.GetRootMotionTransform()); + +#if !(UE_BUILD_SHIPPING) + // debug + /*if (CharacterOwner && false) + { + const FRotator OldRotation = OldRotationQuat.Rotator(); + const FRotator NewRotation = UpdatedComponent->GetComponentRotation(); + const FVector NewLocation = UpdatedComponent->GetComponentLocation(); + DrawDebugCoordinateSystem(GetWorld(), CharacterOwner->GetMesh()->GetComponentLocation() + FVector(0, 0, 1), NewRotation, 50.f, false); + DrawDebugLine(GetWorld(), OldLocation, NewLocation, FColor::Red, false, 10.f); + + UE_LOG(LogRootMotion, Log, TEXT("UCharacterMovementComponent::SimulatedTick DeltaMovement Translation: %s, Rotation: %s, MovementBase: %s"), + *(NewLocation - OldLocation).ToCompactString(), *(NewRotation - OldRotation).GetNormalized().ToCompactString(), *GetNameSafe(CharacterOwner->GetMovementBase())); + }*/ +#endif // !(UE_BUILD_SHIPPING) + } + + // then, once our position is up to date with our animation, + // handle position correction if we have any pending updates received from the server. + if (CharacterOwner && (CharacterOwner->RootMotionRepMoves.Num() > 0)) + { + CharacterOwner->SimulatedRootMotionPositionFixup(DeltaSeconds); + } + + if (!bNetworkSmoothingComplete && (NetworkSmoothingMode == ENetworkSmoothingMode::Linear)) + { + // Same mesh with different rotation? + const FQuat NewCapsuleRotation = UpdatedComponent->GetComponentQuat(); + if (Mesh == CharacterOwner->GetMesh() && !NewCapsuleRotation.Equals(OldRotationQuat, 1e-6f) && ClientPredictionData) + { + // Smoothing should lerp toward this new rotation target, otherwise it will just try to go back toward the old rotation. + ClientPredictionData->MeshRotationTarget = NewCapsuleRotation; + Mesh->SetRelativeLocationAndRotation(SavedMeshRelativeLocation, CharacterOwner->GetBaseRotationOffset()); + } + } + } + else if (CurrentRootMotion.HasActiveRootMotionSources()) + { + // We have root motion sources and possibly animated root motion + bWasSimulatingRootMotion = true; + UE_LOG(LogRootMotion, Verbose, TEXT("UCharacterMovementComponent::SimulatedTick")); + + // If we have RootMotionRepMoves, find the most recent important one and set position/rotation to it + bool bCorrectedToServer = false; + const FVector OldLocation = UpdatedComponent->GetComponentLocation(); + const FQuat OldRotation = UpdatedComponent->GetComponentQuat(); + if (CharacterOwner->RootMotionRepMoves.Num() > 0) + { + // Move Actor back to position of that buffered move. (server replicated position). + FSimulatedRootMotionReplicatedMove& RootMotionRepMove = CharacterOwner->RootMotionRepMoves.Last(); + if (CharacterOwner->RestoreReplicatedMove(RootMotionRepMove)) + { + bCorrectedToServer = true; + } + Acceleration = RootMotionRepMove.RootMotion.Acceleration; + + CharacterOwner->PostNetReceiveVelocity(RootMotionRepMove.RootMotion.LinearVelocity); + LastUpdateVelocity = RootMotionRepMove.RootMotion.LinearVelocity; + + // Convert RootMotionSource Server IDs -> Local IDs in AuthoritativeRootMotion and cull invalid + // so that when we use this root motion it has the correct IDs + ConvertRootMotionServerIDsToLocalIDs(CurrentRootMotion, RootMotionRepMove.RootMotion.AuthoritativeRootMotion, RootMotionRepMove.Time); + RootMotionRepMove.RootMotion.AuthoritativeRootMotion.CullInvalidSources(); + + // Set root motion states to that of repped in state + CurrentRootMotion.UpdateStateFrom(RootMotionRepMove.RootMotion.AuthoritativeRootMotion, true); + + // Clear out existing RootMotionRepMoves since we've consumed the most recent + UE_LOG(LogRootMotion, Log, TEXT("\tClearing old moves in SimulatedTick (%d)"), CharacterOwner->RootMotionRepMoves.Num()); + CharacterOwner->RootMotionRepMoves.Reset(); + } + + // Update replicated gravity direction + if (bNetworkGravityDirectionChanged) + { + SetGravityDirection(CharacterOwner->GetReplicatedGravityDirection()); + bNetworkGravityDirectionChanged = false; + } + + // Update replicated movement mode. + if (bNetworkMovementModeChanged) + { + ApplyNetworkMovementMode(CharacterOwner->GetReplicatedMovementMode()); + bNetworkMovementModeChanged = false; + } + + // Perform movement + PerformMovement(DeltaSeconds); + + // After movement correction, smooth out error in position if any. + if (bCorrectedToServer || CurrentRootMotion.NeedsSimulatedSmoothing()) + { + SmoothCorrection(OldLocation, OldRotation, UpdatedComponent->GetComponentLocation(), UpdatedComponent->GetComponentQuat()); + } + } + // Not playing RootMotion AnimMontage + else + { + // if we were simulating root motion, we've been ignoring regular ReplicatedMovement updates. + // If we're not simulating root motion anymore, force us to sync our movement properties. + // (Root Motion could leave Velocity out of sync w/ ReplicatedMovement) + if (bWasSimulatingRootMotion) + { + CharacterOwner->RootMotionRepMoves.Empty(); + CharacterOwner->OnRep_ReplicatedMovement(); + CharacterOwner->OnRep_ReplicatedBasedMovement(); + SetGravityDirection(GetCharacterOwner()->GetReplicatedGravityDirection()); + ApplyNetworkMovementMode(GetCharacterOwner()->GetReplicatedMovementMode()); + } + + if (CharacterOwner->IsReplicatingMovement() && UpdatedComponent) + { + //USkeletalMeshComponent* Mesh = CharacterOwner->GetMesh(); + //const FVector SavedMeshRelativeLocation = Mesh ? Mesh->GetRelativeLocation() : FVector::ZeroVector; + //const FQuat SavedCapsuleRotation = UpdatedComponent->GetComponentQuat(); + const bool bPreventMeshMovement = !bNetworkSmoothingComplete; + + // Avoid moving the mesh during movement if SmoothClientPosition will take care of it. + if(NetworkSmoothingMode != ENetworkSmoothingMode::Disabled) + { + const FScopedPreventAttachedComponentMove PreventMeshMove(bPreventMeshMovement ? BaseVRCharacterOwner->NetSmoother : nullptr); + //const FScopedPreventAttachedComponentMove PreventMeshMovement(bPreventMeshMovement ? Mesh : nullptr); + if (CharacterOwner->IsPlayingRootMotion()) + { + // Update replicated gravity direction + if (bNetworkGravityDirectionChanged) + { + SetGravityDirection(CharacterOwner->GetReplicatedGravityDirection()); + bNetworkGravityDirectionChanged = false; + } + + // Update replicated movement mode. + if (bNetworkMovementModeChanged) + { + ApplyNetworkMovementMode(CharacterOwner->GetReplicatedMovementMode()); + bNetworkMovementModeChanged = false; + } + + PerformMovement(DeltaSeconds); + } + else + { + // Moved this var into the VRChar to control smoothing + //if(!bDisableSimulatedTickWhenSmoothingMovement) + SimulateMovement(DeltaSeconds); + } + } + else + { + if (CharacterOwner->IsPlayingRootMotion()) + { + PerformMovement(DeltaSeconds); + } + else + { + SimulateMovement(DeltaSeconds); + } + } + + // With Linear smoothing we need to know if the rotation changes, since the mesh should follow along with that (if it was prevented above). + // This should be rare that rotation changes during simulation, but it can happen when ShouldRemainVertical() changes, or standing on a moving base. + /*const bool bValidateRotation = bPreventMeshMovement && (NetworkSmoothingMode == ENetworkSmoothingMode::Linear); + if (bValidateRotation && UpdatedComponent) + { + // Same mesh with different rotation? + const FQuat NewCapsuleRotation = UpdatedComponent->GetComponentQuat(); + if (Mesh == CharacterOwner->GetMesh() && !NewCapsuleRotation.Equals(SavedCapsuleRotation, 1e-6f) && ClientPredictionData) + { + // Smoothing should lerp toward this new rotation target, otherwise it will just try to go back toward the old rotation. + ClientPredictionData->MeshRotationTarget = NewCapsuleRotation; + Mesh->SetRelativeLocationAndRotation(SavedMeshRelativeLocation, CharacterOwner->GetBaseRotationOffset()); + } + }*/ + } + + if (bWasSimulatingRootMotion) + { + bWasSimulatingRootMotion = false; + } + } + + // Smooth mesh location after moving the capsule above. + if (!bNetworkSmoothingComplete) + { + QUICK_SCOPE_CYCLE_COUNTER(STAT_Character_CharacterMovementSmoothClientPosition); + SmoothClientPosition(DeltaSeconds); + } + else + { + UE_LOG(LogVRBaseCharacterMovement, Verbose, TEXT("Skipping network smoothing for %s."), *GetNameSafe(CharacterOwner)); + } +} + +void UVRBaseCharacterMovementComponent::MoveAutonomous( + float ClientTimeStamp, + float DeltaTime, + uint8 CompressedFlags, + const FVector& NewAccel +) +{ + if (!HasValidData()) + { + return; + } + + UpdateFromCompressedFlags(CompressedFlags); + CharacterOwner->CheckJumpInput(DeltaTime); + + Acceleration = ConstrainInputAcceleration(NewAccel); + Acceleration = Acceleration.GetClampedToMaxSize(GetMaxAcceleration()); + AnalogInputModifier = ComputeAnalogInputModifier(); + + FVector OldLocation = UpdatedComponent->GetComponentLocation(); + FQuat OldRotation = UpdatedComponent->GetComponentQuat(); + + if (BaseVRCharacterOwner && NetworkSmoothingMode == ENetworkSmoothingMode::Exponential) + { + OldLocation = BaseVRCharacterOwner->OffsetComponentToWorld.GetTranslation(); + OldRotation = BaseVRCharacterOwner->OffsetComponentToWorld.GetRotation(); + } + + const bool bWasPlayingRootMotion = CharacterOwner->IsPlayingRootMotion(); + + // Scope these, they nest with Outer references so it should work fine, this keeps the update rotation and move autonomous from double updating the char + //const FScopedPreventAttachedComponentMove PreventMeshMove(BaseVRCharacterOwner ? BaseVRCharacterOwner->NetSmoother : nullptr); + + PerformMovement(DeltaTime); + + // Check if data is valid as PerformMovement can mark character for pending kill + if (!HasValidData()) + { + return; + } + + // If not playing root motion, tick animations after physics. We do this here to keep events, notifies, states and transitions in sync with client updates. + if (CharacterOwner && !CharacterOwner->bClientUpdating && !CharacterOwner->IsPlayingRootMotion() && CharacterOwner->GetMesh()) + { + if (!bWasPlayingRootMotion) // If we were playing root motion before PerformMovement but aren't anymore, we're on the last frame of anim root motion and have already ticked character + { + TickCharacterPose(DeltaTime); + } + // TODO: SaveBaseLocation() in case tick moves us? + + + USkeletalMeshComponent* OwnerMesh = CharacterOwner->GetMesh(); + check(OwnerMesh != nullptr) + + static const auto CVarEnableQueuedAnimEventsOnServer = IConsoleManager::Get().FindConsoleVariable(TEXT("a.EnableQueuedAnimEventsOnServer")); + if (CVarEnableQueuedAnimEventsOnServer->GetInt()) + { + if (const UAnimInstance* AnimInstance = OwnerMesh->GetAnimInstance()) + { + if (OwnerMesh->VisibilityBasedAnimTickOption <= EVisibilityBasedAnimTickOption::AlwaysTickPose && AnimInstance->NeedsUpdate()) + { + // If we are doing a full graph update on the server but its doing a parallel update, + // trigger events right away since these are notifies queued from the montage update and we could be receiving multiple ServerMoves per frame. + OwnerMesh->ConditionallyDispatchQueuedAnimEvents(); + OwnerMesh->AllowQueuedAnimEventsNextDispatch(); + } + } + } + else + { + // Revert back to old behavior if wanted/needed. + if (OwnerMesh->ShouldOnlyTickMontages(DeltaTime)) + { + OwnerMesh->ConditionallyDispatchQueuedAnimEvents(); + } + } + } + + if (CharacterOwner && UpdatedComponent) + { + // Smooth local view of remote clients on listen servers + static const auto CVarNetEnableListenServerSmoothing = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetEnableListenServerSmoothing")); + if (CVarNetEnableListenServerSmoothing->GetInt() && + CharacterOwner->GetRemoteRole() == ROLE_AutonomousProxy && + IsNetMode(NM_ListenServer)) + { + SmoothCorrection(OldLocation, OldRotation, UpdatedComponent->GetComponentLocation(), UpdatedComponent->GetComponentQuat()); + } + } +} + +void UVRBaseCharacterMovementComponent::SmoothCorrection(const FVector& OldLocation, const FQuat& OldRotation, const FVector& NewLocation, const FQuat& NewRotation) +{ + + //SCOPE_CYCLE_COUNTER(STAT_CharacterMovementSmoothCorrection); + if (!HasValidData()) + { + return; + } + + if (!BaseVRCharacterOwner) + Super::SmoothCorrection(OldLocation, OldRotation, NewLocation, NewRotation); + + // We shouldn't be running this on a server that is not a listen server. + checkSlow(GetNetMode() != NM_DedicatedServer); + + // Only client proxies or remote clients on a listen server should run this code. + const bool bIsSimulatedProxy = (CharacterOwner->GetLocalRole() == ROLE_SimulatedProxy); + const bool bIsRemoteAutoProxy = (CharacterOwner->GetRemoteRole() == ROLE_AutonomousProxy); + ensure(bIsSimulatedProxy || bIsRemoteAutoProxy); + + // Getting a correction means new data, so smoothing needs to run. + bNetworkSmoothingComplete = false; + + // Handle selected smoothing mode. + if (NetworkSmoothingMode == ENetworkSmoothingMode::Disabled || GetNetMode() == NM_Standalone) + { + UpdatedComponent->SetWorldLocationAndRotation(NewLocation, NewRotation, false, nullptr, ETeleportType::TeleportPhysics); + bNetworkSmoothingComplete = true; + } + else if (FNetworkPredictionData_Client_Character* ClientData = GetPredictionData_Client_Character()) + { + const UWorld* MyWorld = GetWorld(); + if (!ensure(MyWorld != nullptr)) + { + return; + } + + // Handle my custom VR Offset + FVector OldWorldLocation = OldLocation; + FQuat OldWorldRotation = OldRotation; + FVector NewWorldLocation = NewLocation; + FQuat NewWorldRotation = NewRotation; + + if (BaseVRCharacterOwner && NetworkSmoothingMode == ENetworkSmoothingMode::Exponential) + { + if (GetNetMode() < ENetMode::NM_Client) + { + NewWorldLocation = BaseVRCharacterOwner->OffsetComponentToWorld.GetTranslation(); + NewWorldRotation = BaseVRCharacterOwner->OffsetComponentToWorld.GetRotation(); + } + else + { + FTransform NewWorldTransform(NewRotation, NewLocation, UpdatedComponent->GetRelativeScale3D()); + FTransform CurrentRelative = BaseVRCharacterOwner->OffsetComponentToWorld.GetRelativeTransform(UpdatedComponent->GetComponentTransform()); + FTransform NewWorld = CurrentRelative * NewWorldTransform; + OldWorldLocation = BaseVRCharacterOwner->OffsetComponentToWorld.GetLocation(); + OldWorldRotation = BaseVRCharacterOwner->OffsetComponentToWorld.GetRotation(); + NewWorldLocation = NewWorld.GetLocation(); + NewWorldRotation = NewWorld.GetRotation(); + } + } + + // The mesh doesn't move, but the capsule does so we have a new offset. + FVector NewToOldVector = (OldWorldLocation - NewWorldLocation); + if (bIsNavWalkingOnServer && FMath::Abs(NewToOldVector.Z) < NavWalkingFloorDistTolerance) + { + // ignore smoothing on Z axis + // don't modify new location (local simulation result), since it's probably more accurate than server data + // and shouldn't matter as long as difference is relatively small + NewToOldVector.Z = 0; + } + + const float DistSq = NewToOldVector.SizeSquared(); + if (DistSq > FMath::Square(ClientData->MaxSmoothNetUpdateDist)) + { + ClientData->MeshTranslationOffset = (DistSq > FMath::Square(ClientData->NoSmoothNetUpdateDist)) + ? FVector::ZeroVector + : ClientData->MeshTranslationOffset + ClientData->MaxSmoothNetUpdateDist * NewToOldVector.GetSafeNormal(); + } + else + { + ClientData->MeshTranslationOffset = ClientData->MeshTranslationOffset + NewToOldVector; + } + + UE_LOG(LogVRBaseCharacterMovement, Verbose, TEXT("Proxy %s SmoothCorrection(%.2f)"), *GetNameSafe(CharacterOwner), FMath::Sqrt(DistSq)); + if (NetworkSmoothingMode == ENetworkSmoothingMode::Linear) + { + // #TODO: Get this working in the future? + // I am currently skipping smoothing on rotation operations + if ((!OldRotation.Equals(NewRotation, 1e-5f)))// || Velocity.IsNearlyZero())) + { + if (BaseVRCharacterOwner->NetSmoother) + { + BaseVRCharacterOwner->NetSmoother->SetRelativeLocation(BaseVRCharacterOwner->bRetainRoomscale ? FVector::ZeroVector : BaseVRCharacterOwner->VRRootReference->GetTargetHeightOffset()); + //BaseVRCharacterOwner->NetSmoother->SetRelativeLocation(FVector::ZeroVector); + } + UpdatedComponent->SetWorldLocationAndRotation(NewLocation, NewRotation, false, nullptr, GetTeleportType()); + ClientData->MeshTranslationOffset = FVector::ZeroVector; + ClientData->MeshRotationOffset = ClientData->MeshRotationTarget; + bNetworkSmoothingComplete = true; + } + else + { + ClientData->OriginalMeshTranslationOffset = ClientData->MeshTranslationOffset; + + // Remember the current and target rotation, we're going to lerp between them + ClientData->OriginalMeshRotationOffset = OldRotation; + ClientData->MeshRotationOffset = OldRotation; + ClientData->MeshRotationTarget = NewRotation; + + // Move the capsule, but not the mesh. + // Note: we don't change rotation, we lerp towards it in SmoothClientPosition. + if (NewLocation != OldLocation) + { + const FScopedPreventAttachedComponentMove PreventMeshMove(BaseVRCharacterOwner->NetSmoother); + UpdatedComponent->SetWorldLocation(NewLocation, false, nullptr, GetTeleportType()); + } + } + } + else + { + // #TODO: Get this working in the future? + // I am currently skipping smoothing on rotation operations + /*if ((!OldRotation.Equals(NewRotation, 1e-5f)))// || Velocity.IsNearlyZero())) + { + BaseVRCharacterOwner->NetSmoother->SetRelativeLocation(BaseVRCharacterOwner->bRetainRoomscale ? FVector::ZeroVector : BaseVRCharacterOwner->VRRootReference->GetTargetHeightOffset()); + UpdatedComponent->SetWorldLocationAndRotation(NewLocation, NewRotation, false, nullptr, GetTeleportType()); + ClientData->MeshTranslationOffset = FVector::ZeroVector; + ClientData->MeshRotationOffset = ClientData->MeshRotationTarget; + bNetworkSmoothingComplete = true; + } + else*/ + { + // Calc rotation needed to keep current world rotation after UpdatedComponent moves. + // Take difference between where we were rotated before, and where we're going + ClientData->MeshRotationOffset = FQuat::Identity;// (NewRotation.Inverse() * OldRotation) * ClientData->MeshRotationOffset; + ClientData->MeshRotationTarget = FQuat::Identity; + + const FScopedPreventAttachedComponentMove PreventMeshMove(BaseVRCharacterOwner->NetSmoother); + UpdatedComponent->SetWorldLocationAndRotation(NewLocation, NewRotation, false, nullptr, GetTeleportType()); + } + } + + ////////////////////////////////////////////////////////////////////////// + // Update smoothing timestamps + + // If running ahead, pull back slightly. This will cause the next delta to seem slightly longer, and cause us to lerp to it slightly slower. + if (ClientData->SmoothingClientTimeStamp > ClientData->SmoothingServerTimeStamp) + { + const double OldClientTimeStamp = ClientData->SmoothingClientTimeStamp; + ClientData->SmoothingClientTimeStamp = FMath::LerpStable(ClientData->SmoothingServerTimeStamp, OldClientTimeStamp, 0.5); + + UE_LOG(LogVRBaseCharacterMovement, VeryVerbose, TEXT("SmoothCorrection: Pull back client from ClientTimeStamp: %.6f to %.6f, ServerTimeStamp: %.6f for %s"), + OldClientTimeStamp, ClientData->SmoothingClientTimeStamp, ClientData->SmoothingServerTimeStamp, *GetNameSafe(CharacterOwner)); + } + + // Using server timestamp lets us know how much time actually elapsed, regardless of packet lag variance. + double OldServerTimeStamp = ClientData->SmoothingServerTimeStamp; + + if (bIsSimulatedProxy) + { + // This value is normally only updated on the server, however some code paths might try to read it instead of the replicated value so copy it for proxies as well. + ServerLastTransformUpdateTimeStamp = CharacterOwner->GetReplicatedServerLastTransformUpdateTimeStamp(); + } + ClientData->SmoothingServerTimeStamp = ServerLastTransformUpdateTimeStamp; + + // Initial update has no delta. + if (ClientData->LastCorrectionTime == 0) + { + ClientData->SmoothingClientTimeStamp = ClientData->SmoothingServerTimeStamp; + OldServerTimeStamp = ClientData->SmoothingServerTimeStamp; + } + + // Don't let the client fall too far behind or run ahead of new server time. + const double ServerDeltaTime = ClientData->SmoothingServerTimeStamp - OldServerTimeStamp; + const double MaxOffset = ClientData->MaxClientSmoothingDeltaTime; + const double MinOffset = FMath::Min(double(ClientData->SmoothNetUpdateTime), MaxOffset); + + // MaxDelta is the farthest behind we're allowed to be after receiving a new server time. + const double MaxDelta = FMath::Clamp(ServerDeltaTime * 1.25, MinOffset, MaxOffset); + ClientData->SmoothingClientTimeStamp = FMath::Clamp(ClientData->SmoothingClientTimeStamp, ClientData->SmoothingServerTimeStamp - MaxDelta, ClientData->SmoothingServerTimeStamp); + + // Compute actual delta between new server timestamp and client simulation. + ClientData->LastCorrectionDelta = ClientData->SmoothingServerTimeStamp - ClientData->SmoothingClientTimeStamp; + ClientData->LastCorrectionTime = MyWorld->GetTimeSeconds(); + + UE_LOG(LogVRBaseCharacterMovement, VeryVerbose, TEXT("SmoothCorrection: WorldTime: %.6f, ServerTimeStamp: %.6f, ClientTimeStamp: %.6f, Delta: %.6f for %s"), + MyWorld->GetTimeSeconds(), ClientData->SmoothingServerTimeStamp, ClientData->SmoothingClientTimeStamp, ClientData->LastCorrectionDelta, *GetNameSafe(CharacterOwner)); + /* + Visualize network smoothing was here, removed it + */ + } +} + +void UVRBaseCharacterMovementComponent::SmoothClientPosition(float DeltaSeconds) +{ + if (!HasValidData() || NetworkSmoothingMode == ENetworkSmoothingMode::Disabled) + { + return; + } + + // We shouldn't be running this on a server that is not a listen server. + checkSlow(GetNetMode() != NM_DedicatedServer); + checkSlow(GetNetMode() != NM_Standalone); + + // Only client proxies or remote clients on a listen server should run this code. + const bool bIsSimulatedProxy = (CharacterOwner->GetLocalRole() == ROLE_SimulatedProxy); + const bool bIsRemoteAutoProxy = (CharacterOwner->GetRemoteRole() == ROLE_AutonomousProxy); + if (!ensure(bIsSimulatedProxy || bIsRemoteAutoProxy)) + { + return; + } + + SmoothClientPosition_Interpolate(DeltaSeconds); + + //SmoothClientPosition_UpdateVisuals(); No mesh, don't bother to run this + SmoothClientPosition_UpdateVRVisuals(); +} + +void UVRBaseCharacterMovementComponent::SmoothClientPosition_UpdateVRVisuals() +{ + //SCOPE_CYCLE_COUNTER(STAT_CharacterMovementSmoothClientPosition_Visual); + FNetworkPredictionData_Client_Character* ClientData = GetPredictionData_Client_Character(); + + if (!BaseVRCharacterOwner || !ClientData) + return; + + if (ClientData) + { + if (NetworkSmoothingMode == ENetworkSmoothingMode::Linear && BaseVRCharacterOwner->NetSmoother) + { + // Erased most of the code here, check back in later + const USceneComponent* MeshParent = BaseVRCharacterOwner->NetSmoother->GetAttachParent(); + FVector MeshParentScale = MeshParent != nullptr ? MeshParent->GetComponentScale() : FVector(1.0f, 1.0f, 1.0f); + + MeshParentScale.X = FMath::IsNearlyZero(MeshParentScale.X) ? 1.0f : MeshParentScale.X; + MeshParentScale.Y = FMath::IsNearlyZero(MeshParentScale.Y) ? 1.0f : MeshParentScale.Y; + MeshParentScale.Z = FMath::IsNearlyZero(MeshParentScale.Z) ? 1.0f : MeshParentScale.Z; + + const FVector NewRelLocation = ClientData->MeshRotationOffset.UnrotateVector(ClientData->MeshTranslationOffset);// + CharacterOwner->GetBaseTranslationOffset(); + + FVector HeightOffset = (BaseVRCharacterOwner->bRetainRoomscale ? FVector::ZeroVector : BaseVRCharacterOwner->VRRootReference->GetTargetHeightOffset()); + BaseVRCharacterOwner->NetSmoother->SetRelativeLocation(NewRelLocation + HeightOffset); + } + else if (NetworkSmoothingMode == ENetworkSmoothingMode::Exponential && BaseVRCharacterOwner->NetSmoother) + { + const USceneComponent* MeshParent = BaseVRCharacterOwner->NetSmoother->GetAttachParent(); + FVector MeshParentScale = MeshParent != nullptr ? MeshParent->GetComponentScale() : FVector(1.0f, 1.0f, 1.0f); + + MeshParentScale.X = FMath::IsNearlyZero(MeshParentScale.X) ? 1.0f : MeshParentScale.X; + MeshParentScale.Y = FMath::IsNearlyZero(MeshParentScale.Y) ? 1.0f : MeshParentScale.Y; + MeshParentScale.Z = FMath::IsNearlyZero(MeshParentScale.Z) ? 1.0f : MeshParentScale.Z; + + // Adjust mesh location and rotation + const FVector NewRelTranslation = (UpdatedComponent->GetComponentToWorld().InverseTransformVectorNoScale(ClientData->MeshTranslationOffset) / MeshParentScale);// +CharacterOwner->GetBaseTranslationOffset(); + const FQuat NewRelRotation = ClientData->MeshRotationOffset;// *CharacterOwner->GetBaseRotationOffset(); + //Basechar->NetSmoother->SetRelativeLocation(NewRelTranslation); + + FVector HeightOffset = BaseVRCharacterOwner->bRetainRoomscale ? FVector::ZeroVector : BaseVRCharacterOwner->VRRootReference->GetTargetHeightOffset(); + BaseVRCharacterOwner->NetSmoother->SetRelativeLocationAndRotation(NewRelTranslation + HeightOffset, NewRelRotation); + } + else + { + // Unhandled mode + } + } +} + +void UVRBaseCharacterMovementComponent::SetHasRequestedVelocity(bool bNewHasRequestedVelocity) +{ + bHasRequestedVelocity = bNewHasRequestedVelocity; +} + +bool UVRBaseCharacterMovementComponent::IsClimbing() const +{ + return ((MovementMode == MOVE_Custom) && (CustomMovementMode == (uint8)EVRCustomMovementMode::VRMOVE_Climbing)) && UpdatedComponent; +} + +FVector UVRBaseCharacterMovementComponent::RewindVRMovement() +{ + RewindVRRelativeMovement(); + return AdditionalVRInputVector; +} + +FVector UVRBaseCharacterMovementComponent::GetCustomInputVector() +{ + return CustomVRInputVector; +} + +void UVRBaseCharacterMovementComponent::UpdateFromCompressedFlags(uint8 Flags) +{ + // If is a custom or VR custom movement mode + //int32 MovementFlags = (Flags >> 2) & 15; + //VRReplicatedMovementMode = (EVRConjoinedMovementModes)MovementFlags; + + //bWantsToSnapTurn = ((Flags & FSavedMove_VRBaseCharacter::FLAG_SnapTurn) != 0); + + Super::UpdateFromCompressedFlags(Flags); +} + +FVector UVRBaseCharacterMovementComponent::RoundDirectMovement(FVector InMovement) const +{ + // Match FVector_NetQuantize100 (2 decimal place of precision). + UE::Net::QuantizeVector(100, InMovement); + //InMovement.X = FMath::RoundToFloat(InMovement.X * 100.f) / 100.f; + //InMovement.Y = FMath::RoundToFloat(InMovement.Y * 100.f) / 100.f; + //InMovement.Z = FMath::RoundToFloat(InMovement.Z * 100.f) / 100.f; + return InMovement; +} + +void UVRBaseCharacterMovementComponent::SetAutoOrientToFloorNormal(bool bAutoOrient, bool bRevertGravityWhenDisabled) +{ + bAutoOrientToFloorNormal = bAutoOrient; + + if (!bAutoOrientToFloorNormal && bRevertGravityWhenDisabled) + { + //DefaultGravityDirection, could also get world gravity + SetCharacterToNewGravity(FVector(0.0f, 0.0f, -1.0f), true); + } +} + +void UVRBaseCharacterMovementComponent::AutoTraceAndSetCharacterToNewGravity(FHitResult & TargetFloor, float DeltaTime) +{ + if (TargetFloor.Component.IsValid()) + { + // Should we really be tracing complex? (true should maybe be false?) + FCollisionQueryParams QueryParams(SCENE_QUERY_STAT(AutoTraceFloorNormal), /*true*/false, CharacterOwner); + FCollisionResponseParams ResponseParam; + InitCollisionParams(QueryParams, ResponseParam); + const ECollisionChannel CollisionChannel = UpdatedComponent->GetCollisionObjectType(); + + FVector TraceStart = BaseVRCharacterOwner->GetVRLocation_Inline(); + FVector Offset = (-UpdatedComponent->GetComponentQuat().GetUpVector()) * (BaseVRCharacterOwner->VRRootReference->GetScaledCapsuleHalfHeight() + 10.0f); + + FHitResult OutHit; + //const bool bDidHit = TargetFloor.Component->LineTraceComponent(OutHit, TraceStart, TraceStart + Offset, QueryParams); + bool bDidHit = GetWorld()->LineTraceSingleByChannel(OutHit, TraceStart, TraceStart + Offset, CollisionChannel, QueryParams, ResponseParam); + + if (!bDidHit) + { + GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Yellow, TEXT("Didn't hit!")); + } + else + { + if (!IsWalkable(OutHit)) + { + bDidHit = false; + } + } + + //DrawDebugLine(GetWorld(), TraceStart, TraceStart + Offset, FColor::Red, true); + //DrawDebugCapsule(GetWorld(), BaseVRCharacterOwner->GetVRLocation(), BaseVRCharacterOwner->VRRootReference->GetScaledCapsuleHalfHeight(), 5.0f, BaseVRCharacterOwner->VRRootReference->GetComponentQuat(), FColor::Green, true); + if (bDidHit) + { + FVector NewGravityDir = -OutHit.Normal; + + // Don't run gravity changes within our walkable slope + float AngleOfChange = FMath::Abs(FMath::RadiansToDegrees(acosf(FVector::DotProduct(-OutHit.Normal, GetGravityDirection())))); + if (AngleOfChange > GetWalkableFloorAngle() || AngleOfChange < 0.01f) + { + return; + } + else + { + if (bBlendGravityFloorChanges) + { + // Blend the angle over time + //const float Alpha = FMath::Clamp(DeltaTime * FloorOrientationChangeBlendRate, 0.f, 1.f); + //NewGravityDir = FMath::Lerp(GetGravityDirection(), NewGravityDir, Alpha); + //bIsBlendingOrientation = true; + } + } + + SetCharacterToNewGravity(NewGravityDir, true, DeltaTime); + } + } +} + +bool UVRBaseCharacterMovementComponent::SetCharacterToNewGravity(FVector NewGravityDirection, bool bOrientToNewGravity, float DeltaTime) +{ + // Ensure its normalized + NewGravityDirection.Normalize(); + + if (NewGravityDirection.Equals(GetGravityDirection())) + return false; + + //SetGravityDirection(NewGravityDirection); + + if (bOrientToNewGravity && IsValid(BaseVRCharacterOwner)) + { + FQuat CurrentRotQ = UpdatedComponent->GetComponentQuat(); + FQuat DeltaRot = FQuat::FindBetweenNormals(-CurrentRotQ.GetUpVector(), NewGravityDirection); + + if (bBlendGravityFloorChanges) + { + // Blend the angle over time + const float Alpha = FMath::Clamp(DeltaTime * FloorOrientationChangeBlendRate, 0.f, 1.f); + DeltaRot = FQuat::Slerp(FQuat::Identity, DeltaRot, Alpha); + + //NewGravityDir = FMath::Lerp(GetGravityDirection(), NewGravityDir, Alpha); + bIsBlendingOrientation = true; + } + + FQuat NewRot = (DeltaRot * CurrentRotQ); + NewRot.Normalize(); + + NewGravityDirection = -NewRot.GetUpVector(); + + AController* OwningController = BaseVRCharacterOwner->GetController(); + + float PivotZ = BaseVRCharacterOwner->bRetainRoomscale ? 0.0f : -BaseVRCharacterOwner->VRRootReference->GetUnscaledCapsuleHalfHeight(); + FQuat NewRotation = NewRot; + + // Clamp to 2 decimal precision + /*NewRotation = NewRotation.Clamp(); + //NewRotation.Pitch = (NewRotation.Pitch * 100.f) / 100.f; + //NewRotation.Yaw = (NewRotation.Yaw * 100.f) / 100.f; + //NewRotation.Roll = (NewRotation.Roll * 100.f) / 100.f;*/ + //NewRotation.Normalize(); + + FTransform BaseTransform = BaseVRCharacterOwner->VRRootReference->GetComponentTransform(); + FVector PivotPoint = BaseTransform.TransformPosition(FVector(0.0f, 0.0f, PivotZ)); + + //DrawDebugSphere(GetWorld(), BaseVRCharacterOwner->GetVRLocation(), 10.0f, 12.0f, FColor::White, true); + //DrawDebugSphere(GetWorld(), PivotPoint, 10.0f, 12.0f, FColor::Orange, true); + + FVector BasePoint = PivotPoint; // Get our pivot point + const FTransform PivotToWorld = FTransform(FQuat::Identity, BasePoint); + const FTransform WorldToPivot = FTransform(FQuat::Identity, -BasePoint); + + // Rebase the world transform to the pivot point, add the rotation, remove the pivot point rebase + FTransform NewTransform = BaseTransform * WorldToPivot * FTransform(DeltaRot, FVector::ZeroVector, FVector(1.0f)) * PivotToWorld; + + //FVector NewLoc = BaseVRCharacterOwner->VRRootReference->OffsetComponentToWorld.InverseTransformPosition(PivotPoint); + //GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("NewLoc %s"), *NewLoc.ToString())); + + //DrawDebugLine(GetWorld(), OrigLocation, OrigLocation + ((-NewGravityDirection) * 40.0f), FColor::Red, true); + + // Also setting actor rot because the control rot transfers to it anyway eventually + MoveUpdatedComponent(NewTransform.GetLocation()/*NewLocation*/ - BaseTransform.GetLocation(), NewRotation, /*bSweep*/ false); + + if (BaseVRCharacterOwner->bUseControllerRotationYaw && OwningController) + OwningController->SetControlRotation(NewRotation.Rotator()); + + SetGravityDirection(NewGravityDirection); + return true; + } + else + { + SetGravityDirection(NewGravityDirection); + return true; + } + + //return false; +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRCharacter.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRCharacter.cpp new file mode 100644 index 0000000..a81130a --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRCharacter.cpp @@ -0,0 +1,288 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "VRCharacter.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRCharacter) + +#include "NavigationSystem.h" +#include "VRBPDatatypes.h" +//#include "GripMotionControllerComponent.h" +//#include "VRExpansionFunctionLibrary.h" +//#include "ReplicatedVRCameraComponent.h" +//#include "ParentRelativeAttachmentComponent.h" +#include "VRRootComponent.h" +#include "VRCharacterMovementComponent.h" +#include "GameFramework/Controller.h" +#include "Runtime/Launch/Resources/Version.h" +#include "VRPathFollowingComponent.h" +#include "NavFilters/NavigationQueryFilter.h" +//#include "Runtime/Engine/Private/EnginePrivate.h" + +DEFINE_LOG_CATEGORY(LogVRCharacter); + +AVRCharacter::AVRCharacter(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer.SetDefaultSubobjectClass(ACharacter::CapsuleComponentName).SetDefaultSubobjectClass(ACharacter::CharacterMovementComponentName)) +{ + VRRootReference = NULL; + if (GetCapsuleComponent()) + { + VRRootReference = Cast(GetCapsuleComponent()); + VRRootReference->SetCapsuleSize(20.0f, 96.0f); + //VRRootReference->VRCapsuleOffset = FVector(-8.0f, 0.0f, 0.0f); + VRRootReference->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore); + VRRootReference->SetCollisionResponseToChannel(ECollisionChannel::ECC_WorldStatic, ECollisionResponse::ECR_Block); + } + + VRMovementReference = NULL; + if (GetMovementComponent()) + { + VRMovementReference = Cast(GetMovementComponent()); + //AddTickPrerequisiteComponent(this->GetCharacterMovement()); + } +} + + +FVector AVRCharacter::GetTeleportLocation(FVector OriginalLocation) +{ + if (!bRetainRoomscale) + { + return OriginalLocation + FVector(0.f, 0.f, VRRootReference->GetScaledCapsuleHalfHeight()); + } + else + { + FVector modifier = VRRootReference->OffsetComponentToWorld.GetLocation() - this->GetActorLocation(); + modifier.Z = 0.0f; // Null out Z + return OriginalLocation - modifier; + } +} + +bool AVRCharacter::TeleportTo(const FVector& DestLocation, const FRotator& DestRotation, bool bIsATest, bool bNoCheck) +{ + bool bTeleportSucceeded = Super::TeleportTo(DestLocation, DestRotation, bIsATest, bNoCheck); + + if (bTeleportSucceeded) + { + NotifyOfTeleport(); + } + + return bTeleportSucceeded; +} + +FVector AVRCharacter::GetNavAgentLocation() const +{ + FVector AgentLocation = FNavigationSystem::InvalidLocation; + + if (GetCharacterMovement() != nullptr) + { + if (VRMovementReference) + { + AgentLocation = VRMovementReference->GetActorFeetLocationVR(); + } + else + AgentLocation = GetCharacterMovement()->GetActorFeetLocation(); + } + + if (FNavigationSystem::IsValidLocation(AgentLocation) == false /*&& GetCapsuleComponent() != nullptr*/) + { + if (VRRootReference) + { + AgentLocation = VRRootReference->OffsetComponentToWorld.GetLocation() - FVector(0, 0, VRRootReference->GetScaledCapsuleHalfHeight()); + } + else if(GetCapsuleComponent() != nullptr) + AgentLocation = GetActorLocation() - FVector(0, 0, GetCapsuleComponent()->GetScaledCapsuleHalfHeight()); + } + + return AgentLocation; +} + +void AVRCharacter::ExtendedSimpleMoveToLocation(const FVector& GoalLocation, float AcceptanceRadius, bool bStopOnOverlap, bool bUsePathfinding, bool bProjectDestinationToNavigation, bool bCanStrafe, TSubclassOf FilterClass, bool bAllowPartialPaths) +{ + UNavigationSystemV1* NavSys = Controller ? FNavigationSystem::GetCurrent(Controller->GetWorld()) : nullptr; + if (NavSys == nullptr || Controller == nullptr ) + { + UE_LOG(LogVRCharacter, Warning, TEXT("UVRCharacter::ExtendedSimpleMoveToLocation called for NavSys:%s Controller:%s (if any of these is None then there's your problem"), + *GetNameSafe(NavSys), *GetNameSafe(Controller)); + return; + } + + UPathFollowingComponent* PFollowComp = nullptr; + //Controller->InitNavigationControl(PFollowComp); + + if (Controller) + { + // New for 4.20, spawning the missing path following component here if there isn't already one + PFollowComp = Controller->FindComponentByClass(); + if (PFollowComp == nullptr) + { + PFollowComp = NewObject(Controller); + PFollowComp->RegisterComponentWithWorld(Controller->GetWorld()); + PFollowComp->Initialize(); + } + } + + if (PFollowComp == nullptr) + { + UE_LOG(LogVRCharacter, Warning, TEXT("ExtendedSimpleMoveToLocation - No PathFollowingComponent Found")); + return; + } + + if (!PFollowComp->IsPathFollowingAllowed()) + { + UE_LOG(LogVRCharacter, Warning, TEXT("ExtendedSimpleMoveToLocation - Path Following Movement Is Not Set To Allowed")); + return; + } + + EPathFollowingReachMode ReachMode; + if (bStopOnOverlap) + ReachMode = EPathFollowingReachMode::OverlapAgent; + else + ReachMode = EPathFollowingReachMode::ExactLocation; + + bool bAlreadyAtGoal = false; + + if(UVRPathFollowingComponent * pathcomp = Cast(PFollowComp)) + bAlreadyAtGoal = pathcomp->HasReached(GoalLocation, /*EPathFollowingReachMode::OverlapAgent*/ReachMode); + else + bAlreadyAtGoal = PFollowComp->HasReached(GoalLocation, /*EPathFollowingReachMode::OverlapAgent*/ReachMode); + + // script source, keep only one move request at time + if (PFollowComp->GetStatus() != EPathFollowingStatus::Idle) + { + if (GetNetMode() == ENetMode::NM_Client) + { + // Stop the movement here, not keeping the velocity because it bugs out for clients, might be able to fix. + PFollowComp->AbortMove(*NavSys, FPathFollowingResultFlags::ForcedScript | FPathFollowingResultFlags::NewRequest + , FAIRequestID::AnyRequest, /*bAlreadyAtGoal ? */EPathFollowingVelocityMode::Reset /*: EPathFollowingVelocityMode::Keep*/); + } + else + { + PFollowComp->AbortMove(*NavSys, FPathFollowingResultFlags::ForcedScript | FPathFollowingResultFlags::NewRequest + , FAIRequestID::AnyRequest, bAlreadyAtGoal ? EPathFollowingVelocityMode::Reset : EPathFollowingVelocityMode::Keep); + } + } + + if (bAlreadyAtGoal) + { + PFollowComp->RequestMoveWithImmediateFinish(EPathFollowingResult::Success); + } + else + { + const ANavigationData* NavData = NavSys->GetNavDataForProps(Controller->GetNavAgentPropertiesRef()); + if (NavData) + { + FPathFindingQuery Query(Controller, *NavData, Controller->GetNavAgentLocation(), GoalLocation); + FPathFindingResult Result = NavSys->FindPathSync(Query); + if (Result.IsSuccessful()) + { + FAIMoveRequest MoveReq(GoalLocation); + MoveReq.SetUsePathfinding(bUsePathfinding); + MoveReq.SetAllowPartialPath(bAllowPartialPaths); + MoveReq.SetProjectGoalLocation(bProjectDestinationToNavigation); + MoveReq.SetNavigationFilter(*FilterClass ? FilterClass : DefaultNavigationFilterClass); + MoveReq.SetAcceptanceRadius(AcceptanceRadius); + MoveReq.SetReachTestIncludesAgentRadius(bStopOnOverlap); + MoveReq.SetCanStrafe(bCanStrafe); + MoveReq.SetReachTestIncludesGoalRadius(true); + + PFollowComp->RequestMove(/*FAIMoveRequest(GoalLocation)*/MoveReq, Result.Path); + } + else if (PFollowComp->GetStatus() != EPathFollowingStatus::Idle) + { + PFollowComp->RequestMoveWithImmediateFinish(EPathFollowingResult::Invalid); + } + } + } +} + +FVector AVRCharacter::GetTargetHeightOffset() +{ + return bRetainRoomscale ? FVector::ZeroVector : VRRootReference->GetTargetHeightOffset(); +} + +void AVRCharacter::OnStartCrouch(float HeightAdjust, float ScaledHeightAdjust) +{ + RecalculateBaseEyeHeight(); + + /*const ACharacter* DefaultChar = GetDefault(GetClass()); + if (Mesh && DefaultChar->Mesh) + { + FVector& MeshRelativeLocation = Mesh->GetRelativeLocation_DirectMutable(); + MeshRelativeLocation.Z = DefaultChar->Mesh->GetRelativeLocation().Z + HeightAdjust; + BaseTranslationOffset.Z = MeshRelativeLocation.Z; + } + else + { + BaseTranslationOffset.Z = DefaultChar->BaseTranslationOffset.Z + HeightAdjust; + }*/ + + K2_OnStartCrouch(HeightAdjust, ScaledHeightAdjust); +} + +void AVRCharacter::OnEndCrouch(float HeightAdjust, float ScaledHeightAdjust) +{ + RecalculateBaseEyeHeight(); + + /*const ACharacter* DefaultChar = GetDefault(GetClass()); + if (Mesh && DefaultChar->Mesh) + { + FVector& MeshRelativeLocation = Mesh->GetRelativeLocation_DirectMutable(); + MeshRelativeLocation.Z = DefaultChar->Mesh->GetRelativeLocation().Z; + BaseTranslationOffset.Z = MeshRelativeLocation.Z; + } + else + { + BaseTranslationOffset.Z = DefaultChar->BaseTranslationOffset.Z; + }*/ + + K2_OnEndCrouch(HeightAdjust, ScaledHeightAdjust); +} + + +void AVRCharacter::RegenerateOffsetComponentToWorld(bool bUpdateBounds, bool bCalculatePureYaw) +{ + if (VRRootReference) + { + VRRootReference->GenerateOffsetToWorld(bUpdateBounds, bCalculatePureYaw); + } +} + +void AVRCharacter::SetCharacterSizeVR(float NewRadius, float NewHalfHeight, bool bUpdateOverlaps) +{ + if (VRRootReference) + { + VRRootReference->SetCapsuleSizeVR(NewRadius, NewHalfHeight, bUpdateOverlaps); + + if (GetNetMode() < ENetMode::NM_Client) + ReplicatedCapsuleHeight.CapsuleHeight = VRRootReference->GetUnscaledCapsuleHalfHeight(); + } + else + { + Super::SetCharacterSizeVR(NewRadius, NewHalfHeight, bUpdateOverlaps); + } +} + +void AVRCharacter::SetCharacterHalfHeightVR(float HalfHeight, bool bUpdateOverlaps) +{ + if (VRRootReference) + { + VRRootReference->SetCapsuleHalfHeightVR(HalfHeight, bUpdateOverlaps); + + if (GetNetMode() < ENetMode::NM_Client) + ReplicatedCapsuleHeight.CapsuleHeight = VRRootReference->GetUnscaledCapsuleHalfHeight(); + } + else + { + Super::SetCharacterHalfHeightVR(HalfHeight, bUpdateOverlaps); + } +} + +FVector AVRCharacter::GetProjectedVRLocation() const +{ + if (VRRootReference) + { + return OffsetComponentToWorld.TransformPosition(-FVector(VRRootReference->VRCapsuleOffset.X, VRRootReference->VRCapsuleOffset.Y, 0.0f)); + } + else + { + return AVRBaseCharacter::GetProjectedVRLocation(); + } +} diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRCharacterMovementComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRCharacterMovementComponent.cpp new file mode 100644 index 0000000..504ad79 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRCharacterMovementComponent.cpp @@ -0,0 +1,4870 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +/*============================================================================= + Movement.cpp: Character movement implementation + +=============================================================================*/ + +#include "VRCharacterMovementComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRCharacterMovementComponent) + +#include "GameFramework/PhysicsVolume.h" +#include "GameFramework/GameNetworkManager.h" +#include "GameFramework/Character.h" +#include "GameFramework/GameState.h" +#include "GameFramework/WorldSettings.h" +#include "Components/PrimitiveComponent.h" +#include "Animation/AnimMontage.h" +#include "DrawDebugHelpers.h" +//#include "PhysicsEngine/DestructibleActor.h" +#include "VRCharacter.h" +#include "VRExpansionFunctionLibrary.h" + +// @todo this is here only due to circular dependency to AIModule. To be removed +#include "Navigation/PathFollowingComponent.h" +#include "AI/Navigation/AvoidanceManager.h" +#include "Components/CapsuleComponent.h" +#include "Components/BrushComponent.h" +//#include "Components/DestructibleComponent.h" + +#include "Engine/DemoNetDriver.h" +#include "Engine/NetworkObjectList.h" +#include "UObject/Package.h" + +#include "VRRootComponent.h" +#include "WorldCollision.h" +#include "Runtime/Launch/Resources/Version.h" +#include "GameFramework/CharacterMovementReplication.h" +#include "Interfaces/NetworkPredictionInterface.h" + +//#include "PerfCountersHelpers.h" + +DEFINE_LOG_CATEGORY(LogVRCharacterMovement); + +/** + * Character stats + */ +DECLARE_CYCLE_STAT(TEXT("Char StepUp"), STAT_CharStepUp, STATGROUP_Character); +DECLARE_CYCLE_STAT(TEXT("Char FindFloor"), STAT_CharFindFloor, STATGROUP_Character); +DECLARE_CYCLE_STAT(TEXT("Char ReplicateMoveToServer"), STAT_CharacterMovementReplicateMoveToServer, STATGROUP_Character); +DECLARE_CYCLE_STAT(TEXT("Char CallServerMove"), STAT_CharacterMovementCallServerMove, STATGROUP_Character); +DECLARE_CYCLE_STAT(TEXT("Char CombineNetMove"), STAT_CharacterMovementCombineNetMove, STATGROUP_Character); +DECLARE_CYCLE_STAT(TEXT("Char PhysWalking"), STAT_CharPhysWalking, STATGROUP_Character); +DECLARE_CYCLE_STAT(TEXT("Char PhysFalling"), STAT_CharPhysFalling, STATGROUP_Character); +DECLARE_CYCLE_STAT(TEXT("Char PhysNavWalking"), STAT_CharPhysNavWalking, STATGROUP_Character); +DECLARE_CYCLE_STAT(TEXT("Char NavProjectPoint"), STAT_CharNavProjectPoint, STATGROUP_Character); +DECLARE_CYCLE_STAT(TEXT("Char NavProjectLocation"), STAT_CharNavProjectLocation, STATGROUP_Character); +DECLARE_CYCLE_STAT(TEXT("Char AdjustFloorHeight"), STAT_CharAdjustFloorHeight, STATGROUP_Character); +DECLARE_CYCLE_STAT(TEXT("Char ProcessLanded"), STAT_CharProcessLanded, STATGROUP_Character); + +namespace CharacterMovementConstants +{ + // MAGIC NUMBERS + const float MAX_STEP_SIDE_ZVR = 0.08f; // maximum z value for the normal on the vertical side of steps + const float SWIMBOBSPEEDVR = -80.f; + const float VERTICAL_SLOPE_NORMAL_ZVR = 0.001f; // Slope is vertical if Abs(Normal.Z) <= this threshold. Accounts for precision problems that sometimes angle normals slightly off horizontal for vertical surface. +} + +// Defines for build configs +#if DO_CHECK && !UE_BUILD_SHIPPING // Disable even if checks in shipping are enabled. +#define devCodeVR( Code ) checkCode( Code ) +#else +#define devCodeVR(...) +#endif + +// Statics +namespace CharacterMovementComponentStatics +{ + static const FName CrouchTraceName = FName(TEXT("CrouchTrace")); + static const FName ImmersionDepthName = FName(TEXT("MovementComp_Character_ImmersionDepth")); + + static float fRotationCorrectionThreshold = 0.02f; + FAutoConsoleVariableRef CVarRotationCorrectionThreshold( + TEXT("vre.RotationCorrectionThreshold"), + fRotationCorrectionThreshold, + TEXT("Error threshold value before correcting a clients rotation.\n") + TEXT("Rotation is replicated at 2 decimal precision, so values less than 0.01 won't matter."), + ECVF_Default); + + static float fRotationChangingCorrectionThreshold = 0.3f; + FAutoConsoleVariableRef CVarRotationChangingCorrectionThreshold( + TEXT("vre.RotationChangingCorrectionThreshold"), + fRotationChangingCorrectionThreshold, + TEXT("Error threshold value before correcting a clients rotation when actively changing rotation.\n") + TEXT("Rotation is replicated at 2 decimal precision, so values less than 0.01 won't matter."), + ECVF_Default); +} + +void UVRCharacterMovementComponent::StoreSetTrackingPaused(bool bNewTrackingPaused) +{ + FVRMoveActionContainer MoveAction; + MoveAction.MoveAction = EVRMoveAction::VRMOVEACTION_PauseTracking; + MoveAction.MoveActionFlags = bNewTrackingPaused; + MoveAction.MoveActionLoc = VRRootCapsule->curCameraLoc; + MoveAction.MoveActionRot = VRRootCapsule->StoredCameraRotOffset; + MoveActionArray.MoveActions.Add(MoveAction); + CheckServerAuthedMoveAction(); +} + +void UVRCharacterMovementComponent::Crouch(bool bClientSimulation) +{ + if (!HasValidData()) + { + return; + } + + if (!bClientSimulation && !CanCrouchInCurrentState()) + { + return; + } + + // See if collision is already at desired size. + if (CharacterOwner->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight() == GetCrouchedHalfHeight()) + { + if (!bClientSimulation) + { + CharacterOwner->bIsCrouched = true; + } + CharacterOwner->OnStartCrouch(0.f, 0.f); + return; + } + + if (bClientSimulation && CharacterOwner->GetLocalRole() == ROLE_SimulatedProxy) + { + // restore collision size before crouching + ACharacter* DefaultCharacter = CharacterOwner->GetClass()->GetDefaultObject(); + if (VRRootCapsule) + VRRootCapsule->SetCapsuleSizeVR(DefaultCharacter->GetCapsuleComponent()->GetUnscaledCapsuleRadius(), DefaultCharacter->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight()); + else + CharacterOwner->GetCapsuleComponent()->SetCapsuleSize(DefaultCharacter->GetCapsuleComponent()->GetUnscaledCapsuleRadius(), DefaultCharacter->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight()); + + bShrinkProxyCapsule = true; + } + + // Change collision size to crouching dimensions + const float ComponentScale = CharacterOwner->GetCapsuleComponent()->GetShapeScale(); + const float OldUnscaledHalfHeight = CharacterOwner->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight(); + const float OldUnscaledRadius = CharacterOwner->GetCapsuleComponent()->GetUnscaledCapsuleRadius(); + // Height is not allowed to be smaller than radius. + const float ClampedCrouchedHalfHeight = FMath::Max3(0.f, OldUnscaledRadius, GetCrouchedHalfHeight()); + + if (VRRootCapsule) + VRRootCapsule->SetCapsuleSizeVR(OldUnscaledRadius, ClampedCrouchedHalfHeight); + else + CharacterOwner->GetCapsuleComponent()->SetCapsuleSize(OldUnscaledRadius, ClampedCrouchedHalfHeight); + + float HalfHeightAdjust = (OldUnscaledHalfHeight - ClampedCrouchedHalfHeight); + float ScaledHalfHeightAdjust = HalfHeightAdjust * ComponentScale; + + if (!bClientSimulation) + { + // Crouching to a larger height? (this is rare) + if (ClampedCrouchedHalfHeight > OldUnscaledHalfHeight) + { + FCollisionQueryParams CapsuleParams(CharacterMovementComponentStatics::CrouchTraceName, false, CharacterOwner); + FCollisionResponseParams ResponseParam; + InitCollisionParams(CapsuleParams, ResponseParam); + + FVector capLocation; + if (VRRootCapsule) + { + capLocation = VRRootCapsule->OffsetComponentToWorld.GetLocation(); + } + else + capLocation = UpdatedComponent->GetComponentLocation(); + + const bool bEncroached = GetWorld()->OverlapBlockingTestByChannel(capLocation - FVector(0.f, 0.f, ScaledHalfHeightAdjust), FQuat::Identity, + UpdatedComponent->GetCollisionObjectType(), GetPawnCapsuleCollisionShape(SHRINK_None), CapsuleParams, ResponseParam); + + // If encroached, cancel + if (bEncroached) + { + if (VRRootCapsule) + VRRootCapsule->SetCapsuleSizeVR(OldUnscaledRadius, OldUnscaledHalfHeight); + else + CharacterOwner->GetCapsuleComponent()->SetCapsuleSize(OldUnscaledRadius, OldUnscaledHalfHeight); + return; + } + } + + // Skipping this move down as the VR character's base root doesn't behave the same + // Retain roomscale off also covers it in the capsule size rescale + if (bCrouchMaintainsBaseLocation) + { + // Intentionally not using MoveUpdatedComponent, where a horizontal plane constraint would prevent the base of the capsule from staying at the same spot. + //UpdatedComponent->MoveComponent(FVector(0.f, 0.f, -ScaledHalfHeightAdjust), UpdatedComponent->GetComponentQuat(), true, nullptr, EMoveComponentFlags::MOVECOMP_NoFlags, ETeleportType::TeleportPhysics); + } + + CharacterOwner->bIsCrouched = true; + } + + bForceNextFloorCheck = true; + + // OnStartCrouch takes the change from the Default size, not the current one (though they are usually the same). + const float MeshAdjust = ScaledHalfHeightAdjust; + ACharacter* DefaultCharacter = CharacterOwner->GetClass()->GetDefaultObject(); + HalfHeightAdjust = (DefaultCharacter->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight() - ClampedCrouchedHalfHeight); + ScaledHalfHeightAdjust = HalfHeightAdjust * ComponentScale; + + AdjustProxyCapsuleSize(); + CharacterOwner->OnStartCrouch(HalfHeightAdjust, ScaledHalfHeightAdjust); + + // Don't smooth this change in mesh position + // Set CapsuleSize VR already handles this + /*if (!BaseVRCharacterOwner->bRetainRoomscale) + { + if ((bClientSimulation && CharacterOwner->GetLocalRole() == ROLE_SimulatedProxy) || (IsNetMode(NM_ListenServer) && CharacterOwner->GetRemoteRole() == ROLE_AutonomousProxy)) + { + FNetworkPredictionData_Client_Character* ClientData = GetPredictionData_Client_Character(); + + if (ClientData) + { + ClientData->MeshTranslationOffset -= FVector(0.f, 0.f, MeshAdjust); + ClientData->OriginalMeshTranslationOffset = ClientData->MeshTranslationOffset; + } + } + }*/ +} + +void UVRCharacterMovementComponent::UnCrouch(bool bClientSimulation) +{ + if (!HasValidData()) + { + return; + } + + ACharacter* DefaultCharacter = CharacterOwner->GetClass()->GetDefaultObject(); + + // See if collision is already at desired size. + if (CharacterOwner->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight() == DefaultCharacter->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight()) + { + if (!bClientSimulation) + { + CharacterOwner->bIsCrouched = false; + } + CharacterOwner->OnEndCrouch(0.f, 0.f); + return; + } + + const float CurrentCrouchedHalfHeight = CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleHalfHeight(); + + const float ComponentScale = CharacterOwner->GetCapsuleComponent()->GetShapeScale(); + const float OldUnscaledHalfHeight = CharacterOwner->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight(); + const float HalfHeightAdjust = DefaultCharacter->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight() - OldUnscaledHalfHeight; + const float ScaledHalfHeightAdjust = HalfHeightAdjust * ComponentScale; + + /*const*/ FVector PawnLocation = UpdatedComponent->GetComponentLocation(); + + if (VRRootCapsule) + { + PawnLocation = VRRootCapsule->OffsetComponentToWorld.GetLocation(); + } + + // Grow to uncrouched size. + check(CharacterOwner->GetCapsuleComponent()); + + if (!bClientSimulation) + { + // Try to stay in place and see if the larger capsule fits. We use a slightly taller capsule to avoid penetration. + const UWorld* MyWorld = GetWorld(); + const float SweepInflation = UE_KINDA_SMALL_NUMBER * 10.f; + FCollisionQueryParams CapsuleParams(CharacterMovementComponentStatics::CrouchTraceName, false, CharacterOwner); + FCollisionResponseParams ResponseParam; + InitCollisionParams(CapsuleParams, ResponseParam); + + // Compensate for the difference between current capsule size and standing size + const FCollisionShape StandingCapsuleShape = GetPawnCapsuleCollisionShape(SHRINK_HeightCustom, -SweepInflation - ScaledHalfHeightAdjust); // Shrink by negative amount, so actually grow it. + const ECollisionChannel CollisionChannel = UpdatedComponent->GetCollisionObjectType(); + bool bEncroached = true; + + if (!bCrouchMaintainsBaseLocation) + { + // Expand in place + bEncroached = MyWorld->OverlapBlockingTestByChannel(PawnLocation, FQuat::Identity, CollisionChannel, StandingCapsuleShape, CapsuleParams, ResponseParam); + + if (bEncroached) + { + // Try adjusting capsule position to see if we can avoid encroachment. + if (ScaledHalfHeightAdjust > 0.f) + { + // Shrink to a short capsule, sweep down to base to find where that would hit something, and then try to stand up from there. + float PawnRadius, PawnHalfHeight; + CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleSize(PawnRadius, PawnHalfHeight); + const float ShrinkHalfHeight = PawnHalfHeight - PawnRadius; + const float TraceDist = PawnHalfHeight - ShrinkHalfHeight; + const FVector Down = FVector(0.f, 0.f, -TraceDist); + + FHitResult Hit(1.f); + const FCollisionShape ShortCapsuleShape = GetPawnCapsuleCollisionShape(SHRINK_HeightCustom, ShrinkHalfHeight); + const bool bBlockingHit = MyWorld->SweepSingleByChannel(Hit, PawnLocation, PawnLocation + Down, FQuat::Identity, CollisionChannel, ShortCapsuleShape, CapsuleParams); + if (Hit.bStartPenetrating) + { + bEncroached = true; + } + else + { + // Compute where the base of the sweep ended up, and see if we can stand there + const float DistanceToBase = (Hit.Time * TraceDist) + ShortCapsuleShape.Capsule.HalfHeight; + const FVector NewLoc = FVector(PawnLocation.X, PawnLocation.Y, PawnLocation.Z - DistanceToBase + StandingCapsuleShape.Capsule.HalfHeight + SweepInflation + MIN_FLOOR_DIST / 2.f); + bEncroached = MyWorld->OverlapBlockingTestByChannel(NewLoc, FQuat::Identity, CollisionChannel, StandingCapsuleShape, CapsuleParams, ResponseParam); + if (!bEncroached) + { + // Intentionally not using MoveUpdatedComponent, where a horizontal plane constraint would prevent the base of the capsule from staying at the same spot. + UpdatedComponent->MoveComponent(NewLoc - PawnLocation, UpdatedComponent->GetComponentQuat(), false, nullptr, EMoveComponentFlags::MOVECOMP_NoFlags, ETeleportType::TeleportPhysics); + } + } + } + } + } + else + { + // Expand while keeping base location the same. + FVector StandingLocation = PawnLocation + FVector(0.f, 0.f, StandingCapsuleShape.GetCapsuleHalfHeight() - CurrentCrouchedHalfHeight); + bEncroached = MyWorld->OverlapBlockingTestByChannel(StandingLocation, FQuat::Identity, CollisionChannel, StandingCapsuleShape, CapsuleParams, ResponseParam); + + if (bEncroached) + { + if (IsMovingOnGround()) + { + // Something might be just barely overhead, try moving down closer to the floor to avoid it. + const float MinFloorDist = UE_KINDA_SMALL_NUMBER * 10.f; + if (CurrentFloor.bBlockingHit && CurrentFloor.FloorDist > MinFloorDist) + { + StandingLocation.Z -= CurrentFloor.FloorDist - MinFloorDist; + bEncroached = MyWorld->OverlapBlockingTestByChannel(StandingLocation, FQuat::Identity, CollisionChannel, StandingCapsuleShape, CapsuleParams, ResponseParam); + } + } + } + + // Canceling this move because our VR capsule isn't actor based like it expects it to be + if (!bEncroached) + { + // Commit the change in location. + //UpdatedComponent->MoveComponent(StandingLocation - PawnLocation, UpdatedComponent->GetComponentQuat(), false, nullptr, EMoveComponentFlags::MOVECOMP_NoFlags, ETeleportType::TeleportPhysics); + bForceNextFloorCheck = true; + } + } + + // If still encroached then abort. + if (bEncroached) + { + return; + } + + CharacterOwner->bIsCrouched = false; + } + else + { + bShrinkProxyCapsule = true; + } + + // Now call SetCapsuleSize() to cause touch/untouch events and actually grow the capsule + if (VRRootCapsule) + VRRootCapsule->SetCapsuleSizeVR(DefaultCharacter->GetCapsuleComponent()->GetUnscaledCapsuleRadius(), DefaultCharacter->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight(), true); + else + CharacterOwner->GetCapsuleComponent()->SetCapsuleSize(DefaultCharacter->GetCapsuleComponent()->GetUnscaledCapsuleRadius(), DefaultCharacter->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight(), true); + + const float MeshAdjust = ScaledHalfHeightAdjust; + AdjustProxyCapsuleSize(); + CharacterOwner->OnEndCrouch(HalfHeightAdjust, ScaledHalfHeightAdjust); + + // Don't smooth this change in mesh position + /*if ((bClientSimulation && CharacterOwner->GetLocalRole() == ROLE_SimulatedProxy) || (IsNetMode(NM_ListenServer) && CharacterOwner->GetRemoteRole() == ROLE_AutonomousProxy)) + { + FNetworkPredictionData_Client_Character* ClientData = GetPredictionData_Client_Character(); + + if (ClientData) + { + ClientData->MeshTranslationOffset += FVector(0.f, 0.f, MeshAdjust); + ClientData->OriginalMeshTranslationOffset = ClientData->MeshTranslationOffset; + } + }*/ +} + +FNetworkPredictionData_Client* UVRCharacterMovementComponent::GetPredictionData_Client() const +{ + // Should only be called on client or listen server (for remote clients) in network games + check(CharacterOwner != NULL); + checkSlow(CharacterOwner->GetLocalRole() < ROLE_Authority || (CharacterOwner->GetRemoteRole() == ROLE_AutonomousProxy && GetNetMode() == NM_ListenServer)); + checkSlow(GetNetMode() == NM_Client || GetNetMode() == NM_ListenServer); + + if (!ClientPredictionData) + { + UVRCharacterMovementComponent* MutableThis = const_cast(this); + MutableThis->ClientPredictionData = new FNetworkPredictionData_Client_VRCharacter(*this); + } + + return ClientPredictionData; +} + +FNetworkPredictionData_Server* UVRCharacterMovementComponent::GetPredictionData_Server() const +{ + // Should only be called on server in network games + check(CharacterOwner != NULL); + check(CharacterOwner->GetLocalRole() == ROLE_Authority); + checkSlow(GetNetMode() < NM_Client); + + if (!ServerPredictionData) + { + UVRCharacterMovementComponent* MutableThis = const_cast(this); + MutableThis->ServerPredictionData = new FNetworkPredictionData_Server_VRCharacter(*this); + } + + return ServerPredictionData; +} + +void FSavedMove_VRCharacter::SetInitialPosition(ACharacter* C) +{ + + // See if we can get the VR capsule location + if (AVRCharacter * VRC = Cast(C)) + { + UVRCharacterMovementComponent * CharMove = Cast(VRC->GetCharacterMovement()); + if (VRC->VRRootReference) + { + VRCapsuleLocation = VRC->VRRootReference->curCameraLoc; + VRCapsuleRotation = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(VRC->VRRootReference->curCameraRot); + + // Don't reset this unless its zero, after that its from a movement merge + if (LFDiff.IsZero()) + { + LFDiff = VRC->VRRootReference->DifferenceFromLastFrame; + } + } + else + { + VRCapsuleLocation = FVector::ZeroVector; + VRCapsuleRotation = FRotator::ZeroRotator; + LFDiff = FVector::ZeroVector; + } + } + + FSavedMove_VRBaseCharacter::SetInitialPosition(C); +} + +void FSavedMove_VRCharacter::PrepMoveFor(ACharacter* Character) +{ + UVRCharacterMovementComponent * CharMove = Cast(Character->GetCharacterMovement()); + + // Set capsule location prior to testing movement + // I am overriding the replicated value here when movement is made on purpose + if (CharMove && CharMove->VRRootCapsule) + { + CharMove->VRRootCapsule->curCameraLoc = this->VRCapsuleLocation; + CharMove->VRRootCapsule->curCameraRot = this->VRCapsuleRotation;//FRotator(0.0f, FRotator::DecompressAxisFromByte(CapsuleYaw), 0.0f); + CharMove->VRRootCapsule->DifferenceFromLastFrame = LFDiff;// FVector(LFDiff.X, LFDiff.Y, 0.0f); + CharMove->AdditionalVRInputVector = CharMove->VRRootCapsule->DifferenceFromLastFrame; + + if (AVRBaseCharacter * BaseChar = Cast(CharMove->GetCharacterOwner())) + { + if (BaseChar->GetVRReplicateCapsuleHeight() && this->CapsuleHeight > 0.0f && !FMath::IsNearlyEqual(this->CapsuleHeight, CharMove->VRRootCapsule->GetUnscaledCapsuleHalfHeight())) + { + BaseChar->SetCharacterHalfHeightVR(CapsuleHeight, false); + //CharMove->VRRootCapsule->SetCapsuleHalfHeight(this->LFDiff.Z, false); + } + } + + CharMove->VRRootCapsule->StoredCameraRotOffset = CharMove->VRRootCapsule->curCameraRot; + CharMove->VRRootCapsule->GenerateOffsetToWorld(false, false); + } + + FSavedMove_VRBaseCharacter::PrepMoveFor(Character); +} + + +void UVRCharacterMovementComponent::RegenerateOffset() +{ + if(VRRootCapsule) + VRRootCapsule->GenerateOffsetToWorld(); +} + +void UVRCharacterMovementComponent::ServerMove_PerformMovement(const FCharacterNetworkMoveData& MoveData) +{ + QUICK_SCOPE_CYCLE_COUNTER(VRCharacterMovementServerMove_PerformMovement); + //SCOPE_CYCLE_COUNTER(STAT_VRCharacterMovementServerMove); + //CSV_SCOPED_TIMING_STAT(CharacterMovement, CharacterMovementServerMove); + + if (!HasValidData() || !IsActive()) + { + return; + } + + bool bAutoAcceptPacket = false; + + FNetworkPredictionData_Server_Character* ServerData = GetPredictionData_Server_Character(); + check(ServerData); + + // Convert to our stored move data array + const FVRCharacterNetworkMoveData* MoveDataVR = (const FVRCharacterNetworkMoveData*)&MoveData; + + if (MovementMode == MOVE_Custom && CustomMovementMode == (uint8)EVRCustomMovementMode::VRMOVE_Seated) + { + return; + } + else if (bJustUnseated && MoveDataVR->ReplicatedMovementMode != EVRConjoinedMovementModes::C_VRMOVE_Seated) + { + // If the client isn't still registered as seated then we accept this first change of movement and go + ServerData->CurrentClientTimeStamp = MoveData.TimeStamp; + bAutoAcceptPacket = true; + bJustUnseated = false; + } + + const float ClientTimeStamp = MoveData.TimeStamp; + FVector ClientAccel = MoveData.Acceleration; + + static const auto CVarNetUseBaseRelativeAcceleration = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetUseBaseRelativeAcceleration")); + // Convert the move's acceleration to worldspace if necessary + if (CVarNetUseBaseRelativeAcceleration->GetInt() && MovementBaseUtility::IsDynamicBase(MoveData.MovementBase)) + { + MovementBaseUtility::TransformDirectionToWorld(MoveData.MovementBase, MoveData.MovementBaseBoneName, MoveData.Acceleration, ClientAccel); + } + + const uint8 ClientMoveFlags = MoveData.CompressedMoveFlags; + const FRotator ClientControlRotation = MoveData.ControlRotation; + + if (!bAutoAcceptPacket && !VerifyClientTimeStamp(ClientTimeStamp, *ServerData)) + { + const float ServerTimeStamp = ServerData->CurrentClientTimeStamp; + // This is more severe if the timestamp has a large discrepancy and hasn't been recently reset. + static const auto CVarNetServerMoveTimestampExpiredWarningThreshold = IConsoleManager::Get().FindConsoleVariable(TEXT("net.NetServerMoveTimestampExpiredWarningThreshold")); + if (ServerTimeStamp > 1.0f && FMath::Abs(ServerTimeStamp - ClientTimeStamp) > CVarNetServerMoveTimestampExpiredWarningThreshold->GetFloat()) + { + UE_LOG(LogNetPlayerMovement, Warning, TEXT("ServerMove: TimeStamp expired: %f, CurrentTimeStamp: %f, Character: %s"), ClientTimeStamp, ServerTimeStamp, *GetNameSafe(CharacterOwner)); + } + else + { + UE_LOG(LogNetPlayerMovement, Log, TEXT("ServerMove: TimeStamp expired: %f, CurrentTimeStamp: %f, Character: %s"), ClientTimeStamp, ServerTimeStamp, *GetNameSafe(CharacterOwner)); + } + return; + } + + // Scope these, they nest with Outer references so it should work fine, this keeps the update rotation and move autonomous from double updating the char + FVRCharacterScopedMovementUpdate ScopedMovementUpdate(UpdatedComponent, bEnableScopedMovementUpdates ? EScopedUpdate::DeferredUpdates : EScopedUpdate::ImmediateUpdates); + + bool bServerReadyForClient = true; + APlayerController* PC = Cast(CharacterOwner->GetController()); + if (PC) + { + bServerReadyForClient = PC->NotifyServerReceivedClientData(CharacterOwner, ClientTimeStamp); + if (!bServerReadyForClient) + { + ClientAccel = FVector::ZeroVector; + } + } + + const UWorld* MyWorld = GetWorld(); + /*const*/ float DeltaTime = 0.0f; + + // If we are auto accepting this packet, then accept it and use the maximum delta time as we don't know how long it has actually been since + // The last valid update + if (bAutoAcceptPacket) + { + DeltaTime = ServerData->MaxMoveDeltaTime * CharacterOwner->GetActorTimeDilation(*MyWorld); + } + else + { + DeltaTime = ServerData->GetServerMoveDeltaTime(ClientTimeStamp, CharacterOwner->GetActorTimeDilation(*MyWorld)); + } + + // They added a scope here, im not using it as im doing the full capsule above + // Scope these, they nest with Outer references so it should work fine, this keeps the update rotation and move autonomous from double updating the char + //const FScopedPreventAttachedComponentMove PreventMeshMove(BaseVRCharacterOwner ? BaseVRCharacterOwner->NetSmoother : nullptr); + + if (DeltaTime > 0.f) + { + ServerData->CurrentClientTimeStamp = ClientTimeStamp; + ServerData->ServerAccumulatedClientTimeStamp += DeltaTime; + ServerData->ServerTimeStamp = MyWorld->GetTimeSeconds(); + ServerData->ServerTimeStampLastServerMove = ServerData->ServerTimeStamp; + + if (bUseClientControlRotation) + { + if (AController* CharacterController = Cast(CharacterOwner->GetController())) + { + CharacterController->SetControlRotation(ClientControlRotation); + } + } + + if (!bServerReadyForClient) + { + return; + } + + // Perform actual movement + if ((MyWorld->GetWorldSettings()->GetPauserPlayerState() == NULL)) + { + if (PC) + { + PC->UpdateRotation(DeltaTime); + } + + if (!MoveDataVR->ConditionalMoveReps.RequestedVelocity.IsZero()) + { + RequestedVelocity = MoveDataVR->ConditionalMoveReps.RequestedVelocity; + bHasRequestedVelocity = true; + } + + CustomVRInputVector = MoveDataVR->ConditionalMoveReps.CustomVRInputVector; + MoveActionArray = MoveDataVR->ConditionalMoveReps.MoveActionArray; + VRReplicatedMovementMode = MoveDataVR->ReplicatedMovementMode; + + // Set capsule location prior to testing movement + // I am overriding the replicated value here when movement is made on purpose + if (VRRootCapsule) + { + VRRootCapsule->curCameraLoc = MoveDataVR->VRCapsuleLocation; + VRRootCapsule->curCameraRot = FRotator(0.0f, FRotator::DecompressAxisFromShort(MoveDataVR->VRCapsuleRotation), 0.0f); + VRRootCapsule->DifferenceFromLastFrame = MoveDataVR->LFDiff;//FVector(MoveDataVR->LFDiff.X, MoveDataVR->LFDiff.Y, 0.0f); + AdditionalVRInputVector = VRRootCapsule->DifferenceFromLastFrame; + + if (BaseVRCharacterOwner) + { + if (BaseVRCharacterOwner->GetVRReplicateCapsuleHeight() && MoveDataVR->CapsuleHeight > 0.0f && !FMath::IsNearlyEqual(MoveDataVR->CapsuleHeight, VRRootCapsule->GetUnscaledCapsuleHalfHeight())) + { + BaseVRCharacterOwner->SetCharacterHalfHeightVR(MoveDataVR->CapsuleHeight, false); + // BaseChar->ReplicatedCapsuleHeight.CapsuleHeight = LFDiff.Z; + //VRRootCapsule->SetCapsuleHalfHeight(LFDiff.Z, false); + } + } + + VRRootCapsule->StoredCameraRotOffset = VRRootCapsule->curCameraRot; + VRRootCapsule->GenerateOffsetToWorld(false, false); + } + + MoveAutonomous(ClientTimeStamp, DeltaTime, ClientMoveFlags, ClientAccel); + bHasRequestedVelocity = false; + } + + + UE_CLOG(CharacterOwner && UpdatedComponent, LogNetPlayerMovement, VeryVerbose, TEXT("ServerMove Time %f Acceleration %s Velocity %s Position %s Rotation %s GravityDirection %s DeltaTime %f Mode %s MovementBase %s.%s (Dynamic:%d)"), + ClientTimeStamp, *ClientAccel.ToString(), *Velocity.ToString(), *UpdatedComponent->GetComponentLocation().ToString(), *UpdatedComponent->GetComponentRotation().ToCompactString(), *GetGravityDirection().ToCompactString(), DeltaTime, *GetMovementName(), + *GetNameSafe(GetMovementBase()), *CharacterOwner->GetBasedMovement().BoneName.ToString(), MovementBaseUtility::IsDynamicBase(GetMovementBase()) ? 1 : 0); + } + + // #TODO: Handle this better at some point? Client also denies it later on during correction (ApplyNetworkMovementMode in base movement) + // Pre handling the errors, lets avoid rolling back to/from custom movement modes, they tend to be scripted and this can screw things up + const uint8 CurrentPackedMovementMode = PackNetworkMovementMode(); + if (CurrentPackedMovementMode != MoveData.MovementMode) + { + TEnumAsByte NetMovementMode(MOVE_None); + TEnumAsByte NetGroundMode(MOVE_None); + uint8 NetCustomMode(0); + UnpackNetworkMovementMode(MoveData.MovementMode, NetMovementMode, NetCustomMode, NetGroundMode); + + // Custom movement modes aren't going to be rolled back as they are client authed for our pawns + if (NetMovementMode == EMovementMode::MOVE_Custom || MovementMode == EMovementMode::MOVE_Custom) + { + if (NetCustomMode == (uint8)EVRCustomMovementMode::VRMOVE_Climbing || CustomMovementMode == (uint8)EVRCustomMovementMode::VRMOVE_Climbing) + SetMovementMode(NetMovementMode, NetCustomMode); + } + } + + // Validate move only after old and first dual portion, after all moves are completed. + if (MoveData.NetworkMoveType == FCharacterNetworkMoveData::ENetworkMoveType::NewMove) + { + ServerMoveHandleClientErrorVR(ClientTimeStamp, DeltaTime, ClientAccel, MoveData.Location, ClientControlRotation, MoveData.MovementBase, MoveData.MovementBaseBoneName, MoveData.MovementMode); + //ServerMoveHandleClientErrorVR(ClientTimeStamp, DeltaTime, ClientAccel, MoveData.Location, ClientControlRotation.Yaw, MoveData.MovementBase, MoveData.MovementBaseBoneName, MoveData.MovementMode); + //ServerMoveHandleClientError(ClientTimeStamp, DeltaTime, ClientAccel, MoveData.Location, MoveData.MovementBase, MoveData.MovementBaseBoneName, MoveData.MovementMode); + } +} + +/*void UVRCharacterMovementComponent::CallServerMove +( + const class FSavedMove_Character* NewCMove, + const class FSavedMove_Character* OldCMove + ) +{ + // This is technically "safe", I know for sure that I am using my own FSavedMove + // I would have like to not override any of this, but I need a lot more specific information about the pawn + // So just setting flags in the FSaved Move doesn't cut it + // I could see a problem if someone overrides this override though + const FSavedMove_VRCharacter * NewMove = (const FSavedMove_VRCharacter *)NewCMove; + const FSavedMove_VRCharacter * OldMove = (const FSavedMove_VRCharacter *)OldCMove; + + check(NewMove != nullptr); + //uint32 ClientYawPitchINT = 0; + //uint8 ClientRollBYTE = 0; + //NewMove->GetPackedAngles(ClientYawPitchINT, ClientRollBYTE); + const uint16 CapsuleYawShort = FRotator::CompressAxisToShort(NewMove->VRCapsuleRotation.Yaw); + const uint16 ClientYawShort = FRotator::CompressAxisToShort(NewMove->SavedControlRotation.Yaw); + + // Determine if we send absolute or relative location + UPrimitiveComponent* ClientMovementBase = NewMove->EndBase.Get(); + const FName ClientBaseBone = NewMove->EndBoneName; + const FVector SendLocation = MovementBaseUtility::UseRelativeLocation(ClientMovementBase) ? NewMove->SavedRelativeLocation : NewMove->SavedLocation; + + // send old move if it exists + if (OldMove) + { + //const uint16 CapsuleYawShort = FRotator::CompressAxisToShort(OldMove->VRCapsuleRotation.Yaw); + ServerMoveVROld(OldMove->TimeStamp, OldMove->Acceleration, OldMove->GetCompressedFlags(), OldMove->ConditionalValues); + } + + // Pass these in here, don't pass in to old move, it will receive the new move values in dual operations + // Will automatically not replicate them if movement base is nullptr (1 bit cost to check this) + FVRConditionalMoveRep2 NewMoveConds; + NewMoveConds.ClientMovementBase = ClientMovementBase; + NewMoveConds.ClientBaseBoneName = ClientBaseBone; + + if (CharacterOwner && (CharacterOwner->bUseControllerRotationRoll || CharacterOwner->bUseControllerRotationPitch)) + { + NewMoveConds.ClientPitch = FRotator::CompressAxisToShort(NewMove->SavedControlRotation.Pitch); + NewMoveConds.ClientRoll = FRotator::CompressAxisToByte(NewMove->SavedControlRotation.Roll); + } + + NewMoveConds.ClientYaw = FRotator::CompressAxisToShort(NewMove->SavedControlRotation.Yaw); + + FNetworkPredictionData_Client_Character* ClientData = GetPredictionData_Client_Character(); + if (const FSavedMove_Character* const PendingMove = ClientData->PendingMove.Get()) + { + // This should send same as the uint16 because it uses a packedINT send by default for shorts + //uint32 OldClientYawPitchINT = 0; + //uint8 OldClientRollBYTE = 0; + //ClientData->PendingMove->GetPackedAngles(OldClientYawPitchINT, OldClientRollBYTE); + + uint32 cPitch = 0; + if (CharacterOwner && (CharacterOwner->bUseControllerRotationPitch)) + cPitch = FRotator::CompressAxisToShort(ClientData->PendingMove->SavedControlRotation.Pitch); + + uint32 cYaw = FRotator::CompressAxisToShort(ClientData->PendingMove->SavedControlRotation.Yaw); + + // Switch the order of pitch and yaw to place Yaw in smallest value, this will cut down on rep cost since normally pitch is zero'd out in VR + uint32 OldClientYawPitchINT = (cPitch << 16) | (cYaw); + + FSavedMove_VRCharacter* oldMove = (FSavedMove_VRCharacter*)ClientData->PendingMove.Get(); + const uint16 OldCapsuleYawShort = FRotator::CompressAxisToShort(oldMove->VRCapsuleRotation.Yaw); + //const uint16 OldClientYawShort = FRotator::CompressAxisToShort(ClientData->PendingMove->SavedControlRotation.Yaw); + + + // If we delayed a move without root motion, and our new move has root motion, send these through a special function, so the server knows how to process them. + if ((PendingMove->RootMotionMontage == NULL) && (NewMove->RootMotionMontage != NULL)) + { + // send two moves simultaneously + ServerMoveVRDualHybridRootMotion + ( + PendingMove->TimeStamp, + PendingMove->Acceleration, + PendingMove->GetCompressedFlags(), + OldClientYawPitchINT, + oldMove->VRCapsuleLocation, + oldMove->ConditionalValues, + oldMove->LFDiff, + OldCapsuleYawShort, + NewMove->TimeStamp, + NewMove->Acceleration, + SendLocation, + NewMove->VRCapsuleLocation, + NewMove->ConditionalValues, + NewMove->LFDiff, + CapsuleYawShort, + NewMove->GetCompressedFlags(), + NewMoveConds, + NewMove->EndPackedMovementMode + ); + } + else // Not Hybrid root motion rpc + { + // send two moves simultaneously + if (oldMove->Acceleration.IsZero() && NewMove->Acceleration.IsZero()) + { + ServerMoveVRDualExLight + ( + PendingMove->TimeStamp, + PendingMove->GetCompressedFlags(), + OldClientYawPitchINT, + oldMove->VRCapsuleLocation, + oldMove->ConditionalValues, + oldMove->LFDiff, + OldCapsuleYawShort, + NewMove->TimeStamp, + SendLocation, + NewMove->VRCapsuleLocation, + NewMove->ConditionalValues, + NewMove->LFDiff, + CapsuleYawShort, + NewMove->GetCompressedFlags(), + NewMoveConds, + NewMove->EndPackedMovementMode + ); + } + else + { + ServerMoveVRDual + ( + PendingMove->TimeStamp, + PendingMove->Acceleration, + PendingMove->GetCompressedFlags(), + OldClientYawPitchINT, + oldMove->VRCapsuleLocation, + oldMove->ConditionalValues, + oldMove->LFDiff, + OldCapsuleYawShort, + NewMove->TimeStamp, + NewMove->Acceleration, + SendLocation, + NewMove->VRCapsuleLocation, + NewMove->ConditionalValues, + NewMove->LFDiff, + CapsuleYawShort, + NewMove->GetCompressedFlags(), + NewMoveConds, + NewMove->EndPackedMovementMode + ); + } + } + } + else + { + + if (NewMove->Acceleration.IsZero()) + { + ServerMoveVRExLight + ( + NewMove->TimeStamp, + SendLocation, + NewMove->VRCapsuleLocation, + NewMove->ConditionalValues, + NewMove->LFDiff, + CapsuleYawShort, + NewMove->GetCompressedFlags(), + NewMoveConds, + NewMove->EndPackedMovementMode + ); + } + else + { + ServerMoveVR + ( + NewMove->TimeStamp, + NewMove->Acceleration, + SendLocation, + NewMove->VRCapsuleLocation, + NewMove->ConditionalValues, + NewMove->LFDiff, + CapsuleYawShort, + NewMove->GetCompressedFlags(), + NewMoveConds, + NewMove->EndPackedMovementMode + ); + } + } + + MarkForClientCameraUpdate(); +}*/ + +bool UVRCharacterMovementComponent::ShouldCheckForValidLandingSpot(float DeltaTime, const FVector& Delta, const FHitResult& Hit) const +{ + // See if we hit an edge of a surface on the lower portion of the capsule. + // In this case the normal will not equal the impact normal, and a downward sweep may find a walkable surface on top of the edge. + if (Hit.Normal.Z > UE_KINDA_SMALL_NUMBER && !Hit.Normal.Equals(Hit.ImpactNormal)) + { + FVector PawnLocation = UpdatedComponent->GetComponentLocation(); + if (VRRootCapsule) + PawnLocation = VRRootCapsule->OffsetComponentToWorld.GetLocation(); + + if (IsWithinEdgeTolerance(PawnLocation, Hit.ImpactPoint, CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleRadius())) + { + return true; + } + } + + return false; +} + +void UVRCharacterMovementComponent::PhysWalking(float deltaTime, int32 Iterations) +{ + SCOPE_CYCLE_COUNTER(STAT_CharPhysWalking); + + if (deltaTime < MIN_TICK_TIME) + { + return; + } + + if (!CharacterOwner || (!CharacterOwner->Controller && !bRunPhysicsWithNoController && !HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity() && (CharacterOwner->GetLocalRole() != ROLE_SimulatedProxy))) + { + Acceleration = FVector::ZeroVector; + Velocity = FVector::ZeroVector; + return; + } + + if (!UpdatedComponent->IsQueryCollisionEnabled()) + { + SetMovementMode(MOVE_Walking); + return; + } + + devCodeVR(ensureMsgf(!Velocity.ContainsNaN(), TEXT("PhysWalking: Velocity contains NaN before Iteration (%s)\n%s"), *GetPathNameSafe(this), *Velocity.ToString())); + + bJustTeleported = false; + bool bCheckedFall = false; + bool bTriedLedgeMove = false; + float remainingTime = deltaTime; + + const EMovementMode StartingMovementMode = MovementMode; + const uint8 StartingCustomMovementMode = CustomMovementMode; + + // Rewind the players position by the new capsule location + RewindVRRelativeMovement(); + + // Perform the move + while ((remainingTime >= MIN_TICK_TIME) && (Iterations < MaxSimulationIterations) && CharacterOwner && (CharacterOwner->Controller || bRunPhysicsWithNoController || HasAnimRootMotion() || CurrentRootMotion.HasOverrideVelocity() || (CharacterOwner->GetLocalRole() == ROLE_SimulatedProxy))) + { + Iterations++; + bJustTeleported = false; + const float timeTick = GetSimulationTimeStep(remainingTime, Iterations); + remainingTime -= timeTick; + + // Save current values + UPrimitiveComponent * const OldBase = GetMovementBase(); + const FVector PreviousBaseLocation = (OldBase != NULL) ? OldBase->GetComponentLocation() : FVector::ZeroVector; + const FVector OldLocation = UpdatedComponent->GetComponentLocation(); + + // Used for ledge check + FVector OldCapsuleLocation = VRRootCapsule ? VRRootCapsule->OffsetComponentToWorld.GetLocation() : OldLocation; + + const FFindFloorResult OldFloor = CurrentFloor; + + RestorePreAdditiveRootMotionVelocity(); + //RestorePreAdditiveVRMotionVelocity(); + + // Ensure velocity is horizontal. + MaintainHorizontalGroundVelocity(); + const FVector OldVelocity = Velocity; + Acceleration = FVector::VectorPlaneProject(Acceleration, -GetGravityDirection()); + + // Apply acceleration + if (!HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity()) + { + CalcVelocity(timeTick, GroundFriction, false, GetMaxBrakingDeceleration()); + devCodeVR(ensureMsgf(!Velocity.ContainsNaN(), TEXT("PhysWalking: Velocity contains NaN after CalcVelocity (%s)\n%s"), *GetPathNameSafe(this), *Velocity.ToString())); + } + + ApplyRootMotionToVelocity(timeTick); + ApplyVRMotionToVelocity(deltaTime);//timeTick); + + devCodeVR(ensureMsgf(!Velocity.ContainsNaN(), TEXT("PhysWalking: Velocity contains NaN after Root Motion application (%s)\n%s"), *GetPathNameSafe(this), *Velocity.ToString())); + + if (MovementMode != StartingMovementMode || CustomMovementMode != StartingCustomMovementMode) + { + // Root motion could have taken us out of our current mode + // No movement has taken place this movement tick so we pass on full time/past iteration count + StartNewPhysics(remainingTime + timeTick, Iterations - 1); + return; + } + + // Compute move parameters + const FVector MoveVelocity = Velocity; + + const FVector Delta = timeTick * MoveVelocity; + + const bool bZeroDelta = Delta.IsNearlyZero(); + FStepDownResult StepDownResult; + + if (bZeroDelta) + { + remainingTime = 0.f; + // TODO: Bugged currently + /*if (VRRootCapsule && VRRootCapsule->bUseWalkingCollisionOverride) + { + + FHitResult HitRes; + FCollisionQueryParams Params("RelativeMovementSweep", false, GetOwner()); + FCollisionResponseParams ResponseParam; + + VRRootCapsule->InitSweepCollisionParams(Params, ResponseParam); + Params.bFindInitialOverlaps = true; + bool bWasBlockingHit = false; + + bWasBlockingHit = GetWorld()->SweepSingleByChannel(HitRes, VRRootCapsule->OffsetComponentToWorld.GetLocation(), VRRootCapsule->OffsetComponentToWorld.GetLocation() + VRRootCapsule->DifferenceFromLastFrame, FQuat(0.0f, 0.0f, 0.0f, 1.0f), VRRootCapsule->GetCollisionObjectType(), VRRootCapsule->GetCollisionShape(), Params, ResponseParam); + + const FVector GravDir(0.f, 0.f, -1.f); + if (CanStepUp(HitRes) || (CharacterOwner->GetMovementBase() != NULL && CharacterOwner->GetMovementBase()->GetOwner() == HitRes.GetActor())) + StepUp(GravDir,VRRootCapsule->DifferenceFromLastFrame.GetSafeNormal2D(), HitRes, &StepDownResult); + }*/ + } + else + { + // try to move forward + MoveAlongFloor(MoveVelocity, timeTick, &StepDownResult); + + if (IsSwimming()) //just entered water + { + StartSwimming(OldLocation, OldVelocity, timeTick, remainingTime, Iterations); + return; + } + else if (MovementMode != StartingMovementMode || CustomMovementMode != StartingCustomMovementMode) + { + // pawn ended up in a different mode, probably due to the step-up-and-over flow + // let's refund the estimated unused time (if any) and keep moving in the new mode + const float DesiredDist = Delta.Size(); + if (DesiredDist > UE_KINDA_SMALL_NUMBER) + { + const float ActualDist = (UpdatedComponent->GetComponentLocation() - OldLocation).Size2D(); + remainingTime += timeTick * (1.f - FMath::Min(1.f, ActualDist / DesiredDist)); + } + RestorePreAdditiveVRMotionVelocity(); + StartNewPhysics(remainingTime, Iterations); + return; + } + } + + // Update floor. + // StepUp might have already done it for us. + if (StepDownResult.bComputedFloor) + { + CurrentFloor = StepDownResult.FloorResult; + } + else + { + FindFloor(UpdatedComponent->GetComponentLocation(), CurrentFloor, bZeroDelta, NULL); + } + + // check for ledges here + const bool bCheckLedges = !CanWalkOffLedges(); + if (bCheckLedges && !CurrentFloor.IsWalkableFloor()) + { + // calculate possible alternate movement + const FVector GravDir = GetGravityDirection(); + const FVector NewDelta = bTriedLedgeMove ? FVector::ZeroVector : GetLedgeMove(OldCapsuleLocation, Delta, GravDir); + if (!NewDelta.IsZero()) + { + // first revert this move + RevertMove(OldLocation, OldBase, PreviousBaseLocation, OldFloor, false); + + // avoid repeated ledge moves if the first one fails + bTriedLedgeMove = true; + + // Try new movement direction + Velocity = NewDelta / timeTick; + remainingTime += timeTick; + RestorePreAdditiveVRMotionVelocity(); + continue; + } + else + { + // see if it is OK to jump + // @todo collision : only thing that can be problem is that oldbase has world collision on + /*bool bMustJump = bZeroDelta || (OldBase == NULL || (!OldBase->IsQueryCollisionEnabled() && MovementBaseUtility::IsDynamicBase(OldBase))); + if ((bMustJump || !bCheckedFall) && CheckFall(OldFloor, CurrentFloor.HitResult, Delta, OldLocation, remainingTime, timeTick, Iterations, bMustJump)) + { + RestorePreAdditiveVRMotionVelocity(); + return; + }*/ + bCheckedFall = true; + + // revert this move + RevertMove(OldLocation, OldBase, PreviousBaseLocation, OldFloor, true); + remainingTime = 0.f; + RestorePreAdditiveVRMotionVelocity(); + break; + } + } + else + { + // Validate the floor check + if (CurrentFloor.IsWalkableFloor()) + { + if (ShouldCatchAir(OldFloor, CurrentFloor)) + { + RestorePreAdditiveVRMotionVelocity(); + HandleWalkingOffLedge(OldFloor.HitResult.ImpactNormal, OldFloor.HitResult.Normal, OldLocation, timeTick); + if (IsMovingOnGround()) + { + // If still walking, then fall. If not, assume the user set a different mode they want to keep. + StartFalling(Iterations, remainingTime, timeTick, Delta, OldLocation); + } + return; + } + + AdjustFloorHeight(); + SetBase(CurrentFloor.HitResult.Component.Get(), CurrentFloor.HitResult.BoneName); + } + else if (CurrentFloor.HitResult.bStartPenetrating && remainingTime <= 0.f) + { + // The floor check failed because it started in penetration + // We do not want to try to move downward because the downward sweep failed, rather we'd like to try to pop out of the floor. + FHitResult Hit(CurrentFloor.HitResult); + Hit.TraceEnd = Hit.TraceStart + RotateGravityToWorld(FVector(0.f, 0.f, MAX_FLOOR_DIST)); + const FVector RequestedAdjustment = GetPenetrationAdjustment(Hit); + ResolvePenetration(RequestedAdjustment, Hit, UpdatedComponent->GetComponentQuat()); + bForceNextFloorCheck = true; + } + + // check if just entered water + if (IsSwimming()) + { + RestorePreAdditiveVRMotionVelocity(); + StartSwimmingVR(OldCapsuleLocation, Velocity, timeTick, remainingTime, Iterations); + return; + } + + // See if we need to start falling. + if (!CurrentFloor.IsWalkableFloor() && !CurrentFloor.HitResult.bStartPenetrating) + { + const bool bMustJump = bJustTeleported || bZeroDelta || (OldBase == NULL || (!OldBase->IsQueryCollisionEnabled() && MovementBaseUtility::IsDynamicBase(OldBase))); + if ((bMustJump || !bCheckedFall) && CheckFall(OldFloor, CurrentFloor.HitResult, Delta, OldLocation, remainingTime, timeTick, Iterations, bMustJump)) + { + RestorePreAdditiveVRMotionVelocity(); + return; + } + bCheckedFall = true; + } + + if (bAutoOrientToFloorNormal && CurrentFloor.IsWalkableFloor()) + { + // Auto Align to the new floor normal + // Set gravity direction to the new floor normal + AutoTraceAndSetCharacterToNewGravity(CurrentFloor.HitResult, timeTick); + } + } + + + // Allow overlap events and such to change physics state and velocity + if (IsMovingOnGround()) + { + // Make velocity reflect actual move + + if (!bJustTeleported && timeTick >= MIN_TICK_TIME) + { + if (!HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity()) + { + // TODO-RootMotionSource: Allow this to happen during partial override Velocity, but only set allowed axes? + Velocity = ((UpdatedComponent->GetComponentLocation() - OldLocation) / timeTick); + MaintainHorizontalGroundVelocity(); + } + + RestorePreAdditiveVRMotionVelocity(); + } + } + + // If we didn't move at all this iteration then abort (since future iterations will also be stuck). + if (UpdatedComponent->GetComponentLocation() == OldLocation) + { + RestorePreAdditiveVRMotionVelocity(); + remainingTime = 0.f; + break; + } + } + + if (IsMovingOnGround()) + { + MaintainHorizontalGroundVelocity(); + } +} + +void UVRCharacterMovementComponent::CapsuleTouched(UPrimitiveComponent* OverlappedComp, AActor* Other, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) +{ + if (!bEnablePhysicsInteraction) + { + return; + } + + if (OtherComp != NULL && OtherComp->IsAnySimulatingPhysics()) + { + /*const*/FVector OtherLoc = OtherComp->GetComponentLocation(); + if (UVRRootComponent * rCap = Cast(OtherComp)) + { + OtherLoc = rCap->OffsetComponentToWorld.GetLocation(); + } + + const FVector Loc = VRRootCapsule->OffsetComponentToWorld.GetLocation();//UpdatedComponent->GetComponentLocation(); + FVector ImpulseDir = FVector(OtherLoc.X - Loc.X, OtherLoc.Y - Loc.Y, 0.25f).GetSafeNormal(); + ImpulseDir = (ImpulseDir + Velocity.GetSafeNormal2D()) * 0.5f; + ImpulseDir.Normalize(); + + FName BoneName = NAME_None; + if (OtherBodyIndex != INDEX_NONE) + { + BoneName = ((USkinnedMeshComponent*)OtherComp)->GetBoneName(OtherBodyIndex); + } + + float TouchForceFactorModified = TouchForceFactor; + + if (bTouchForceScaledToMass) + { + FBodyInstance* BI = OtherComp->GetBodyInstance(BoneName); + TouchForceFactorModified *= BI ? BI->GetBodyMass() : 1.0f; + } + + float ImpulseStrength = FMath::Clamp(Velocity.Size2D() * TouchForceFactorModified, + MinTouchForce > 0.0f ? MinTouchForce : -FLT_MAX, + MaxTouchForce > 0.0f ? MaxTouchForce : FLT_MAX); + + FVector Impulse = ImpulseDir * ImpulseStrength; + + OtherComp->AddImpulse(Impulse, BoneName); + } +} + +void UVRCharacterMovementComponent::ReplicateMoveToServer(float DeltaTime, const FVector& NewAcceleration) +{ + SCOPE_CYCLE_COUNTER(STAT_CharacterMovementReplicateMoveToServer); + check(CharacterOwner != NULL); + + // Can only start sending moves if our controllers are synced up over the network, otherwise we flood the reliable buffer. + APlayerController* PC = Cast(CharacterOwner->GetController()); + if (PC && PC->AcknowledgedPawn != CharacterOwner) + { + return; + } + + // Bail out if our character's controller doesn't have a Player. This may be the case when the local player + // has switched to another controller, such as a debug camera controller. + if (PC && PC->Player == nullptr) + { + return; + } + + FNetworkPredictionData_Client_Character* ClientData = GetPredictionData_Client_Character(); + if (!ClientData) + { + return; + } + + // Update our delta time for physics simulation. + DeltaTime = ClientData->UpdateTimeStampAndDeltaTime(DeltaTime, *CharacterOwner, *this); + + // Find the oldest (unacknowledged) important move (OldMove). + // Don't include the last move because it may be combined with the next new move. + // A saved move is interesting if it differs significantly from the last acknowledged move + FSavedMovePtr OldMove = NULL; + if (ClientData->LastAckedMove.IsValid()) + { + for (int32 i = 0; i < ClientData->SavedMoves.Num() - 1; i++) + { + const FSavedMovePtr& CurrentMove = ClientData->SavedMoves[i]; + if (CurrentMove->IsImportantMove(ClientData->LastAckedMove)) + { + OldMove = CurrentMove; + break; + } + } + } + + // Get a SavedMove object to store the movement in. + FSavedMovePtr NewMovePtr = ClientData->CreateSavedMove(); + FSavedMove_Character* const NewMove = NewMovePtr.Get(); + if (NewMove == nullptr) + { + return; + } + + NewMove->SetMoveFor(CharacterOwner, DeltaTime, NewAcceleration, *ClientData); + const UWorld* MyWorld = GetWorld(); + // Causing really bad crash when using vr offset location, rather remove for now than have it merge move improperly. + + // see if the two moves could be combined + // do not combine moves which have different TimeStamps (before and after reset). + if (const FSavedMove_Character* PendingMove = ClientData->PendingMove.Get()) + { + if (bAllowMovementMerging && PendingMove->CanCombineWith(NewMovePtr, CharacterOwner, ClientData->MaxMoveDeltaTime * CharacterOwner->GetActorTimeDilation(*MyWorld))) + { + QUICK_SCOPE_CYCLE_COUNTER(STAT_VRCharacterMovementComponent_CombineNetMove); + //SCOPE_CYCLE_COUNTER(STAT_CharacterMovementCombineNetMove); + + // Only combine and move back to the start location if we don't move back in to a spot that would make us collide with something new. + /*const */FVector OldStartLocation = PendingMove->GetRevertedLocation(); + + // Modifying the location to account for capsule loc + FVector OverlapLocation = OldStartLocation; + if (VRRootCapsule) + OverlapLocation += VRRootCapsule->OffsetComponentToWorld.GetLocation() - VRRootCapsule->GetComponentLocation(); + + const bool bAttachedToObject = (NewMovePtr->StartAttachParent != nullptr); + if (bAttachedToObject || !OverlapTest(OverlapLocation, PendingMove->StartRotation.Quaternion(), UpdatedComponent->GetCollisionObjectType(), GetPawnCapsuleCollisionShape(SHRINK_None), CharacterOwner)) + { + // Avoid updating Mesh bones to physics during the teleport back, since PerformMovement() will update it right away anyway below. + // Note: this must be before the FScopedMovementUpdate below, since that scope is what actually moves the character and mesh. + //AVRBaseCharacter * BaseCharacter = Cast(CharacterOwner); + + FScopedMeshBoneUpdateOverrideVR ScopedNoMeshBoneUpdate(CharacterOwner->GetMesh(), EKinematicBonesUpdateToPhysics::SkipAllBones); + + // Accumulate multiple transform updates until scope ends. + FVRCharacterScopedMovementUpdate ScopedMovementUpdate(UpdatedComponent, EScopedUpdate::DeferredUpdates); + UE_LOG(LogVRCharacterMovement, VeryVerbose, TEXT("CombineMove: add delta %f + %f and revert from %f %f to %f %f"), DeltaTime, ClientData->PendingMove->DeltaTime, UpdatedComponent->GetComponentLocation().X, UpdatedComponent->GetComponentLocation().Y, /*OldStartLocation.X*/OverlapLocation.X, /*OldStartLocation.Y*/OverlapLocation.Y); + + NewMove->CombineWith(PendingMove, CharacterOwner, PC, OldStartLocation); + + // Update the input vector to the new values!! We were always forgetting to do this + FSavedMove_VRBaseCharacter * BaseCharMove = ((FSavedMove_VRBaseCharacter*)NewMove); + AdditionalVRInputVector = BaseCharMove->LFDiff;// FVector(BaseCharMove->LFDiff.X, BaseCharMove->LFDiff.Y, 0.0f); + + /************************/ + if (PC) + { + // We reverted position to that at the start of the pending move (above), however some code paths expect rotation to be set correctly + // before character movement occurs (via FaceRotation), so try that now. The bOrientRotationToMovement path happens later as part of PerformMovement() and PhysicsRotation(). + CharacterOwner->FaceRotation(PC->GetControlRotation(), NewMove->DeltaTime); + } + + SaveBaseLocation(); + NewMove->SetInitialPosition(CharacterOwner); + + // Remove pending move from move list. It would have to be the last move on the list. + if (ClientData->SavedMoves.Num() > 0 && ClientData->SavedMoves.Last() == ClientData->PendingMove) + { + ClientData->SavedMoves.Pop(EAllowShrinking::No); + } + ClientData->FreeMove(ClientData->PendingMove); + ClientData->PendingMove = nullptr; + PendingMove = nullptr; // Avoid dangling reference, it's deleted above. + } + else + { + UE_LOG(LogVRCharacterMovement, Verbose, TEXT("Not combining move [would collide at start location]")); + } + } + /*else + { + UE_LOG(LogVRCharacterMovement, Verbose, TEXT("Not combining move [not allowed by CanCombineWith()]")); + }*/ + } + + // Acceleration should match what we send to the server, plus any other restrictions the server also enforces (see MoveAutonomous). + Acceleration = NewMove->Acceleration.GetClampedToMaxSize(GetMaxAcceleration()); + AnalogInputModifier = ComputeAnalogInputModifier(); // recompute since acceleration may have changed. + + // Perform the move locally + CharacterOwner->ClientRootMotionParams.Clear(); + CharacterOwner->SavedRootMotion.Clear(); + PerformMovement(NewMove->DeltaTime); + + NewMove->PostUpdate(CharacterOwner, FSavedMove_Character::PostUpdate_Record); + + // Add NewMove to the list + if (CharacterOwner->IsReplicatingMovement()) + { + check(NewMove == NewMovePtr.Get()); + ClientData->SavedMoves.Push(NewMovePtr); + + static const auto CVarNetEnableMoveCombining = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetEnableMoveCombining")); + const bool bCanDelayMove = (CVarNetEnableMoveCombining->GetInt() != 0) && CanDelaySendingMove(NewMovePtr); + + if (bCanDelayMove && ClientData->PendingMove.IsValid() == false) + { + // Decide whether to hold off on move + const float NetMoveDeltaSeconds = FMath::Clamp(GetClientNetSendDeltaTime(PC, ClientData, NewMovePtr), 1.f / 120.f, 1.f / 5.f); + const float SecondsSinceLastMoveSent = MyWorld->GetRealTimeSeconds() - ClientData->ClientUpdateRealTime; + + if (SecondsSinceLastMoveSent < NetMoveDeltaSeconds) + { + // Delay sending this move. + ClientData->PendingMove = NewMovePtr; + return; + } + } + + ClientData->ClientUpdateRealTime = MyWorld->GetRealTimeSeconds(); + + UE_CLOG(CharacterOwner&& UpdatedComponent, LogVRCharacterMovement, VeryVerbose, TEXT("ClientMove Time %f Acceleration %s Velocity %s Position %s Rotation %s DeltaTime %f Mode %s MovementBase %s.%s (Dynamic:%d) DualMove? %d"), + NewMove->TimeStamp, *NewMove->Acceleration.ToString(), *Velocity.ToString(), *UpdatedComponent->GetComponentLocation().ToString(), *UpdatedComponent->GetComponentRotation().ToCompactString(), NewMove->DeltaTime, *GetMovementName(), + *GetNameSafe(NewMove->EndBase.Get()), *NewMove->EndBoneName.ToString(), MovementBaseUtility::IsDynamicBase(NewMove->EndBase.Get()) ? 1 : 0, ClientData->PendingMove.IsValid() ? 1 : 0); + + bool bSendServerMove = true; + +#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) + + // Testing options: Simulated packet loss to server + const float TimeSinceLossStart = (MyWorld->RealTimeSeconds - ClientData->DebugForcedPacketLossTimerStart); + + static const auto CVarNetForceClientServerMoveLossDuration = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetForceClientServerMoveLossDuration")); + static const auto CVarNetForceClientServerMoveLossPercent = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetForceClientServerMoveLossPercent")); + if (ClientData->DebugForcedPacketLossTimerStart > 0.f && (TimeSinceLossStart < CVarNetForceClientServerMoveLossDuration->GetFloat())) + { + bSendServerMove = false; + UE_LOG(LogVRCharacterMovement, Log, TEXT("Drop ServerMove, %.2f time remains"), CVarNetForceClientServerMoveLossDuration->GetFloat() - TimeSinceLossStart); + } + else if (CVarNetForceClientServerMoveLossPercent->GetFloat() != 0.f && (RandomStream.FRand() < CVarNetForceClientServerMoveLossPercent->GetFloat())) + { + bSendServerMove = false; + ClientData->DebugForcedPacketLossTimerStart = (CVarNetForceClientServerMoveLossDuration->GetFloat() > 0) ? MyWorld->RealTimeSeconds : 0.0f; + UE_LOG(LogVRCharacterMovement, Log, TEXT("Drop ServerMove, %.2f time remains"), CVarNetForceClientServerMoveLossDuration->GetFloat()); + } + else + { + ClientData->DebugForcedPacketLossTimerStart = 0.f; + } +#endif + + // Send move to server if this character is replicating movement + if (bSendServerMove) + { + SCOPE_CYCLE_COUNTER(STAT_CharacterMovementCallServerMove); + if (ShouldUsePackedMovementRPCs()) + { + CallServerMovePacked(NewMove, ClientData->PendingMove.Get(), OldMove.Get()); + } + /*else + { + CallServerMove(NewMove, OldMove.Get()); + }*/ + } + } + + ClientData->PendingMove = NULL; +} + +/* +* +* +* END TEST AREA +* +* +*/ + +UVRCharacterMovementComponent::UVRCharacterMovementComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + PostPhysicsTickFunction.bCanEverTick = true; + PostPhysicsTickFunction.bStartWithTickEnabled = false; + PrimaryComponentTick.TickGroup = TG_PrePhysics; + VRRootCapsule = NULL; + //VRCameraCollider = NULL; + // 0.1f is low slide and still impacts surfaces well + // This variable is a bit of a hack, it reduces the movement of the pawn in the direction of relative movement + //WallRepulsionMultiplier = 0.01f; + bUseClientControlRotation = false; + bAllowMovementMerging = true; + bRunClientCorrectionToHMD = false; + bRequestedMoveUseAcceleration = false; +} + +void UVRCharacterMovementComponent::OnRegister() +{ + Super::OnRegister(); + + //#TODO: double check that this works, they enforce linear usually + // Force exponential smoothing for replays. + const UWorld* MyWorld = GetWorld(); + const bool bIsReplay = (MyWorld && MyWorld->IsPlayingReplay()); + + if (bIsReplay) + { + //NetworkSmoothingMode = ENetworkSmoothingMode::Linear; + NetworkSmoothingMode = ENetworkSmoothingMode::Exponential; + } +} + + +void UVRCharacterMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) +{ + if (!HasValidData()) + { + return; + } + + if (CharacterOwner && CharacterOwner->IsLocallyControlled()) + { + // Root capsule is now throwing out the difference itself, I use the difference for multiplayer sends + if (VRRootCapsule) + { + AdditionalVRInputVector = VRRootCapsule->DifferenceFromLastFrame; + } + else + { + AdditionalVRInputVector = FVector::ZeroVector; + } + } + + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); +} + +// No support for crouching code yet +bool UVRCharacterMovementComponent::CanCrouch() +{ + return false; +} + + +void UVRCharacterMovementComponent::ApplyRepulsionForce(float DeltaSeconds) +{ + if (UpdatedPrimitive && RepulsionForce > 0.0f && CharacterOwner != nullptr) + { + const TArray& Overlaps = UpdatedPrimitive->GetOverlapInfos(); + if (Overlaps.Num() > 0) + { + FCollisionQueryParams QueryParams; + QueryParams.bReturnFaceIndex = false; + QueryParams.bReturnPhysicalMaterial = false; + + float CapsuleRadius = 0.f; + float CapsuleHalfHeight = 0.f; + CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleSize(CapsuleRadius, CapsuleHalfHeight); + const float RepulsionForceRadius = CapsuleRadius * 1.2f; + const float StopBodyDistance = 2.5f; + FVector MyLocation; + + if (VRRootCapsule) + MyLocation = VRRootCapsule->OffsetComponentToWorld.GetLocation(); + else + MyLocation = UpdatedPrimitive->GetComponentLocation(); + + for (int32 i = 0; i < Overlaps.Num(); i++) + { + const FOverlapInfo& Overlap = Overlaps[i]; + + UPrimitiveComponent* OverlapComp = Overlap.OverlapInfo.Component.Get(); + if (!OverlapComp || OverlapComp->Mobility < EComponentMobility::Movable) + { + continue; + } + + // Use the body instead of the component for cases where we have multi-body overlaps enabled + FBodyInstance* OverlapBody = nullptr; + const int32 OverlapBodyIndex = Overlap.GetBodyIndex(); + const USkeletalMeshComponent* SkelMeshForBody = (OverlapBodyIndex != INDEX_NONE) ? Cast(OverlapComp) : nullptr; + if (SkelMeshForBody != nullptr) + { + OverlapBody = SkelMeshForBody->Bodies.IsValidIndex(OverlapBodyIndex) ? SkelMeshForBody->Bodies[OverlapBodyIndex] : nullptr; + } + else + { + OverlapBody = OverlapComp->GetBodyInstance(); + } + + if (!OverlapBody) + { + UE_LOG(LogVRCharacterMovement, Warning, TEXT("%s could not find overlap body for body index %d"), *GetName(), OverlapBodyIndex); + continue; + } + + if (!OverlapBody->IsInstanceSimulatingPhysics()) + { + continue; + } + + FTransform BodyTransform = OverlapBody->GetUnrealWorldTransform(); + + FVector BodyVelocity = OverlapBody->GetUnrealWorldVelocity(); + FVector BodyLocation = BodyTransform.GetLocation(); + + // Trace to get the hit location on the capsule + FHitResult Hit; + bool bHasHit = UpdatedPrimitive->LineTraceComponent(Hit, BodyLocation, + FVector(MyLocation.X, MyLocation.Y, BodyLocation.Z), + QueryParams); + + FVector HitLoc = Hit.ImpactPoint; + bool bIsPenetrating = Hit.bStartPenetrating || Hit.PenetrationDepth > StopBodyDistance; + + // If we didn't hit the capsule, we're inside the capsule + if (!bHasHit) + { + HitLoc = BodyLocation; + bIsPenetrating = true; + } + + const float DistanceNow = (HitLoc - BodyLocation).SizeSquared2D(); + const float DistanceLater = (HitLoc - (BodyLocation + BodyVelocity * DeltaSeconds)).SizeSquared2D(); + + if (bHasHit && DistanceNow < StopBodyDistance && !bIsPenetrating) + { + OverlapBody->SetLinearVelocity(FVector(0.0f, 0.0f, 0.0f), false); + } + else if (DistanceLater <= DistanceNow || bIsPenetrating) + { + FVector ForceCenter = MyLocation; + + if (bHasHit) + { + ForceCenter.Z = HitLoc.Z; + } + else + { + ForceCenter.Z = FMath::Clamp(BodyLocation.Z, MyLocation.Z - CapsuleHalfHeight, MyLocation.Z + CapsuleHalfHeight); + } + + OverlapBody->AddRadialForceToBody(ForceCenter, RepulsionForceRadius, RepulsionForce * Mass, ERadialImpulseFalloff::RIF_Constant); + } + } + } + } +} + + +void UVRCharacterMovementComponent::SetUpdatedComponent(USceneComponent* NewUpdatedComponent) +{ + Super::SetUpdatedComponent(NewUpdatedComponent); + + if (UpdatedComponent) + { + // Fill the VRRootCapsule if we can + VRRootCapsule = Cast(UpdatedComponent); + + // Fill in the camera collider if we can + /*if (AVRCharacter * vrOwner = Cast(this->GetOwner())) + { + VRCameraCollider = vrOwner->VRCameraCollider; + }*/ + + // Stop the tick forcing + UpdatedComponent->PrimaryComponentTick.RemovePrerequisite(this, PrimaryComponentTick); + + // Start forcing the root to tick before this, the actor tick will still tick after the movement component + // We want the root component to tick first because it is setting its offset location based off of tick + this->PrimaryComponentTick.AddPrerequisite(UpdatedComponent, UpdatedComponent->PrimaryComponentTick); + } +} + +FORCEINLINE_DEBUGGABLE bool UVRCharacterMovementComponent::SafeMoveUpdatedComponent(const FVector& Delta, const FRotator& NewRotation, bool bSweep, FHitResult& OutHit, ETeleportType Teleport) +{ + return SafeMoveUpdatedComponent(Delta, NewRotation.Quaternion(), bSweep, OutHit, Teleport); +} + +bool UVRCharacterMovementComponent::SafeMoveUpdatedComponent(const FVector& Delta, const FQuat& NewRotation, bool bSweep, FHitResult& OutHit, ETeleportType Teleport) +{ + if (UpdatedComponent == NULL) + { + OutHit.Reset(1.f); + return false; + } + + bool bMoveResult = MoveUpdatedComponent(Delta, NewRotation, bSweep, &OutHit, Teleport); + + // Handle initial penetrations + if (OutHit.bStartPenetrating && UpdatedComponent) + { + const FVector RequestedAdjustment = GetPenetrationAdjustment(OutHit); + if (ResolvePenetration(RequestedAdjustment, OutHit, NewRotation)) + { + FHitResult TempHit; + // Retry original move + bMoveResult = MoveUpdatedComponent(Delta, NewRotation, bSweep, &TempHit, Teleport); + + // Remove start penetrating if this is a clean move, otherwise use the last moves hit as the result so step up actually attempts to work. + if (TempHit.bStartPenetrating) + OutHit = TempHit; + else + OutHit.bStartPenetrating = TempHit.bStartPenetrating; + } + } + + return bMoveResult; +} + +void UVRCharacterMovementComponent::MoveAlongFloor(const FVector& InVelocity, float DeltaSeconds, FStepDownResult* OutStepDownResult) +{ + if (!CurrentFloor.IsWalkableFloor()) + { + return; + } + + // Move along the current floor + const FVector Delta = RotateGravityToWorld(RotateWorldToGravity(InVelocity) * FVector(1.0, 1.0, 0.0)) * DeltaSeconds; + FHitResult Hit(1.f); + FVector RampVector = ComputeGroundMovementDelta(Delta, CurrentFloor.HitResult, CurrentFloor.bLineTrace); + SafeMoveUpdatedComponent(RampVector, UpdatedComponent->GetComponentQuat(), true, Hit); + float LastMoveTimeSlice = DeltaSeconds; + + if (Hit.bStartPenetrating) + { + // Allow this hit to be used as an impact we can deflect off, otherwise we do nothing the rest of the update and appear to hitch. + HandleImpact(Hit); + SlideAlongSurface(Delta, 1.f, Hit.Normal, Hit, true); + + if (Hit.bStartPenetrating) + { + OnCharacterStuckInGeometry(&Hit); + } + } + else if (Hit.IsValidBlockingHit()) + { + // We impacted something (most likely another ramp, but possibly a barrier). + float PercentTimeApplied = Hit.Time; + if ((Hit.Time > 0.f) && (Hit.Normal.Z > UE_KINDA_SMALL_NUMBER) && IsWalkable(Hit)) + { + // Another walkable ramp. + const float InitialPercentRemaining = 1.f - PercentTimeApplied; + RampVector = ComputeGroundMovementDelta(Delta * InitialPercentRemaining, Hit, false); + LastMoveTimeSlice = InitialPercentRemaining * LastMoveTimeSlice; + SafeMoveUpdatedComponent(RampVector, UpdatedComponent->GetComponentQuat(), true, Hit); + + const float SecondHitPercent = Hit.Time * InitialPercentRemaining; + PercentTimeApplied = FMath::Clamp(PercentTimeApplied + SecondHitPercent, 0.f, 1.f); + } + + if (Hit.IsValidBlockingHit()) + { + if (CanStepUp(Hit) || (CharacterOwner->GetMovementBase() != nullptr && Hit.HitObjectHandle == CharacterOwner->GetMovementBase()->GetOwner())) + { + // hit a barrier, try to step up + const FVector PreStepUpLocation = UpdatedComponent->GetComponentLocation(); + const FVector GravDir = GetGravityDirection(); + + // I add in the HMD difference from last frame to the step up check to enforce it stepping up + if (!StepUp(GravDir, (Delta * (1.f - PercentTimeApplied)) /*+ AdditionalVRInputVector.GetSafeNormal2D()*/, Hit, OutStepDownResult)) + { + UE_LOG(LogVRCharacterMovement, Verbose, TEXT("- StepUp (ImpactNormal %s, Normal %s"), *Hit.ImpactNormal.ToString(), *Hit.Normal.ToString()); + HandleImpact(Hit, LastMoveTimeSlice, RampVector); + SlideAlongSurface(Delta, 1.f - PercentTimeApplied, Hit.Normal, Hit, true); + + } + else + { + UE_LOG(LogVRCharacterMovement, Verbose, TEXT("+ StepUp (ImpactNormal %s, Normal %s"), *Hit.ImpactNormal.ToString(), *Hit.Normal.ToString()); + if (!bMaintainHorizontalGroundVelocity) + { + // Don't recalculate velocity based on this height adjustment, if considering vertical adjustments. Only consider horizontal movement. + bJustTeleported = true; + const float StepUpTimeSlice = (1.f - PercentTimeApplied) * DeltaSeconds; + if (!HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity() && StepUpTimeSlice >= UE_KINDA_SMALL_NUMBER) + { + Velocity = (UpdatedComponent->GetComponentLocation() - PreStepUpLocation) / StepUpTimeSlice; + Velocity = FVector::VectorPlaneProject(Velocity, -GravDir); + } + } + } + } + else if (Hit.Component.IsValid() && !Hit.Component.Get()->CanCharacterStepUp(CharacterOwner)) + { + HandleImpact(Hit, LastMoveTimeSlice, RampVector); + SlideAlongSurface(Delta, 1.f - PercentTimeApplied, Hit.Normal, Hit, true); + + } + } + } +} + +bool UVRCharacterMovementComponent::StepUp(const FVector& GravDir, const FVector& Delta, const FHitResult &InHit, FStepDownResult* OutStepDownResult) +{ + SCOPE_CYCLE_COUNTER(STAT_CharStepUp); + + if (!CanStepUp(InHit) || MaxStepHeight <= 0.f) + { + return false; + } + + FVector OldLocation; + + if (VRRootCapsule) + OldLocation = VRRootCapsule->OffsetComponentToWorld.GetLocation(); + else + OldLocation = UpdatedComponent->GetComponentLocation(); + + float PawnRadius, PawnHalfHeight; + CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleSize(PawnRadius, PawnHalfHeight); + + // Don't bother stepping up if top of capsule is hitting something. + const float InitialImpactZ = InHit.ImpactPoint.Z; + if (InitialImpactZ > OldLocation.Z + (PawnHalfHeight - PawnRadius)) + { + return false; + } + + if (GravDir.IsZero()) + { + return false; + } + + // Gravity should be a normalized direction + ensure(GravDir.IsNormalized()); + + float StepTravelUpHeight = MaxStepHeight; + float StepTravelDownHeight = StepTravelUpHeight; + const float StepSideZ = -1.f * FVector::DotProduct(InHit.ImpactNormal, GravDir);//const float StepSideZ = -1.f * (InHit.ImpactNormal | GravDir); + float PawnInitialFloorBaseZ = OldLocation.Z -PawnHalfHeight; + float PawnFloorPointZ = PawnInitialFloorBaseZ; + + if (IsMovingOnGround() && CurrentFloor.IsWalkableFloor()) + { + // Since we float a variable amount off the floor, we need to enforce max step height off the actual point of impact with the floor. + const float FloorDist = FMath::Max(0.f, CurrentFloor.GetDistanceToFloor()); + PawnInitialFloorBaseZ -= FloorDist; + StepTravelUpHeight = FMath::Max(StepTravelUpHeight - FloorDist, 0.f); + StepTravelDownHeight = (MaxStepHeight + MAX_FLOOR_DIST*2.f); + + const bool bHitVerticalFace = !IsWithinEdgeTolerance(InHit.Location, InHit.ImpactPoint, PawnRadius); + if (!CurrentFloor.bLineTrace && !bHitVerticalFace) + { + PawnFloorPointZ = CurrentFloor.HitResult.ImpactPoint.Z; + } + else + { + // Base floor point is the base of the capsule moved down by how far we are hovering over the surface we are hitting. + PawnFloorPointZ -= CurrentFloor.FloorDist; + } + } + + // Don't step up if the impact is below us, accounting for distance from floor. + if (InitialImpactZ <= PawnInitialFloorBaseZ) + { + return false; + } + + // Scope our movement updates, and do not apply them until all intermediate moves are completed. + /*FScopedMovementUpdate*/ FVRCharacterScopedMovementUpdate ScopedStepUpMovement(UpdatedComponent, EScopedUpdate::DeferredUpdates); + + // step up - treat as vertical wall + FHitResult SweepUpHit(1.f); + const FQuat PawnRotation = UpdatedComponent->GetComponentQuat(); + MoveUpdatedComponent(-GravDir * StepTravelUpHeight, PawnRotation, true, &SweepUpHit); + + if (SweepUpHit.bStartPenetrating) + { + // Undo movement + ScopedStepUpMovement.RevertMove(); + return false; + } + + + // step fwd + FHitResult Hit(1.f); + MoveUpdatedComponent(Delta, PawnRotation, true, &Hit); + + // Check result of forward movement + if (Hit.bBlockingHit) + { + if (Hit.bStartPenetrating) + { + // Undo movement + ScopedStepUpMovement.RevertMove(); + return false; + } + + // If we hit something above us and also something ahead of us, we should notify about the upward hit as well. + // The forward hit will be handled later (in the bSteppedOver case below). + // In the case of hitting something above but not forward, we are not blocked from moving so we don't need the notification. + if (SweepUpHit.bBlockingHit && Hit.bBlockingHit) + { + HandleImpact(SweepUpHit); + } + + // pawn ran into a wall + HandleImpact(Hit); + if (IsFalling()) + { + return true; + } + + // adjust and try again + const float ForwardHitTime = Hit.Time; + const float ForwardSlideAmount = SlideAlongSurface(Delta, 1.f - Hit.Time, Hit.Normal, Hit, true); + + if (IsFalling()) + { + ScopedStepUpMovement.RevertMove(); + return false; + } + + // If both the forward hit and the deflection got us nowhere, there is no point in this step up. + if (ForwardHitTime == 0.f && ForwardSlideAmount == 0.f) + { + ScopedStepUpMovement.RevertMove(); + return false; + } + } + + // Step down + MoveUpdatedComponent(GravDir * StepTravelDownHeight, UpdatedComponent->GetComponentQuat(), true, &Hit); + + // If step down was initially penetrating abort the step up + if (Hit.bStartPenetrating) + { + ScopedStepUpMovement.RevertMove(); + return false; + } + + FStepDownResult StepDownResult; + if (Hit.IsValidBlockingHit()) + { + // See if this step sequence would have allowed us to travel higher than our max step height allows. + const float DeltaZ = Hit.ImpactPoint.Z - PawnFloorPointZ; + if (DeltaZ > MaxStepHeight) + { + //UE_LOG(LogVRCharacterMovement, VeryVerbose, TEXT("- Reject StepUp (too high Height %.3f) up from floor base %f"), DeltaZ, PawnInitialFloorBaseZ); + ScopedStepUpMovement.RevertMove(); + return false; + } + + // Reject unwalkable surface normals here. + if (!IsWalkable(Hit)) + { + // Reject if normal opposes movement direction + const bool bNormalTowardsMe = (Delta | Hit.ImpactNormal) < 0.f; + if (bNormalTowardsMe) + { + //UE_LOG(LogVRCharacterMovement, VeryVerbose, TEXT("- Reject StepUp (unwalkable normal %s opposed to movement)"), *Hit.ImpactNormal.ToString()); + ScopedStepUpMovement.RevertMove(); + return false; + } + + // Also reject if we would end up being higher than our starting location by stepping down. + // It's fine to step down onto an unwalkable normal below us, we will just slide off. Rejecting those moves would prevent us from being able to walk off the edge. + if (Hit.Location.Z > OldLocation.Z) + { + //UE_LOG(LogVRCharacterMovement, VeryVerbose, TEXT("- Reject StepUp (unwalkable normal %s above old position)"), *Hit.ImpactNormal.ToString()); + ScopedStepUpMovement.RevertMove(); + return false; + } + } + + // Reject moves where the downward sweep hit something very close to the edge of the capsule. This maintains consistency with FindFloor as well. + if (!IsWithinEdgeTolerance(Hit.Location, Hit.ImpactPoint, PawnRadius)) + { + //UE_LOG(LogVRCharacterMovement, VeryVerbose, TEXT("- Reject StepUp (outside edge tolerance)")); + ScopedStepUpMovement.RevertMove(); + return false; + } + + // Don't step up onto invalid surfaces if traveling higher. + if (DeltaZ > 0.f && !CanStepUp(Hit)) + { + //UE_LOG(LogVRCharacterMovement, VeryVerbose, TEXT("- Reject StepUp (up onto surface with !CanStepUp())")); + ScopedStepUpMovement.RevertMove(); + return false; + } + + // See if we can validate the floor as a result of this step down. In almost all cases this should succeed, and we can avoid computing the floor outside this method. + if (OutStepDownResult != NULL) + { + FindFloor(UpdatedComponent->GetComponentLocation(), StepDownResult.FloorResult, false, &Hit); + + // Reject unwalkable normals if we end up higher than our initial height. + // It's fine to walk down onto an unwalkable surface, don't reject those moves. + if (Hit.Location.Z > OldLocation.Z) + { + // We should reject the floor result if we are trying to step up an actual step where we are not able to perch (this is rare). + // In those cases we should instead abort the step up and try to slide along the stair. + if (!StepDownResult.FloorResult.bBlockingHit && StepSideZ < CharacterMovementConstants::MAX_STEP_SIDE_ZVR) + { + ScopedStepUpMovement.RevertMove(); + return false; + } + } + + StepDownResult.bComputedFloor = true; + + if (bAutoOrientToFloorNormal && StepDownResult.FloorResult.IsWalkableFloor()) + { + // Auto Align to the new floor normal + // Set gravity direction to the new floor normal, don't blend the change, snap to it on a step up + AutoTraceAndSetCharacterToNewGravity(StepDownResult.FloorResult.HitResult); + } + } + } + + // Copy step down result. + if (OutStepDownResult != NULL) + { + *OutStepDownResult = StepDownResult; + } + + // Don't recalculate velocity based on this height adjustment, if considering vertical adjustments. + bJustTeleported |= !bMaintainHorizontalGroundVelocity; + + return true; +} + +bool UVRCharacterMovementComponent::IsWithinEdgeTolerance(const FVector& CapsuleLocation, const FVector& TestImpactPoint, const float CapsuleRadius) const +{ + const FVector GravityRelativeToTestImpactPoint = RotateWorldToGravity(TestImpactPoint - CapsuleLocation); + const float DistFromCenterSq = GravityRelativeToTestImpactPoint.SizeSquared2D(); + const float ReducedRadiusSq = FMath::Square(FMath::Max(VREdgeRejectDistance + UE_KINDA_SMALL_NUMBER, CapsuleRadius - VREdgeRejectDistance)); + return DistFromCenterSq < ReducedRadiusSq; +} + +bool UVRCharacterMovementComponent::IsWithinClimbingEdgeTolerance(const FVector& CapsuleLocation, const FVector& TestImpactPoint, const float CapsuleRadius) const +{ + const float DistFromCenterSq = (TestImpactPoint - CapsuleLocation).SizeSquared2D(); + const float ReducedRadiusSq = FMath::Square(FMath::Max(VRClimbingEdgeRejectDistance + UE_KINDA_SMALL_NUMBER, CapsuleRadius - VRClimbingEdgeRejectDistance)); + return DistFromCenterSq < ReducedRadiusSq; +} + +bool UVRCharacterMovementComponent::VRClimbStepUp(const FVector& GravDir, const FVector& Delta, const FHitResult &InHit, FStepDownResult* OutStepDownResult) +{ + SCOPE_CYCLE_COUNTER(STAT_CharStepUp); + + if (!CanStepUp(InHit) || MaxStepHeight <= 0.f) + { + return false; + } + + FVector OldLocation; + + if (VRRootCapsule) + OldLocation = VRRootCapsule->OffsetComponentToWorld.GetLocation(); + else + OldLocation = UpdatedComponent->GetComponentLocation(); + + float PawnRadius, PawnHalfHeight; + CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleSize(PawnRadius, PawnHalfHeight); + + // Don't bother stepping up if top of capsule is hitting something. + const float InitialImpactZ = InHit.ImpactPoint.Z; + if (InitialImpactZ > OldLocation.Z + (PawnHalfHeight - PawnRadius)) + { + return false; + } + + // Don't step up if the impact is below us + if (InitialImpactZ <= OldLocation.Z - PawnHalfHeight) + { + return false; + } + + if (GravDir.IsZero()) + { + return false; + } + + // Gravity should be a normalized direction + ensure(GravDir.IsNormalized()); + + float StepTravelUpHeight = MaxStepHeight; + float StepTravelDownHeight = StepTravelUpHeight; + const float StepSideZ = -1.f * (InHit.ImpactNormal | GravDir); + float PawnInitialFloorBaseZ = OldLocation.Z - PawnHalfHeight; + float PawnFloorPointZ = PawnInitialFloorBaseZ; + + // Scope our movement updates, and do not apply them until all intermediate moves are completed. + FVRCharacterScopedMovementUpdate ScopedStepUpMovement(UpdatedComponent, EScopedUpdate::DeferredUpdates); + + // step up - treat as vertical wall + FHitResult SweepUpHit(1.f); + const FQuat PawnRotation = UpdatedComponent->GetComponentQuat(); + MoveUpdatedComponent(-GravDir * StepTravelUpHeight, PawnRotation, true, &SweepUpHit); + + if (SweepUpHit.bStartPenetrating) + { + // Undo movement + ScopedStepUpMovement.RevertMove(); + return false; + } + + // step fwd + FHitResult Hit(1.f); + + + // Adding in the directional difference of the last HMD movement to promote stepping up + // Probably entirely wrong as Delta is divided by movement ticks but I want the effect to be stronger anyway + // This won't effect control based movement unless stepping forward at the same time, but gives RW movement + // the extra boost to get up over a lip + // #TODO test this more, currently appears to be needed for walking, but is harmful for other modes +// if (VRRootCapsule) +// MoveUpdatedComponent(Delta + VRRootCapsule->DifferenceFromLastFrame.GetSafeNormal2D(), PawnRotation, true, &Hit); +// else + MoveUpdatedComponent(Delta, PawnRotation, true, &Hit); + + //MoveUpdatedComponent(Delta, PawnRotation, true, &Hit); + + // Check result of forward movement + if (Hit.bBlockingHit) + { + if (Hit.bStartPenetrating) + { + // Undo movement + ScopedStepUpMovement.RevertMove(); + return false; + } + + // If we hit something above us and also something ahead of us, we should notify about the upward hit as well. + // The forward hit will be handled later (in the bSteppedOver case below). + // In the case of hitting something above but not forward, we are not blocked from moving so we don't need the notification. + if (SweepUpHit.bBlockingHit && Hit.bBlockingHit) + { + + HandleImpact(SweepUpHit); + } + + // pawn ran into a wall + HandleImpact(Hit); + if (IsFalling()) + { + return true; + } + + //Don't adjust for VR, it doesn't work correctly + ScopedStepUpMovement.RevertMove(); + return false; + + // adjust and try again + //const float ForwardHitTime = Hit.Time; + //const float ForwardSlideAmount = SlideAlongSurface(Delta, 1.f - Hit.Time, Hit.Normal, Hit, true); + + //if (IsFalling()) + //{ + // ScopedStepUpMovement.RevertMove(); + // return false; + //} + + // If both the forward hit and the deflection got us nowhere, there is no point in this step up. + //if (ForwardHitTime == 0.f && ForwardSlideAmount == 0.f) + //{ + // ScopedStepUpMovement.RevertMove(); + // return false; + //} + } + + // Step down + MoveUpdatedComponent(GravDir * StepTravelDownHeight, UpdatedComponent->GetComponentQuat(), true, &Hit); + + // If step down was initially penetrating abort the step up + if (Hit.bStartPenetrating) + { + ScopedStepUpMovement.RevertMove(); + return false; + } + + FStepDownResult StepDownResult; + if (Hit.IsValidBlockingHit()) + { + // See if this step sequence would have allowed us to travel higher than our max step height allows. + const float DeltaZ = Hit.ImpactPoint.Z - PawnFloorPointZ; + if (DeltaZ > MaxStepHeight) + { + UE_LOG(LogVRCharacterMovement, VeryVerbose, TEXT("- Reject StepUp (too high Height %.3f) up from floor base %f"), DeltaZ, PawnInitialFloorBaseZ); + ScopedStepUpMovement.RevertMove(); + return false; + } + + // Reject unwalkable surface normals here. + if (!IsWalkable(Hit)) + { + // Reject if normal opposes movement direction + const bool bNormalTowardsMe = (Delta | Hit.ImpactNormal) < 0.f; + if (bNormalTowardsMe) + { + //UE_LOG(LogVRCharacterMovement, VeryVerbose, TEXT("- Reject StepUp (unwalkable normal %s opposed to movement)"), *Hit.ImpactNormal.ToString()); + ScopedStepUpMovement.RevertMove(); + return false; + } + + // Also reject if we would end up being higher than our starting location by stepping down. + // It's fine to step down onto an unwalkable normal below us, we will just slide off. Rejecting those moves would prevent us from being able to walk off the edge. + if (Hit.Location.Z > OldLocation.Z) + { + UE_LOG(LogVRCharacterMovement, VeryVerbose, TEXT("- Reject StepUp (unwalkable normal %s above old position)"), *Hit.ImpactNormal.ToString()); + ScopedStepUpMovement.RevertMove(); + return false; + } + } + + // Reject moves where the downward sweep hit something very close to the edge of the capsule. This maintains consistency with FindFloor as well. + if (!IsWithinClimbingEdgeTolerance(Hit.Location, Hit.ImpactPoint, PawnRadius)) + { + UE_LOG(LogVRCharacterMovement, VeryVerbose, TEXT("- Reject StepUp (outside edge tolerance)")); + ScopedStepUpMovement.RevertMove(); + return false; + } + + // Don't step up onto invalid surfaces if traveling higher. + if (DeltaZ > 0.f && !CanStepUp(Hit)) + { + UE_LOG(LogVRCharacterMovement, VeryVerbose, TEXT("- Reject StepUp (up onto surface with !CanStepUp())")); + ScopedStepUpMovement.RevertMove(); + return false; + } + + // See if we can validate the floor as a result of this step down. In almost all cases this should succeed, and we can avoid computing the floor outside this method. + if (OutStepDownResult != NULL) + { + FindFloor(UpdatedComponent->GetComponentLocation(), StepDownResult.FloorResult, false, &Hit); + + // Reject unwalkable normals if we end up higher than our initial height. + // It's fine to walk down onto an unwalkable surface, don't reject those moves. + if (Hit.Location.Z > OldLocation.Z) + { + // We should reject the floor result if we are trying to step up an actual step where we are not able to perch (this is rare). + // In those cases we should instead abort the step up and try to slide along the stair. + if (!StepDownResult.FloorResult.bBlockingHit && StepSideZ < CharacterMovementConstants::MAX_STEP_SIDE_ZVR) + { + ScopedStepUpMovement.RevertMove(); + return false; + } + } + + StepDownResult.bComputedFloor = true; + + if (bAutoOrientToFloorNormal && StepDownResult.FloorResult.IsWalkableFloor()) + { + // Auto Align to the new floor normal + // Set gravity direction to the new floor normal, don't blend the change, snap to it on a step down + AutoTraceAndSetCharacterToNewGravity(StepDownResult.FloorResult.HitResult); + } + } + } + + // Copy step down result. + if (OutStepDownResult != NULL) + { + *OutStepDownResult = StepDownResult; + } + + // Don't recalculate velocity based on this height adjustment, if considering vertical adjustments. + bJustTeleported |= !bMaintainHorizontalGroundVelocity; + return true; +} + + +void UVRCharacterMovementComponent::UpdateBasedMovement(float DeltaSeconds) +{ + if (!HasValidData()) + { + return; + } + + const UPrimitiveComponent* MovementBase = CharacterOwner->GetMovementBase(); + if (!MovementBaseUtility::UseRelativeLocation(MovementBase)) + { + return; + } + + if (!IsValid(MovementBase) || !IsValid(MovementBase->GetOwner())) + { + SetBase(NULL); + return; + } + + // Ignore collision with bases during these movements. + TGuardValue ScopedFlagRestore(MoveComponentFlags, MoveComponentFlags | MOVECOMP_IgnoreBases); + + FQuat DeltaQuat = FQuat::Identity; + FVector DeltaPosition = FVector::ZeroVector; + + FQuat NewBaseQuat; + FVector NewBaseLocation; + if (!MovementBaseUtility::GetMovementBaseTransform(MovementBase, CharacterOwner->GetBasedMovement().BoneName, NewBaseLocation, NewBaseQuat)) + { + return; + } + + // Find change in rotation + const bool bRotationChanged = !OldBaseQuat.Equals(NewBaseQuat, 1e-8f); + if (bRotationChanged) + { + DeltaQuat = NewBaseQuat * OldBaseQuat.Inverse(); + } + + // only if base moved + if (bRotationChanged || (OldBaseLocation != NewBaseLocation)) + { + // Calculate new transform matrix of base actor (ignoring scale). + const FQuatRotationTranslationMatrix OldLocalToWorld(OldBaseQuat, OldBaseLocation); + const FQuatRotationTranslationMatrix NewLocalToWorld(NewBaseQuat, NewBaseLocation); + + FQuat FinalQuat = UpdatedComponent->GetComponentQuat(); + + if (bRotationChanged && !bIgnoreBaseRotation) + { + // Apply change in rotation and pipe through FaceRotation to maintain axis restrictions + const FQuat PawnOldQuat = UpdatedComponent->GetComponentQuat(); + const FQuat TargetQuat = DeltaQuat * FinalQuat; + FRotator TargetRotator(TargetQuat); + CharacterOwner->FaceRotation(TargetRotator, 0.f); + FinalQuat = UpdatedComponent->GetComponentQuat(); + + if (PawnOldQuat.Equals(FinalQuat, 1e-6f)) + { + // Nothing changed. This means we probably are using another rotation mechanism (bOrientToMovement etc). We should still follow the base object. + // @todo: This assumes only Yaw is used, currently a valid assumption. This is the only reason FaceRotation() is used above really, aside from being a virtual hook. + if (bOrientRotationToMovement || (bUseControllerDesiredRotation && CharacterOwner->Controller)) + { + TargetRotator.Pitch = 0.f; + TargetRotator.Roll = 0.f; + MoveUpdatedComponent(FVector::ZeroVector, TargetRotator, false); + FinalQuat = UpdatedComponent->GetComponentQuat(); + } + } + + // Pipe through ControlRotation, to affect camera. + if (CharacterOwner->Controller) + { + const FQuat PawnDeltaRotation = FinalQuat * PawnOldQuat.Inverse(); + FRotator FinalRotation = FinalQuat.Rotator(); + UpdateBasedRotation(FinalRotation, PawnDeltaRotation.Rotator()); + FinalQuat = UpdatedComponent->GetComponentQuat(); + } + } + + // We need to offset the base of the character here, not its origin, so offset by half height + float HalfHeight, Radius; + CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleSize(Radius, HalfHeight); + + if (!BaseVRCharacterOwner || BaseVRCharacterOwner->bRetainRoomscale) + { + HalfHeight = 0; + } + + FVector const BaseOffset(0.0f, 0.0f, HalfHeight); + + FVector const LocalBasePos = OldLocalToWorld.InverseTransformPosition(UpdatedComponent->GetComponentLocation() - BaseOffset); + FVector const NewWorldPos = ConstrainLocationToPlane(NewLocalToWorld.TransformPosition(LocalBasePos) + BaseOffset); + DeltaPosition = ConstrainDirectionToPlane(NewWorldPos - UpdatedComponent->GetComponentLocation()); + + // move attached actor + if (bFastAttachedMove) + { + // we're trusting no other obstacle can prevent the move here + UpdatedComponent->SetWorldLocationAndRotation(NewWorldPos, FinalQuat, false); + } + else + { + // Set MovementBase's root actor as ignored when moving the character primitive component, + // only perform if bDeferUpdateBasedMovement is true since this means the MovementBase is simulating physics + const bool bIgnoreBaseActor = bDeferUpdateBasedMovement && bBasedMovementIgnorePhysicsBase; + AActor* MovementBaseRootActor = nullptr; + if (bIgnoreBaseActor) + { + MovementBaseRootActor = MovementBase->GetAttachmentRootActor(); + UpdatedPrimitive->IgnoreActorWhenMoving(MovementBaseRootActor, true); + MoveComponentFlags |= MOVECOMP_CheckBlockingRootActorInIgnoreList; // Hit actors during MoveUpdatedComponent will have their root actor compared with the ignored actors array + } + + // hack - transforms between local and world space introducing slight error FIXMESTEVE - discuss with engine team: just skip the transforms if no rotation? + FVector BaseMoveDelta = NewBaseLocation - OldBaseLocation; + if (!bRotationChanged && (BaseMoveDelta.X == 0.f) && (BaseMoveDelta.Y == 0.f)) + { + DeltaPosition.X = 0.f; + DeltaPosition.Y = 0.f; + } + + FHitResult MoveOnBaseHit(1.f); + const FVector OldLocation = UpdatedComponent->GetComponentLocation(); + MoveUpdatedComponent(DeltaPosition, FinalQuat, true, &MoveOnBaseHit); + + if ((UpdatedComponent->GetComponentLocation() - (OldLocation + DeltaPosition)).IsNearlyZero() == false) + { + OnUnableToFollowBaseMove(DeltaPosition, OldLocation, MoveOnBaseHit); + } + + // Reset base actor ignore state + if (bIgnoreBaseActor) + { + MoveComponentFlags &= ~MOVECOMP_CheckBlockingRootActorInIgnoreList; + UpdatedPrimitive->IgnoreActorWhenMoving(MovementBaseRootActor, false); + } + } + + if (MovementBase->IsSimulatingPhysics() && CharacterOwner->GetMesh()) + { + CharacterOwner->GetMesh()->ApplyDeltaToAllPhysicsTransforms(DeltaPosition, DeltaQuat); + } + } + + + // Check if falling above current base + if (IsFalling() && bStayBasedInAir) + { + FVector PawnLocation = UpdatedComponent->GetComponentLocation(); + if (VRRootCapsule) + PawnLocation = VRRootCapsule->OffsetComponentToWorld.GetLocation(); + + FFindFloorResult OutFloorResult; + ComputeFloorDist(PawnLocation, StayBasedInAirHeight, StayBasedInAirHeight, OutFloorResult, CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleRadius(), NULL); + + UPrimitiveComponent* HitComponent = OutFloorResult.HitResult.Component.Get(); + if (!HitComponent || HitComponent->GetAttachmentRoot() != MovementBase->GetAttachmentRoot()) + { + // New or no base under the character + ApplyImpartedMovementBaseVelocity(); + SetBase(NULL); + return; + } + } +} + +FVector UVRCharacterMovementComponent::GetImpartedMovementBaseVelocity() const +{ + FVector Result = FVector::ZeroVector; + + if (CharacterOwner) + { + UPrimitiveComponent* MovementBase = CharacterOwner->GetMovementBase(); + if (MovementBaseUtility::IsDynamicBase(MovementBase)) + { + FVector BaseVelocity = MovementBaseUtility::GetMovementBaseVelocity(MovementBase, CharacterOwner->GetBasedMovement().BoneName); + + if (bImpartBaseAngularVelocity) + { + // Base position should be the bottom of the actor since I offset the capsule now + + float HalfHeight = CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleHalfHeight(); + if (!BaseVRCharacterOwner || BaseVRCharacterOwner->bRetainRoomscale) + { + HalfHeight = 0.0f; + } + + const FVector CharacterBasePosition = (UpdatedComponent->GetComponentLocation() - FVector(0.f, 0.f, HalfHeight)); + + + const FVector BaseTangentialVel = MovementBaseUtility::GetMovementBaseTangentialVelocity(MovementBase, CharacterOwner->GetBasedMovement().BoneName, CharacterBasePosition); + BaseVelocity += BaseTangentialVel; + } + + if (bImpartBaseVelocityX) + { + Result.X = BaseVelocity.X; + } + if (bImpartBaseVelocityY) + { + Result.Y = BaseVelocity.Y; + } + if (bImpartBaseVelocityZ) + { + Result.Z = BaseVelocity.Z; + } + } + } + + return Result; +} + + + +void UVRCharacterMovementComponent::FindFloor(const FVector& CapsuleLocation, FFindFloorResult& OutFloorResult, bool bCanUseCachedLocation, const FHitResult* DownwardSweepResult) const +{ + SCOPE_CYCLE_COUNTER(STAT_CharFindFloor); + //UE_LOG(LogVRCharacterMovement, Warning, TEXT("Find Floor")); + // No collision, no floor... + if (!HasValidData() || !UpdatedComponent->IsQueryCollisionEnabled()) + { + OutFloorResult.Clear(); + return; + } + + //UE_LOG(LogVRCharacterMovement, VeryVerbose, TEXT("[Role:%d] FindFloor: %s at location %s"), (int32)CharacterOwner->Role, *GetNameSafe(CharacterOwner), *CapsuleLocation.ToString()); + check(CharacterOwner->GetCapsuleComponent()); + + FVector UseCapsuleLocation = CapsuleLocation; + if (VRRootCapsule) + UseCapsuleLocation = VRRootCapsule->OffsetComponentToWorld.GetLocation(); + + // Increase height check slightly if walking, to prevent floor height adjustment from later invalidating the floor result. + const float HeightCheckAdjust = ((IsMovingOnGround() || IsClimbing()) ? MAX_FLOOR_DIST + UE_KINDA_SMALL_NUMBER : -MAX_FLOOR_DIST); + + float FloorSweepTraceDist = FMath::Max(MAX_FLOOR_DIST, MaxStepHeight + HeightCheckAdjust); + float FloorLineTraceDist = FloorSweepTraceDist; + bool bNeedToValidateFloor = true; + + // For reverting + FFindFloorResult LastFloor = CurrentFloor; + + // Sweep floor + if (FloorLineTraceDist > 0.f || FloorSweepTraceDist > 0.f) + { + UCharacterMovementComponent* MutableThis = const_cast((UCharacterMovementComponent*)this); + + if (bAlwaysCheckFloor || !bCanUseCachedLocation || bForceNextFloorCheck || bJustTeleported) + { + MutableThis->bForceNextFloorCheck = false; + ComputeFloorDist(UseCapsuleLocation, FloorLineTraceDist, FloorSweepTraceDist, OutFloorResult, CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleRadius(), DownwardSweepResult); + } + else + { + // Force floor check if base has collision disabled or if it does not block us. + UPrimitiveComponent* MovementBase = CharacterOwner->GetMovementBase(); + const AActor* BaseActor = MovementBase ? MovementBase->GetOwner() : NULL; + + const ECollisionChannel CollisionChannel = UpdatedComponent->GetCollisionObjectType(); + + if (MovementBase != NULL) + { + MutableThis->bForceNextFloorCheck = !MovementBase->IsQueryCollisionEnabled() + || MovementBase->GetCollisionResponseToChannel(CollisionChannel) != ECR_Block + || MovementBaseUtility::IsDynamicBase(MovementBase); + } + + const bool IsActorBasePendingKill = !IsValid(BaseActor); + + if (!bForceNextFloorCheck && !IsActorBasePendingKill && MovementBase) + { + //UE_LOG(LogVRCharacterMovement, Log, TEXT("%s SKIP check for floor"), *CharacterOwner->GetName()); + OutFloorResult = CurrentFloor; + bNeedToValidateFloor = false; + } + else + { + MutableThis->bForceNextFloorCheck = false; + ComputeFloorDist(UseCapsuleLocation, FloorLineTraceDist, FloorSweepTraceDist, OutFloorResult, CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleRadius(), DownwardSweepResult); + } + } + } + + // #TODO: Modify the floor compute floor distance instead? Or just run movement logic differently for the bWalkingCollisionOverride setup. + // #VR Specific - ignore floor traces that are negative, this can be caused by a failed floor check while starting in penetration + if (VRRootCapsule && VRRootCapsule->bUseWalkingCollisionOverride && OutFloorResult.bBlockingHit && OutFloorResult.FloorDist <= 0.0f) + { + + if (OutFloorResult.FloorDist <= -FMath::Max(MAX_FLOOR_DIST, CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleRadius())) + { + // This was a negative trace result, the game wants us to pull out of penetration + // But with walking collision override we don't want to do that, so check for the correct channel and throw away + // the new floor if it matches + ECollisionResponse FloorResponse; + if (OutFloorResult.HitResult.Component.IsValid()) + { + FloorResponse = OutFloorResult.HitResult.Component->GetCollisionResponseToChannel(VRRootCapsule->WalkingCollisionOverride); + if (FloorResponse == ECR_Ignore || FloorResponse == ECR_Overlap) + OutFloorResult = LastFloor; // Move back to the last floor value, we are in penetration with a walking override + } + } + } + + // OutFloorResult.HitResult is now the result of the vertical floor check. + // See if we should try to "perch" at this location. + if (bNeedToValidateFloor && OutFloorResult.bBlockingHit && !OutFloorResult.bLineTrace) + { + const bool bCheckRadius = true; + if (ShouldComputePerchResult(OutFloorResult.HitResult, bCheckRadius)) + { + float MaxPerchFloorDist = FMath::Max(MAX_FLOOR_DIST, MaxStepHeight + HeightCheckAdjust); + if (IsMovingOnGround() || IsClimbing()) + { + MaxPerchFloorDist += FMath::Max(0.f, PerchAdditionalHeight); + } + + FFindFloorResult PerchFloorResult; + if (ComputePerchResult(GetValidPerchRadius(), OutFloorResult.HitResult, MaxPerchFloorDist, PerchFloorResult)) + { + // Don't allow the floor distance adjustment to push us up too high, or we will move beyond the perch distance and fall next time. + const float AvgFloorDist = (MIN_FLOOR_DIST + MAX_FLOOR_DIST) * 0.5f; + const float MoveUpDist = (AvgFloorDist - OutFloorResult.FloorDist); + if (MoveUpDist + PerchFloorResult.FloorDist >= MaxPerchFloorDist) + { + OutFloorResult.FloorDist = AvgFloorDist; + } + + // If the regular capsule is on an unwalkable surface but the perched one would allow us to stand, override the normal to be one that is walkable. + if (!OutFloorResult.bWalkableFloor) + { + OutFloorResult.SetFromLineTrace(PerchFloorResult.HitResult, OutFloorResult.FloorDist, FMath::Max(OutFloorResult.FloorDist, MIN_FLOOR_DIST), true); + } + } + else + { + // We had no floor (or an invalid one because it was unwalkable), and couldn't perch here, so invalidate floor (which will cause us to start falling). + OutFloorResult.bWalkableFloor = false; + } + } + } +} + +float UVRCharacterMovementComponent::ImmersionDepth() const +{ + float depth = 0.f; + + if (CharacterOwner && GetPhysicsVolume()->bWaterVolume) + { + const float CollisionHalfHeight = CharacterOwner->GetSimpleCollisionHalfHeight(); + + if ((CollisionHalfHeight == 0.f) || (Buoyancy == 0.f)) + { + depth = 1.f; + } + else + { + UBrushComponent* VolumeBrushComp = GetPhysicsVolume()->GetBrushComponent(); + FHitResult Hit(1.f); + if (VolumeBrushComp) + { + FVector TraceStart; + FVector TraceEnd; + + if (VRRootCapsule) + { + TraceStart = VRRootCapsule->OffsetComponentToWorld.GetLocation() + FVector(0.f, 0.f, CollisionHalfHeight); + TraceEnd = VRRootCapsule->OffsetComponentToWorld.GetLocation() - FVector(0.f, 0.f, CollisionHalfHeight); + } + else + { + TraceStart = UpdatedComponent->GetComponentLocation() + FVector(0.f, 0.f, CollisionHalfHeight); + TraceEnd = UpdatedComponent->GetComponentLocation() -FVector(0.f, 0.f, CollisionHalfHeight); + } + + FCollisionQueryParams NewTraceParams(CharacterMovementComponentStatics::ImmersionDepthName, true); + VolumeBrushComp->LineTraceComponent(Hit, TraceStart, TraceEnd, NewTraceParams); + } + + depth = (Hit.Time == 1.f) ? 1.f : (1.f - Hit.Time); + } + } + return depth; +} + +/////////////////////////// +// Navigation Functions +/////////////////////////// + +bool UVRCharacterMovementComponent::TryToLeaveNavWalking() +{ + SetNavWalkingPhysics(false); + + bool bCanTeleport = true; + if (CharacterOwner) + { + FVector CollisionFreeLocation; + if (VRRootCapsule) + CollisionFreeLocation = VRRootCapsule->OffsetComponentToWorld.GetLocation(); + else + CollisionFreeLocation = UpdatedComponent->GetComponentLocation(); + + // Think I need to create a custom "FindTeleportSpot" function, it is using ComponentToWorld location + bCanTeleport = GetWorld()->FindTeleportSpot(CharacterOwner, CollisionFreeLocation, UpdatedComponent->GetComponentRotation()); + if (bCanTeleport) + { + + if (VRRootCapsule) + { + // Technically the same actor but i am keepign the usage convention for clarity. + // Subtracting actor location from capsule to get difference in worldspace, then removing from collision free location + // So that it uses the correct location. + CharacterOwner->SetActorLocation(CollisionFreeLocation - (VRRootCapsule->OffsetComponentToWorld.GetLocation() - UpdatedComponent->GetComponentLocation())); + } + else + CharacterOwner->SetActorLocation(CollisionFreeLocation); + } + else + { + SetNavWalkingPhysics(true); + } + } + + bWantsToLeaveNavWalking = !bCanTeleport; + return bCanTeleport; +} + +void UVRCharacterMovementComponent::PhysFlying(float deltaTime, int32 Iterations) +{ + if (deltaTime < MIN_TICK_TIME) + { + return; + } + + // Rewind the players position by the new capsule location + RewindVRRelativeMovement(); + + RestorePreAdditiveRootMotionVelocity(); + //RestorePreAdditiveVRMotionVelocity(); + + if (!HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity()) + { + if (bCheatFlying && Acceleration.IsZero()) + { + Velocity = FVector::ZeroVector; + } + const float Friction = 0.5f * GetPhysicsVolume()->FluidFriction; + CalcVelocity(deltaTime, Friction, true, GetMaxBrakingDeceleration()); + } + + ApplyRootMotionToVelocity(deltaTime); + //ApplyVRMotionToVelocity(deltaTime); + + // Manually handle the velocity setup + LastPreAdditiveVRVelocity = (AdditionalVRInputVector) / deltaTime; + bool bExtremeInput = false; + if (LastPreAdditiveVRVelocity.SizeSquared() > FMath::Square(TrackingLossThreshold)) + { + // Default to always holding position during flight to avoid too much velocity injection + AdditionalVRInputVector = FVector::ZeroVector; + LastPreAdditiveVRVelocity = FVector::ZeroVector; + } + + Iterations++; + bJustTeleported = false; + + FVector OldLocation = UpdatedComponent->GetComponentLocation(); + const FVector Adjusted = Velocity * deltaTime; + FHitResult Hit(1.f); + SafeMoveUpdatedComponent(Adjusted + AdditionalVRInputVector, UpdatedComponent->GetComponentQuat(), true, Hit); + + if (Hit.Time < 1.f) + { + const FVector GravDir = FVector(0.f, 0.f, -1.f); + const FVector VelDir = Velocity.GetSafeNormal(); + const float UpDown = GravDir | VelDir; + + bool bSteppedUp = false; + if ((FMath::Abs(Hit.ImpactNormal.Z) < 0.2f) && (UpDown < 0.5f) && (UpDown > -0.2f) && CanStepUp(Hit)) + { + float stepZ = UpdatedComponent->GetComponentLocation().Z; + bSteppedUp = StepUp(GravDir, (Adjusted + AdditionalVRInputVector) * (1.f - Hit.Time) /*+ AdditionalVRInputVector.GetSafeNormal2D()*/, Hit, nullptr); + if (bSteppedUp) + { + OldLocation.Z = UpdatedComponent->GetComponentLocation().Z + (OldLocation.Z - stepZ); + } + } + + if (!bSteppedUp) + { + //adjust and try again + HandleImpact(Hit, deltaTime, Adjusted); + SlideAlongSurface(Adjusted, (1.f - Hit.Time), Hit.Normal, Hit, true); + } + } + + if (!bJustTeleported) + { + if (!HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity()) + { + //Velocity = ((UpdatedComponent->GetComponentLocation() - OldLocation) - AdditionalVRInputVector) / deltaTime; + Velocity = ((UpdatedComponent->GetComponentLocation() - OldLocation)) / deltaTime; + } + + RestorePreAdditiveVRMotionVelocity(); + } +} + +void UVRCharacterMovementComponent::PhysFalling(float deltaTime, int32 Iterations) +{ + SCOPE_CYCLE_COUNTER(STAT_CharPhysFalling); + + if (deltaTime < MIN_TICK_TIME) + { + return; + } + + FVector FallAcceleration = GetFallingLateralAcceleration(deltaTime); + const FVector GravityRelativeFallAcceleration = RotateWorldToGravity(FallAcceleration); + FallAcceleration = RotateGravityToWorld(FVector(GravityRelativeFallAcceleration.X, GravityRelativeFallAcceleration.Y, 0)); + const bool bHasLimitedAirControl = ShouldLimitAirControl(deltaTime, FallAcceleration); + + // Rewind the players position by the new capsule location + RewindVRRelativeMovement(); + + float remainingTime = deltaTime; + while ((remainingTime >= MIN_TICK_TIME) && (Iterations < MaxSimulationIterations)) + { + Iterations++; + float timeTick = GetSimulationTimeStep(remainingTime, Iterations); + remainingTime -= timeTick; + + const FVector OldLocation = UpdatedComponent->GetComponentLocation(); + const FVector OldCapsuleLocation = VRRootCapsule ? VRRootCapsule->OffsetComponentToWorld.GetLocation() : OldLocation; + + const FQuat PawnRotation = UpdatedComponent->GetComponentQuat(); + bJustTeleported = false; + + const FVector OldVelocityWithRootMotion = Velocity; + + RestorePreAdditiveRootMotionVelocity(); + // RestorePreAdditiveVRMotionVelocity(); + + const FVector OldVelocity = Velocity; + + // Apply input + const float MaxDecel = GetMaxBrakingDeceleration(); + if (!HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity()) + { + // Compute Velocity + { + // Acceleration = FallAcceleration for CalcVelocity(), but we restore it after using it. + TGuardValue RestoreAcceleration(Acceleration, FallAcceleration); + if (HasCustomGravity()) + { + Velocity = FVector::VectorPlaneProject(Velocity, RotateGravityToWorld(FVector::UpVector)); + const FVector GravityRelativeOffset = OldVelocity - Velocity; + CalcVelocity(timeTick, FallingLateralFriction, false, MaxDecel); + Velocity += GravityRelativeOffset; + } + else + { + Velocity.Z = 0.f; + CalcVelocity(timeTick, FallingLateralFriction, false, MaxDecel); + Velocity.Z = OldVelocity.Z; + } + } + } + + //Velocity += CustomVRInputVector / deltaTime; + + // Compute current gravity + const FVector Gravity = -GetGravityDirection() * GetGravityZ(); + + float GravityTime = timeTick; + + // If jump is providing force, gravity may be affected. + bool bEndingJumpForce = false; + if (CharacterOwner->JumpForceTimeRemaining > 0.0f) + { + // Consume some of the force time. Only the remaining time (if any) is affected by gravity when bApplyGravityWhileJumping=false. + const float JumpForceTime = FMath::Min(CharacterOwner->JumpForceTimeRemaining, timeTick); + GravityTime = bApplyGravityWhileJumping ? timeTick : FMath::Max(0.0f, timeTick - JumpForceTime); + + // Update Character state + CharacterOwner->JumpForceTimeRemaining -= JumpForceTime; + if (CharacterOwner->JumpForceTimeRemaining <= 0.0f) + { + CharacterOwner->ResetJumpState(); + bEndingJumpForce = true; + } + } + + // Apply gravity + Velocity = NewFallVelocity(Velocity, Gravity, GravityTime); + + //UE_LOG(LogCharacterMovement, Log, TEXT("dt=(%.6f) OldLocation=(%s) OldVelocity=(%s) OldVelocityWithRootMotion=(%s) NewVelocity=(%s)"), timeTick, *(UpdatedComponent->GetComponentLocation()).ToString(), *OldVelocity.ToString(), *OldVelocityWithRootMotion.ToString(), *Velocity.ToString()); + ApplyRootMotionToVelocity(timeTick); + DecayFormerBaseVelocity(timeTick); + + // See if we need to sub-step to exactly reach the apex. This is important for avoiding "cutting off the top" of the trajectory as framerate varies. + const FVector GravityRelativeOldVelocityWithRootMotion = RotateWorldToGravity(OldVelocityWithRootMotion); + static const auto CVarForceJumpPeakSubstep = IConsoleManager::Get().FindConsoleVariable(TEXT("p.ForceJumpPeakSubstep")); + if (CVarForceJumpPeakSubstep->GetInt() != 0 && GravityRelativeOldVelocityWithRootMotion.Z > 0.f && RotateWorldToGravity(Velocity).Z <= 0.f && NumJumpApexAttempts < MaxJumpApexAttemptsPerSimulation) + { + const FVector DerivedAccel = (Velocity - OldVelocityWithRootMotion) / timeTick; + const FVector GravityRelativeDerivedAccel = RotateWorldToGravity(DerivedAccel); + if (!FMath::IsNearlyZero(GravityRelativeDerivedAccel.Z)) + { + const float TimeToApex = -GravityRelativeOldVelocityWithRootMotion.Z / GravityRelativeDerivedAccel.Z; + + // The time-to-apex calculation should be precise, and we want to avoid adding a substep when we are basically already at the apex from the previous iteration's work. + const float ApexTimeMinimum = 0.0001f; + if (TimeToApex >= ApexTimeMinimum && TimeToApex < timeTick) + { + const FVector ApexVelocity = OldVelocityWithRootMotion + (DerivedAccel * TimeToApex); + if (HasCustomGravity()) + { + const FVector GravityRelativeApexVelocity = RotateWorldToGravity(ApexVelocity); + Velocity = RotateGravityToWorld(FVector(GravityRelativeApexVelocity.X, GravityRelativeApexVelocity.Y, 0)); // Should be nearly zero anyway, but this makes apex notifications consistent. + } + else + { + Velocity = ApexVelocity; + Velocity.Z = 0.f; // Should be nearly zero anyway, but this makes apex notifications consistent. + + } + + // We only want to move the amount of time it takes to reach the apex, and refund the unused time for next iteration. + const float TimeToRefund = (timeTick - TimeToApex); + + remainingTime += TimeToRefund; + timeTick = TimeToApex; + Iterations--; + NumJumpApexAttempts++; + + // Refund time to any active Root Motion Sources as well + for (TSharedPtr RootMotionSource : CurrentRootMotion.RootMotionSources) + { + const float RewoundRMSTime = FMath::Max(0.0f, RootMotionSource->GetTime() - TimeToRefund); + RootMotionSource->SetTime(RewoundRMSTime); + } + } + } + } + + //UE_LOG(LogCharacterMovement, Log, TEXT("dt=(%.6f) OldLocation=(%s) OldVelocity=(%s) NewVelocity=(%s)"), timeTick, *(UpdatedComponent->GetComponentLocation()).ToString(), *OldVelocity.ToString(), *Velocity.ToString()); + + ApplyRootMotionToVelocity(timeTick); + //ApplyVRMotionToVelocity(deltaTime); + + if (bNotifyApex && (RotateWorldToGravity(Velocity).Z < 0.f)) + { + // Just passed jump apex since now going down + bNotifyApex = false; + NotifyJumpApex(); + } + + // Compute change in position (using midpoint integration method). + FVector Adjusted = (0.5f * (OldVelocityWithRootMotion + Velocity) * timeTick) + ((AdditionalVRInputVector / deltaTime) * timeTick); + + ApplyVRMotionToVelocity(deltaTime); + + // Special handling if ending the jump force where we didn't apply gravity during the jump. + if (bEndingJumpForce && !bApplyGravityWhileJumping) + { + // We had a portion of the time at constant speed then a portion with acceleration due to gravity. + // Account for that here with a more correct change in position. + const float NonGravityTime = FMath::Max(0.f, timeTick - GravityTime); + Adjusted = ((OldVelocityWithRootMotion * NonGravityTime) + (0.5f * (OldVelocityWithRootMotion + Velocity) * GravityTime)) /*+ ((AdditionalVRInputVector / deltaTime) * timeTick)*/; + } + + // Move + FHitResult Hit(1.f); + SafeMoveUpdatedComponent(Adjusted, PawnRotation, true, Hit); + + if (!HasValidData()) + { + RestorePreAdditiveVRMotionVelocity(); + return; + } + + float LastMoveTimeSlice = timeTick; + float subTimeTickRemaining = timeTick * (1.f - Hit.Time); + + if (IsSwimming()) //just entered water + { + RestorePreAdditiveVRMotionVelocity(); + remainingTime += subTimeTickRemaining; + StartSwimmingVR(OldCapsuleLocation, OldVelocity, timeTick, remainingTime, Iterations); + return; + } + else if (Hit.bBlockingHit) + { + if (IsValidLandingSpot(VRRootCapsule->OffsetComponentToWorld.GetLocation()/*UpdatedComponent->GetComponentLocation()*/, Hit)) + { + RestorePreAdditiveVRMotionVelocity(); + remainingTime += subTimeTickRemaining; + ProcessLanded(Hit, remainingTime, Iterations); + return; + } + else + { + // Compute impact deflection based on final velocity, not integration step. + // This allows us to compute a new velocity from the deflected vector, and ensures the full gravity effect is included in the slide result. + Adjusted = Velocity * timeTick; + + // See if we can convert a normally invalid landing spot (based on the hit result) to a usable one. + if (!Hit.bStartPenetrating && ShouldCheckForValidLandingSpot(timeTick, Adjusted, Hit)) + { + /*const */FVector PawnLocation = UpdatedComponent->GetComponentLocation(); + if (VRRootCapsule) + PawnLocation = VRRootCapsule->OffsetComponentToWorld.GetLocation(); + + FFindFloorResult FloorResult; + FindFloor(PawnLocation, FloorResult, false, NULL); + if (FloorResult.IsWalkableFloor() && IsValidLandingSpot(PawnLocation, FloorResult.HitResult)) + { + //RestorePreAdditiveVRMotionVelocity(); + remainingTime += subTimeTickRemaining; + ProcessLanded(FloorResult.HitResult, remainingTime, Iterations); + + if (bAutoOrientToFloorNormal && FloorResult.IsWalkableFloor()) + { + // Auto Align to the new floor normal + // Set gravity direction to the new floor normal + AutoTraceAndSetCharacterToNewGravity(FloorResult.HitResult, timeTick); + } + return; + } + } + + HandleImpact(Hit, LastMoveTimeSlice, Adjusted); + + // If we've changed physics mode, abort. + if (!HasValidData() || !IsFalling()) + { + RestorePreAdditiveVRMotionVelocity(); + return; + } + + // Limit air control based on what we hit. + // We moved to the impact point using air control, but may want to deflect from there based on a limited air control acceleration. + FVector VelocityNoAirControl = OldVelocity; + FVector AirControlAccel = Acceleration; + if (bHasLimitedAirControl) + { + // Compute VelocityNoAirControl + { + // Find velocity *without* acceleration. + TGuardValue RestoreAcceleration(Acceleration, FVector::ZeroVector); + TGuardValue RestoreVelocity(Velocity, OldVelocity); + if (HasCustomGravity()) + { + Velocity = FVector::VectorPlaneProject(Velocity, RotateGravityToWorld(FVector::UpVector)); + const FVector GravityRelativeOffset = OldVelocity - Velocity; + CalcVelocity(timeTick, FallingLateralFriction, false, MaxDecel); + VelocityNoAirControl = Velocity + GravityRelativeOffset; + } + else + { + Velocity.Z = 0.f; + CalcVelocity(timeTick, FallingLateralFriction, false, MaxDecel); + VelocityNoAirControl = FVector(Velocity.X, Velocity.Y, OldVelocity.Z); + } + VelocityNoAirControl = NewFallVelocity(VelocityNoAirControl, Gravity, GravityTime); + } + + const bool bCheckLandingSpot = false; // we already checked above. + AirControlAccel = (Velocity - VelocityNoAirControl) / timeTick; + const FVector AirControlDeltaV = LimitAirControl(LastMoveTimeSlice, AirControlAccel, Hit, bCheckLandingSpot) * LastMoveTimeSlice; + Adjusted = (VelocityNoAirControl + AirControlDeltaV) * LastMoveTimeSlice; + } + + const FVector OldHitNormal = Hit.Normal; + const FVector OldHitImpactNormal = Hit.ImpactNormal; + FVector Delta = ComputeSlideVector(Adjusted, 1.f - Hit.Time, OldHitNormal, Hit); + + // Compute velocity after deflection (only gravity component for RootMotion) + const UPrimitiveComponent* HitComponent = Hit.GetComponent(); + static const auto CVarUseTargetVelocityOnImpact = IConsoleManager::Get().FindConsoleVariable(TEXT("p.UseTargetVelocityOnImpact")); + if (CVarUseTargetVelocityOnImpact->GetInt() && !Velocity.IsNearlyZero() && MovementBaseUtility::IsSimulatedBase(HitComponent)) + { + const FVector ContactVelocity = MovementBaseUtility::GetMovementBaseVelocity(HitComponent, NAME_None) + MovementBaseUtility::GetMovementBaseTangentialVelocity(HitComponent, NAME_None, Hit.ImpactPoint); + const FVector NewVelocity = Velocity - Hit.ImpactNormal * FVector::DotProduct(Velocity - ContactVelocity, Hit.ImpactNormal); + Velocity = HasAnimRootMotion() || CurrentRootMotion.HasOverrideVelocityWithIgnoreZAccumulate() ? FVector(Velocity.X, Velocity.Y, NewVelocity.Z) : NewVelocity; + } + else if (subTimeTickRemaining > UE_KINDA_SMALL_NUMBER && !bJustTeleported) + { + const FVector NewVelocity = (Delta / subTimeTickRemaining); + Velocity = HasAnimRootMotion() || CurrentRootMotion.HasOverrideVelocityWithIgnoreZAccumulate() ? FVector(Velocity.X, Velocity.Y, NewVelocity.Z) : NewVelocity; + } + + if (subTimeTickRemaining > UE_KINDA_SMALL_NUMBER && (Delta | Adjusted) > 0.f) + { + // Move in deflected direction. + SafeMoveUpdatedComponent(Delta, PawnRotation, true, Hit); + + if (Hit.bBlockingHit) + { + // hit second wall + LastMoveTimeSlice = subTimeTickRemaining; + subTimeTickRemaining = subTimeTickRemaining * (1.f - Hit.Time); + + + if (IsValidLandingSpot(VRRootCapsule->OffsetComponentToWorld.GetLocation()/*UpdatedComponent->GetComponentLocation()*/, Hit)) + { + RestorePreAdditiveVRMotionVelocity(); + remainingTime += subTimeTickRemaining; + ProcessLanded(Hit, remainingTime, Iterations); + return; + } + + HandleImpact(Hit, LastMoveTimeSlice, Delta); + + // If we've changed physics mode, abort. + if (!HasValidData() || !IsFalling()) + { + RestorePreAdditiveVRMotionVelocity(); + return; + } + + // Act as if there was no air control on the last move when computing new deflection. + if (bHasLimitedAirControl && RotateWorldToGravity(Hit.Normal).Z > CharacterMovementConstants::VERTICAL_SLOPE_NORMAL_ZVR) + { + const FVector LastMoveNoAirControl = VelocityNoAirControl * LastMoveTimeSlice; + Delta = ComputeSlideVector(LastMoveNoAirControl, 1.f, OldHitNormal, Hit); + } + + FVector PreTwoWallDelta = Delta; + TwoWallAdjust(Delta, Hit, OldHitNormal); + + // Limit air control, but allow a slide along the second wall. + if (bHasLimitedAirControl) + { + const bool bCheckLandingSpot = false; // we already checked above. + const FVector AirControlDeltaV = LimitAirControl(subTimeTickRemaining, AirControlAccel, Hit, bCheckLandingSpot) * subTimeTickRemaining; + + // Only allow if not back in to first wall + if (FVector::DotProduct(AirControlDeltaV, OldHitNormal) > 0.f) + { + Delta += (AirControlDeltaV * subTimeTickRemaining); + } + } + + // Compute velocity after deflection (only gravity component for RootMotion) + if (subTimeTickRemaining > UE_KINDA_SMALL_NUMBER && !bJustTeleported) + { + const FVector NewVelocity = (Delta / subTimeTickRemaining); + Velocity = HasAnimRootMotion() || CurrentRootMotion.HasOverrideVelocityWithIgnoreZAccumulate() ? FVector(Velocity.X, Velocity.Y, NewVelocity.Z) : NewVelocity; + } + + // bDitch=true means that pawn is straddling two slopes, neither of which he can stand on + bool bDitch = ((RotateWorldToGravity(OldHitImpactNormal).Z > 0.f) && (RotateWorldToGravity(Hit.ImpactNormal).Z > 0.f) && (FMath::Abs(Delta.Z) <= UE_KINDA_SMALL_NUMBER) && ((Hit.ImpactNormal | OldHitImpactNormal) < 0.f)); + SafeMoveUpdatedComponent(Delta, PawnRotation, true, Hit); + if (Hit.Time == 0.f) + { + // if we are stuck then try to side step + FVector SideDelta = (OldHitNormal + Hit.ImpactNormal).GetSafeNormal2D(); + if (SideDelta.IsNearlyZero()) + { + SideDelta = FVector(OldHitNormal.Y, -OldHitNormal.X, 0).GetSafeNormal(); + } + SafeMoveUpdatedComponent(SideDelta, PawnRotation, true, Hit); + } + + if (bDitch || IsValidLandingSpot(VRRootCapsule->OffsetComponentToWorld.GetLocation()/*UpdatedComponent->GetComponentLocation()*/, Hit) || Hit.Time == 0.f) + { + RestorePreAdditiveVRMotionVelocity(); + remainingTime = 0.f; + ProcessLanded(Hit, remainingTime, Iterations); + return; + } + else if (GetPerchRadiusThreshold() > 0.f && Hit.Time == 1.f && RotateWorldToGravity(OldHitImpactNormal).Z >= GetWalkableFloorZ()) + { + // We might be in a virtual 'ditch' within our perch radius. This is rare. + const FVector PawnLocation = UpdatedComponent->GetComponentLocation(); + const float ZMovedDist = FMath::Abs(RotateWorldToGravity(PawnLocation - OldLocation).Z); + const float MovedDist2DSq = FVector::VectorPlaneProject(PawnLocation - OldLocation, RotateGravityToWorld(FVector::UpVector)).Size2D(); + if (ZMovedDist <= 0.2f * timeTick && MovedDist2DSq <= 4.f * timeTick) + { + FVector GravityRelativeVelocity = RotateWorldToGravity(Velocity); + GravityRelativeVelocity.X += 0.25f * GetMaxSpeed() * (RandomStream.FRand() - 0.5f); + GravityRelativeVelocity.Y += 0.25f * GetMaxSpeed() * (RandomStream.FRand() - 0.5f); + GravityRelativeVelocity.Z = FMath::Max(JumpZVelocity * 0.25f, 1.f); + Velocity = RotateGravityToWorld(GravityRelativeVelocity); + Delta = Velocity * timeTick; + SafeMoveUpdatedComponent(Delta, PawnRotation, true, Hit); + } + } + } + } + } + } + else + { + // We are finding the floor and adjusting here now + // This matches the final falling Z up to the PhysWalking floor offset to prevent the visible hitch when going + // From falling to walking. + FindFloor(UpdatedComponent->GetComponentLocation(), CurrentFloor, false, NULL); + + if (CurrentFloor.IsWalkableFloor()) + { + // If the current floor distance is within the physwalking required floor offset + if (CurrentFloor.GetDistanceToFloor() < (MIN_FLOOR_DIST + MAX_FLOOR_DIST) / 2) + { + // Adjust to correct height + AdjustFloorHeight(); + + SetBase(CurrentFloor.HitResult.Component.Get(), CurrentFloor.HitResult.BoneName); + + // If this is a valid landing spot, stop falling now so that we land correctly + if (IsValidLandingSpot(VRRootCapsule->OffsetComponentToWorld.GetLocation()/*UpdatedComponent->GetComponentLocation()*/, CurrentFloor.HitResult)) + { + remainingTime += subTimeTickRemaining; + ProcessLanded(CurrentFloor.HitResult, remainingTime, Iterations); + return; + } + } + } + else if (CurrentFloor.HitResult.bStartPenetrating) + { + // The floor check failed because it started in penetration + // We do not want to try to move downward because the downward sweep failed, rather we'd like to try to pop out of the floor. + FHitResult Hit2(CurrentFloor.HitResult); + Hit.TraceEnd = Hit2.TraceStart + RotateGravityToWorld(FVector(0.f, 0.f, MAX_FLOOR_DIST)); + const FVector RequestedAdjustment = GetPenetrationAdjustment(Hit2); + ResolvePenetration(RequestedAdjustment, Hit2, UpdatedComponent->GetComponentQuat()); + bForceNextFloorCheck = true; + } + + if (bAutoOrientToFloorNormal && CurrentFloor.IsWalkableFloor()) + { + // Auto Align to the new floor normal + // Set gravity direction to the new floor normal + AutoTraceAndSetCharacterToNewGravity(CurrentFloor.HitResult, timeTick); + } + } + + FVector GravityRelativeVelocity = RotateWorldToGravity(Velocity); + if (GravityRelativeVelocity.SizeSquared2D() <= UE_KINDA_SMALL_NUMBER * 10.f) + { + GravityRelativeVelocity.X = 0.f; + GravityRelativeVelocity.Y = 0.f; + Velocity = RotateGravityToWorld(GravityRelativeVelocity); + } + + RestorePreAdditiveVRMotionVelocity(); + } +} + + +void UVRCharacterMovementComponent::PhysNavWalking(float deltaTime, int32 Iterations) +{ + SCOPE_CYCLE_COUNTER(STAT_CharPhysNavWalking); + + if (deltaTime < MIN_TICK_TIME) + { + return; + } + + // Root motion not for VR + if ((!CharacterOwner || !CharacterOwner->Controller) && !bRunPhysicsWithNoController && !HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity()) + { + Acceleration = FVector::ZeroVector; + Velocity = FVector::ZeroVector; + return; + } + + const EMovementMode StartingMovementMode = MovementMode; + const uint8 StartingCustomMovementMode = CustomMovementMode; + + // Rewind the players position by the new capsule location + RewindVRRelativeMovement(); + + RestorePreAdditiveRootMotionVelocity(); + //RestorePreAdditiveVRMotionVelocity(); + + // Ensure velocity is horizontal. + MaintainHorizontalGroundVelocity(); + devCodeVR(ensureMsgf(!Velocity.ContainsNaN(), TEXT("PhysNavWalking: Velocity contains NaN before CalcVelocity (%s)\n%s"), *GetPathNameSafe(this), *Velocity.ToString())); + + //bound acceleration + Acceleration.Z = 0.f; + //if (!HasRootMotion()) + //{ + CalcVelocity(deltaTime, GroundFriction, false, BrakingDecelerationWalking); + devCodeVR(ensureMsgf(!Velocity.ContainsNaN(), TEXT("PhysNavWalking: Velocity contains NaN after CalcVelocity (%s)\n%s"), *GetPathNameSafe(this), *Velocity.ToString())); + //} + + ApplyRootMotionToVelocity(deltaTime); + ApplyVRMotionToVelocity(deltaTime); + + if (MovementMode != StartingMovementMode || CustomMovementMode != StartingCustomMovementMode) + { + // Root motion could have taken us out of our current mode + StartNewPhysics(deltaTime, Iterations); + return; + } + + Iterations++; + + FVector DesiredMove = Velocity; + DesiredMove.Z = 0.f; + + //const FVector OldPlayerLocation = GetActorFeetLocation(); + const FVector OldLocation = GetActorFeetLocationVR(); + const FVector DeltaMove = DesiredMove * deltaTime; + const bool bDeltaMoveNearlyZero = DeltaMove.IsNearlyZero(); + + FVector AdjustedDest = OldLocation + DeltaMove; + FNavLocation DestNavLocation; + + bool bSameNavLocation = false; + if (CachedNavLocation.NodeRef != INVALID_NAVNODEREF) + { + if (bProjectNavMeshWalking) + { + const float DistSq2D = (OldLocation - CachedNavLocation.Location).SizeSquared2D(); + const float DistZ = FMath::Abs(OldLocation.Z - CachedNavLocation.Location.Z); + + const float TotalCapsuleHeight = CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleHalfHeight() * 2.0f; + const float ProjectionScale = (OldLocation.Z > CachedNavLocation.Location.Z) ? NavMeshProjectionHeightScaleUp : NavMeshProjectionHeightScaleDown; + const float DistZThr = TotalCapsuleHeight * FMath::Max(0.f, ProjectionScale); + + bSameNavLocation = (DistSq2D <= UE_KINDA_SMALL_NUMBER) && (DistZ < DistZThr); + } + else + { + bSameNavLocation = CachedNavLocation.Location.Equals(OldLocation); + } + + if (bDeltaMoveNearlyZero && bSameNavLocation) + { + if (const INavigationDataInterface * NavData = GetNavData()) + { + if (!NavData->IsNodeRefValid(CachedNavLocation.NodeRef)) + { + CachedNavLocation.NodeRef = INVALID_NAVNODEREF; + bSameNavLocation = false; + } + } + } + } + + if (bDeltaMoveNearlyZero && bSameNavLocation) + { + DestNavLocation = CachedNavLocation; + UE_LOG(LogVRCharacterMovement, VeryVerbose, TEXT("%s using cached navmesh location! (bProjectNavMeshWalking = %d)"), *GetNameSafe(CharacterOwner), bProjectNavMeshWalking); + } + else + { + SCOPE_CYCLE_COUNTER(STAT_CharNavProjectPoint); + + // Start the trace from the Z location of the last valid trace. + // Otherwise if we are projecting our location to the underlying geometry and it's far above or below the navmesh, + // we'll follow that geometry's plane out of range of valid navigation. + if (bSameNavLocation && bProjectNavMeshWalking) + { + AdjustedDest.Z = CachedNavLocation.Location.Z; + } + + // Find the point on the NavMesh + const bool bHasNavigationData = FindNavFloor(AdjustedDest, DestNavLocation); + if (!bHasNavigationData) + { + RestorePreAdditiveVRMotionVelocity(); + SetMovementMode(MOVE_Walking); + return; + } + + CachedNavLocation = DestNavLocation; + } + + if (DestNavLocation.NodeRef != INVALID_NAVNODEREF) + { + FVector NewLocation(AdjustedDest.X, AdjustedDest.Y, DestNavLocation.Location.Z); + if (bProjectNavMeshWalking) + { + SCOPE_CYCLE_COUNTER(STAT_CharNavProjectLocation); + const float TotalCapsuleHeight = CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleHalfHeight() * 2.0f; + const float UpOffset = TotalCapsuleHeight * FMath::Max(0.f, NavMeshProjectionHeightScaleUp); + const float DownOffset = TotalCapsuleHeight * FMath::Max(0.f, NavMeshProjectionHeightScaleDown); + NewLocation = ProjectLocationFromNavMesh(deltaTime, OldLocation, NewLocation, UpOffset, DownOffset); + } + + FVector AdjustedDelta = NewLocation - OldLocation; + + if (!AdjustedDelta.IsNearlyZero()) + { + // 4.16 UNCOMMENT + FHitResult HitResult; + SafeMoveUpdatedComponent(AdjustedDelta, UpdatedComponent->GetComponentQuat(), bSweepWhileNavWalking, HitResult); + + /* 4.16 Delete*/ + //const bool bSweep = UpdatedPrimitive ? UpdatedPrimitive->bGenerateOverlapEvents : false; + //FHitResult HitResult; + //SafeMoveUpdatedComponent(AdjustedDelta, UpdatedComponent->GetComponentQuat(), bSweep, HitResult); + // End 4.16 delete + } + + // Update velocity to reflect actual move + if (!bJustTeleported && !HasAnimRootMotion() && !CurrentRootMotion.HasVelocity()) + { + Velocity = (GetActorFeetLocationVR() - OldLocation) / deltaTime; + MaintainHorizontalGroundVelocity(); + } + + bJustTeleported = false; + } + else + { + StartFalling(Iterations, deltaTime, deltaTime, DeltaMove, OldLocation); + } + + RestorePreAdditiveVRMotionVelocity(); +} + +void UVRCharacterMovementComponent::PhysSwimming(float deltaTime, int32 Iterations) +{ + if (deltaTime < MIN_TICK_TIME) + { + return; + } + + // Rewind the players position by the new capsule location + RewindVRRelativeMovement(); + + RestorePreAdditiveRootMotionVelocity(); + //RestorePreAdditiveVRMotionVelocity(); + + float NetFluidFriction = 0.f; + float Depth = ImmersionDepth(); + float NetBuoyancy = Buoyancy * Depth; + float OriginalAccelZ = Acceleration.Z; + bool bLimitedUpAccel = false; + + if (!HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity() && (Velocity.Z > 0.33f * MaxSwimSpeed) && (NetBuoyancy != 0.f)) + { + //damp positive Z out of water + Velocity.Z = FMath::Max(0.33f * MaxSwimSpeed, Velocity.Z * Depth * Depth); + } + else if (Depth < 0.65f) + { + bLimitedUpAccel = (Acceleration.Z > 0.f); + Acceleration.Z = FMath::Min(0.1f, Acceleration.Z); + } + + Iterations++; + FVector OldLocation = UpdatedComponent->GetComponentLocation(); + bJustTeleported = false; + if (!HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity()) + { + const float Friction = 0.5f * GetPhysicsVolume()->FluidFriction * Depth; + CalcVelocity(deltaTime, Friction, true, GetMaxBrakingDeceleration()); + Velocity.Z += GetGravityZ() * deltaTime * (1.f - NetBuoyancy); + } + + ApplyRootMotionToVelocity(deltaTime); + ApplyVRMotionToVelocity(deltaTime); + + FVector Adjusted = Velocity * deltaTime; + FHitResult Hit(1.f); + float remainingTime = deltaTime * SwimVR(Adjusted/* + AdditionalVRInputVector*/, Hit); + + //may have left water - if so, script might have set new physics mode + if (!IsSwimming()) + { + RestorePreAdditiveVRMotionVelocity(); + StartNewPhysics(remainingTime, Iterations); + return; + } + + if (Hit.Time < 1.f && CharacterOwner) + { + HandleSwimmingWallHit(Hit, deltaTime); + if (bLimitedUpAccel && (Velocity.Z >= 0.f)) + { + // allow upward velocity at surface if against obstacle + Velocity.Z += OriginalAccelZ * deltaTime; + Adjusted = Velocity * (1.f - Hit.Time)*deltaTime; + SwimVR(Adjusted, Hit); + if (!IsSwimming()) + { + RestorePreAdditiveVRMotionVelocity(); + StartNewPhysics(remainingTime, Iterations); + return; + } + } + + const FVector GravDir = FVector(0.f, 0.f, -1.f); + const FVector VelDir = Velocity.GetSafeNormal(); + const float UpDown = GravDir | VelDir; + + bool bSteppedUp = false; + if ((FMath::Abs(Hit.ImpactNormal.Z) < 0.2f) && (UpDown < 0.5f) && (UpDown > -0.2f) && CanStepUp(Hit)) + { + float stepZ = UpdatedComponent->GetComponentLocation().Z; + const FVector RealVelocity = Velocity; + Velocity.Z = 1.f; // HACK: since will be moving up, in case pawn leaves the water + bSteppedUp = StepUp(GravDir, (Adjusted/* + AdditionalVRInputVector*/) * (1.f - Hit.Time), Hit); + if (bSteppedUp) + { + //may have left water - if so, script might have set new physics mode + if (!IsSwimming()) + { + RestorePreAdditiveVRMotionVelocity(); + StartNewPhysics(remainingTime, Iterations); + return; + } + OldLocation.Z = UpdatedComponent->GetComponentLocation().Z + (OldLocation.Z - stepZ); + } + Velocity = RealVelocity; + } + + if (!bSteppedUp) + { + //adjust and try again + HandleImpact(Hit, deltaTime, Adjusted); + SlideAlongSurface(Adjusted, (1.f - Hit.Time), Hit.Normal, Hit, true); + } + } + + if (!HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity() && !bJustTeleported && ((deltaTime - remainingTime) > UE_KINDA_SMALL_NUMBER) && CharacterOwner) + { + bool bWaterJump = !GetPhysicsVolume()->bWaterVolume; + float velZ = Velocity.Z; + Velocity = ((UpdatedComponent->GetComponentLocation() - OldLocation)/* - AdditionalVRInputVector*/) / (deltaTime - remainingTime); + if (bWaterJump) + { + Velocity.Z = velZ; + } + } + + if (!GetPhysicsVolume()->bWaterVolume && IsSwimming()) + { + SetMovementMode(MOVE_Falling); //in case script didn't change it (w/ zone change) + } + + RestorePreAdditiveVRMotionVelocity(); + + //may have left water - if so, script might have set new physics mode + if (!IsSwimming()) + { + StartNewPhysics(remainingTime, Iterations); + } +} + + +void UVRCharacterMovementComponent::StartSwimmingVR(FVector OldLocation, FVector OldVelocity, float timeTick, float remainingTime, int32 Iterations) +{ + if (remainingTime < MIN_TICK_TIME || timeTick < MIN_TICK_TIME) + { + return; + } + + FVector NewLocation = VRRootCapsule ? VRRootCapsule->OffsetComponentToWorld.GetLocation() : UpdatedComponent->GetComponentLocation(); + + if (!HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity() && !bJustTeleported) + { + Velocity = (NewLocation - OldLocation) / timeTick; //actual average velocity + Velocity = 2.f*Velocity - OldVelocity; //end velocity has 2* accel of avg + Velocity = Velocity.GetClampedToMaxSize(GetPhysicsVolume()->TerminalVelocity); + } + const FVector End = FindWaterLine(NewLocation, OldLocation); + float waterTime = 0.f; + if (End != NewLocation) + { + const float ActualDist = (NewLocation - OldLocation).Size(); + if (ActualDist > UE_KINDA_SMALL_NUMBER) + { + waterTime = timeTick * (End - NewLocation).Size() / ActualDist; + remainingTime += waterTime; + } + MoveUpdatedComponent(End - NewLocation, UpdatedComponent->GetComponentQuat(), true); + } + if (!HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity() && (Velocity.Z > 2.f* CharacterMovementConstants::SWIMBOBSPEEDVR) && (Velocity.Z < 0.f)) //allow for falling out of water + { + Velocity.Z = CharacterMovementConstants::SWIMBOBSPEEDVR - Velocity.Size2D() * 0.7f; //smooth bobbing + } + if ((remainingTime >= MIN_TICK_TIME) && (Iterations < MaxSimulationIterations)) + { + PhysSwimming(remainingTime, Iterations); + } +} + +float UVRCharacterMovementComponent::SwimVR(FVector Delta, FHitResult& Hit) +{ + FVector Start = VRRootCapsule ? VRRootCapsule->OffsetComponentToWorld.GetLocation() : UpdatedComponent->GetComponentLocation(); + + float airTime = 0.f; + SafeMoveUpdatedComponent(Delta, UpdatedComponent->GetComponentQuat(), true, Hit); + + if (!GetPhysicsVolume()->bWaterVolume) //then left water + { + FVector NewLoc = VRRootCapsule ? VRRootCapsule->OffsetComponentToWorld.GetLocation() : UpdatedComponent->GetComponentLocation(); + + const FVector End = FindWaterLine(Start, NewLoc); + const float DesiredDist = Delta.Size(); + if (End != NewLoc && DesiredDist > UE_KINDA_SMALL_NUMBER) + { + airTime = (End - NewLoc).Size() / DesiredDist; + if (((NewLoc - Start) | (End - NewLoc)) > 0.f) + { + airTime = 0.f; + } + SafeMoveUpdatedComponent(End - NewLoc, UpdatedComponent->GetComponentQuat(), true, Hit); + } + } + return airTime; +} + +bool UVRCharacterMovementComponent::CheckWaterJump(FVector CheckPoint, FVector& WallNormal) +{ + if (!HasValidData()) + { + return false; + } + FVector currentLoc = VRRootCapsule ? VRRootCapsule->OffsetComponentToWorld.GetLocation() : UpdatedComponent->GetComponentLocation(); + + // check if there is a wall directly in front of the swimming pawn + CheckPoint.Z = 0.f; + FVector CheckNorm = CheckPoint.GetSafeNormal(); + float PawnCapsuleRadius, PawnCapsuleHalfHeight; + CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleSize(PawnCapsuleRadius, PawnCapsuleHalfHeight); + CheckPoint = currentLoc + 1.2f * PawnCapsuleRadius * CheckNorm; + FVector Extent(PawnCapsuleRadius, PawnCapsuleRadius, PawnCapsuleHalfHeight); + FHitResult HitInfo(1.f); + FCollisionQueryParams CapsuleParams(SCENE_QUERY_STAT(CheckWaterJump), false, CharacterOwner); + FCollisionResponseParams ResponseParam; + InitCollisionParams(CapsuleParams, ResponseParam); + FCollisionShape CapsuleShape = GetPawnCapsuleCollisionShape(SHRINK_None); + const ECollisionChannel CollisionChannel = UpdatedComponent->GetCollisionObjectType(); + bool bHit = GetWorld()->SweepSingleByChannel(HitInfo, currentLoc, CheckPoint, FQuat::Identity, CollisionChannel, CapsuleShape, CapsuleParams, ResponseParam); + + if (bHit && !HitInfo.HitObjectHandle.DoesRepresentClass(APawn::StaticClass())) + { + // hit a wall - check if it is low enough + WallNormal = -1.f * HitInfo.ImpactNormal; + FVector Start = currentLoc;//UpdatedComponent->GetComponentLocation(); + Start.Z += MaxOutOfWaterStepHeight; + CheckPoint = Start + 3.2f * PawnCapsuleRadius * WallNormal; + FCollisionQueryParams LineParams(SCENE_QUERY_STAT(CheckWaterJump), true, CharacterOwner); + FCollisionResponseParams LineResponseParam; + InitCollisionParams(LineParams, LineResponseParam); + bHit = GetWorld()->LineTraceSingleByChannel(HitInfo, Start, CheckPoint, CollisionChannel, LineParams, LineResponseParam); + // if no high obstruction, or it's a valid floor, then pawn can jump out of water + return !bHit || IsWalkable(HitInfo); + } + return false; +} + +FBasedPosition UVRCharacterMovementComponent::GetActorFeetLocationBased() const +{ + return FBasedPosition(NULL, GetActorFeetLocationVR()); +} + +void UVRCharacterMovementComponent::ProcessLanded(const FHitResult& Hit, float remainingTime, int32 Iterations) +{ + SCOPE_CYCLE_COUNTER(STAT_CharProcessLanded); + + if (CharacterOwner && CharacterOwner->ShouldNotifyLanded(Hit)) + { + CharacterOwner->Landed(Hit); + } + if (IsFalling()) + { + + if (GetGroundMovementMode() == MOVE_NavWalking) + { + // verify navmesh projection and current floor + // otherwise movement will be stuck in infinite loop: + // navwalking -> (no navmesh) -> falling -> (standing on something) -> navwalking -> .... + + const FVector TestLocation = GetActorFeetLocationVR(); + FNavLocation NavLocation; + + const bool bHasNavigationData = FindNavFloor(TestLocation, NavLocation); + if (!bHasNavigationData || NavLocation.NodeRef == INVALID_NAVNODEREF) + { + SetGroundMovementMode(MOVE_Walking); + //GroundMovementMode = MOVE_Walking; + UE_LOG(LogVRCharacterMovement, Verbose, TEXT("ProcessLanded(): %s tried to go to NavWalking but couldn't find NavMesh! Using Walking instead."), *GetNameSafe(CharacterOwner)); + } + } + + SetPostLandedPhysics(Hit); + } + + IPathFollowingAgentInterface* PFAgent = GetPathFollowingAgent(); + if (PFAgent) + { + PFAgent->OnLanded(); + } + + StartNewPhysics(remainingTime, Iterations); +} + +/////////////////////////// +// End Navigation Functions +/////////////////////////// + +void UVRCharacterMovementComponent::PostPhysicsTickComponent(float DeltaTime, FCharacterMovementComponentPostPhysicsTickFunction& ThisTickFunction) +{ + if (bDeferUpdateBasedMovement) + { + FVRCharacterScopedMovementUpdate ScopedMovementUpdate(UpdatedComponent, bEnableScopedMovementUpdates ? EScopedUpdate::DeferredUpdates : EScopedUpdate::ImmediateUpdates); + UpdateBasedMovement(DeltaTime); + SaveBaseLocation(); + bDeferUpdateBasedMovement = false; + } +} + + +void UVRCharacterMovementComponent::SimulateMovement(float DeltaSeconds) +{ + if (!HasValidData() || UpdatedComponent->Mobility != EComponentMobility::Movable || UpdatedComponent->IsSimulatingPhysics()) + { + return; + } + + const bool bIsSimulatedProxy = (CharacterOwner->GetLocalRole() == ROLE_SimulatedProxy); + const FRepMovement& ConstRepMovement = CharacterOwner->GetReplicatedMovement(); + + // Workaround for replication not being updated initially + if (bIsSimulatedProxy && + ConstRepMovement.Location.IsZero() && + ConstRepMovement.Rotation.IsZero() && + ConstRepMovement.LinearVelocity.IsZero()) + { + return; + } + + // If base is not resolved on the client, we should not try to simulate at all + if (CharacterOwner->GetReplicatedBasedMovement().IsBaseUnresolved()) + { + UE_LOG(LogVRCharacterMovement, Verbose, TEXT("Base for simulated character '%s' is not resolved on client, skipping SimulateMovement"), *CharacterOwner->GetName()); + return; + } + + FVector OldVelocity; + FVector OldLocation; + + // Scoped updates can improve performance of multiple MoveComponent calls. + { + FVRCharacterScopedMovementUpdate ScopedMovementUpdate(UpdatedComponent, bEnableScopedMovementUpdates ? EScopedUpdate::DeferredUpdates : EScopedUpdate::ImmediateUpdates); + + bool bHandledNetUpdate = false; + if (bIsSimulatedProxy) + { + // Handle network changes + if (bNetworkUpdateReceived) + { + bNetworkUpdateReceived = false; + bHandledNetUpdate = true; + UE_LOG(LogVRCharacterMovement, Verbose, TEXT("Proxy %s received net update"), *GetNameSafe(CharacterOwner)); + if (bNetworkGravityDirectionChanged) + { + SetGravityDirection(CharacterOwner->GetReplicatedGravityDirection()); + bNetworkGravityDirectionChanged = false; + } + + if (bNetworkMovementModeChanged) + { + ApplyNetworkMovementMode(CharacterOwner->GetReplicatedMovementMode()); + bNetworkMovementModeChanged = false; + } + else if (bJustTeleported || bForceNextFloorCheck) + { + // Make sure floor is current. We will continue using the replicated base, if there was one. + bJustTeleported = false; + UpdateFloorFromAdjustment(); + } + } + else if (bForceNextFloorCheck) + { + UpdateFloorFromAdjustment(); + } + } + + UpdateCharacterStateBeforeMovement(DeltaSeconds); + + if (MovementMode != MOVE_None) + { + //TODO: Also ApplyAccumulatedForces()? + HandlePendingLaunch(); + } + ClearAccumulatedForces(); + + if (MovementMode == MOVE_None) + { + return; + } + + const bool bSimGravityDisabled = (bIsSimulatedProxy && CharacterOwner->bSimGravityDisabled); + const bool bZeroReplicatedGroundVelocity = (bIsSimulatedProxy && IsMovingOnGround() && ConstRepMovement.LinearVelocity.IsZero()); + + // bSimGravityDisabled means velocity was zero when replicated and we were stuck in something. Avoid external changes in velocity as well. + // Being in ground movement with zero velocity, we cannot simulate proxy velocities safely because we might not get any further updates from the server. + if (bSimGravityDisabled || bZeroReplicatedGroundVelocity) + { + Velocity = FVector::ZeroVector; + } + + + MaybeUpdateBasedMovement(DeltaSeconds); + + // simulated pawns predict location + OldVelocity = Velocity; + OldLocation = UpdatedComponent->GetComponentLocation(); + + UpdateProxyAcceleration(); + + static const auto CVarNetEnableSkipProxyPredictionOnNetUpdate = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetEnableSkipProxyPredictionOnNetUpdate")); + // May only need to simulate forward on frames where we haven't just received a new position update. + if (!bHandledNetUpdate || !bNetworkSkipProxyPredictionOnNetUpdate || !CVarNetEnableSkipProxyPredictionOnNetUpdate->GetInt()) + { + UE_LOG(LogVRCharacterMovement, Verbose, TEXT("Proxy %s simulating movement"), *GetNameSafe(CharacterOwner)); + FStepDownResult StepDownResult; + + // Skip the estimated movement when movement simulation is off, but keep the floor find + if(!bDisableSimulatedTickWhenSmoothingMovement) + { + MoveSmooth(Velocity, DeltaSeconds, &StepDownResult); + } + + // find floor and check if falling + if (IsMovingOnGround() || MovementMode == MOVE_Falling) + { + bool bShouldFindFloor = Velocity.Z <= 0.f; + if (HasCustomGravity()) + { + bShouldFindFloor = RotateWorldToGravity(Velocity).Z <= 0.0; + } + + if (StepDownResult.bComputedFloor) + { + CurrentFloor = StepDownResult.FloorResult; + } + else if (bDisableSimulatedTickWhenSmoothingMovement || bShouldFindFloor) + { + FindFloor(UpdatedComponent->GetComponentLocation(), CurrentFloor, Velocity.IsZero(), NULL); + } + else + { + CurrentFloor.Clear(); + } + + // Possible for dynamic movement bases, particularly those that align to slopes while the character does not, to encroach the character. + // Check to see if we can resolve the penetration in those cases, and if so find the floor. + if (CurrentFloor.HitResult.bStartPenetrating && MovementBaseUtility::IsDynamicBase(GetMovementBase())) + { + // Follows PhysWalking approach for encroachment on floor tests + FHitResult Hit(CurrentFloor.HitResult); + if (HasCustomGravity()) + { + Hit.TraceEnd = Hit.TraceStart - GetGravityDirection() * MAX_FLOOR_DIST; + } + else + { + Hit.TraceEnd = Hit.TraceStart + FVector(0.f, 0.f, MAX_FLOOR_DIST); + } + + const FVector RequestedAdjustment = GetPenetrationAdjustment(Hit); + const bool bResolved = ResolvePenetration(RequestedAdjustment, Hit, UpdatedComponent->GetComponentQuat()); + bForceNextFloorCheck |= bResolved; + + if (bAutoOrientToFloorNormal && CurrentFloor.IsWalkableFloor()) + { + // Auto Align to the new floor normal + // Set gravity direction to the new floor normal + AutoTraceAndSetCharacterToNewGravity(CurrentFloor.HitResult, DeltaSeconds); + } + } + else if (!CurrentFloor.IsWalkableFloor()) + { + if (!bSimGravityDisabled) + { + // No floor, must fall. + if (HasCustomGravity()) + { + if (RotateWorldToGravity(Velocity).Z <= 0.f || bApplyGravityWhileJumping || !CharacterOwner->IsJumpProvidingForce()) + { + Velocity = NewFallVelocity(Velocity, -GetGravityDirection() * GetGravityZ(), DeltaSeconds); + } + } + else if (Velocity.Z <= 0.f || bApplyGravityWhileJumping || !CharacterOwner->IsJumpProvidingForce()) + { + Velocity = NewFallVelocity(Velocity, FVector(0.f, 0.f, GetGravityZ()), DeltaSeconds); + } + } + + SetMovementMode(MOVE_Falling); + } + else + { + // Walkable floor + if (IsMovingOnGround()) + { + AdjustFloorHeight(); + SetBase(CurrentFloor.HitResult.Component.Get(), CurrentFloor.HitResult.BoneName); + } + else if (MovementMode == MOVE_Falling) + { + if (CurrentFloor.FloorDist <= MIN_FLOOR_DIST || (bSimGravityDisabled && CurrentFloor.FloorDist <= MAX_FLOOR_DIST)) + { + // Landed + SetPostLandedPhysics(CurrentFloor.HitResult); + } + else + { + if (!bSimGravityDisabled) + { + // Continue falling. + Velocity = NewFallVelocity(Velocity, -GetGravityDirection() * GetGravityZ(), DeltaSeconds); + } + CurrentFloor.Clear(); + } + } + + if (bAutoOrientToFloorNormal && CurrentFloor.IsWalkableFloor()) + { + // Auto Align to the new floor normal + // Set gravity direction to the new floor normal + AutoTraceAndSetCharacterToNewGravity(CurrentFloor.HitResult, DeltaSeconds); + } + } + } + } + else + { + UE_LOG(LogVRCharacterMovement, Verbose, TEXT("Proxy %s SKIPPING simulate movement"), *GetNameSafe(CharacterOwner)); + } + + UpdateCharacterStateAfterMovement(DeltaSeconds); + + // consume path following requested velocity + LastUpdateRequestedVelocity = bHasRequestedVelocity ? RequestedVelocity : FVector::ZeroVector; + bHasRequestedVelocity = false; + + OnMovementUpdated(DeltaSeconds, OldLocation, OldVelocity); + } // End scoped movement update + + // Call custom post-movement events. These happen after the scoped movement completes in case the events want to use the current state of overlaps etc. + CallMovementUpdateDelegate(DeltaSeconds, OldLocation, OldVelocity); + + static const auto CVarBasedMovementMode = IConsoleManager::Get().FindConsoleVariable(TEXT("p.BasedMovementMode")); + if (CVarBasedMovementMode->GetInt() == 0) + { + SaveBaseLocation(); // behaviour before implementing this fix + } + else + { + MaybeSaveBaseLocation(); + } + + UpdateComponentVelocity(); + bJustTeleported = false; + + LastUpdateLocation = UpdatedComponent ? UpdatedComponent->GetComponentLocation() : FVector::ZeroVector; + LastUpdateRotation = UpdatedComponent ? UpdatedComponent->GetComponentQuat() : FQuat::Identity; + LastUpdateVelocity = Velocity; +} + +void UVRCharacterMovementComponent::MoveSmooth(const FVector& InVelocity, const float DeltaSeconds, FStepDownResult* OutStepDownResult) +{ + if (!HasValidData()) + { + return; + } + + // Custom movement mode. + // Custom movement may need an update even if there is zero velocity. + if (MovementMode == MOVE_Custom) + { + FVRCharacterScopedMovementUpdate ScopedMovementUpdate(UpdatedComponent, bEnableScopedMovementUpdates ? EScopedUpdate::DeferredUpdates : EScopedUpdate::ImmediateUpdates); + PhysCustom(DeltaSeconds, 0); + return; + } + + FVector Delta = InVelocity * DeltaSeconds; + if (Delta.IsZero()) + { + return; + } + + FVRCharacterScopedMovementUpdate ScopedMovementUpdate(UpdatedComponent, bEnableScopedMovementUpdates ? EScopedUpdate::DeferredUpdates : EScopedUpdate::ImmediateUpdates); + + if (IsMovingOnGround()) + { + MoveAlongFloor(InVelocity, DeltaSeconds, OutStepDownResult); + } + else + { + FHitResult Hit(1.f); + SafeMoveUpdatedComponent(Delta, UpdatedComponent->GetComponentQuat(), true, Hit); + + if (Hit.IsValidBlockingHit()) + { + bool bSteppedUp = false; + + if (IsFlying()) + { + if (CanStepUp(Hit)) + { + OutStepDownResult = NULL; // No need for a floor when not walking. + bool bShouldAttemptStepUp = false; + bShouldAttemptStepUp = FMath::Abs(RotateWorldToGravity(Hit.ImpactNormal).Z) < 0.2; + if (bShouldAttemptStepUp) + { + const FVector GravDir = GetGravityDirection(); + const FVector DesiredDir = Delta.GetSafeNormal(); + const float UpDown = GravDir | DesiredDir; + if ((UpDown < 0.5f) && (UpDown > -0.2f)) + { + bSteppedUp = StepUp(GravDir, Delta * (1.f - Hit.Time), Hit, OutStepDownResult); + } + } + } + } + + // If StepUp failed, try sliding. + if (!bSteppedUp) + { + SlideAlongSurface(Delta, 1.f - Hit.Time, Hit.Normal, Hit, false); + } + } + } +} + +void UVRCharacterMovementComponent::ClientHandleMoveResponse(const FCharacterMoveResponseDataContainer& MoveResponse) +{ + if (MoveResponse.IsGoodMove()) + { + ClientAckGoodMove_Implementation(MoveResponse.ClientAdjustment.TimeStamp); + } + else + { + // Wrappers to old RPC handlers, to maintain compatibility. If overrides need additional serialized data, they can access GetMoveResponseDataContainer() + if (MoveResponse.bRootMotionSourceCorrection) + { + if (FRootMotionSourceGroup* RootMotionSourceGroup = MoveResponse.GetRootMotionSourceGroup(*this)) + { + ClientAdjustRootMotionSourcePosition_Implementation( + MoveResponse.ClientAdjustment.TimeStamp, + *RootMotionSourceGroup, + MoveResponse.bRootMotionMontageCorrection, + MoveResponse.RootMotionTrackPosition, + MoveResponse.ClientAdjustment.NewLoc, + MoveResponse.RootMotionRotation, + MoveResponse.ClientAdjustment.NewVel.Z, + MoveResponse.ClientAdjustment.NewBase, + MoveResponse.ClientAdjustment.NewBaseBoneName, + MoveResponse.bHasBase, + MoveResponse.ClientAdjustment.bBaseRelativePosition, + MoveResponse.ClientAdjustment.MovementMode); + } + } + else if (MoveResponse.bRootMotionMontageCorrection) + { + ClientAdjustRootMotionPosition_Implementation( + MoveResponse.ClientAdjustment.TimeStamp, + MoveResponse.RootMotionTrackPosition, + MoveResponse.ClientAdjustment.NewLoc, + MoveResponse.RootMotionRotation, + MoveResponse.ClientAdjustment.NewVel.Z, + MoveResponse.ClientAdjustment.NewBase, + MoveResponse.ClientAdjustment.NewBaseBoneName, + MoveResponse.bHasBase, + MoveResponse.ClientAdjustment.bBaseRelativePosition, + MoveResponse.ClientAdjustment.MovementMode); + } + else + { + ClientAdjustPositionVR_Implementation( + MoveResponse.ClientAdjustment.TimeStamp, + MoveResponse.ClientAdjustment.NewLoc, + //FRotator::CompressAxisToShort(MoveResponse.ClientAdjustment.NewRot.Yaw), + MoveResponse.ClientAdjustment.NewVel, + MoveResponse.ClientAdjustment.NewBase, + MoveResponse.ClientAdjustment.NewBaseBoneName, + MoveResponse.bHasBase, + MoveResponse.ClientAdjustment.bBaseRelativePosition, + MoveResponse.ClientAdjustment.MovementMode, + MoveResponse.bHasRotation ? MoveResponse.ClientAdjustment.NewRot : TOptional(), + MoveResponse.ClientAdjustment.GravityDirection + ); + + // #TODO: Epic added rotation adjustment in 5.1 + //MoveResponse.bHasRotation ? MoveResponse.ClientAdjustment.NewRot : TOptional() + } + } +} + +// #TODO: Epic added their own rotation correct in 5.1 +//TOptional OptionalRotation /* = TOptional()*/ +void UVRCharacterMovementComponent::ClientAdjustPositionVR_Implementation +( + float TimeStamp, + FVector NewLocation, + //uint16 NewYaw, + FVector NewVelocity, + UPrimitiveComponent* NewBase, + FName NewBaseBoneName, + bool bHasBase, + bool bBaseRelativePosition, + uint8 ServerMovementMode, + TOptional OptionalRotation, + TOptional OptionalGravityDirection +) +{ + if (!HasValidData() || !IsActive()) + { + return; + } + + + FNetworkPredictionData_Client_Character* ClientData = GetPredictionData_Client_Character(); + check(ClientData); + + // Make sure the base actor exists on this client. + const bool bUnresolvedBase = bHasBase && (NewBase == NULL); + if (bUnresolvedBase) + { + if (bBaseRelativePosition) + { + UE_LOG(LogNetPlayerMovement, Warning, TEXT("ClientAdjustPosition_Implementation could not resolve the new relative movement base actor, ignoring server correction! Client currently at world location %s on base %s"), + *UpdatedComponent->GetComponentLocation().ToString(), *GetNameSafe(GetMovementBase())); + return; + } + else + { + UE_LOG(LogNetPlayerMovement, Verbose, TEXT("ClientAdjustPosition_Implementation could not resolve the new absolute movement base actor, but WILL use the position!")); + } + } + + // Ack move if it has not expired. + int32 MoveIndex = ClientData->GetSavedMoveIndex(TimeStamp); + if (MoveIndex == INDEX_NONE) + { + if (ClientData->LastAckedMove.IsValid()) + { + UE_LOG(LogNetPlayerMovement, Log, TEXT("ClientAdjustPosition_Implementation could not find Move for TimeStamp: %f, LastAckedTimeStamp: %f, CurrentTimeStamp: %f"), TimeStamp, ClientData->LastAckedMove->TimeStamp, ClientData->CurrentTimeStamp); + } + return; + } + + // Trying to use epics rotation code now + // Comment this when we port to it + /*if (!bUseClientControlRotation) + { + float YawValue = FRotator::DecompressAxisFromShort(NewYaw); + // Trust the server's control yaw + if (ClientData->LastAckedMove.IsValid() && !FMath::IsNearlyEqual(ClientData->LastAckedMove->SavedControlRotation.Yaw, YawValue)) + { + if (BaseVRCharacterOwner) + { + if (BaseVRCharacterOwner->bUseControllerRotationYaw) + { + AController * myController = BaseVRCharacterOwner->GetController(); + if (myController) + { + //FRotator newRot = myController->GetControlRotation(); + myController->SetControlRotation(FRotator(0.f, YawValue, 0.f));//(ClientData->LastAckedMove->SavedControlRotation); + } + } + + BaseVRCharacterOwner->SetActorRotation(FRotator(0.f, YawValue, 0.f)); + } + } + }*/ + + ClientData->AckMove(MoveIndex, *this); + + FVector WorldShiftedNewLocation; + // Received Location is relative to dynamic base + if (bBaseRelativePosition) + { + MovementBaseUtility::TransformLocationToWorld(NewBase, NewBaseBoneName, NewLocation, WorldShiftedNewLocation); // TODO: error handling if returns false + } + else + { + WorldShiftedNewLocation = FRepMovement::RebaseOntoLocalOrigin(NewLocation, this); + } + + // Server's world velocity may need to be converted to velocity relative to the movement base orientation, if the base orientations don't match. + const FCharacterMoveResponseDataContainer& ResponseDataContainer = GetMoveResponseDataContainer(); + if (ResponseDataContainer.ClientAdjustment.bBaseRelativeVelocity) + { + // Convert Relative Velocity -> World Velocity + const FVector CurrentVelocity = NewVelocity; + MovementBaseUtility::TransformDirectionToWorld(NewBase, NewBaseBoneName, CurrentVelocity, NewVelocity); + } + + + // #TODO: Epics 5.1 rotation enforce, we use our own currently + + // Fall back to the last-known good rotation if the server didn't send one + /*static const auto CVarUseLastGoodRotationDuringCorrection = IConsoleManager::Get().FindConsoleVariable(TEXT("p.UseLastGoodRotationDuringCorrection")); + if (CVarUseLastGoodRotationDuringCorrection->GetInt() + && (bOrientRotationToMovement || bUseControllerDesiredRotation) + && (!OptionalRotation.IsSet() && ClientData->LastAckedMove.IsValid())) + { + OptionalRotation = ClientData->LastAckedMove->SavedRotation; + }*/ + + // #TODO: Currently epic isn't using the gravity direction in corrections, which should be incorrect + // Trigger event + FVector GravityCorrection = OptionalGravityDirection.IsSet() ? OptionalGravityDirection.GetValue() : DefaultGravityDirection; + OnClientCorrectionReceived(*ClientData, TimeStamp, WorldShiftedNewLocation, NewVelocity, NewBase, NewBaseBoneName, bHasBase, bBaseRelativePosition, ServerMovementMode, GravityCorrection); + + // Trust the server's positioning. + if (UpdatedComponent) + { + // Orient to new gravity value + SetCharacterToNewGravity(GravityCorrection, bAutoOrientToFloorNormal); + + // #TODO: Epics 5.1 rotation enforce, we use our own currently + /*if (OptionalRotation.IsSet()) + { + UpdatedComponent->SetWorldLocationAndRotation(WorldShiftedNewLocation, OptionalRotation.GetValue(), false, nullptr, ETeleportType::TeleportPhysics); + } + else + { + UpdatedComponent->SetWorldLocation(WorldShiftedNewLocation, false, nullptr, ETeleportType::TeleportPhysics); + }*/ + + if (bRunClientCorrectionToHMD && BaseVRCharacterOwner) + { + if (OptionalRotation.IsSet()) + { + BaseVRCharacterOwner->SetActorLocationAndRotationVR(WorldShiftedNewLocation, OptionalRotation.GetValue(), false, false, true, true); + //BaseVRCharacterOwner->SetActorRotation(OptionalRotation.GetValue(), ETeleportType::TeleportPhysics); + + // Trust the server's control yaw + if (ClientData->LastAckedMove.IsValid() && !ClientData->LastAckedMove->SavedControlRotation.Equals(OptionalRotation.GetValue())) + { + if (BaseVRCharacterOwner) + { + if (BaseVRCharacterOwner->bUseControllerRotationYaw) + { + AController* myController = BaseVRCharacterOwner->GetController(); + if (myController) + { + //FRotator newRot = myController->GetControlRotation(); + myController->SetControlRotation(OptionalRotation.GetValue());//(ClientData->LastAckedMove->SavedControlRotation); + } + } + } + } + + } + else + { + BaseVRCharacterOwner->SetActorLocationVR(WorldShiftedNewLocation, true); + } + } + else + { + if (OptionalRotation.IsSet()) + { + UpdatedComponent->SetWorldLocationAndRotation(WorldShiftedNewLocation, OptionalRotation.GetValue(), false, nullptr, ETeleportType::TeleportPhysics); + + // Trust the server's control yaw + if (ClientData->LastAckedMove.IsValid() && !ClientData->LastAckedMove->SavedControlRotation.Equals(OptionalRotation.GetValue())) + { + if (BaseVRCharacterOwner) + { + if (BaseVRCharacterOwner->bUseControllerRotationYaw) + { + AController* myController = BaseVRCharacterOwner->GetController(); + if (myController) + { + //FRotator newRot = myController->GetControlRotation(); + myController->SetControlRotation(OptionalRotation.GetValue());//(ClientData->LastAckedMove->SavedControlRotation); + } + } + } + } + } + else + { + UpdatedComponent->SetWorldLocation(WorldShiftedNewLocation, false, nullptr, ETeleportType::TeleportPhysics); + } + } + } + + Velocity = NewVelocity; + + // Trust the server's movement mode + UPrimitiveComponent* PreviousBase = CharacterOwner->GetMovementBase(); + ApplyNetworkMovementMode(ServerMovementMode); + + // Set base component + UPrimitiveComponent* FinalBase = NewBase; + FName FinalBaseBoneName = NewBaseBoneName; + if (bUnresolvedBase) + { + check(NewBase == NULL); + check(!bBaseRelativePosition); + + // We had an unresolved base from the server + // If walking, we'd like to continue walking if possible, to avoid falling for a frame, so try to find a base where we moved to. + if (PreviousBase && UpdatedComponent) + { + FindFloor(UpdatedComponent->GetComponentLocation(), CurrentFloor, false); + if (CurrentFloor.IsWalkableFloor()) + { + FinalBase = CurrentFloor.HitResult.Component.Get(); + FinalBaseBoneName = CurrentFloor.HitResult.BoneName; + } + else + { + FinalBase = nullptr; + FinalBaseBoneName = NAME_None; + } + + /*if (bAutoOrientToFloorNormal && CurrentFloor.IsWalkableFloor()) + { + // Auto Align to the new floor normal + // Set gravity direction to the new floor normal, snap to new rotation on correction + // #TODO: Might need to entirely remove this and let the correction set everything? + AutoTraceAndSetCharacterToNewGravity(CurrentFloor.HitResult); + }*/ + } + } + SetBase(FinalBase, FinalBaseBoneName); + + // Update floor at new location + UpdateFloorFromAdjustment(); + bJustTeleported = true; + + // Even if base has not changed, we need to recompute the relative offsets (since we've moved). + SaveBaseLocation(); + + LastUpdateLocation = UpdatedComponent ? UpdatedComponent->GetComponentLocation() : FVector::ZeroVector; + LastUpdateRotation = UpdatedComponent ? UpdatedComponent->GetComponentQuat() : FQuat::Identity; + LastUpdateVelocity = Velocity; + + UpdateComponentVelocity(); + ClientData->bUpdatePosition = true; +} + +bool UVRCharacterMovementComponent::ServerCheckClientErrorVR(float ClientTimeStamp, float DeltaTime, const FVector& Accel, const FVector& ClientWorldLocation, FRotator ClientRot, const FVector& RelativeClientLocation, UPrimitiveComponent* ClientMovementBase, FName ClientBaseBoneName, uint8 ClientMovementMode) +{ + // Check location difference against global setting + if (!bIgnoreClientMovementErrorChecksAndCorrection) + { + //const FVector LocDiff = UpdatedComponent->GetComponentLocation() - ClientWorldLocation; + + + // If we are rolling back client rotation + //if (!bUseClientControlRotation && !FMath::IsNearlyEqual(FRotator::ClampAxis(ClientYaw), FRotator::ClampAxis(UpdatedComponent->GetComponentRotation().Yaw), CharacterMovementComponentStatics::fRotationCorrectionThreshold)) + + if (!bUseClientControlRotation) + { + // If we are using default gravity direction just match to the yaw only for now (less precision errors) + if (GetGravityDirection().Equals(DefaultGravityDirection)) + { + if (!FMath::IsNearlyEqual(FRotator::ClampAxis(ClientRot.Yaw), FRotator::ClampAxis(UpdatedComponent->GetComponentRotation().Yaw), CharacterMovementComponentStatics::fRotationCorrectionThreshold)) + { + return true; + } + } + else + { + float CorrectionValue = bIsBlendingOrientation ? CharacterMovementComponentStatics::fRotationChangingCorrectionThreshold : CharacterMovementComponentStatics::fRotationCorrectionThreshold; + bIsBlendingOrientation = false; + + if (FQuat::ErrorAutoNormalize(UpdatedComponent->GetComponentQuat(), ClientRot.Quaternion()) > CorrectionValue) + { + return true; + } + } + } + + +#if ROOT_MOTION_DEBUG + if (RootMotionSourceDebug::CVarDebugRootMotionSources.GetValueOnAnyThread() == 1) + { + const FVector LocDiff = UpdatedComponent->GetComponentLocation() - ClientWorldLocation; + FString AdjustedDebugString = FString::Printf(TEXT("ServerCheckClientError LocDiff(%.1f) ExceedsAllowablePositionError(%d) TimeStamp(%f)"), + LocDiff.Size(), GetDefault()->ExceedsAllowablePositionError(LocDiff), ClientTimeStamp); + RootMotionSourceDebug::PrintOnScreen(*CharacterOwner, AdjustedDebugString); + } +#endif + + if (ServerExceedsAllowablePositionError(ClientTimeStamp, DeltaTime, Accel, ClientWorldLocation, RelativeClientLocation, ClientMovementBase, ClientBaseBoneName, ClientMovementMode)) + { + return true; + } + +#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) + static const auto CVarNetForceClientAdjustmentPercent = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetForceClientAdjustmentPercent")); + if (CVarNetForceClientAdjustmentPercent->GetFloat() > UE_SMALL_NUMBER) + { + if (RandomStream.FRand() < CVarNetForceClientAdjustmentPercent->GetFloat()) + { + UE_LOG(LogVRCharacterMovement, VeryVerbose, TEXT("** ServerCheckClientError forced by p.NetForceClientAdjustmentPercent")); + return true; + } + } +#endif + } + else + { +#if !UE_BUILD_SHIPPING + static const auto CVarNetShowCorrections = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetShowCorrections")); + if (CVarNetShowCorrections->GetInt() != 0) + { + UE_LOG(LogVRCharacterMovement, Warning, TEXT("*** Server: %s is set to ignore error checks and corrections."), *GetNameSafe(CharacterOwner)); + } +#endif // !UE_BUILD_SHIPPING + } + + return false; +} + +void UVRCharacterMovementComponent::ServerMoveHandleClientErrorVR(float ClientTimeStamp, float DeltaTime, const FVector& Accel, const FVector& RelativeClientLoc, FRotator ClientRot, UPrimitiveComponent* ClientMovementBase, FName ClientBaseBoneName, uint8 ClientMovementMode) +{ + if (!ShouldUsePackedMovementRPCs()) + { + if (RelativeClientLoc == FVector(1.f, 2.f, 3.f)) // first part of double servermove + { + return; + } + } + + FNetworkPredictionData_Server_VRCharacter* ServerData = ((FNetworkPredictionData_Server_VRCharacter*)GetPredictionData_Server_Character()); + check(ServerData); + + // Don't prevent more recent updates from being sent if received this frame. + // We're going to send out an update anyway, might as well be the most recent one. + APlayerController* PC = Cast(CharacterOwner->GetController()); + if ((ServerData->LastUpdateTime != GetWorld()->TimeSeconds)) + { + const AGameNetworkManager* GameNetworkManager = (const AGameNetworkManager*)(AGameNetworkManager::StaticClass()->GetDefaultObject()); + if (GameNetworkManager->WithinUpdateDelayBounds(PC, ServerData->LastUpdateTime)) + { + return; + } + } + + // Offset may be relative to base component + FVector ClientLoc = RelativeClientLoc; + if (MovementBaseUtility::UseRelativeLocation(ClientMovementBase)) + { + MovementBaseUtility::TransformLocationToWorld(ClientMovementBase, ClientBaseBoneName, RelativeClientLoc, ClientLoc); + } + else + { + ClientLoc = FRepMovement::RebaseOntoLocalOrigin(ClientLoc, this); + } + + FVector ServerLoc = UpdatedComponent->GetComponentLocation(); + + // Client may send a null movement base when walking on bases with no relative location (to save bandwidth). + // In this case don't check movement base in error conditions, use the server one (which avoids an error based on differing bases). Position will still be validated. + if (ClientMovementBase == nullptr) + { + TEnumAsByte NetMovementMode(MOVE_None); + TEnumAsByte NetGroundMode(MOVE_None); + uint8 NetCustomMode(0); + UnpackNetworkMovementMode(ClientMovementMode, NetMovementMode, NetCustomMode, NetGroundMode); + if (NetMovementMode == MOVE_Walking) + { + ClientMovementBase = CharacterOwner->GetBasedMovement().MovementBase; + ClientBaseBoneName = CharacterOwner->GetBasedMovement().BoneName; + } + } + + // If base location is out of sync on server and client, changing base can result in a jarring correction. + // So in the case that the base has just changed on server or client, server trusts the client (within a threshold) + UPrimitiveComponent* MovementBase = CharacterOwner->GetMovementBase(); + FName MovementBaseBoneName = CharacterOwner->GetBasedMovement().BoneName; + const bool bServerIsFalling = IsFalling(); + const bool bClientIsFalling = ClientMovementMode == MOVE_Falling; + const bool bServerJustLanded = bLastServerIsFalling && !bServerIsFalling; + const bool bClientJustLanded = bLastClientIsFalling && !bClientIsFalling; + + FVector RelativeLocation = ServerLoc; + FVector RelativeVelocity = Velocity; + bool bUseLastBase = false; + bool bFallingWithinAcceptableError = false; + + // Potentially trust the client a little when landing + static const auto CVarClientAuthorityThresholdOnBaseChange = IConsoleManager::Get().FindConsoleVariable(TEXT("p.ClientAuthorityThresholdOnBaseChange")); + static const auto CVarMaxFallingCorrectionLeash = IConsoleManager::Get().FindConsoleVariable(TEXT("p.MaxFallingCorrectionLeash")); + + const float ClientAuthorityThreshold = CVarClientAuthorityThresholdOnBaseChange->GetFloat(); + const float MaxFallingCorrectionLeash = CVarMaxFallingCorrectionLeash->GetFloat(); + const bool bDeferServerCorrectionsWhenFalling = ClientAuthorityThreshold > 0.f || MaxFallingCorrectionLeash > 0.f; + if (bDeferServerCorrectionsWhenFalling) + { + // Teleports and other movement modes mean we should just trust the server like we normally would + if (bTeleportedSinceLastUpdate || (MovementMode != MOVE_Walking && MovementMode != MOVE_Falling)) + { + MaxServerClientErrorWhileFalling = 0.f; + bCanTrustClientOnLanding = false; + } + + // MaxFallingCorrectionLeash indicates we'll use a variable correction size based on the error on take-off and the direction of movement. + // ClientAuthorityThreshold is an static client-trusting correction upon landing. + // If both are set, use the smaller of the two. If only one is set, use that. If neither are set, we wouldn't even be inside this block. + float MaxLandingCorrection = 0.f; + if (ClientAuthorityThreshold > 0.f && MaxFallingCorrectionLeash > 0.f) + { + MaxLandingCorrection = FMath::Min(ClientAuthorityThreshold, MaxServerClientErrorWhileFalling); + } + else + { + MaxLandingCorrection = FMath::Max(ClientAuthorityThreshold, MaxServerClientErrorWhileFalling); + } + + if (bCanTrustClientOnLanding && MaxLandingCorrection > 0.f && (bClientJustLanded || bServerJustLanded)) + { + // no longer falling; server should trust client up to a point to finish the landing as the client sees it + const FVector LocDiff = ServerLoc - ClientLoc; + + if (!LocDiff.IsNearlyZero(UE_KINDA_SMALL_NUMBER)) + { + if (LocDiff.SizeSquared() < FMath::Square(MaxLandingCorrection)) + { + ServerLoc = ClientLoc; + UpdatedComponent->MoveComponent(ServerLoc - UpdatedComponent->GetComponentLocation(), UpdatedComponent->GetComponentQuat(), true, nullptr, EMoveComponentFlags::MOVECOMP_NoFlags, ETeleportType::TeleportPhysics); + bJustTeleported = true; + } + else + { + const FVector ClampedDiff = LocDiff.GetSafeNormal() * MaxLandingCorrection; + ServerLoc -= ClampedDiff; + UpdatedComponent->MoveComponent(ServerLoc - UpdatedComponent->GetComponentLocation(), UpdatedComponent->GetComponentQuat(), true, nullptr, EMoveComponentFlags::MOVECOMP_NoFlags, ETeleportType::TeleportPhysics); + bJustTeleported = true; + } + } + + MaxServerClientErrorWhileFalling = 0.f; + bCanTrustClientOnLanding = false; + } + + // They have it private.... + // Check for lift-off, going from walking to falling. + // Note that if bStayBasedInAir is enabled we can't rely on the walking to falling transition, instead run logic on the first tick after clearing the MovementBase + //const bool bCanLiftOffFromBase = bStayBasedInAir + // ? !MovementBase && LastServerMovementBase.Get() // If we keep the base while in air, consider lift-off if base gets set to null and we had a base last tick + // : bLastServerIsWalking; // If walking last tick, we were can consider lift-off logic + //if (bServerIsFalling && bCanLiftOffFromBase && !bTeleportedSinceLastUpdate) + + if (bServerIsFalling && bLastServerIsWalking && !bTeleportedSinceLastUpdate) + { + float ClientForwardFactor = 1.f; + UPrimitiveComponent* LastServerMovementBaseVRPtr = LastServerMovementBaseVR.Get(); + if (IsValid(LastServerMovementBaseVRPtr) && MovementBaseUtility::IsDynamicBase(LastServerMovementBaseVRPtr) && MaxWalkSpeed > UE_KINDA_SMALL_NUMBER) + { + const FVector LastBaseVelocity = MovementBaseUtility::GetMovementBaseVelocity(LastServerMovementBaseVRPtr, LastServerMovementBaseBoneName); + RelativeVelocity = Velocity - LastBaseVelocity; + const FVector BaseDirection = LastBaseVelocity.GetSafeNormal2D(); + const FVector RelativeDirection = RelativeVelocity * (1.f / MaxWalkSpeed); + + ClientForwardFactor = FMath::Clamp(FVector::DotProduct(BaseDirection, RelativeDirection), 0.f, 1.f); + + // To improve position syncing, use old base for take-off + if (MovementBaseUtility::UseRelativeLocation(LastServerMovementBaseVRPtr)) + { + // Relative Location + MovementBaseUtility::TransformLocationToLocal(LastServerMovementBaseVRPtr, LastServerMovementBaseBoneName, UpdatedComponent->GetComponentLocation(), RelativeLocation); + bUseLastBase = true; + } + } + + if (ClientAuthorityThreshold > 0.f && ClientForwardFactor < 1.f) + { + const float AdjustedClientAuthorityThreshold = ClientAuthorityThreshold * (1.f - ClientForwardFactor); + const FVector LocDiff = ServerLoc - ClientLoc; + + // Potentially trust the client a little when taking off in the opposite direction to the base (to help not get corrected back onto the base) + if (!LocDiff.IsNearlyZero(UE_KINDA_SMALL_NUMBER)) + { + if (LocDiff.SizeSquared() < FMath::Square(AdjustedClientAuthorityThreshold)) + { + ServerLoc = ClientLoc; + UpdatedComponent->MoveComponent(ServerLoc - UpdatedComponent->GetComponentLocation(), UpdatedComponent->GetComponentQuat(), true, nullptr, EMoveComponentFlags::MOVECOMP_NoFlags, ETeleportType::TeleportPhysics); + bJustTeleported = true; + } + else + { + const FVector ClampedDiff = LocDiff.GetSafeNormal() * AdjustedClientAuthorityThreshold; + ServerLoc -= ClampedDiff; + UpdatedComponent->MoveComponent(ServerLoc - UpdatedComponent->GetComponentLocation(), UpdatedComponent->GetComponentQuat(), true, nullptr, EMoveComponentFlags::MOVECOMP_NoFlags, ETeleportType::TeleportPhysics); + bJustTeleported = true; + } + } + } + + if (ClientForwardFactor < 1.f) + { + MaxServerClientErrorWhileFalling = FMath::Min((ServerLoc - ClientLoc).Size() * (1.f - ClientForwardFactor), MaxFallingCorrectionLeash); + bCanTrustClientOnLanding = true; + } + else + { + MaxServerClientErrorWhileFalling = 0.f; + bCanTrustClientOnLanding = false; + } + } + else if (!bServerIsFalling && bCanTrustClientOnLanding) + { + MaxServerClientErrorWhileFalling = 0.f; + bCanTrustClientOnLanding = false; + } + + if (MaxServerClientErrorWhileFalling > 0.f && (bServerIsFalling || bClientIsFalling)) + { + const FVector LocDiff = ServerLoc - ClientLoc; + if (LocDiff.SizeSquared() <= FMath::Square(MaxServerClientErrorWhileFalling)) + { + ServerLoc = ClientLoc; + // Still want a velocity update when we first take off + bFallingWithinAcceptableError = true; + } + else + { + // Change ServerLoc to be on the edge of the acceptable error rather than doing a full correction. + // This is not actually changing the server position, but changing it as far as corrections are concerned. + // This means we're just holding the client on a longer leash while we're falling. + static const auto CVarMaxFallingCorrectionLeashBuffer = IConsoleManager::Get().FindConsoleVariable(TEXT("p.MaxFallingCorrectionLeashBuffer")); + ServerLoc = ServerLoc - LocDiff.GetSafeNormal() * FMath::Clamp(MaxServerClientErrorWhileFalling - CVarMaxFallingCorrectionLeashBuffer->GetFloat(), 0.f, MaxServerClientErrorWhileFalling); + } + } + } + + bool bInClientAuthoritativeMovementMode = false; + // Custom movement modes aren't going to be rolled back as they are client authed for our pawns + + TEnumAsByte NetMovementMode(MOVE_None); + TEnumAsByte NetGroundMode(MOVE_None); + uint8 NetCustomMode(0); + UnpackNetworkMovementMode(ClientMovementMode, NetMovementMode, NetCustomMode, NetGroundMode); + if (NetMovementMode == EMovementMode::MOVE_Custom) + { + if (NetCustomMode == (uint8)EVRCustomMovementMode::VRMOVE_Climbing) + bInClientAuthoritativeMovementMode = true; + } + + // Compute the client error from the server's position + // If client has accumulated a noticeable positional error, correct them. + bNetworkLargeClientCorrection = ServerData->bForceClientUpdate; + if (!bInClientAuthoritativeMovementMode && (ServerData->bForceClientUpdate || (!bFallingWithinAcceptableError && ServerCheckClientErrorVR(ClientTimeStamp, DeltaTime, Accel, ClientLoc, ClientRot, RelativeClientLoc, ClientMovementBase, ClientBaseBoneName, ClientMovementMode)))) + { + //UPrimitiveComponent* MovementBase = CharacterOwner->GetMovementBase(); + ServerData->PendingAdjustment.NewVel = Velocity; + ServerData->PendingAdjustment.NewBase = MovementBase; + ServerData->PendingAdjustment.NewBaseBoneName = MovementBaseBoneName; + ServerData->PendingAdjustment.NewRot = UpdatedComponent->GetComponentRotation(); + ServerData->PendingAdjustment.GravityDirection = GetGravityDirection(); + + if (bRunClientCorrectionToHMD && IsValid(BaseVRCharacterOwner)) + { + FVector CapsuleLoc = BaseVRCharacterOwner->GetVRLocation(); + CapsuleLoc.Z = ServerLoc.Z; + ServerData->PendingAdjustment.NewLoc = FRepMovement::RebaseOntoZeroOrigin(CapsuleLoc, this); + //ServerData->PendingAdjustment.NewRot = BaseVRCharacterOwner->GetVRRotation(); + } + else + { + ServerData->PendingAdjustment.NewLoc = FRepMovement::RebaseOntoZeroOrigin(ServerLoc, this); + //ServerData->PendingAdjustment.NewRot = UpdatedComponent->GetComponentRotation(); + } + + ServerData->PendingAdjustment.bBaseRelativePosition = (bDeferServerCorrectionsWhenFalling && bUseLastBase) || MovementBaseUtility::UseRelativeLocation(MovementBase); + ServerData->PendingAdjustment.bBaseRelativeVelocity = false; + + // Relative location? + if (ServerData->PendingAdjustment.bBaseRelativePosition) + { + if (bDeferServerCorrectionsWhenFalling && bUseLastBase) + { + ServerData->PendingAdjustment.NewVel = RelativeVelocity; + ServerData->PendingAdjustment.NewBase = LastServerMovementBaseVR.Get(); + ServerData->PendingAdjustment.NewBaseBoneName = LastServerMovementBaseBoneName; + + if (bRunClientCorrectionToHMD && IsValid(BaseVRCharacterOwner)) + { + FBasedMovementInfo BaseInfo = CharacterOwner->GetBasedMovement(); + FVector BaseLocation; + FQuat BaseQuat; + + const bool bResult = MovementBaseUtility::GetMovementBaseTransform(BaseInfo.MovementBase, BaseInfo.BoneName, BaseLocation, BaseQuat); + if (bResult) + { + ServerData->PendingAdjustment.NewLoc = FTransform(BaseQuat, BaseLocation).InverseTransformPositionNoScale(CharacterOwner->GetBasedMovement().Location); + } + else + { + ServerData->PendingAdjustment.NewLoc = RelativeLocation; + } + } + else + { + ServerData->PendingAdjustment.NewLoc = RelativeLocation; + } + } + else + { + if (bRunClientCorrectionToHMD && IsValid(BaseVRCharacterOwner)) + { + ServerData->PendingAdjustment.NewLoc = CharacterOwner->GetMovementBase()->GetComponentTransform().InverseTransformPosition(ServerData->PendingAdjustment.NewLoc); + } + else + { + ServerData->PendingAdjustment.NewLoc = CharacterOwner->GetBasedMovement().Location; + } + + static const auto CVarNetUseBaseRelativeVelocity = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetUseBaseRelativeVelocity")); + if (CVarNetUseBaseRelativeVelocity->GetInt()) + { + // Store world velocity converted to local space of movement base + ServerData->PendingAdjustment.bBaseRelativeVelocity = true; + const FVector CurrentVelocity = ServerData->PendingAdjustment.NewVel; + MovementBaseUtility::TransformDirectionToLocal(MovementBase, MovementBaseBoneName, CurrentVelocity, ServerData->PendingAdjustment.NewVel); + } + } + + // TODO: this could be a relative rotation, but all client corrections ignore rotation right now except the root motion one, which would need to be updated. + //ServerData->PendingAdjustment.NewRot = CharacterOwner->GetBasedMovement().Rotation; + } + +#if !UE_BUILD_SHIPPING + static const auto CVarNetShowCorrections = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetShowCorrections")); + static const auto CVarNetCorrectionLifetime = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetCorrectionLifetime")); + if (CVarNetShowCorrections->GetInt() != 0) + { + const FVector LocDiff = UpdatedComponent->GetComponentLocation() - ClientLoc; + const FString BaseString = MovementBase ? MovementBase->GetPathName(MovementBase->GetOutermost()) : TEXT("None"); + UE_LOG(LogVRCharacterMovement, Warning, TEXT("*** Server: Error for %s at Time=%.3f is %3.3f LocDiff(%s) ClientLoc(%s) ServerLoc(%s) Base: %s Bone: %s Accel(%s) Velocity(%s)"), + *GetNameSafe(CharacterOwner), ClientTimeStamp, LocDiff.Size(), *LocDiff.ToString(), *ClientLoc.ToString(), *UpdatedComponent->GetComponentLocation().ToString(), *BaseString, *ServerData->PendingAdjustment.NewBaseBoneName.ToString(), *Accel.ToString(), *Velocity.ToString()); + const float DebugLifetime = CVarNetCorrectionLifetime->GetFloat(); + DrawDebugCapsule(GetWorld(), UpdatedComponent->GetComponentLocation(), CharacterOwner->GetSimpleCollisionHalfHeight(), CharacterOwner->GetSimpleCollisionRadius(), FQuat::Identity, FColor(100, 255, 100), false, DebugLifetime); + DrawDebugCapsule(GetWorld(), ClientLoc, CharacterOwner->GetSimpleCollisionHalfHeight(), CharacterOwner->GetSimpleCollisionRadius(), FQuat::Identity, FColor(255, 100, 100), false, DebugLifetime); + } +#endif + + ServerData->LastUpdateTime = GetWorld()->TimeSeconds; + ServerData->PendingAdjustment.DeltaTime = DeltaTime; + ServerData->PendingAdjustment.TimeStamp = ClientTimeStamp; + ServerData->PendingAdjustment.bAckGoodMove = false; + ServerData->PendingAdjustment.MovementMode = PackNetworkMovementMode(); + + //PerfCountersIncrement(PerfCounter_NumServerMoveCorrections); + } + else + { + if (bInClientAuthoritativeMovementMode || ServerShouldUseAuthoritativePosition(ClientTimeStamp, DeltaTime, Accel, ClientLoc, RelativeClientLoc, ClientMovementBase, ClientBaseBoneName, ClientMovementMode)) + { + const FVector LocDiff = UpdatedComponent->GetComponentLocation() - ClientLoc; //-V595 + if (!LocDiff.IsZero() || ClientMovementMode != PackNetworkMovementMode() || GetMovementBase() != ClientMovementBase || (CharacterOwner && CharacterOwner->GetBasedMovement().BoneName != ClientBaseBoneName)) + { + // Just set the position. On subsequent moves we will resolve initially overlapping conditions. + UpdatedComponent->SetWorldLocation(ClientLoc, false); //-V595 + + // Trust the client's movement mode. + ApplyNetworkMovementMode(ClientMovementMode); + + // Update base and floor at new location. + SetBase(ClientMovementBase, ClientBaseBoneName); + UpdateFloorFromAdjustment(); + + // Even if base has not changed, we need to recompute the relative offsets (since we've moved). + SaveBaseLocation(); + + LastUpdateLocation = UpdatedComponent ? UpdatedComponent->GetComponentLocation() : FVector::ZeroVector; + LastUpdateRotation = UpdatedComponent ? UpdatedComponent->GetComponentQuat() : FQuat::Identity; + LastUpdateVelocity = Velocity; + } + } + + // acknowledge receipt of this successful servermove() + ServerData->PendingAdjustment.TimeStamp = ClientTimeStamp; + ServerData->PendingAdjustment.bAckGoodMove = true; + } + + //PerfCountersIncrement(PerfCounter_NumServerMoves); + + ServerData->bForceClientUpdate = false; + + LastServerMovementBaseVR = MovementBase; + LastServerMovementBaseBoneName = MovementBaseBoneName; + bLastClientIsFalling = bClientIsFalling; + bLastServerIsFalling = bServerIsFalling; + bLastServerIsWalking = MovementMode == MOVE_Walking; +} + +bool UVRCharacterMovementComponent::ClientUpdatePositionAfterServerUpdate() +{ + //SCOPE_CYCLE_COUNTER(STAT_CharacterMovementClientUpdatePositionAfterServerUpdate); + if (!HasValidData()) + { + return false; + } + + FNetworkPredictionData_Client_Character* ClientData = GetPredictionData_Client_Character(); + check(ClientData); + + if (!ClientData->bUpdatePosition) + { + return false; + } + + ClientData->bUpdatePosition = false; + + // Don't do any network position updates on things running PHYS_RigidBody + if (CharacterOwner->GetRootComponent() && CharacterOwner->GetRootComponent()->IsSimulatingPhysics()) + { + return false; + } + + if (ClientData->SavedMoves.Num() == 0) + { + UE_LOG(LogNetPlayerMovement, Verbose, TEXT("ClientUpdatePositionAfterServerUpdate No saved moves to replay"), ClientData->SavedMoves.Num()); + + // With no saved moves to resimulate, the move the server updated us with is the last move we've done, no resimulation needed. + CharacterOwner->bClientResimulateRootMotion = false; + if (CharacterOwner->bClientResimulateRootMotionSources) + { + // With no resimulation, we just update our current root motion to what the server sent us + UE_LOG(LogRootMotion, VeryVerbose, TEXT("CurrentRootMotion getting updated to ServerUpdate state: %s"), *CharacterOwner->GetName()); + CurrentRootMotion.UpdateStateFrom(CharacterOwner->SavedRootMotion); + CharacterOwner->bClientResimulateRootMotionSources = false; + } + CharacterOwner->SavedRootMotion.Clear(); + + return false; + } + + // Save important values that might get affected by the replay. + const float SavedAnalogInputModifier = AnalogInputModifier; + const FRootMotionMovementParams BackupRootMotionParams = RootMotionParams; // For animation root motion + const FRootMotionSourceGroup BackupRootMotion = CurrentRootMotion; + const bool bRealPressedJump = CharacterOwner->bPressedJump; + const float RealJumpMaxHoldTime = CharacterOwner->JumpMaxHoldTime; + const int32 RealJumpMaxCount = CharacterOwner->JumpMaxCount; + const bool bRealCrouch = bWantsToCrouch; + const bool bRealForceMaxAccel = bForceMaxAccel; + CharacterOwner->bClientWasFalling = (MovementMode == MOVE_Falling); + CharacterOwner->bClientUpdating = true; + bForceNextFloorCheck = true; + + // Scope these, they nest with Outer references so it should work fine, this keeps the update rotation and move autonomous from double updating the char + //const FScopedPreventAttachedComponentMove PreventMeshMove(BaseVRCharacterOwner ? BaseVRCharacterOwner->NetSmoother : nullptr); + + // Store out our custom properties to restore after replaying + const FVRMoveActionArray Orig_MoveActions = MoveActionArray; + const FVector Orig_CustomInput = CustomVRInputVector; + const EVRConjoinedMovementModes Orig_VRReplicatedMovementMode = VRReplicatedMovementMode; + const FVector Orig_RequestedVelocity = RequestedVelocity; + const bool Orig_HasRequestedVelocity = HasRequestedVelocity(); + + // Store our VRchar custom properties + FVector Orig_CameraLoc = VRRootCapsule->curCameraLoc; + FRotator Orig_curCameraRot = VRRootCapsule->curCameraRot; + FVector Orig_DifferenceFromLastFrame = VRRootCapsule->DifferenceFromLastFrame; + FVector Orig_AdditionalVRInputVector = AdditionalVRInputVector; + FRotator Orig_CameraRotOffset = VRRootCapsule->StoredCameraRotOffset; + + // Replay moves that have not yet been acked. + UE_LOG(LogNetPlayerMovement, Verbose, TEXT("ClientUpdatePositionAfterServerUpdate Replaying %d Moves, starting at Timestamp %f"), ClientData->SavedMoves.Num(), ClientData->SavedMoves[0]->TimeStamp); + for (int32 i = 0; i < ClientData->SavedMoves.Num(); i++) + { + FSavedMove_Character* const CurrentMove = ClientData->SavedMoves[i].Get(); + checkSlow(CurrentMove != nullptr); + + // Make current SavedMove accessible to any functions that might need it.PrepMoveFor + SetCurrentReplayedSavedMove(CurrentMove); + + CurrentMove->PrepMoveFor(CharacterOwner); + + if (ShouldUsePackedMovementRPCs()) + { + // Make current move data accessible to MoveAutonomous or any other functions that might need it. + if (FCharacterNetworkMoveData* NewMove = GetNetworkMoveDataContainer().GetNewMoveData()) + { + SetCurrentNetworkMoveData(NewMove); + NewMove->ClientFillNetworkMoveData(*CurrentMove, FCharacterNetworkMoveData::ENetworkMoveType::NewMove); + } + } + + MoveAutonomous(CurrentMove->TimeStamp, CurrentMove->DeltaTime, CurrentMove->GetCompressedFlags(), CurrentMove->Acceleration); + + CurrentMove->PostUpdate(CharacterOwner, FSavedMove_Character::PostUpdate_Replay); + SetCurrentNetworkMoveData(nullptr); + SetCurrentReplayedSavedMove(nullptr); + } + const bool bPostReplayPressedJump = CharacterOwner->bPressedJump; + + if (FSavedMove_Character* const PendingMove = ClientData->PendingMove.Get()) + { + PendingMove->bForceNoCombine = true; + } + + // Restore saved values. + AnalogInputModifier = SavedAnalogInputModifier; + RootMotionParams = BackupRootMotionParams; + CurrentRootMotion = BackupRootMotion; + if (CharacterOwner->bClientResimulateRootMotionSources) + { + // If we were resimulating root motion sources, it's because we had mismatched state + // with the server - we just resimulated our SavedMoves and now need to restore + // CurrentRootMotion with the latest "good state" + UE_LOG(LogRootMotion, VeryVerbose, TEXT("CurrentRootMotion getting updated after ServerUpdate replays: %s"), *CharacterOwner->GetName()); + CurrentRootMotion.UpdateStateFrom(CharacterOwner->SavedRootMotion); + CharacterOwner->bClientResimulateRootMotionSources = false; + } + + CharacterOwner->SavedRootMotion.Clear(); + CharacterOwner->bClientResimulateRootMotion = false; + CharacterOwner->bClientUpdating = false; + CharacterOwner->bPressedJump = bRealPressedJump || bPostReplayPressedJump; + CharacterOwner->JumpMaxHoldTime = RealJumpMaxHoldTime; + CharacterOwner->JumpMaxCount = RealJumpMaxCount; + bWantsToCrouch = bRealCrouch; + bForceMaxAccel = bRealForceMaxAccel; + bForceNextFloorCheck = true; + + // Restore our custom properties + MoveActionArray = Orig_MoveActions; + CustomVRInputVector = Orig_CustomInput; + VRReplicatedMovementMode = Orig_VRReplicatedMovementMode; + RequestedVelocity = Orig_RequestedVelocity; + SetHasRequestedVelocity(Orig_HasRequestedVelocity); + + // Restore our VRchar custom properties + VRRootCapsule->curCameraLoc = Orig_CameraLoc; + VRRootCapsule->curCameraRot = Orig_curCameraRot; + VRRootCapsule->DifferenceFromLastFrame = Orig_DifferenceFromLastFrame; + AdditionalVRInputVector = Orig_AdditionalVRInputVector; + VRRootCapsule->StoredCameraRotOffset = Orig_CameraRotOffset; + VRRootCapsule->GenerateOffsetToWorld(false, false); + + return (ClientData->SavedMoves.Num() > 0); +} + +FVector UVRCharacterMovementComponent::GetPenetrationAdjustment(const FHitResult& Hit) const +{ + // This checks for a walking collision override on the penetrated object + // If found then it stops penetration adjustments. + if (MovementMode == EMovementMode::MOVE_Walking && VRRootCapsule && VRRootCapsule->bUseWalkingCollisionOverride && Hit.Component.IsValid()) + { + ECollisionResponse WalkingResponse; + WalkingResponse = Hit.Component->GetCollisionResponseToChannel(VRRootCapsule->WalkingCollisionOverride); + + if (WalkingResponse == ECR_Ignore || WalkingResponse == ECR_Overlap) + { + return FVector::ZeroVector; + } + } + + FVector Result = Super::GetPenetrationAdjustment(Hit); + + if (CharacterOwner) + { + const bool bIsProxy = (CharacterOwner->GetLocalRole() == ROLE_SimulatedProxy); + float MaxDistance = bIsProxy ? MaxDepenetrationWithGeometryAsProxy : MaxDepenetrationWithGeometry; + if (Hit.HitObjectHandle.DoesRepresentClass(APawn::StaticClass())) + { + MaxDistance = bIsProxy ? MaxDepenetrationWithPawnAsProxy : MaxDepenetrationWithPawn; + } + + Result = Result.GetClampedToMaxSize(MaxDistance); + } + + return Result; +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRExpansionFunctionLibrary.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRExpansionFunctionLibrary.cpp new file mode 100644 index 0000000..c634b3b --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRExpansionFunctionLibrary.cpp @@ -0,0 +1,784 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "VRExpansionFunctionLibrary.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRExpansionFunctionLibrary) + +#include "DrawDebugHelpers.h" +#include "Engine/Engine.h" +#include "IXRTrackingSystem.h" +#include "IHeadMountedDisplay.h" +#include "InputCoreTypes.h" +#include "Grippables/HandSocketComponent.h" +#include "Misc/CollisionIgnoreSubsystem.h" +#include "Components/SplineComponent.h" +#include "Components/SplineMeshComponent.h" +#include "Components/PrimitiveComponent.h" +#include "GripMotionControllerComponent.h" +//#include "IMotionController.h" +//#include "HeadMountedDisplayFunctionLibrary.h" +#include "Grippables/GrippablePhysicsReplication.h" +#include "GameplayTagContainer.h" +#include "XRMotionControllerBase.h" +//#include "IHeadMountedDisplay.h" + +#include "Chaos/ParticleHandle.h" +#include "Chaos/KinematicGeometryParticles.h" +#include "Chaos/ParticleHandle.h" +#include "PhysicsProxy/SingleParticlePhysicsProxy.h" +#include "PBDRigidsSolver.h" + +#if WITH_EDITOR +#include "Editor/UnrealEd/Classes/Editor/EditorEngine.h" +#endif + +//General Log +DEFINE_LOG_CATEGORY(VRExpansionFunctionLibraryLog); + +UGameViewportClient* UVRExpansionFunctionLibrary::GetGameViewportClient(UObject* WorldContextObject) +{ + if (WorldContextObject) + { + return WorldContextObject->GetWorld()->GetGameViewport(); + } + + return nullptr; +} + +void UVRExpansionFunctionLibrary::SetActorsIgnoreAllCollision(UObject* WorldContextObject, AActor* Actor1, AActor* Actor2, bool bIgnoreCollision) +{ + TInlineComponentArray PrimitiveComponents1; + Actor1->GetComponents(PrimitiveComponents1); + + TInlineComponentArray PrimitiveComponents2; + Actor2->GetComponents(PrimitiveComponents2); + + UCollisionIgnoreSubsystem* CollisionIgnoreSubsystem = WorldContextObject->GetWorld()->GetSubsystem(); + + if (CollisionIgnoreSubsystem) + { + // Just a temp flag to only check state on the first component pair + bool bIgnorefirst = true; + for (int i = 0; i < PrimitiveComponents1.Num(); ++i) + { + for (int j = 0; j < PrimitiveComponents2.Num(); ++j) + { + + // Don't ignore collision if one is already invalid + if (!IsValid(PrimitiveComponents1[i]) || !IsValid(PrimitiveComponents2[j])) + { + continue; + } + + // Don't ignore collision if no collision on at least one of the objects + if (PrimitiveComponents1[i]->GetCollisionEnabled() == ECollisionEnabled::NoCollision || PrimitiveComponents2[j]->GetCollisionEnabled() == ECollisionEnabled::NoCollision) + { + if (!bIgnoreCollision) + { + if (CollisionIgnoreSubsystem->AreComponentsIgnoringCollisions(PrimitiveComponents1[i], PrimitiveComponents2[j])) + { + UE_LOG(VRExpansionFunctionLibraryLog, Error, TEXT("Set Actors Ignore Collision called with at least one object set to no collision that are ignoring collision already!! %s, %s"),*PrimitiveComponents1[i]->GetName(), *PrimitiveComponents2[j]->GetName()); + } + } + continue; + } + + CollisionIgnoreSubsystem->SetComponentCollisionIgnoreState(true, true, PrimitiveComponents1[i], NAME_None, PrimitiveComponents2[j], NAME_None, bIgnoreCollision, bIgnorefirst); + bIgnorefirst = false; + } + } + } +} + +void UVRExpansionFunctionLibrary::SetObjectsIgnoreCollision(UObject* WorldContextObject, UPrimitiveComponent* Prim1, FName OptionalBoneName1, bool bAddChildBones1, UPrimitiveComponent* Prim2, FName OptionalBoneName2, bool bAddChildBones2, bool bIgnoreCollision) +{ + UCollisionIgnoreSubsystem* CollisionIgnoreSubsystem = WorldContextObject->GetWorld()->GetSubsystem(); + + if (CollisionIgnoreSubsystem) + { + CollisionIgnoreSubsystem->SetComponentCollisionIgnoreState(bAddChildBones1, bAddChildBones2, Prim1, OptionalBoneName1, Prim2, OptionalBoneName2, bIgnoreCollision, true); + } +} + + +bool UVRExpansionFunctionLibrary::IsComponentIgnoringCollision(UObject* WorldContextObject, UPrimitiveComponent* Prim1) +{ + UCollisionIgnoreSubsystem* CollisionIgnoreSubsystem = WorldContextObject->GetWorld()->GetSubsystem(); + + if (CollisionIgnoreSubsystem) + { + return CollisionIgnoreSubsystem->IsComponentIgnoringCollision(Prim1); + } + + return false; +} + +bool UVRExpansionFunctionLibrary::AreComponentsIgnoringCollisions(UObject* WorldContextObject, UPrimitiveComponent* Prim1, UPrimitiveComponent * Prim2) +{ + UCollisionIgnoreSubsystem* CollisionIgnoreSubsystem = WorldContextObject->GetWorld()->GetSubsystem(); + + if (CollisionIgnoreSubsystem && CollisionIgnoreSubsystem->CollisionTrackedPairs.Num() > 0) + { + return CollisionIgnoreSubsystem->AreComponentsIgnoringCollisions(Prim1, Prim2); + } + + return false; +} + +void UVRExpansionFunctionLibrary::RemoveObjectCollisionIgnore(UObject* WorldContextObject, UPrimitiveComponent* Prim1) +{ + UCollisionIgnoreSubsystem* CollisionIgnoreSubsystem = WorldContextObject->GetWorld()->GetSubsystem(); + + if (CollisionIgnoreSubsystem) + { + CollisionIgnoreSubsystem->RemoveComponentCollisionIgnoreState(Prim1); + } +} + +void UVRExpansionFunctionLibrary::RemoveActorCollisionIgnore(UObject* WorldContextObject, AActor* Actor1) +{ + TInlineComponentArray PrimitiveComponents1; + Actor1->GetComponents(PrimitiveComponents1); + + UCollisionIgnoreSubsystem* CollisionIgnoreSubsystem = WorldContextObject->GetWorld()->GetSubsystem(); + + if (CollisionIgnoreSubsystem) + { + for (int i = 0; i < PrimitiveComponents1.Num(); ++i) + { + CollisionIgnoreSubsystem->RemoveComponentCollisionIgnoreState(PrimitiveComponents1[i]); + } + } +} + +void UVRExpansionFunctionLibrary::LowPassFilter_RollingAverage(FVector lastAverage, FVector newSample, FVector& newAverage, int32 numSamples) +{ + newAverage = lastAverage; + newAverage -= newAverage / numSamples; + newAverage += newSample / numSamples; +} + +void UVRExpansionFunctionLibrary::LowPassFilter_Exponential(FVector lastAverage, FVector newSample, FVector& newAverage, float sampleFactor) +{ + newAverage = (newSample * sampleFactor) + ((1 - sampleFactor) * lastAverage); +} + +bool UVRExpansionFunctionLibrary::GetIsActorMovable(AActor* ActorToCheck) +{ + if (!ActorToCheck) + return false; + + if (USceneComponent* rootComp = ActorToCheck->GetRootComponent()) + { + return rootComp->Mobility == EComponentMobility::Movable; + } + + return false; +} + +void UVRExpansionFunctionLibrary::GetGripSlotInRangeByTypeName(FName SlotType, AActor* Actor, FVector WorldLocation, float MaxRange, bool& bHadSlotInRange, FTransform& SlotWorldTransform, FName& SlotName, UGripMotionControllerComponent* QueryController) +{ + bHadSlotInRange = false; + SlotWorldTransform = FTransform::Identity; + SlotName = NAME_None; + UHandSocketComponent* TargetHandSocket = nullptr; + + if (!Actor) + return; + + if (USceneComponent* rootComp = Actor->GetRootComponent()) + { + GetGripSlotInRangeByTypeName_Component(SlotType, rootComp, WorldLocation, MaxRange, bHadSlotInRange, SlotWorldTransform, SlotName, QueryController); + } +} + +void UVRExpansionFunctionLibrary::GetGripSlotInRangeByTypeName_Component(FName SlotType, USceneComponent* Component, FVector WorldLocation, float MaxRange, bool& bHadSlotInRange, FTransform& SlotWorldTransform, FName& SlotName, UGripMotionControllerComponent* QueryController) +{ + bHadSlotInRange = false; + SlotWorldTransform = FTransform::Identity; + SlotName = NAME_None; + UHandSocketComponent* TargetHandSocket = nullptr; + + if (!Component) + return; + + FVector RelativeWorldLocation = Component->GetComponentTransform().InverseTransformPosition(WorldLocation); + MaxRange = FMath::Square(MaxRange); + + float ClosestSlotDistance = -0.1f; + + TArray SocketNames = Component->GetAllSocketNames(); + + FString GripIdentifier = SlotType.ToString(); + + int foundIndex = 0; + + for (int i = 0; i < SocketNames.Num(); ++i) + { + if (SocketNames[i].ToString().Contains(GripIdentifier, ESearchCase::IgnoreCase, ESearchDir::FromStart)) + { + float vecLen = FVector::DistSquared(RelativeWorldLocation, Component->GetSocketTransform(SocketNames[i], ERelativeTransformSpace::RTS_Component).GetLocation()); + + if (MaxRange >= vecLen && (ClosestSlotDistance < 0.0f || vecLen < ClosestSlotDistance)) + { + ClosestSlotDistance = vecLen; + bHadSlotInRange = true; + foundIndex = i; + } + } + } + + TArray AttachChildren = Component->GetAttachChildren(); + + TArray RotationallyMatchingHandSockets; + for (USceneComponent* AttachChild : AttachChildren) + { + if (AttachChild && AttachChild->IsA()) + { + if (UHandSocketComponent* SocketComp = Cast(AttachChild)) + { + if (SocketComp->bDisabled) + continue; + + FName BoneName = SocketComp->GetAttachSocketName(); + FString SlotPrefix = BoneName != NAME_None ? BoneName.ToString() + SocketComp->SlotPrefix.ToString() : SocketComp->SlotPrefix.ToString(); + + if (SlotPrefix.Contains(GripIdentifier, ESearchCase::IgnoreCase, ESearchDir::FromStart)) + { + FVector SocketRelativeLocation = Component->GetComponentTransform().InverseTransformPosition(SocketComp->GetHandSocketTransform(QueryController, true).GetLocation()); + float vecLen = FVector::DistSquared(RelativeWorldLocation, SocketRelativeLocation); + //float vecLen = FVector::DistSquared(RelativeWorldLocation, SocketComp->GetRelativeLocation()); + if (SocketComp->bAlwaysInRange) + { + if (SocketComp->bMatchRotation) + { + RotationallyMatchingHandSockets.Add(SocketComp); + } + else + { + TargetHandSocket = SocketComp; + ClosestSlotDistance = vecLen; + bHadSlotInRange = true; + } + } + else + { + float RangeVal = (SocketComp->OverrideDistance > 0.0f ? FMath::Square(SocketComp->OverrideDistance) : MaxRange); + if (RangeVal >= vecLen && (ClosestSlotDistance < 0.0f || vecLen < ClosestSlotDistance)) + { + if (SocketComp->bMatchRotation) + { + RotationallyMatchingHandSockets.Add(SocketComp); + } + else + { + TargetHandSocket = SocketComp; + ClosestSlotDistance = vecLen; + bHadSlotInRange = true; + } + } + } + } + } + } + } + + // Try and sort through any hand sockets flagged as rotationally matched + if (RotationallyMatchingHandSockets.Num() > 0) + { + FQuat ControllerRot = QueryController->GetPivotTransform().GetRotation(); + //FQuat ClosestQuat = RotationallyMatchingHandSockets[0]->GetComponentTransform().GetRotation(); + FQuat ClosestQuat = RotationallyMatchingHandSockets[0]->GetHandSocketTransform(QueryController, true).GetRotation(); + + TargetHandSocket = RotationallyMatchingHandSockets[0]; + bHadSlotInRange = true; + ClosestSlotDistance = ControllerRot.AngularDistance(ClosestQuat); + for (int i = 1; i < RotationallyMatchingHandSockets.Num(); i++) + { + //float CheckDistance = ControllerRot.AngularDistance(RotationallyMatchingHandSockets[i]->GetComponentTransform().GetRotation()); + float CheckDistance = ControllerRot.AngularDistance(RotationallyMatchingHandSockets[i]->GetHandSocketTransform(QueryController, true).GetRotation()); + if (CheckDistance < ClosestSlotDistance) + { + TargetHandSocket = RotationallyMatchingHandSockets[i]; + ClosestSlotDistance = CheckDistance; + } + } + } + + if (bHadSlotInRange) + { + if (TargetHandSocket) + { + SlotWorldTransform = TargetHandSocket->GetHandSocketTransform(QueryController); + SlotName = TargetHandSocket->GetFName(); + SlotWorldTransform.SetScale3D(FVector(1.0f)); + } + else + { + SlotWorldTransform = Component->GetSocketTransform(SocketNames[foundIndex]); + SlotName = SocketNames[foundIndex]; + SlotWorldTransform.SetScale3D(FVector(1.0f)); + } + } +} + +bool UVRExpansionFunctionLibrary::GetHandFromMotionSourceName(FName MotionSource, EControllerHand& Hand) +{ + Hand = EControllerHand::Left; + if (FXRMotionControllerBase::GetHandEnumForSourceName(MotionSource, Hand)) + { + return true; + } + + return false; +} + +FRotator UVRExpansionFunctionLibrary::GetHMDPureYaw(FRotator HMDRotation) +{ + return GetHMDPureYaw_I(HMDRotation); +} + +EBPHMDWornState UVRExpansionFunctionLibrary::GetIsHMDWorn() +{ + + if (GEngine->XRSystem.IsValid() && GEngine->XRSystem->GetHMDDevice()) + { + return (EBPHMDWornState)GEngine->XRSystem->GetHMDDevice()->GetHMDWornState(); + } + + return EBPHMDWornState::Unknown; +} + +bool UVRExpansionFunctionLibrary::GetIsHMDConnected() +{ + return GEngine->XRSystem.IsValid() && GEngine->XRSystem->GetHMDDevice() && GEngine->XRSystem->GetHMDDevice()->IsHMDConnected(); +} + +EBPHMDDeviceType UVRExpansionFunctionLibrary::GetHMDType() +{ + if (GEngine && GEngine->XRSystem.IsValid()) + { + /* + if (GEngine && GEngine->XRSystem.IsValid()) + { + Ar.Logf(*GEngine->XRSystem->GetVersionString()); + } + */ + + // #TODO 4.19: Figure out a way to replace this...its broken now + /*IHeadMountedDisplay* HMDDevice = GEngine->XRSystem->GetHMDDevice(); + if (HMDDevice) + { + EHMDDeviceType::Type HMDDeviceType = HMDDevice->GetHMDDeviceType(); + + switch (HMDDeviceType) + { + case EHMDDeviceType::DT_ES2GenericStereoMesh: return EBPHMDDeviceType::DT_ES2GenericStereoMesh; break; + case EHMDDeviceType::DT_GearVR: return EBPHMDDeviceType::DT_GearVR; break; + case EHMDDeviceType::DT_Morpheus: return EBPHMDDeviceType::DT_Morpheus; break; + case EHMDDeviceType::DT_OculusRift: return EBPHMDDeviceType::DT_OculusRift; break; + case EHMDDeviceType::DT_SteamVR: return EBPHMDDeviceType::DT_SteamVR; break; + case EHMDDeviceType::DT_GoogleVR: return EBPHMDDeviceType::DT_GoogleVR; break; + } + + }*/ + + // There are no device type entries for these now.... + // Does the device type go away soon leaving only FNames? + // #TODO: 4.19? + // GearVR doesn't even return anything gut OculusHMD in FName currently. + + static const FName SteamVRSystemName(TEXT("SteamVR")); + static const FName OculusSystemName(TEXT("OculusHMD")); + static const FName PSVRSystemName(TEXT("PSVR")); + static const FName OSVRSystemName(TEXT("OSVR")); + static const FName GoogleARCoreSystemName(TEXT("FGoogleARCoreHMD")); + static const FName AppleARKitSystemName(TEXT("AppleARKit")); + static const FName GoogleVRHMDSystemName(TEXT("FGoogleVRHMD")); + + FName DeviceName(NAME_None); + DeviceName = GEngine->XRSystem->GetSystemName(); + + + if (DeviceName == FName(TEXT("SimpleHMD"))) + return EBPHMDDeviceType::DT_ES2GenericStereoMesh; + else if (DeviceName == SteamVRSystemName) + return EBPHMDDeviceType::DT_SteamVR; + else if (DeviceName == OculusSystemName) + return EBPHMDDeviceType::DT_OculusHMD; + else if (DeviceName == PSVRSystemName) + return EBPHMDDeviceType::DT_PSVR; + else if (DeviceName == OSVRSystemName) + return EBPHMDDeviceType::DT_SteamVR; + else if (DeviceName == GoogleARCoreSystemName) + return EBPHMDDeviceType::DT_GoogleARCore; + else if (DeviceName == AppleARKitSystemName) + return EBPHMDDeviceType::DT_AppleARKit; + else if (DeviceName == GoogleVRHMDSystemName) + return EBPHMDDeviceType::DT_GoogleVR; + } + + // Default to unknown + return EBPHMDDeviceType::DT_Unknown; +} + + +bool UVRExpansionFunctionLibrary::IsInVREditorPreviewOrGame() +{ +#if WITH_EDITOR + if (GIsEditor) + { + if (UEditorEngine* EdEngine = Cast(GEngine)) + { + TOptional PlayInfo = EdEngine->GetPlayInEditorSessionInfo(); + if (PlayInfo.IsSet()) + { + return PlayInfo->OriginalRequestParams.SessionPreviewTypeOverride == EPlaySessionPreviewType::VRPreview; + } + else + { + return false; + } + } + } +#endif + + // Is not an editor build, default to true here + return true; +} + +bool UVRExpansionFunctionLibrary::IsInVREditorPreview() +{ +#if WITH_EDITOR + if (GIsEditor) + { + if (UEditorEngine* EdEngine = Cast(GEngine)) + { + TOptional PlayInfo = EdEngine->GetPlayInEditorSessionInfo(); + if (PlayInfo.IsSet()) + { + return PlayInfo->OriginalRequestParams.SessionPreviewTypeOverride == EPlaySessionPreviewType::VRPreview; + } + else + { + return false; + } + } + } +#endif + + // Is not an editor build, default to false here + return false; +} + +void UVRExpansionFunctionLibrary::NonAuthorityMinimumAreaRectangle(class UObject* WorldContextObject, const TArray& InVerts, const FVector& SampleSurfaceNormal, FVector& OutRectCenter, FRotator& OutRectRotation, float& OutSideLengthX, float& OutSideLengthY, bool bDebugDraw) +{ + float MinArea = -1.f; + float CurrentArea = -1.f; + FVector SupportVectorA, SupportVectorB; + FVector RectSideA, RectSideB; + float MinDotResultA, MinDotResultB, MaxDotResultA, MaxDotResultB; + FVector TestEdge; + float TestEdgeDot = 0.f; + FVector PolyNormal(0.f, 0.f, 1.f); + TArray PolyVertIndices; + + // Bail if we receive an empty InVerts array + if (InVerts.Num() == 0) + { + return; + } + + // Compute the approximate normal of the poly, using the direction of SampleSurfaceNormal for guidance + PolyNormal = (InVerts[InVerts.Num() / 3] - InVerts[0]) ^ (InVerts[InVerts.Num() * 2 / 3] - InVerts[InVerts.Num() / 3]); + if ((PolyNormal | SampleSurfaceNormal) < 0.f) + { + PolyNormal = -PolyNormal; + } + + // Transform the sample points to 2D + FMatrix SurfaceNormalMatrix = FRotationMatrix::MakeFromZX(PolyNormal, FVector(1.f, 0.f, 0.f)); + TArray TransformedVerts; + OutRectCenter = FVector(0.f); + for (int32 Idx = 0; Idx < InVerts.Num(); ++Idx) + { + OutRectCenter += InVerts[Idx]; + TransformedVerts.Add(SurfaceNormalMatrix.InverseTransformVector(InVerts[Idx])); + } + OutRectCenter /= InVerts.Num(); + + // Compute the convex hull of the sample points + ConvexHull2D::ComputeConvexHull(TransformedVerts, PolyVertIndices); + + // Minimum area rectangle as computed by http://www.geometrictools.com/Documentation/MinimumAreaRectangle.pdf + for (int32 Idx = 1; Idx < PolyVertIndices.Num() - 1; ++Idx) + { + SupportVectorA = (TransformedVerts[PolyVertIndices[Idx]] - TransformedVerts[PolyVertIndices[Idx - 1]]).GetSafeNormal(); + SupportVectorA.Z = 0.f; + SupportVectorB.X = -SupportVectorA.Y; + SupportVectorB.Y = SupportVectorA.X; + SupportVectorB.Z = 0.f; + MinDotResultA = MinDotResultB = MaxDotResultA = MaxDotResultB = 0.f; + + for (int TestVertIdx = 1; TestVertIdx < PolyVertIndices.Num(); ++TestVertIdx) + { + TestEdge = TransformedVerts[PolyVertIndices[TestVertIdx]] - TransformedVerts[PolyVertIndices[0]]; + TestEdgeDot = SupportVectorA | TestEdge; + if (TestEdgeDot < MinDotResultA) + { + MinDotResultA = TestEdgeDot; + } + else if (TestEdgeDot > MaxDotResultA) + { + MaxDotResultA = TestEdgeDot; + } + + TestEdgeDot = SupportVectorB | TestEdge; + if (TestEdgeDot < MinDotResultB) + { + MinDotResultB = TestEdgeDot; + } + else if (TestEdgeDot > MaxDotResultB) + { + MaxDotResultB = TestEdgeDot; + } + } + + CurrentArea = (MaxDotResultA - MinDotResultA) * (MaxDotResultB - MinDotResultB); + if (MinArea < 0.f || CurrentArea < MinArea) + { + MinArea = CurrentArea; + RectSideA = SupportVectorA * (MaxDotResultA - MinDotResultA); + RectSideB = SupportVectorB * (MaxDotResultB - MinDotResultB); + } + } + + RectSideA = SurfaceNormalMatrix.TransformVector(RectSideA); + RectSideB = SurfaceNormalMatrix.TransformVector(RectSideB); + OutRectRotation = FRotationMatrix::MakeFromZX(PolyNormal, RectSideA).Rotator(); + OutSideLengthX = RectSideA.Size(); + OutSideLengthY = RectSideB.Size(); + +#if ENABLE_DRAW_DEBUG + if (bDebugDraw) + { + UWorld* World = (WorldContextObject) ? GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull) : nullptr; + if (World != nullptr) + { + DrawDebugSphere(World, OutRectCenter, 10.f, 12, FColor::Yellow, true); + DrawDebugCoordinateSystem(World, OutRectCenter, SurfaceNormalMatrix.Rotator(), 100.f, true); + DrawDebugLine(World, OutRectCenter - RectSideA * 0.5f + FVector(0, 0, 10.f), OutRectCenter + RectSideA * 0.5f + FVector(0, 0, 10.f), FColor::Green, true, -1, 0, 5.f); + DrawDebugLine(World, OutRectCenter - RectSideB * 0.5f + FVector(0, 0, 10.f), OutRectCenter + RectSideB * 0.5f + FVector(0, 0, 10.f), FColor::Blue, true, -1, 0, 5.f); + } + else + { + FFrame::KismetExecutionMessage(TEXT("WorldContext required for MinimumAreaRectangle to draw a debug visualization."), ELogVerbosity::Warning); + } + } +#endif +} + +bool UVRExpansionFunctionLibrary::EqualEqual_FBPActorGripInformation(const FBPActorGripInformation& A, const FBPActorGripInformation& B) +{ + return A == B; +} + +bool UVRExpansionFunctionLibrary::IsActiveGrip(const FBPActorGripInformation& Grip) +{ + return Grip.IsActive(); +} + +FTransform_NetQuantize UVRExpansionFunctionLibrary::MakeTransform_NetQuantize(FVector Translation, FRotator Rotation, FVector Scale) +{ + return FTransform_NetQuantize(Rotation, Translation, Scale); +} + +void UVRExpansionFunctionLibrary::BreakTransform_NetQuantize(const FTransform_NetQuantize& InTransform, FVector& Translation, FRotator& Rotation, FVector& Scale) +{ + Translation = InTransform.GetLocation(); + Rotation = InTransform.Rotator(); + Scale = InTransform.GetScale3D(); +} + +FTransform_NetQuantize UVRExpansionFunctionLibrary::Conv_TransformToTransformNetQuantize(const FTransform& InTransform) +{ + return FTransform_NetQuantize(InTransform); +} + +UGripMotionControllerComponent* UVRExpansionFunctionLibrary::Conv_GripPairToMotionController(const FBPGripPair& GripPair) +{ + return GripPair.HoldingController; +} + +uint8 UVRExpansionFunctionLibrary::Conv_GripPairToGripID(const FBPGripPair& GripPair) +{ + return GripPair.GripID; +} + +FVector_NetQuantize UVRExpansionFunctionLibrary::Conv_FVectorToFVectorNetQuantize(const FVector& InVector) +{ + return FVector_NetQuantize(InVector); +} + +FVector_NetQuantize UVRExpansionFunctionLibrary::MakeVector_NetQuantize(FVector InVector) +{ + return FVector_NetQuantize(InVector); +} + +FVector_NetQuantize10 UVRExpansionFunctionLibrary::Conv_FVectorToFVectorNetQuantize10(const FVector& InVector) +{ + return FVector_NetQuantize10(InVector); +} + +FVector_NetQuantize10 UVRExpansionFunctionLibrary::MakeVector_NetQuantize10(FVector InVector) +{ + return FVector_NetQuantize10(InVector); +} + +FVector_NetQuantize100 UVRExpansionFunctionLibrary::Conv_FVectorToFVectorNetQuantize100(const FVector& InVector) +{ + return FVector_NetQuantize100(InVector); +} + +FVector_NetQuantize100 UVRExpansionFunctionLibrary::MakeVector_NetQuantize100(FVector InVector) +{ + return FVector_NetQuantize100(InVector); +} + +USceneComponent* UVRExpansionFunctionLibrary::AddSceneComponentByClass(UObject* Outer, TSubclassOf Class, const FTransform& ComponentRelativeTransform) +{ + if (Class != nullptr && Outer != nullptr) + { + USceneComponent* Component = NewObject(Outer, *Class); + if (Component != nullptr) + { + if (USceneComponent* ParentComp = Cast(Outer)) + Component->SetupAttachment(ParentComp); + + Component->RegisterComponent(); + Component->SetRelativeTransform(ComponentRelativeTransform); + + return Component; + } + else + { + return nullptr; + } + } + + return nullptr; +} + +void UVRExpansionFunctionLibrary::SmoothUpdateLaserSpline(USplineComponent* LaserSplineComponent, TArray LaserSplineMeshComponents, FVector InStartLocation, FVector InEndLocation, FVector InForward, float LaserRadius) +{ + if (LaserSplineComponent == nullptr) + return; + + LaserSplineComponent->ClearSplinePoints(); + + const FVector SmoothLaserDirection = InEndLocation - InStartLocation; + float Distance = SmoothLaserDirection.Size(); + const FVector StraightLaserEndLocation = InStartLocation + (InForward * Distance); + const int32 NumLaserSplinePoints = LaserSplineMeshComponents.Num(); + + LaserSplineComponent->AddSplinePoint(InStartLocation, ESplineCoordinateSpace::World, false); + for (int32 Index = 1; Index < NumLaserSplinePoints; Index++) + { + float Alpha = (float)Index / (float)NumLaserSplinePoints; + Alpha = FMath::Sin(Alpha * PI * 0.5f); + const FVector PointOnStraightLaser = FMath::Lerp(InStartLocation, StraightLaserEndLocation, Alpha); + const FVector PointOnSmoothLaser = FMath::Lerp(InStartLocation, InEndLocation, Alpha); + const FVector PointBetweenLasers = FMath::Lerp(PointOnStraightLaser, PointOnSmoothLaser, Alpha); + LaserSplineComponent->AddSplinePoint(PointBetweenLasers, ESplineCoordinateSpace::World, false); + } + LaserSplineComponent->AddSplinePoint(InEndLocation, ESplineCoordinateSpace::World, false); + + // Update all the segments of the spline + LaserSplineComponent->UpdateSpline(); + + const float LaserPointerRadius = LaserRadius; + Distance *= 0.0001f; + for (int32 Index = 0; Index < NumLaserSplinePoints; Index++) + { + USplineMeshComponent* SplineMeshComponent = LaserSplineMeshComponents[Index]; + check(SplineMeshComponent != nullptr); + + FVector StartLoc, StartTangent, EndLoc, EndTangent; + LaserSplineComponent->GetLocationAndTangentAtSplinePoint(Index, StartLoc, StartTangent, ESplineCoordinateSpace::Local); + LaserSplineComponent->GetLocationAndTangentAtSplinePoint(Index + 1, EndLoc, EndTangent, ESplineCoordinateSpace::Local); + + const float AlphaIndex = (float)Index / (float)NumLaserSplinePoints; + const float AlphaDistance = Distance * AlphaIndex; + float Radius = LaserPointerRadius * ((AlphaIndex * AlphaDistance) + 1); + FVector2D LaserScale(Radius, Radius); + SplineMeshComponent->SetStartScale(LaserScale, false); + + const float NextAlphaIndex = (float)(Index + 1) / (float)NumLaserSplinePoints; + const float NextAlphaDistance = Distance * NextAlphaIndex; + Radius = LaserPointerRadius * ((NextAlphaIndex * NextAlphaDistance) + 1); + LaserScale = FVector2D(Radius, Radius); + SplineMeshComponent->SetEndScale(LaserScale, false); + + SplineMeshComponent->SetStartAndEnd(StartLoc, StartTangent, EndLoc, EndTangent, true); + } + +} + +bool UVRExpansionFunctionLibrary::MatchesAnyTagsWithDirectParentTag(FGameplayTag DirectParentTag, const FGameplayTagContainer& BaseContainer, const FGameplayTagContainer& OtherContainer) +{ + TArray BaseContainerTags; + BaseContainer.GetGameplayTagArray(BaseContainerTags); + + for (const FGameplayTag& OtherTag : BaseContainerTags) + { + if (OtherTag.RequestDirectParent().MatchesTagExact(DirectParentTag)) + { + if (OtherContainer.HasTagExact(OtherTag)) + return true; + } + } + + return false; +} + +bool UVRExpansionFunctionLibrary::GetFirstGameplayTagWithExactParent(FGameplayTag DirectParentTag, const FGameplayTagContainer& BaseContainer, FGameplayTag& FoundTag) +{ + TArray BaseContainerTags; + BaseContainer.GetGameplayTagArray(BaseContainerTags); + + for (const FGameplayTag& OtherTag : BaseContainerTags) + { + if (OtherTag.RequestDirectParent().MatchesTagExact(DirectParentTag)) + { + FoundTag = OtherTag; + return true; + } + } + + return false; +} + +void UVRExpansionFunctionLibrary::ResetPeakLowPassFilter(UPARAM(ref) FBPLowPassPeakFilter& TargetPeakFilter) +{ + TargetPeakFilter.Reset(); +} + +void UVRExpansionFunctionLibrary::UpdatePeakLowPassFilter(UPARAM(ref) FBPLowPassPeakFilter& TargetPeakFilter, FVector NewSample) +{ + TargetPeakFilter.AddSample(NewSample); +} + +FVector UVRExpansionFunctionLibrary::GetPeak_PeakLowPassFilter(UPARAM(ref) FBPLowPassPeakFilter& TargetPeakFilter) +{ + return TargetPeakFilter.GetPeak(); +} + +void UVRExpansionFunctionLibrary::ResetEuroSmoothingFilter(UPARAM(ref) FBPEuroLowPassFilter& TargetEuroFilter) + +{ + TargetEuroFilter.ResetSmoothingFilter(); +} +void UVRExpansionFunctionLibrary::RunEuroSmoothingFilter(UPARAM(ref) FBPEuroLowPassFilter& TargetEuroFilter, FVector InRawValue, const float DeltaTime, FVector & SmoothedValue) + +{ + SmoothedValue = TargetEuroFilter.RunFilterSmoothing(InRawValue, DeltaTime); +} + \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRExpansionPlugin.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRExpansionPlugin.cpp new file mode 100644 index 0000000..707dd4e --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRExpansionPlugin.cpp @@ -0,0 +1,57 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "VRExpansionPlugin.h" + +#include "Grippables/GrippablePhysicsReplication.h" + +#include "VRGlobalSettings.h" +#include "ISettingsContainer.h" +#include "ISettingsModule.h" +#include "ISettingsSection.h" +#include "Physics/Experimental/PhysScene_Chaos.h" + +#define LOCTEXT_NAMESPACE "FVRExpansionPluginModule" + +void FVRExpansionPluginModule::StartupModule() +{ + // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module + RegisterSettings(); + + FPhysScene_Chaos::PhysicsReplicationFactory = MakeShared(); +} + +void FVRExpansionPluginModule::ShutdownModule() +{ + // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, + // we call this function before unloading the module. + UnregisterSettings(); +} + +void FVRExpansionPluginModule::RegisterSettings() +{ + if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings")) + { + // Create the new category + ISettingsContainerPtr SettingsContainer = SettingsModule->GetContainer("Project"); + + + SettingsModule->RegisterSettings("Project", "Plugins", "VRExpansionPlugin", + LOCTEXT("VRExpansionSettingsName", "VRExpansion Settings"), + LOCTEXT("VRExpansionSettingsDescription", "Configure global settings for the VRExpansionPlugin"), + GetMutableDefault()); + } +} + +void FVRExpansionPluginModule::UnregisterSettings() +{ + // Ensure to unregister all of your registered settings here, hot-reload would + // otherwise yield unexpected results. + if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings")) + { + SettingsModule->UnregisterSettings("Project", "Plugins", "VRExpansionPlugin"); + } +} + +#undef LOCTEXT_NAMESPACE + +IMPLEMENT_MODULE(FVRExpansionPluginModule, VRExpansionPlugin) \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRExpansionPluginPrivatePCH.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRExpansionPluginPrivatePCH.h new file mode 100644 index 0000000..7abba6d --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRExpansionPluginPrivatePCH.h @@ -0,0 +1,20 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +//#include "VRExpansionPlugin.h" +//#include "EngineMinimal.h" +//#include "VRBPDatatypes.h" +//#include "GripMotionControllerComponent.h" +//#include "VRExpansionFunctionLibrary.h" +//#include "ReplicatedVRCameraComponent.h" +//#include "ParentRelativeAttachmentComponent.h" +//#include "VRRootComponent.h" +//#include "VRBaseCharacterMovementComponent.h" +//#include "VRCharacterMovementComponent.h" +//#include "VRCharacter.h" +//#include "VRPathFollowingComponent.h" +//#include "VRPlayerController.h" +//#include "VRGripInterface.h" +//#include "Runtime/Launch/Resources/Version.h" + +// You should place include statements to your module's private header files here. You only need to +// add includes for headers that are used in most of your module's source files though. \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRGestureComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRGestureComponent.cpp new file mode 100644 index 0000000..00be260 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRGestureComponent.cpp @@ -0,0 +1,797 @@ +#include "VRGestureComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRGestureComponent) + +#include "VRBaseCharacter.h" +#include "Engine/Engine.h" +#include "Engine/World.h" +#include "Components/SplineMeshComponent.h" +#include "Components/SplineComponent.h" +#include "Components/LineBatchComponent.h" +#include "DrawDebugHelpers.h" +#include "Algo/Reverse.h" +#include "TimerManager.h" + +DECLARE_CYCLE_STAT(TEXT("TickGesture ~ TickingGesture"), STAT_TickGesture, STATGROUP_TickGesture); + +UVRGestureComponent::UVRGestureComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + PrimaryComponentTick.bCanEverTick = false; + //PrimaryComponentTick.bStartWithTickEnabled = false; + //PrimaryComponentTick.TickGroup = TG_PrePhysics; + //PrimaryComponentTick.bTickEvenWhenPaused = false; + + maxSlope = 3;// INT_MAX; + //globalThreshold = 10.0f; + SameSampleTolerance = 0.1f; + MirroringHand = EVRGestureMirrorMode::GES_NoMirror; + bDrawSplinesCurved = true; + bGetGestureInWorldSpace = true; + SplineMeshScaler = FVector2D(1.f); +} + +void UGesturesDatabase::FillSplineWithGesture(FVRGesture &Gesture, USplineComponent * SplineComponent, bool bCenterPointsOnSpline, bool bScaleToBounds, float OptionalBounds, bool bUseCurvedPoints, bool bFillInSplineMeshComponents, UStaticMesh * Mesh, UMaterial * MeshMat) +{ + if (!SplineComponent || Gesture.Samples.Num() < 2) + return; + + UWorld* InWorld = GEngine->GetWorldFromContextObject(SplineComponent, EGetWorldErrorMode::LogAndReturnNull); + + if (!InWorld) + return; + + SplineComponent->ClearSplinePoints(false); + + FVector PointOffset = FVector::ZeroVector; + float Scaler = 1.0f; + if (bScaleToBounds && OptionalBounds > 0.0f) + { + Scaler = OptionalBounds / Gesture.GestureSize.GetSize().GetMax(); + } + + if (bCenterPointsOnSpline) + { + PointOffset = -Gesture.GestureSize.GetCenter(); + } + + int curIndex = 0; + for (int i = Gesture.Samples.Num() - 1; i >= 0; --i) + { + SplineComponent->AddSplinePoint((Gesture.Samples[i] + PointOffset) * Scaler, ESplineCoordinateSpace::Local, false); + curIndex++; + SplineComponent->SetSplinePointType(curIndex, bUseCurvedPoints ? ESplinePointType::Curve : ESplinePointType::Linear, false); + } + + // Update spline now + SplineComponent->UpdateSpline(); + + if (bFillInSplineMeshComponents && Mesh != nullptr && MeshMat != nullptr) + { + TArray CurrentSplineChildren; + + TArray Children; + SplineComponent->GetChildrenComponents(false, Children); + for (auto Child : Children) + { + USplineMeshComponent* SplineMesh = Cast(Child); + if (SplineMesh != nullptr && IsValid(SplineMesh)) + { + CurrentSplineChildren.Add(SplineMesh); + } + } + + if (CurrentSplineChildren.Num() > SplineComponent->GetNumberOfSplinePoints() - 1) + { + int diff = CurrentSplineChildren.Num() - (CurrentSplineChildren.Num() - (SplineComponent->GetNumberOfSplinePoints() -1)); + + for (int i = CurrentSplineChildren.Num()- 1; i >= diff; --i) + { + if (!CurrentSplineChildren[i]->IsBeingDestroyed()) + { + CurrentSplineChildren[i]->SetVisibility(false); + CurrentSplineChildren[i]->Modify(); + CurrentSplineChildren[i]->DestroyComponent(); + CurrentSplineChildren.RemoveAt(i); + } + } + } + else + { + for (int i = CurrentSplineChildren.Num(); i < SplineComponent->GetNumberOfSplinePoints() -1; ++i) + { + USplineMeshComponent * newSplineMesh = NewObject(SplineComponent); + + newSplineMesh->RegisterComponentWithWorld(InWorld); + newSplineMesh->SetMobility(EComponentMobility::Movable); + CurrentSplineChildren.Add(newSplineMesh); + newSplineMesh->SetStaticMesh(Mesh); + newSplineMesh->SetMaterial(0, (UMaterialInterface*)MeshMat); + + newSplineMesh->AttachToComponent(SplineComponent, FAttachmentTransformRules::SnapToTargetIncludingScale); + newSplineMesh->SetVisibility(true); + } + } + + + for(int i=0; iGetNumberOfSplinePoints() - 1; i++) + { + CurrentSplineChildren[i]->SetStartAndEnd(SplineComponent->GetLocationAtSplinePoint(i, ESplineCoordinateSpace::Local), + SplineComponent->GetTangentAtSplinePoint(i, ESplineCoordinateSpace::Local), + SplineComponent->GetLocationAtSplinePoint(i + 1, ESplineCoordinateSpace::Local), + SplineComponent->GetTangentAtSplinePoint(i + 1, ESplineCoordinateSpace::Local), + true); + } + } + +} + +void UVRGestureComponent::BeginRecording(bool bRunDetection, EVRGestureFlattenAxis FlattenAxis, bool bDrawGesture, bool bDrawAsSpline, int SamplingHTZ, int SampleBufferSize, float ClampingTolerance) +{ + RecordingBufferSize = SampleBufferSize; + RecordingDelta = 1.0f / SamplingHTZ; + RecordingClampingTolerance = ClampingTolerance; + bDrawRecordingGesture = bDrawGesture; + bDrawRecordingGestureAsSpline = bDrawAsSpline; + RecordingFlattenAxis = FlattenAxis; + GestureLog.GestureSize.Init(); + + // Reset does the reserve already + GestureLog.Samples.Reset(RecordingBufferSize); + + CurrentState = bRunDetection ? EVRGestureState::GES_Detecting : EVRGestureState::GES_Recording; + + if (TargetCharacter != nullptr) + { + OriginatingTransform = TargetCharacter->OffsetComponentToWorld; + if (!bGetGestureInWorldSpace) + { + ParentRelativeTransform = OriginatingTransform.GetRelativeTransform(TargetCharacter->GetActorTransform()); + } + else + { + ParentRelativeTransform = FTransform::Identity; + } + } + else if (AVRBaseCharacter * own = Cast(GetOwner())) + { + TargetCharacter = own; + OriginatingTransform = TargetCharacter->OffsetComponentToWorld; + if (!bGetGestureInWorldSpace) + { + ParentRelativeTransform = OriginatingTransform.GetRelativeTransform(TargetCharacter->GetActorTransform()); + } + else + { + ParentRelativeTransform = FTransform::Identity; + } + } + else + OriginatingTransform = this->GetComponentTransform(); + + StartVector = OriginatingTransform.InverseTransformPosition(this->GetComponentLocation()); + + // Reinit the drawing spline + if (!bDrawAsSpline || !bDrawGesture) + RecordingGestureDraw.Clear(); // Not drawing or not as a spline, remove the components if they exist + else + { + RecordingGestureDraw.Reset(); // Otherwise just clear points and hide mesh components + + if (RecordingGestureDraw.SplineComponent == nullptr) + { + RecordingGestureDraw.SplineComponent = NewObject(GetAttachParent()); + RecordingGestureDraw.SplineComponent->RegisterComponentWithWorld(GetWorld()); + RecordingGestureDraw.SplineComponent->SetMobility(EComponentMobility::Movable); + } + + RecordingGestureDraw.SplineComponent->ClearSplinePoints(true); + if (!bGetGestureInWorldSpace && TargetCharacter != nullptr) + { + RecordingGestureDraw.SplineComponent->AttachToComponent(TargetCharacter->GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform); + RecordingGestureDraw.SplineComponent->SetRelativeLocationAndRotation(ParentRelativeTransform.TransformPosition(StartVector), ParentRelativeTransform.GetRotation()); + } + else + { + RecordingGestureDraw.SplineComponent->AttachToComponent(GetAttachParent(), FAttachmentTransformRules::KeepRelativeTransform); + } + } + + this->SetComponentTickEnabled(true); + + if (!TickGestureTimer_Handle.IsValid()) + GetWorld()->GetTimerManager().SetTimer(TickGestureTimer_Handle, this, &UVRGestureComponent::TickGesture, RecordingDelta, true); +} + +void UVRGestureComponent::CaptureGestureFrame() +{ + FTransform CalcedTransform = OriginatingTransform; + if (!bGetGestureInWorldSpace) + { + if (TargetCharacter != nullptr) + { + CalcedTransform = ParentRelativeTransform * TargetCharacter->GetActorTransform(); + } + else if (AVRBaseCharacter* own = Cast(GetOwner())) + { + TargetCharacter = own; + CalcedTransform = ParentRelativeTransform * TargetCharacter->GetActorTransform(); + } + } + + FVector NewSample = CalcedTransform.InverseTransformPosition(this->GetComponentLocation()) - StartVector; + + if (CurrentState == EVRGestureState::GES_Recording) + { + switch (RecordingFlattenAxis) + { + case EVRGestureFlattenAxis::GES_FlattenX: {NewSample.X = 0.0; }break; + case EVRGestureFlattenAxis::GES_FlattenY: {NewSample.Y = 0.0; }break; + case EVRGestureFlattenAxis::GES_FlattenZ: {NewSample.Z = 0.0; }break; + default: {}break; + } + + if (RecordingClampingTolerance > 0.0f) + { + NewSample.X = FMath::GridSnap(NewSample.X, RecordingClampingTolerance); + NewSample.Y = FMath::GridSnap(NewSample.Y, RecordingClampingTolerance); + NewSample.Z = FMath::GridSnap(NewSample.Z, RecordingClampingTolerance); + } + } + + // Add in newest sample at beginning (reverse order) + if (NewSample != FVector::ZeroVector && (GestureLog.Samples.Num() < 1 || !GestureLog.Samples[0].Equals(NewSample, SameSampleTolerance))) + { + bool bClearLatestSpline = false; + // Pop off oldest sample + if (GestureLog.Samples.Num() >= RecordingBufferSize) + { + GestureLog.Samples.Pop(false); + bClearLatestSpline = true; + } + + GestureLog.GestureSize.Max.X = FMath::Max(NewSample.X, GestureLog.GestureSize.Max.X); + GestureLog.GestureSize.Max.Y = FMath::Max(NewSample.Y, GestureLog.GestureSize.Max.Y); + GestureLog.GestureSize.Max.Z = FMath::Max(NewSample.Z, GestureLog.GestureSize.Max.Z); + + GestureLog.GestureSize.Min.X = FMath::Min(NewSample.X, GestureLog.GestureSize.Min.X); + GestureLog.GestureSize.Min.Y = FMath::Min(NewSample.Y, GestureLog.GestureSize.Min.Y); + GestureLog.GestureSize.Min.Z = FMath::Min(NewSample.Z, GestureLog.GestureSize.Min.Z); + + + if (bDrawRecordingGesture && bDrawRecordingGestureAsSpline && SplineMesh != nullptr && SplineMaterial != nullptr) + { + if (bClearLatestSpline) + RecordingGestureDraw.ClearLastPoint(); + + RecordingGestureDraw.SplineComponent->AddSplinePoint(NewSample, ESplineCoordinateSpace::Local, false); + int SplineIndex = RecordingGestureDraw.SplineComponent->GetNumberOfSplinePoints() - 1; + RecordingGestureDraw.SplineComponent->SetSplinePointType(SplineIndex, bDrawSplinesCurved ? ESplinePointType::Curve : ESplinePointType::Linear, true); + + bool bFoundEmptyMesh = false; + USplineMeshComponent * MeshComp = nullptr; + int MeshIndex = 0; + + for (int i = 0; i < RecordingGestureDraw.SplineMeshes.Num(); i++) + { + MeshIndex = i; + MeshComp = RecordingGestureDraw.SplineMeshes[i]; + if (MeshComp == nullptr) + { + RecordingGestureDraw.SplineMeshes[i] = NewObject(RecordingGestureDraw.SplineComponent); + MeshComp = RecordingGestureDraw.SplineMeshes[i]; + + MeshComp->RegisterComponentWithWorld(GetWorld()); + MeshComp->SetMobility(EComponentMobility::Movable); + //MeshComp->SetStaticMesh(SplineMesh); + //MeshComp->SetMaterial(0, (UMaterialInterface*)SplineMaterial); + bFoundEmptyMesh = true; + break; + } + else if (!MeshComp->IsVisible()) + { + bFoundEmptyMesh = true; + break; + } + } + + if (!bFoundEmptyMesh) + { + USplineMeshComponent * newSplineMesh = NewObject(RecordingGestureDraw.SplineComponent); + MeshComp = newSplineMesh; + MeshComp->RegisterComponentWithWorld(GetWorld()); + MeshComp->SetMobility(EComponentMobility::Movable); + RecordingGestureDraw.SplineMeshes.Add(MeshComp); + MeshIndex = RecordingGestureDraw.SplineMeshes.Num() - 1; + //MeshComp->SetStaticMesh(SplineMesh); + //MeshComp->SetMaterial(0, (UMaterialInterface*)SplineMaterial); + if (!bGetGestureInWorldSpace && TargetCharacter) + MeshComp->AttachToComponent(TargetCharacter->GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform); + } + + if (MeshComp != nullptr) + { + // Fill in last mesh component tangent and end pos + if (RecordingGestureDraw.LastIndexSet != MeshIndex && RecordingGestureDraw.SplineMeshes[RecordingGestureDraw.LastIndexSet] != nullptr) + { + RecordingGestureDraw.SplineMeshes[RecordingGestureDraw.LastIndexSet]->SetEndPosition(NewSample, false); + RecordingGestureDraw.SplineMeshes[RecordingGestureDraw.LastIndexSet]->SetEndTangent(RecordingGestureDraw.SplineComponent->GetTangentAtSplinePoint(SplineIndex, ESplineCoordinateSpace::Local), true); + } + + // Re-init mesh and material on the spline mesh, won't do anything if its the same + MeshComp->SetStaticMesh(SplineMesh); + MeshComp->SetMaterial(0, (UMaterialInterface*)SplineMaterial); + + MeshComp->SetStartScale(SplineMeshScaler); + MeshComp->SetEndScale(SplineMeshScaler); + MeshComp->SetStartAndEnd(NewSample, + RecordingGestureDraw.SplineComponent->GetTangentAtSplinePoint(SplineIndex, ESplineCoordinateSpace::Local), + NewSample, + FVector::ZeroVector, + true); + + //if (bGetGestureInWorldSpace) + MeshComp->SetWorldLocationAndRotation(CalcedTransform.TransformPosition(StartVector), CalcedTransform.GetRotation()); + //else + //MeshComp->SetRelativeLocationAndRotation(/*OriginatingTransform.TransformPosition(*/StartVector/*)*/, FQuat::Identity/*OriginatingTransform.GetRotation()*/); + + RecordingGestureDraw.LastIndexSet = MeshIndex; + MeshComp->SetVisibility(true); + } + + } + + GestureLog.Samples.Insert(NewSample, 0); + bGestureChanged = true; + } +} + +void UVRGestureComponent::TickGesture() +{ + SCOPE_CYCLE_COUNTER(STAT_TickGesture); + + switch (CurrentState) + { + case EVRGestureState::GES_Detecting: + { + CaptureGestureFrame(); + RecognizeGesture(GestureLog); + bGestureChanged = false; + }break; + + case EVRGestureState::GES_Recording: + { + CaptureGestureFrame(); + }break; + + case EVRGestureState::GES_None: + default: {}break; + } + + if (bDrawRecordingGesture) + { + if (!bDrawRecordingGestureAsSpline) + { + FTransform DrawTransform = FTransform(StartVector) * OriginatingTransform; + // Setting the lifetime to the recording htz now, should remove the flicker. + DrawDebugGesture(this, DrawTransform, GestureLog, FColor::White, false, 0, RecordingDelta, 0.0f); + } + } +} + +void UVRGestureComponent::RecognizeGesture(FVRGesture inputGesture) +{ + if (!GesturesDB || inputGesture.Samples.Num() < 1 || !bGestureChanged) + return; + + float minDist = MAX_FLT; + + int OutGestureIndex = -1; + bool bMirrorGesture = false; + + FVector Size = inputGesture.GestureSize.GetSize(); + float Scaler = GesturesDB->TargetGestureScale / Size.GetMax(); + float FinalScaler = Scaler; + + for (int i = 0; i < GesturesDB->Gestures.Num(); i++) + { + FVRGesture &exampleGesture = GesturesDB->Gestures[i]; + + if (!exampleGesture.GestureSettings.bEnabled || exampleGesture.Samples.Num() < 1 || inputGesture.Samples.Num() < exampleGesture.GestureSettings.Minimum_Gesture_Length) + continue; + + FinalScaler = exampleGesture.GestureSettings.bEnableScaling ? Scaler : 1.f; + + bMirrorGesture = (MirroringHand != EVRGestureMirrorMode::GES_NoMirror && MirroringHand != EVRGestureMirrorMode::GES_MirrorBoth && MirroringHand == exampleGesture.GestureSettings.MirrorMode); + + if (GetGestureDistance(inputGesture.Samples[0] * FinalScaler, exampleGesture.Samples[0], bMirrorGesture) < FMath::Square(exampleGesture.GestureSettings.firstThreshold)) + { + float d = dtw(inputGesture, exampleGesture, bMirrorGesture, FinalScaler) / (exampleGesture.Samples.Num()); + if (d < minDist && d < FMath::Square(exampleGesture.GestureSettings.FullThreshold)) + { + minDist = d; + OutGestureIndex = i; + } + } + else if (exampleGesture.GestureSettings.MirrorMode == EVRGestureMirrorMode::GES_MirrorBoth) + { + bMirrorGesture = true; + if (GetGestureDistance(inputGesture.Samples[0] * FinalScaler, exampleGesture.Samples[0], bMirrorGesture) < FMath::Square(exampleGesture.GestureSettings.firstThreshold)) + { + float d = dtw(inputGesture, exampleGesture, bMirrorGesture, FinalScaler) / (exampleGesture.Samples.Num()); + if (d < minDist && d < FMath::Square(exampleGesture.GestureSettings.FullThreshold)) + { + minDist = d; + OutGestureIndex = i; + } + } + } + + /*if (exampleGesture.MirrorMode == EVRGestureMirrorMode::GES_MirrorBoth) + { + bMirrorGesture = true; + + if (GetGestureDistance(inputGesture.Samples[0], exampleGesture.Samples[0], bMirrorGesture) < FMath::Square(exampleGesture.GestureSettings.firstThreshold)) + { + float d = dtw(inputGesture, exampleGesture, bMirrorGesture) / (exampleGesture.Samples.Num()); + if (d < minDist && d < FMath::Square(exampleGesture.GestureSettings.FullThreshold)) + { + minDist = d; + OutGestureIndex = i; + } + } + }*/ + } + + if (/*minDist < FMath::Square(globalThreshold) && */OutGestureIndex != -1) + { + OnGestureDetected(GesturesDB->Gestures[OutGestureIndex].GestureType, /*minDist,*/ GesturesDB->Gestures[OutGestureIndex].Name, OutGestureIndex, GesturesDB, Size); + OnGestureDetected_Bind.Broadcast(GesturesDB->Gestures[OutGestureIndex].GestureType, /*minDist,*/ GesturesDB->Gestures[OutGestureIndex].Name, OutGestureIndex, GesturesDB, Size); + ClearRecording(); // Clear the recording out, we don't want to detect this gesture again with the same data + RecordingGestureDraw.Reset(); + } +} + +float UVRGestureComponent::dtw(FVRGesture seq1, FVRGesture seq2, bool bMirrorGesture, float Scaler) +{ + + // #TODO: Skip copying the array and reversing it in the future, we only ever use the reversed value. + // So pre-reverse it and keep it stored like that on init. When we do the initial sample we can check off of the first index instead of last then + + // Should also be able to get SizeSquared for values and compared to squared thresholds instead of doing the full SQRT calc. + + // Getting number of average samples recorded over of a gesture (top down) may be able to achieve a basic % completed check + // to see how far into detecting a gesture we are, this would require ignoring the last position threshold though.... + + int RowCount = seq1.Samples.Num() + 1; + int ColumnCount = seq2.Samples.Num() + 1; + + TArray LookupTable; + LookupTable.AddZeroed(ColumnCount * RowCount); + + TArray SlopeI; + SlopeI.AddZeroed(ColumnCount * RowCount); + TArray SlopeJ; + SlopeJ.AddZeroed(ColumnCount * RowCount); + + for (int i = 1; i < (ColumnCount * RowCount); i++) + { + LookupTable[i] = MAX_FLT; + } + // Don't need to do this, it is already handled by add zeroed + //tab[0, 0] = 0; + + int icol = 0, icolneg = 0; + + // Dynamic computation of the DTW matrix. + for (int i = 1; i < RowCount; i++) + { + for (int j = 1; j < ColumnCount; j++) + { + icol = i * ColumnCount; + icolneg = icol - ColumnCount;// (i - 1) * ColumnCount; + + if ( + LookupTable[icol + (j - 1)] < LookupTable[icolneg + (j - 1)] && + LookupTable[icol + (j - 1)] < LookupTable[icolneg + j] && + SlopeI[icol + (j - 1)] < maxSlope) + { + LookupTable[icol + j] = GetGestureDistance(seq1.Samples[i - 1] * Scaler, seq2.Samples[j - 1], bMirrorGesture) + LookupTable[icol + j - 1]; + SlopeI[icol + j] = SlopeJ[icol + j - 1] + 1; + SlopeJ[icol + j] = 0; + } + else if ( + LookupTable[icolneg + j] < LookupTable[icolneg + j - 1] && + LookupTable[icolneg + j] < LookupTable[icol + j - 1] && + SlopeJ[icolneg + j] < maxSlope) + { + LookupTable[icol + j] = GetGestureDistance(seq1.Samples[i - 1] * Scaler, seq2.Samples[j - 1], bMirrorGesture) + LookupTable[icolneg + j]; + SlopeI[icol + j] = 0; + SlopeJ[icol + j] = SlopeJ[icolneg + j] + 1; + } + else + { + LookupTable[icol + j] = GetGestureDistance(seq1.Samples[i - 1] * Scaler, seq2.Samples[j - 1], bMirrorGesture) + LookupTable[icolneg + j - 1]; + SlopeI[icol + j] = 0; + SlopeJ[icol + j] = 0; + } + } + } + + // Find best between seq2 and an ending (postfix) of seq1. + float bestMatch = FLT_MAX; + + for (int i = 1; i < seq1.Samples.Num() + 1/* - seq2.Minimum_Gesture_Length*/; i++) + { + if (LookupTable[(i*ColumnCount) + seq2.Samples.Num()] < bestMatch) + bestMatch = LookupTable[(i*ColumnCount) + seq2.Samples.Num()]; + } + + return bestMatch; +} + +void UVRGestureComponent::DrawDebugGesture(UObject* WorldContextObject, FTransform &StartTransform, FVRGesture GestureToDraw, FColor const& Color, bool bPersistentLines, uint8 DepthPriority, float LifeTime, float Thickness) +{ +#if ENABLE_DRAW_DEBUG + + UWorld* InWorld = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + + if (InWorld != nullptr) + { + // no debug line drawing on dedicated server + if (GEngine->GetNetMode(InWorld) != NM_DedicatedServer && GestureToDraw.Samples.Num() > 1) + { + bool bMirrorGesture = (MirroringHand != EVRGestureMirrorMode::GES_NoMirror && MirroringHand == GestureToDraw.GestureSettings.MirrorMode); + FVector MirrorVector = FVector(1.f, -1.f, 1.f); // Only mirroring on Y axis to flip Left/Right + + // this means foreground lines can't be persistent + ULineBatchComponent* const LineBatcher = (InWorld ? ((DepthPriority == SDPG_Foreground) ? InWorld->ForegroundLineBatcher : ((bPersistentLines || (LifeTime > 0.f)) ? InWorld->PersistentLineBatcher : InWorld->LineBatcher)) : NULL); + + if (LineBatcher != NULL) + { + float const LineLifeTime = (LifeTime > 0.f) ? LifeTime : LineBatcher->DefaultLifeTime; + + TArray Lines; + FBatchedLine Line; + Line.Color = Color; + Line.Thickness = Thickness; + Line.RemainingLifeTime = LineLifeTime; + Line.DepthPriority = DepthPriority; + + FVector FirstLoc = bMirrorGesture ? GestureToDraw.Samples[GestureToDraw.Samples.Num() - 1] * MirrorVector : GestureToDraw.Samples[GestureToDraw.Samples.Num() - 1]; + + for (int i = GestureToDraw.Samples.Num() - 2; i >= 0; --i) + { + Line.Start = bMirrorGesture ? GestureToDraw.Samples[i] * MirrorVector : GestureToDraw.Samples[i]; + + Line.End = FirstLoc; + FirstLoc = Line.Start; + + Line.End = StartTransform.TransformPosition(Line.End); + Line.Start = StartTransform.TransformPosition(Line.Start); + + Lines.Add(Line); + } + + LineBatcher->DrawLines(Lines); + } + } + } +#endif +} + +void UGesturesDatabase::RecalculateGestures(bool bScaleToDatabase) +{ + for (int i = 0; i < Gestures.Num(); ++i) + { + Gestures[i].CalculateSizeOfGesture(bScaleToDatabase, TargetGestureScale); + } +} + +bool UGesturesDatabase::ImportSplineAsGesture(USplineComponent * HostSplineComponent, FString GestureName, bool bKeepSplineCurves, float SegmentLen, bool bScaleToDatabase) +{ + FVRGesture NewGesture; + + if (HostSplineComponent->GetNumberOfSplinePoints() < 2) + return false; + + NewGesture.Name = GestureName; + + FVector FirstPointPos = HostSplineComponent->GetLocationAtSplinePoint(0, ESplineCoordinateSpace::Local); + + float LastDistance = 0.f; + float ThisDistance = 0.f; + FVector LastDistanceV; + FVector ThisDistanceV; + FVector DistNormal; + float DistAlongSegment = 0.f; + + // Realign to xForward on the gesture, normally splines lay out as X to the right + FTransform Realignment = FTransform(FRotator(0.f, 90.f, 0.f), -FirstPointPos); + + // Prefill the first point + NewGesture.Samples.Add(Realignment.TransformPosition(HostSplineComponent->GetLocationAtSplinePoint(HostSplineComponent->GetNumberOfSplinePoints() - 1, ESplineCoordinateSpace::Local))); + + // Inserting in reverse order -2 so we start one down + for (int i = HostSplineComponent->GetNumberOfSplinePoints() - 2; i >= 0; --i) + { + if (bKeepSplineCurves) + { + LastDistance = HostSplineComponent->GetDistanceAlongSplineAtSplinePoint(i + 1); + ThisDistance = HostSplineComponent->GetDistanceAlongSplineAtSplinePoint(i); + + DistAlongSegment = FMath::Abs(ThisDistance - LastDistance); + } + else + { + LastDistanceV = Realignment.TransformPosition(HostSplineComponent->GetLocationAtSplinePoint(i + 1, ESplineCoordinateSpace::Local)); + ThisDistanceV = Realignment.TransformPosition(HostSplineComponent->GetLocationAtSplinePoint(i, ESplineCoordinateSpace::Local)); + + DistAlongSegment = FVector::Dist(ThisDistanceV, LastDistanceV); + DistNormal = ThisDistanceV - LastDistanceV; + DistNormal.Normalize(); + } + + + float SegmentCount = FMath::FloorToFloat(DistAlongSegment / SegmentLen); + float OverFlow = FMath::Fmod(DistAlongSegment, SegmentLen); + + if (SegmentCount < 1) + { + SegmentCount++; + } + + float DistPerSegment = (DistAlongSegment / SegmentCount); + + for (int j = 0; j < SegmentCount; j++) + { + if (j == SegmentCount - 1 && i > 0) + DistPerSegment += OverFlow; + + if (bKeepSplineCurves) + { + LastDistance -= DistPerSegment; + if (j == SegmentCount - 1 && i > 0) + { + LastDistance = ThisDistance; + } + FVector loc = Realignment.TransformPosition(HostSplineComponent->GetLocationAtDistanceAlongSpline(LastDistance, ESplineCoordinateSpace::Local)); + + if (!loc.IsNearlyZero()) + NewGesture.Samples.Add(loc); + } + else + { + LastDistanceV += DistPerSegment * DistNormal; + + if (j == SegmentCount - 1 && i > 0) + { + LastDistanceV = ThisDistanceV; + } + + if (!LastDistanceV.IsNearlyZero()) + NewGesture.Samples.Add(LastDistanceV); + } + } + } + + NewGesture.CalculateSizeOfGesture(bScaleToDatabase, this->TargetGestureScale); + Gestures.Add(NewGesture); + return true; +} + +void FVRGestureSplineDraw::ClearLastPoint() +{ + SplineComponent->RemoveSplinePoint(0, false); + + if (SplineMeshes.Num() < NextIndexCleared + 1) + NextIndexCleared = 0; + + SplineMeshes[NextIndexCleared]->SetVisibility(false); + NextIndexCleared++; +} + +void FVRGestureSplineDraw::Reset() +{ + if (SplineComponent != nullptr) + SplineComponent->ClearSplinePoints(true); + + for (int i = SplineMeshes.Num() - 1; i >= 0; --i) + { + if (SplineMeshes[i] != nullptr) + SplineMeshes[i]->SetVisibility(false); + else + SplineMeshes.RemoveAt(i); + } + + LastIndexSet = 0; + NextIndexCleared = 0; +} + +void FVRGestureSplineDraw::Clear() +{ + for (int i = 0; i < SplineMeshes.Num(); ++i) + { + if (SplineMeshes[i] != nullptr && !SplineMeshes[i]->IsBeingDestroyed()) + { + SplineMeshes[i]->Modify(); + SplineMeshes[i]->DestroyComponent(); + } + } + SplineMeshes.Empty(); + + if (SplineComponent != nullptr) + { + SplineComponent->DestroyComponent(); + SplineComponent = nullptr; + } + + LastIndexSet = 0; + NextIndexCleared = 0; +} + +FVRGestureSplineDraw::FVRGestureSplineDraw() +{ + SplineComponent = nullptr; + NextIndexCleared = 0; + LastIndexSet = 0; +} + +FVRGestureSplineDraw::~FVRGestureSplineDraw() +{ + Clear(); +} + +void UVRGestureComponent::BeginDestroy() +{ + Super::BeginDestroy(); + RecordingGestureDraw.Clear(); + if (TickGestureTimer_Handle.IsValid()) + { + if (UWorld* MyWorld = GetWorld()) + { + MyWorld->GetTimerManager().ClearTimer(TickGestureTimer_Handle); + } + } +} + +void UVRGestureComponent::RecalculateGestureSize(FVRGesture & InputGesture, UGesturesDatabase * GestureDB) +{ + if (GestureDB != nullptr) + InputGesture.CalculateSizeOfGesture(true, GestureDB->TargetGestureScale); + else + InputGesture.CalculateSizeOfGesture(false); +} + +FVRGesture UVRGestureComponent::EndRecording() +{ + if (TickGestureTimer_Handle.IsValid()) + { + if (UWorld* MyWorld = GetWorld()) + { + MyWorld->GetTimerManager().ClearTimer(TickGestureTimer_Handle); + } + } + + this->SetComponentTickEnabled(false); + CurrentState = EVRGestureState::GES_None; + + // Reset the recording gesture + RecordingGestureDraw.Reset(); + + return GestureLog; +} + +void UVRGestureComponent::ClearRecording() +{ + GestureLog.Samples.Reset(RecordingBufferSize); +} + +void UVRGestureComponent::SaveRecording(FVRGesture &Recording, FString RecordingName, bool bScaleRecordingToDatabase) +{ + if (GesturesDB) + { + Recording.CalculateSizeOfGesture(bScaleRecordingToDatabase, GesturesDB->TargetGestureScale); + Recording.Name = RecordingName; + GesturesDB->Gestures.Add(Recording); + } +} diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRGlobalSettings.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRGlobalSettings.cpp new file mode 100644 index 0000000..659b274 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRGlobalSettings.cpp @@ -0,0 +1,463 @@ + +#include "VRGlobalSettings.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRGlobalSettings) + +#include "Chaos/ChaosConstraintSettings.h" +#include "Grippables/GrippableSkeletalMeshComponent.h" + +UVRGlobalSettings::UVRGlobalSettings(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer), + bLerpHybridWithSweepGrips(true), + bOnlyLerpHybridRotation(false), + bHybridWithSweepUseDistanceBasedLerp(true), + HybridWithSweepLerpDuration(0.2f), + bUseGlobalLerpToHand(false), + bSkipLerpToHandIfHeld(false), + MinDistanceForLerp(10.0f), + LerpDuration(0.25f), + MinSpeedForLerp(100.f), + MaxSpeedForLerp(500.f), + LerpInterpolationMode(EVRLerpInterpolationMode::QuatInterp), + bUseCurve(false), + OneEuroMinCutoff(0.1f), + OneEuroCutoffSlope(10.0f), + OneEuroDeltaCutoff(10.0f), + CurrentControllerProfileInUse(NAME_None), + CurrentControllerProfileTransform(FTransform::Identity), + bUseSeperateHandTransforms(false), + CurrentControllerProfileTransformRight(FTransform::Identity) +{ + DefaultGrippableCharacterMeshComponentClass = UGrippableSkeletalMeshComponent::StaticClass(); + + bUseCollisionModificationForCollisionIgnore = false; + CollisionIgnoreSubsystemUpdateRate = 1.f; + + bUseChaosTranslationScalers = false; + bSetEngineChaosScalers = false; + LinearDriveStiffnessScale = 1.0f;// Chaos::ConstraintSettings::LinearDriveStiffnessScale(); + LinearDriveDampingScale = 1.0f;// Chaos::ConstraintSettings::LinearDriveDampingScale(); + AngularDriveStiffnessScale = 0.3f; // 1.5f// Chaos::ConstraintSettings::AngularDriveStiffnessScale(); + AngularDriveDampingScale = 0.3f; // 1.5f// Chaos::ConstraintSettings::AngularDriveDampingScale(); + + // Constraint settings + JointStiffness = 1.0f;// Chaos::ConstraintSettings::JointStiffness(); + SoftLinearStiffnessScale = 1.5f;// Chaos::ConstraintSettings::SoftLinearStiffnessScale(); + SoftLinearDampingScale = 1.2f;// Chaos::ConstraintSettings::SoftLinearDampingScale(); + SoftAngularStiffnessScale = 100000.f;// Chaos::ConstraintSettings::SoftAngularStiffnessScale(); + SoftAngularDampingScale = 1000.f;// Chaos::ConstraintSettings::SoftAngularDampingScale(); + JointLinearBreakScale = 1.0f; //Chaos::ConstraintSettings::LinearBreakScale(); + JointAngularBreakScale = 1.0f; //Chaos::ConstraintSettings::AngularBreakScale(); + +} + +TSubclassOf UVRGlobalSettings::GetDefaultGrippableCharacterMeshComponentClass() +{ + const UVRGlobalSettings* VRSettings = GetDefault(); + + if (VRSettings) + { + // Using a getter to stay safe from bricking peoples projects if they set it to none somehow + if (VRSettings->DefaultGrippableCharacterMeshComponentClass != nullptr) + { + return VRSettings->DefaultGrippableCharacterMeshComponentClass; + } + } + + return UGrippableSkeletalMeshComponent::StaticClass(); +} + +bool UVRGlobalSettings::IsGlobalLerpEnabled() +{ + const UVRGlobalSettings& VRSettings = *GetDefault(); + return VRSettings.bUseGlobalLerpToHand; +} + +FTransform UVRGlobalSettings::AdjustTransformByControllerProfile(FName OptionalControllerProfileName, const FTransform& SocketTransform, bool bIsRightHand) +{ + const UVRGlobalSettings& VRSettings = *GetDefault(); + + if (OptionalControllerProfileName == NAME_None) + { + if (VRSettings.CurrentControllerProfileInUse != NAME_None) + { + // Use currently loaded transform + return SocketTransform * (((bIsRightHand && VRSettings.bUseSeperateHandTransforms) ? VRSettings.CurrentControllerProfileTransformRight : VRSettings.CurrentControllerProfileTransform)); + } + + // No override and no default, return base transform back + return SocketTransform; + } + + // Had an override, find it if possible and use its transform + const FBPVRControllerProfile* FoundProfile = VRSettings.ControllerProfiles.FindByPredicate([OptionalControllerProfileName](const FBPVRControllerProfile& ArrayItem) + { + return ArrayItem.ControllerName == OptionalControllerProfileName; + }); + + if (FoundProfile) + { + return SocketTransform * (((bIsRightHand && VRSettings.bUseSeperateHandTransforms) ? FoundProfile->SocketOffsetTransformRightHand : FoundProfile->SocketOffsetTransform)); + } + + // Couldn't find it, return base transform + return SocketTransform; +} + + +FTransform UVRGlobalSettings::AdjustTransformByGivenControllerProfile(UPARAM(ref) FBPVRControllerProfile& ControllerProfile, const FTransform& SocketTransform, bool bIsRightHand) +{ + // Use currently loaded transform + return SocketTransform * (((bIsRightHand && ControllerProfile.bUseSeperateHandOffsetTransforms) ? ControllerProfile.SocketOffsetTransformRightHand : ControllerProfile.SocketOffsetTransform)); +} + +TArray UVRGlobalSettings::GetControllerProfiles() +{ + const UVRGlobalSettings& VRSettings = *GetDefault(); + + return VRSettings.ControllerProfiles; +} + +void UVRGlobalSettings::OverwriteControllerProfile(UPARAM(ref)FBPVRControllerProfile& OverwritingProfile, bool bSaveOutToConfig) +{ + UVRGlobalSettings& VRSettings = *GetMutableDefault(); + + for (int i = 0; i < VRSettings.ControllerProfiles.Num(); ++i) + { + if (VRSettings.ControllerProfiles[i].ControllerName == OverwritingProfile.ControllerName) + { + VRSettings.ControllerProfiles[i] = OverwritingProfile; + } + } + + if (bSaveOutToConfig) + SaveControllerProfiles(); +} + +void UVRGlobalSettings::AddControllerProfile(UPARAM(ref)FBPVRControllerProfile& NewProfile, bool bSaveOutToConfig) +{ + UVRGlobalSettings& VRSettings = *GetMutableDefault(); + + VRSettings.ControllerProfiles.Add(NewProfile); + + if (bSaveOutToConfig) + SaveControllerProfiles(); +} + +void UVRGlobalSettings::DeleteControllerProfile(FName ControllerProfileName, bool bSaveOutToConfig) +{ + UVRGlobalSettings& VRSettings = *GetMutableDefault(); + + for (int i = VRSettings.ControllerProfiles.Num() - 1; i >= 0; --i) + { + if (VRSettings.ControllerProfiles[i].ControllerName == ControllerProfileName) + { + VRSettings.ControllerProfiles.RemoveAt(i); + } + } + + if (bSaveOutToConfig) + SaveControllerProfiles(); +} + +void UVRGlobalSettings::SaveControllerProfiles() +{ + UVRGlobalSettings& VRSettings = *GetMutableDefault(); + VRSettings.SaveConfig(); + + //VRSettings.SaveConfig(CPF_Config, *VRSettings.GetGlobalUserConfigFilename());//VRSettings.GetDefaultConfigFilename()); +} + + +FName UVRGlobalSettings::GetCurrentProfileName(bool& bHadLoadedProfile) +{ + const UVRGlobalSettings& VRSettings = *GetDefault(); + + bHadLoadedProfile = VRSettings.CurrentControllerProfileInUse != NAME_None; + return VRSettings.CurrentControllerProfileInUse; +} + +FBPVRControllerProfile UVRGlobalSettings::GetCurrentProfile(bool& bHadLoadedProfile) +{ + const UVRGlobalSettings& VRSettings = *GetDefault(); + + FName ControllerProfileName = VRSettings.CurrentControllerProfileInUse; + const FBPVRControllerProfile* FoundProfile = VRSettings.ControllerProfiles.FindByPredicate([ControllerProfileName](const FBPVRControllerProfile& ArrayItem) + { + return ArrayItem.ControllerName == ControllerProfileName; + }); + + bHadLoadedProfile = FoundProfile != nullptr; + + if (bHadLoadedProfile) + { + return *FoundProfile; + } + else + return FBPVRControllerProfile(); +} + +bool UVRGlobalSettings::GetControllerProfile(FName ControllerProfileName, FBPVRControllerProfile& OutProfile) +{ + const UVRGlobalSettings& VRSettings = *GetDefault(); + + const FBPVRControllerProfile* FoundProfile = VRSettings.ControllerProfiles.FindByPredicate([ControllerProfileName](const FBPVRControllerProfile& ArrayItem) + { + return ArrayItem.ControllerName == ControllerProfileName; + }); + + if (FoundProfile) + { + OutProfile = *FoundProfile; + return true; + } + + return false; +} + +bool UVRGlobalSettings::LoadControllerProfileByName(FName ControllerProfileName, bool bSetAsCurrentProfile) +{ + const UVRGlobalSettings& VRSettings = *GetDefault(); + + const FBPVRControllerProfile* FoundProfile = VRSettings.ControllerProfiles.FindByPredicate([ControllerProfileName](const FBPVRControllerProfile& ArrayItem) + { + return ArrayItem.ControllerName == ControllerProfileName; + }); + + if (FoundProfile) + { + return LoadControllerProfile(*FoundProfile, bSetAsCurrentProfile); + } + + + UE_LOG(LogTemp, Warning, TEXT("Could not find controller profile!: %s"), *ControllerProfileName.ToString()); + return false; +} + +bool UVRGlobalSettings::LoadControllerProfile(const FBPVRControllerProfile& ControllerProfile, bool bSetAsCurrentProfile) +{ + + /* + UInputSettings* InputSettings = GetMutableDefault(); + if (false)//InputSettings != nullptr) + { + if (ControllerProfile.ActionOverrides.Num() > 0) + { + // Load button mappings + for (auto& Elem : ControllerProfile.ActionOverrides) + { + FName ActionName = Elem.Key; + FActionMappingDetails Mapping = Elem.Value; + + // We allow for 0 mapped actions here in case you want to delete one + if (ActionName == NAME_None) + continue; + + const TArray& ActionMappings = InputSettings->GetActionMappings(); + for (int32 ActionIndex = ActionMappings.Num() - 1; ActionIndex >= 0; --ActionIndex) + { + if (ActionMappings[ActionIndex].ActionName == ActionName) + { + InputSettings->RemoveActionMapping(ActionMappings[ActionIndex], false); + // we don't break because the mapping may have been in the array twice + } + } + + // Then add the new bindings + for (FInputActionKeyMapping &KeyMapping : Mapping.ActionMappings) + { + // By default the key mappings don't have an action name, add them here + KeyMapping.ActionName = ActionName; + InputSettings->AddActionMapping(KeyMapping, false); + } + } + } + + if (ControllerProfile.AxisOverrides.Num() > 0) + { + // Load axis mappings + for (auto& Elem : ControllerProfile.AxisOverrides) + { + FName AxisName = Elem.Key; + FAxisMappingDetails Mapping = Elem.Value; + + // We allow for 0 mapped Axis's here in case you want to delete one + if (AxisName == NAME_None) + continue; + + const TArray& AxisMappings = InputSettings->GetAxisMappings(); + + // Clear all Axis's that use our Axis name first + for (int32 AxisIndex = AxisMappings.Num() - 1; AxisIndex >= 0; --AxisIndex) + { + if (AxisMappings[AxisIndex].AxisName == AxisName) + { + InputSettings->RemoveAxisMapping(AxisMappings[AxisIndex], false); + // we don't break because the mapping may have been in the array twice + } + } + + // Then add the new bindings + for (FInputAxisKeyMapping &KeyMapping : Mapping.AxisMappings) + { + // By default the key mappings don't have an Axis name, add them here + KeyMapping.AxisName = AxisName; + InputSettings->AddAxisMapping(KeyMapping, false); + } + } + } + + if (ControllerProfile.ActionOverrides.Num() > 0 || ControllerProfile.AxisOverrides.Num() > 0) + { + // Tell all players to use the new keymappings + InputSettings->ForceRebuildKeymaps(); + } + }*/ + + if (bSetAsCurrentProfile) + { + UVRGlobalSettings* VRSettings = GetMutableDefault(); + if (VRSettings) + { + VRSettings->CurrentControllerProfileInUse = ControllerProfile.ControllerName; + VRSettings->CurrentControllerProfileTransform = ControllerProfile.SocketOffsetTransform; + ensure(!VRSettings->CurrentControllerProfileTransform.ContainsNaN()); + VRSettings->bUseSeperateHandTransforms = ControllerProfile.bUseSeperateHandOffsetTransforms; + VRSettings->CurrentControllerProfileTransformRight = ControllerProfile.SocketOffsetTransformRightHand; + ensure(!VRSettings->CurrentControllerProfileTransformRight.ContainsNaN()); + VRSettings->OnControllerProfileChangedEvent.Broadcast(); + } + else + return false; + } + + + // Not saving key mapping in purpose, app will revert to default on next load and profiles will load custom changes + return true; +} + +void UVRGlobalSettings::PostInitProperties() +{ +#if WITH_EDITOR + // Not doing this currently, loading defaults is cool, and I may go back to it later when i get + // controller offsets for vive/touch/MR vs each other. + /*if (ControllerProfiles.Num() == 0) + { + ControllerProfiles.Add(FBPVRControllerProfile(TEXT("Vive_Wands"))); + ControllerProfiles.Add(FBPVRControllerProfile(TEXT("Oculus_Touch"), ControllerProfileStatics::OculusTouchStaticOffset)); + this->SaveConfig(CPF_Config, *this->GetDefaultConfigFilename()); + }*/ +#endif + + SetScalers(); + + Super::PostInitProperties(); +} + +#if WITH_EDITOR + +void UVRGlobalSettings::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) +{ + Super::PostEditChangeProperty(PropertyChangedEvent); + + FProperty* PropertyThatChanged = PropertyChangedEvent.Property; + + if (PropertyThatChanged != nullptr) + { +#if WITH_EDITORONLY_DATA + if ( + PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UVRGlobalSettings, bUseChaosTranslationScalers) || + PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UVRGlobalSettings, bSetEngineChaosScalers) || + PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UVRGlobalSettings, LinearDriveStiffnessScale) || + PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UVRGlobalSettings, LinearDriveDampingScale) || + PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UVRGlobalSettings, AngularDriveStiffnessScale) || + PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UVRGlobalSettings, AngularDriveDampingScale) || + PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UVRGlobalSettings, JointStiffness) || + PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UVRGlobalSettings, SoftLinearStiffnessScale) || + PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UVRGlobalSettings, SoftLinearDampingScale) || + PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UVRGlobalSettings, SoftAngularStiffnessScale) || + PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UVRGlobalSettings, SoftAngularDampingScale) || + PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UVRGlobalSettings, JointLinearBreakScale) || + PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(UVRGlobalSettings, JointAngularBreakScale) + ) + { + SetScalers(); + } +#endif + } +} +#endif + +void UVRGlobalSettings::SetScalers() +{ + auto CVarLinearDriveStiffnessScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.LinearDriveStiffnessScale")); + auto CVarLinearDriveDampingScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.LinaearDriveDampingScale")); + auto CVarAngularDriveStiffnessScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.AngularDriveStiffnessScale")); + auto CVarAngularDriveDampingScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.AngularDriveDampingScale")); + + // Constraint settings + auto CVarJointStiffness = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.JointStiffness")); + auto CVarSoftLinearStiffnessScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.SoftLinearStiffnessScale")); + auto CVarSoftLinearDampingScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.SoftLinearDampingScale")); + auto CVarSoftAngularStiffnessScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.SoftAngularStiffnessScale")); + auto CVarSoftAngularDampingScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.SoftAngularDampingScale")); + auto CVarJointLinearBreakScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.LinearBreakScale")); + auto CVarJointAngularBreakScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.AngularBreakScale")); + + if (bUseChaosTranslationScalers && bSetEngineChaosScalers) + { + CVarLinearDriveStiffnessScale->Set(LinearDriveStiffnessScale, EConsoleVariableFlags::ECVF_SetByCode); + CVarLinearDriveDampingScale->Set(LinearDriveDampingScale, EConsoleVariableFlags::ECVF_SetByCode); + CVarAngularDriveStiffnessScale->Set(AngularDriveStiffnessScale, EConsoleVariableFlags::ECVF_SetByCode); + CVarAngularDriveDampingScale->Set(AngularDriveDampingScale, EConsoleVariableFlags::ECVF_SetByCode); + + // Constraint settings + CVarJointStiffness->Set(JointStiffness, EConsoleVariableFlags::ECVF_SetByCode); + CVarSoftLinearStiffnessScale->Set(SoftLinearStiffnessScale, EConsoleVariableFlags::ECVF_SetByCode); + CVarSoftLinearDampingScale->Set(SoftLinearDampingScale, EConsoleVariableFlags::ECVF_SetByCode); + CVarSoftAngularStiffnessScale->Set(SoftAngularStiffnessScale, EConsoleVariableFlags::ECVF_SetByCode); + CVarSoftAngularDampingScale->Set(SoftAngularDampingScale, EConsoleVariableFlags::ECVF_SetByCode); + CVarJointLinearBreakScale->Set(JointLinearBreakScale, EConsoleVariableFlags::ECVF_SetByCode); + CVarJointAngularBreakScale->Set(JointAngularBreakScale, EConsoleVariableFlags::ECVF_SetByCode); + } + else if (!bSetEngineChaosScalers) + { + CVarLinearDriveStiffnessScale->Set(1.0f, EConsoleVariableFlags::ECVF_SetByCode); + CVarLinearDriveDampingScale->Set(1.0f, EConsoleVariableFlags::ECVF_SetByCode); + CVarAngularDriveStiffnessScale->Set(1.5f, EConsoleVariableFlags::ECVF_SetByCode); + CVarAngularDriveDampingScale->Set(1.5f, EConsoleVariableFlags::ECVF_SetByCode); + + // Constraint settings + CVarJointStiffness->Set(1.0f, EConsoleVariableFlags::ECVF_SetByCode); + CVarSoftLinearStiffnessScale->Set(1.5f, EConsoleVariableFlags::ECVF_SetByCode); + CVarSoftLinearDampingScale->Set(1.2f, EConsoleVariableFlags::ECVF_SetByCode); + CVarSoftAngularStiffnessScale->Set(100000.f, EConsoleVariableFlags::ECVF_SetByCode); + CVarSoftAngularDampingScale->Set(1000.f, EConsoleVariableFlags::ECVF_SetByCode); + CVarJointLinearBreakScale->Set(1.0f, EConsoleVariableFlags::ECVF_SetByCode); + CVarJointAngularBreakScale->Set(1.0f, EConsoleVariableFlags::ECVF_SetByCode); + } +} + +void UVRGlobalSettings::GetMeleeSurfaceGlobalSettings(TArray& OutMeleeSurfaceSettings) +{ + const UVRGlobalSettings& VRSettings = *GetDefault(); + OutMeleeSurfaceSettings = VRSettings.MeleeSurfaceSettings; +} + +void UVRGlobalSettings::GetVirtualStockGlobalSettings(FBPVirtualStockSettings& OutVirtualStockSettings) +{ + const UVRGlobalSettings& VRSettings = *GetDefault(); + + OutVirtualStockSettings.bUseDistanceBasedStockSnapping = VRSettings.VirtualStockSettings.bUseDistanceBasedStockSnapping; + OutVirtualStockSettings.StockSnapDistance = VRSettings.VirtualStockSettings.StockSnapDistance; + OutVirtualStockSettings.StockSnapOffset = VRSettings.VirtualStockSettings.StockSnapOffset; + OutVirtualStockSettings.bSmoothStockHand = VRSettings.VirtualStockSettings.bSmoothStockHand; + OutVirtualStockSettings.SmoothingValueForStock = VRSettings.VirtualStockSettings.SmoothingValueForStock; +} + +void UVRGlobalSettings::SaveVirtualStockGlobalSettings(FBPVirtualStockSettings NewVirtualStockSettings) +{ + UVRGlobalSettings& VRSettings = *GetMutableDefault(); + VRSettings.VirtualStockSettings = NewVirtualStockSettings; + + VRSettings.SaveConfig(); +} diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRGripInterface.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRGripInterface.cpp new file mode 100644 index 0000000..242c872 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRGripInterface.cpp @@ -0,0 +1,20 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#include "VRGripInterface.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRGripInterface) + +#include "UObject/ObjectMacros.h" +#include "GripScripts/VRGripScriptBase.h" +#include "UObject/Interface.h" + +UVRGripInterface::UVRGripInterface(const class FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + +} + + +void IVRGripInterface::Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed) +{ + +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRPathFollowingComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRPathFollowingComponent.cpp new file mode 100644 index 0000000..ffdc6df --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRPathFollowingComponent.cpp @@ -0,0 +1,474 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "VRPathFollowingComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRPathFollowingComponent) + +#include "CoreMinimal.h" +#include "Engine/World.h" +//#include "Runtime/Engine/Private/EnginePrivate.h" + +//#if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 13 +#include "Navigation/MetaNavMeshPath.h" +#include "NavLinkCustomInterface.h" +//#endif + +// Force to use new movement comp + +DEFINE_LOG_CATEGORY(LogPathFollowingVR); + +void UVRPathFollowingComponent::SetMovementComponent(UNavMovementComponent* MoveComp) +{ + Super::SetMovementComponent(MoveComp); + + VRMovementComp = Cast(MovementComp); + + if (VRMovementComp) + { + OnRequestFinished.AddUObject(VRMovementComp, &UVRBaseCharacterMovementComponent::OnMoveCompleted); + } +} + + +void UVRPathFollowingComponent::GetDebugStringTokens(TArray& Tokens, TArray& Flags) const +{ + Tokens.Add(GetStatusDesc()); + Flags.Add(EPathFollowingDebugTokens::Description); + + if (Status != EPathFollowingStatus::Moving) + { + return; + } + + FString& StatusDesc = Tokens[0]; + if (Path.IsValid()) + { + const int32 NumMoveSegments = (Path.IsValid() && Path->IsValid()) ? Path->GetPathPoints().Num() : -1; + const bool bIsDirect = (Path->CastPath() != NULL); + const bool bIsCustomLink = CurrentCustomLinkOb.IsValid(); + + if (!bIsDirect) + { + StatusDesc += FString::Printf(TEXT(" (%d..%d/%d)%s"), MoveSegmentStartIndex + 1, MoveSegmentEndIndex + 1, NumMoveSegments, + bIsCustomLink ? TEXT(" (custom NavLink)") : TEXT("")); + } + else + { + StatusDesc += TEXT(" (direct)"); + } + } + else + { + StatusDesc += TEXT(" (invalid path)"); + } + + // add debug params + float CurrentDot = 0.0f, CurrentDistance = 0.0f, CurrentHeight = 0.0f; + uint8 bFailedDot = 0, bFailedDistance = 0, bFailedHeight = 0; + DebugReachTest(CurrentDot, CurrentDistance, CurrentHeight, bFailedHeight, bFailedDistance, bFailedHeight); + + Tokens.Add(TEXT("dot")); + Flags.Add(EPathFollowingDebugTokens::ParamName); + Tokens.Add(FString::Printf(TEXT("%.2f"), CurrentDot)); + Flags.Add(bFailedDot ? EPathFollowingDebugTokens::FailedValue : EPathFollowingDebugTokens::PassedValue); + + Tokens.Add(TEXT("dist2D")); + Flags.Add(EPathFollowingDebugTokens::ParamName); + Tokens.Add(FString::Printf(TEXT("%.0f"), CurrentDistance)); + Flags.Add(bFailedDistance ? EPathFollowingDebugTokens::FailedValue : EPathFollowingDebugTokens::PassedValue); + + Tokens.Add(TEXT("distZ")); + Flags.Add(EPathFollowingDebugTokens::ParamName); + Tokens.Add(FString::Printf(TEXT("%.0f"), CurrentHeight)); + Flags.Add(bFailedHeight ? EPathFollowingDebugTokens::FailedValue : EPathFollowingDebugTokens::PassedValue); +} + +void UVRPathFollowingComponent::PauseMove(FAIRequestID RequestID, EPathFollowingVelocityMode VelocityMode) +{ + //UE_VLOG(GetOwner(), LogPathFollowing, Log, TEXT("PauseMove: RequestID(%u)"), RequestID); + if (Status == EPathFollowingStatus::Paused) + { + return; + } + + if (RequestID.IsEquivalent(GetCurrentRequestId())) + { + if ((VelocityMode == EPathFollowingVelocityMode::Reset) && MovementComp && HasMovementAuthority()) + { + MovementComp->StopMovementKeepPathing(); + } + + LocationWhenPaused = MovementComp ? (VRMovementComp != nullptr ? VRMovementComp->GetActorFeetLocationVR() : MovementComp->GetActorFeetLocation()) : FVector::ZeroVector; + PathTimeWhenPaused = Path.IsValid() ? Path->GetTimeStamp() : 0.; + Status = EPathFollowingStatus::Paused; + + UpdateMoveFocus(); + } +} + + + +bool UVRPathFollowingComponent::ShouldCheckPathOnResume() const +{ + bool bCheckPath = true; + if (MovementComp != NULL) + { + float AgentRadius = 0.0f, AgentHalfHeight = 0.0f; + MovementComp->GetOwner()->GetSimpleCollisionCylinder(AgentRadius, AgentHalfHeight); + + const FVector CurrentLocation = (VRMovementComp != nullptr ? VRMovementComp->GetActorFeetLocation() : MovementComp->GetActorFeetLocation()); + const FVector::FReal DeltaMove2DSq = (CurrentLocation - LocationWhenPaused).SizeSquared2D(); + const FVector::FReal DeltaZ = FMath::Abs(CurrentLocation.Z - LocationWhenPaused.Z); + if (DeltaMove2DSq < FMath::Square(AgentRadius) && DeltaZ < (AgentHalfHeight * 0.5)) + { + bCheckPath = false; + } + } + + return bCheckPath; +} + +int32 UVRPathFollowingComponent::DetermineStartingPathPoint(const FNavigationPath* ConsideredPath) const +{ + int32 PickedPathPoint = INDEX_NONE; + + if (ConsideredPath && ConsideredPath->IsValid()) + { + // if we already have some info on where we were on previous path + // we can find out if there's a segment on new path we're currently at + if (MoveSegmentStartRef != INVALID_NAVNODEREF && + MoveSegmentEndRef != INVALID_NAVNODEREF && + ConsideredPath->GetNavigationDataUsed() != NULL) + { + // iterate every new path node and see if segment match + for (int32 PathPoint = 0; PathPoint < ConsideredPath->GetPathPoints().Num() - 1; ++PathPoint) + { + if (ConsideredPath->GetPathPoints()[PathPoint].NodeRef == MoveSegmentStartRef && + ConsideredPath->GetPathPoints()[PathPoint + 1].NodeRef == MoveSegmentEndRef) + { + PickedPathPoint = PathPoint; + break; + } + } + } + + if (MovementComp && PickedPathPoint == INDEX_NONE) + { + if (ConsideredPath->GetPathPoints().Num() > 2) + { + // check if is closer to first or second path point (don't assume AI's standing) + const FVector CurrentLocation = (VRMovementComp != nullptr ? VRMovementComp->GetActorFeetLocationVR() : MovementComp->GetActorFeetLocation()); + const FVector PathPt0 = *ConsideredPath->GetPathPointLocation(0); + const FVector PathPt1 = *ConsideredPath->GetPathPointLocation(1); + // making this test in 2d to avoid situation where agent's Z location not being in "navmesh plane" + // would influence the result + const FVector::FReal SqDistToFirstPoint = (CurrentLocation - PathPt0).SizeSquared2D(); + const FVector::FReal SqDistToSecondPoint = (CurrentLocation - PathPt1).SizeSquared2D(); + PickedPathPoint = FMath::IsNearlyEqual(SqDistToFirstPoint, SqDistToSecondPoint) ? + ((FMath::Abs(CurrentLocation.Z - PathPt0.Z) < FMath::Abs(CurrentLocation.Z - PathPt1.Z)) ? 0 : 1) : + ((SqDistToFirstPoint < SqDistToSecondPoint) ? 0 : 1); + } + else + { + // If there are only two point we probably should start from the beginning + PickedPathPoint = 0; + } + } + } + + return PickedPathPoint; +} + +bool UVRPathFollowingComponent::UpdateBlockDetection() +{ + const double GameTime = GetWorld()->GetTimeSeconds(); + if (bUseBlockDetection && + MovementComp && + GameTime > (LastSampleTime + BlockDetectionInterval) && + BlockDetectionSampleCount > 0) + { + LastSampleTime = GameTime; + + if (LocationSamples.Num() == NextSampleIdx) + { + LocationSamples.AddZeroed(1); + } + + LocationSamples[NextSampleIdx] = (VRMovementComp != nullptr ? VRMovementComp->GetActorFeetLocationBased() : MovementComp->GetActorFeetLocationBased()); + NextSampleIdx = (NextSampleIdx + 1) % BlockDetectionSampleCount; + return true; + } + + return false; +} + +void UVRPathFollowingComponent::UpdatePathSegment() +{ +#if !UE_BUILD_SHIPPING + DEBUG_bMovingDirectlyToGoal = false; +#endif // !UE_BUILD_SHIPPING + + if ((Path.IsValid() == false) || (MovementComp == nullptr)) + { + //UE_CVLOG(Path.IsValid() == false, this, LogPathFollowing, Log, TEXT("Aborting move due to not having a valid path object")); + OnPathFinished(EPathFollowingResult::Aborted, FPathFollowingResultFlags::InvalidPath); + return; + } + + if (!Path->IsValid()) + { + if (!Path->IsWaitingForRepath()) + { + //UE_VLOG(this, LogPathFollowing, Log, TEXT("Aborting move due to path being invelid and not waiting for repath")); + OnPathFinished(EPathFollowingResult::Aborted, FPathFollowingResultFlags::InvalidPath); + } + + return; + } + + FMetaNavMeshPath* MetaNavPath = bIsUsingMetaPath ? Path->CastPath() : nullptr; + + // if agent has control over its movement, check finish conditions + const FVector CurrentLocation = (VRMovementComp != nullptr ? VRMovementComp->GetActorFeetLocationVR() : MovementComp->GetActorFeetLocation()); + const bool bCanUpdateState = HasMovementAuthority(); + if (bCanUpdateState && Status == EPathFollowingStatus::Moving) + { + const int32 LastSegmentEndIndex = Path->GetPathPoints().Num() - 1; + const bool bFollowingLastSegment = (MoveSegmentEndIndex >= LastSegmentEndIndex); + const bool bLastPathChunk = (MetaNavPath == nullptr || MetaNavPath->IsLastSection()); + + if (bCollidedWithGoal) + { + // check if collided with goal actor + OnSegmentFinished(); + OnPathFinished(EPathFollowingResult::Success, FPathFollowingResultFlags::None); + } + else if (HasReachedDestination(CurrentLocation)) + { + // always check for destination, acceptance radius may cause it to pass before reaching last segment + OnSegmentFinished(); + OnPathFinished(EPathFollowingResult::Success, FPathFollowingResultFlags::None); + } + else if (bFollowingLastSegment && bMoveToGoalOnLastSegment && bLastPathChunk) + { + // use goal actor for end of last path segment + // UNLESS it's partial path (can't reach goal) + if (DestinationActor.IsValid() && Path->IsPartial() == false) + { + const FVector AgentLocation = DestinationAgent ? DestinationAgent->GetNavAgentLocation() : DestinationActor->GetActorLocation(); + // note that the condition below requires GoalLocation to be in world space. + FVector GoalLocation = FQuatRotationTranslationMatrix(DestinationActor->GetActorQuat(), AgentLocation).TransformPosition(MoveOffset); + + if (bMoveToGoalClampedToNavigation && NavigationFilter) + { + FVector HitLocation; + if (MyNavData->Raycast(CurrentLocation, GoalLocation, HitLocation, NavigationFilter)) + { + GoalLocation = HitLocation; + } + } + CurrentDestination.Set(NULL, GoalLocation); + + //UE_VLOG(this, LogPathFollowing, Log, TEXT("Moving directly to move goal rather than following last path segment")); + //UE_VLOG_LOCATION(this, LogPathFollowing, VeryVerbose, GoalLocation, 30, FColor::Green, TEXT("Last-segment-to-actor")); + //UE_VLOG_SEGMENT(this, LogPathFollowing, VeryVerbose, CurrentLocation, GoalLocation, FColor::Green, TEXT_EMPTY); + } + + UpdateMoveFocus(); + +#if !UE_BUILD_SHIPPING + DEBUG_bMovingDirectlyToGoal = true; +#endif // !UE_BUILD_SHIPPING + } + // check if current move segment is finished + else if (HasReachedCurrentTarget(CurrentLocation)) + { + OnSegmentFinished(); + SetNextMoveSegment(); + } + } + + if (bCanUpdateState && Status == EPathFollowingStatus::Moving) + { + // check waypoint switch condition in meta paths + if (MetaNavPath && Status == EPathFollowingStatus::Moving) + { + MetaNavPath->ConditionalMoveToNextSection(CurrentLocation, EMetaPathUpdateReason::MoveTick); + } + + // gather location samples to detect if moving agent is blocked + const bool bHasNewSample = UpdateBlockDetection(); + if (bHasNewSample && IsBlocked()) + { + if (Path->GetPathPoints().IsValidIndex(MoveSegmentEndIndex) && Path->GetPathPoints().IsValidIndex(MoveSegmentStartIndex)) + { + //LogBlockHelper(GetOwner(), MovementComp, MinAgentRadiusPct, MinAgentHalfHeightPct, + //*Path->GetPathPointLocation(MoveSegmentStartIndex), + //*Path->GetPathPointLocation(MoveSegmentEndIndex)); + } + else + { + if ((GetOwner() != NULL) && (MovementComp != NULL)) + { + // UE_VLOG(GetOwner(), LogPathFollowing, Verbose, TEXT("Path blocked, but move segment indices are not valid: start %d, end %d of %d"), MoveSegmentStartIndex, MoveSegmentEndIndex, Path->GetPathPoints().Num()); + } + } + OnPathFinished(EPathFollowingResult::Blocked, FPathFollowingResultFlags::None); + } + } +} + +void UVRPathFollowingComponent::FollowPathSegment(float DeltaTime) +{ + if (!Path.IsValid() || MovementComp == nullptr) + { + return; + } + + const FVector CurrentLocation = (VRMovementComp != nullptr ? VRMovementComp->GetActorFeetLocationVR() : MovementComp->GetActorFeetLocation()); + const FVector CurrentTarget = GetCurrentTargetLocation(); + + // set to false by default, we will set set this back to true if appropriate + bIsDecelerating = false; + + const bool bAccelerationBased = MovementComp->UseAccelerationForPathFollowing(); + if (bAccelerationBased) + { + CurrentMoveInput = (CurrentTarget - CurrentLocation).GetSafeNormal(); + + if (bStopMovementOnFinish && (MoveSegmentStartIndex >= DecelerationSegmentIndex)) + { + const FVector PathEnd = Path->GetEndLocation(); + const FVector::FReal DistToEndSq = FVector::DistSquared(CurrentLocation, PathEnd); + const bool bShouldDecelerate = DistToEndSq < FMath::Square(CachedBrakingDistance); + if (bShouldDecelerate) + { + bIsDecelerating = true; + + const FVector::FReal SpeedPct = FMath::Clamp(FMath::Sqrt(DistToEndSq) / CachedBrakingDistance, 0., 1.); + CurrentMoveInput *= SpeedPct; + } + } + + PostProcessMove.ExecuteIfBound(this, CurrentMoveInput); + MovementComp->RequestPathMove(CurrentMoveInput); + } + else + { + FVector MoveVelocity = (CurrentTarget - CurrentLocation) / DeltaTime; + + const int32 LastSegmentStartIndex = Path->GetPathPoints().Num() - 2; + const bool bNotFollowingLastSegment = (MoveSegmentStartIndex < LastSegmentStartIndex); + + PostProcessMove.ExecuteIfBound(this, MoveVelocity); + MovementComp->RequestDirectMove(MoveVelocity, bNotFollowingLastSegment); + } +} + +bool UVRPathFollowingComponent::HasReachedCurrentTarget(const FVector& CurrentLocation) const +{ + if (MovementComp == NULL) + { + return false; + } + + // If the next segment is a link with a custom reach condition, we need to call the HasReachedLinkStart on the link interface. + if (bMoveSegmentIsUsingCustomLinkReachCondition) + { + if (const INavLinkCustomInterface* MoveSegmentCustomLink = Cast(MoveSegmentCustomLinkOb.Get())) + { + if (ensureMsgf(Path.IsValid(), TEXT("%hs: Path should be valid when we get here. Owner [%s]."), __FUNCTION__, *GetNameSafe(GetOwner()))) + { + const FNavPathPoint& LinkStart = Path->GetPathPoints()[MoveSegmentEndIndex]; + if (Path->GetPathPoints().IsValidIndex(MoveSegmentEndIndex + 1)) + { + const FNavPathPoint& LinkEnd = Path->GetPathPoints()[MoveSegmentEndIndex + 1]; + return MoveSegmentCustomLink->HasReachedLinkStart(this, CurrentLocation, LinkStart, LinkEnd); + } + else + { + UE_LOG(LogPathFollowing, Error, TEXT("%hs: NavLink has a start, but no end. Custom reach condition won't be called. NavLinkID [%llu] - LinkStartPos [%s] - Owner [%s]"), __FUNCTION__, LinkStart.CustomNavLinkId.GetId(), *LinkStart.Location.ToString(), *GetNameSafe(GetOwner())); + } + } + } + } + + const FVector CurrentTarget = GetCurrentTargetLocation(); + const FVector CurrentDirection = GetCurrentDirection(); + + // check if moved too far + const FVector ToTarget = (CurrentTarget - (VRMovementComp != nullptr ? VRMovementComp->GetActorFeetLocationVR() : MovementComp->GetActorFeetLocation())); + const FVector::FReal SegmentDot = FVector::DotProduct(ToTarget, CurrentDirection); + if (SegmentDot < 0.) + { + return true; + } + + // or standing at target position + // don't use acceptance radius here, it has to be exact for moving near corners (2D test < 5% of agent radius) + const float GoalRadius = 0.0f; + const float GoalHalfHeight = 0.0f; + + return HasReachedInternal(CurrentTarget, GoalRadius, GoalHalfHeight, CurrentLocation, CurrentAcceptanceRadius, 0.05f); +} + +void UVRPathFollowingComponent::DebugReachTest(float& CurrentDot, float& CurrentDistance, float& CurrentHeight, uint8& bDotFailed, uint8& bDistanceFailed, uint8& bHeightFailed) const +{ + if (!Path.IsValid() || MovementComp == NULL) + { + return; + } + + const int32 LastSegmentEndIndex = Path->GetPathPoints().Num() - 1; + const bool bFollowingLastSegment = (MoveSegmentEndIndex >= LastSegmentEndIndex); + + float GoalRadius = 0.0f; + float GoalHalfHeight = 0.0f; + float RadiusThreshold = 0.0f; + float AgentRadiusPct = 0.05f; + + FVector AgentLocation = (VRMovementComp != nullptr ? VRMovementComp->GetActorFeetLocationVR() : MovementComp->GetActorFeetLocation()); + FVector GoalLocation = GetCurrentTargetLocation(); + RadiusThreshold = CurrentAcceptanceRadius; + + if (bFollowingLastSegment) + { + GoalLocation = *Path->GetPathPointLocation(Path->GetPathPoints().Num() - 1); + AgentRadiusPct = MinAgentRadiusPct; + + // take goal's current location, unless path is partial or last segment doesn't reach goal actor (used by tethered AI) + if (DestinationActor.IsValid() && !Path->IsPartial() && bMoveToGoalOnLastSegment) + { + if (DestinationAgent) + { + FVector GoalOffset; + + const AActor* OwnerActor = GetOwner(); + DestinationAgent->GetMoveGoalReachTest(OwnerActor, MoveOffset, GoalOffset, GoalRadius, GoalHalfHeight); + GoalLocation = FQuatRotationTranslationMatrix(DestinationActor->GetActorQuat(), DestinationAgent->GetNavAgentLocation()).TransformPosition(GoalOffset); + } + else + { + GoalLocation = DestinationActor->GetActorLocation(); + } + } + } + + const FVector ToGoal = (GoalLocation - AgentLocation); + const FVector CurrentDirection = GetCurrentDirection(); + CurrentDot = FloatCastChecked(FVector::DotProduct(ToGoal.GetSafeNormal(), CurrentDirection), /* Precision */ 1. / 128.); + bDotFailed = (CurrentDot < 0.0f) ? 1 : 0; + + // get cylinder of moving agent + float AgentRadius = 0.0f; + float AgentHalfHeight = 0.0f; + AActor* MovingAgent = MovementComp->GetOwner(); + MovingAgent->GetSimpleCollisionCylinder(AgentRadius, AgentHalfHeight); + + CurrentDistance = FloatCastChecked(ToGoal.Size2D(), UE::LWC::DefaultFloatPrecision); + const float UseRadius = FMath::Max(RadiusThreshold, GoalRadius + (AgentRadius * AgentRadiusPct)); + bDistanceFailed = (CurrentDistance > UseRadius) ? 1 : 0; + + CurrentHeight = FloatCastChecked(FMath::Abs(ToGoal.Z), UE::LWC::DefaultFloatPrecision); + const float UseHeight = GoalHalfHeight + (AgentHalfHeight * MinAgentHalfHeightPct); + bHeightFailed = (CurrentHeight > UseHeight) ? 1 : 0; +} diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRPlayerController.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRPlayerController.cpp new file mode 100644 index 0000000..94614cb --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRPlayerController.cpp @@ -0,0 +1,104 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "VRPlayerController.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRPlayerController) + +#include "AI/NavigationSystemBase.h" +#include "VRBaseCharacterMovementComponent.h" +#include "VRPathFollowingComponent.h" +//#include "VRBPDatatypes.h" +#include "Engine/Player.h" +//#include "Runtime/Engine/Private/EnginePrivate.h" + + +AVRPlayerController::AVRPlayerController(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + bDisableServerUpdateCamera = true; +} + +void AVRPlayerController::SpawnPlayerCameraManager() +{ + Super::SpawnPlayerCameraManager(); + + // Turn off the default FOV and position replication of the camera manager, most functions should be sending values anyway and I am replicating + // the actual camera position myself so this is just wasted bandwidth + if(PlayerCameraManager != NULL && bDisableServerUpdateCamera) + PlayerCameraManager->bUseClientSideCameraUpdates = false; +} + +void AVRPlayerController::PlayerTick(float DeltaTime) +{ + + // #TODO: Should I be only doing this if ticking CMC and CMC is active? + if (AVRBaseCharacter * VRChar = Cast(GetPawn())) + { + // Keep from calling multiple times + UVRBaseCharacterMovementComponent * BaseCMC = Cast(VRChar->GetMovementComponent()); + + if (!BaseCMC || !BaseCMC->bRunControlRotationInMovementComponent) + return Super::PlayerTick(DeltaTime); + + if (!bShortConnectTimeOut) + { + bShortConnectTimeOut = true; + ServerShortTimeout(); + } + + TickPlayerInput(DeltaTime, DeltaTime == 0.f); + LastRotationInput = RotationInput; + + if ((Player != NULL) && (Player->PlayerController == this)) + { + // Validate current state + bool bUpdateRotation = false; + if (IsInState(NAME_Playing)) + { + if (GetPawn() == NULL) + { + ChangeState(NAME_Inactive); + } + else if (Player && GetPawn() == AcknowledgedPawn && (!BaseCMC || (BaseCMC && !BaseCMC->IsActive()))) + { + bUpdateRotation = true; + } + } + + if (IsInState(NAME_Inactive)) + { + if (GetLocalRole() < ROLE_Authority) + { + SafeServerCheckClientPossession(); + } + + //bUpdateRotation = !IsFrozen(); + } + else if (IsInState(NAME_Spectating)) + { + if (GetLocalRole() < ROLE_Authority) + { + SafeServerUpdateSpectatorState(); + } + + // Keep it when spectating + bUpdateRotation = true; + } + + // Update rotation + if (bUpdateRotation) + { + UpdateRotation(DeltaTime); + } + } + } + else + { + // Not our character, forget it + Super::PlayerTick(DeltaTime); + } +} + +UVRLocalPlayer::UVRLocalPlayer(const FObjectInitializer & ObjectInitializer) + : Super(ObjectInitializer) +{ +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRRootComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRRootComponent.cpp new file mode 100644 index 0000000..2da97a2 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRRootComponent.cpp @@ -0,0 +1,1743 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "VRRootComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRRootComponent) + +//#include "Runtime/Engine/Private/EnginePrivate.h" +//#include "WorldCollision.h" +#include "PhysicsPublic.h" +#include "Engine/World.h" +#include "Engine/Engine.h" +#include "Engine/ScopedMovementUpdate.h" +#include "SceneManagement.h" +#include "PrimitiveSceneProxy.h" +//#include "DrawDebugHelpers.h" +#include "IHeadMountedDisplay.h" +#include "IXRTrackingSystem.h" +#include "VRCharacter.h" +#include "Engine/OverlapResult.h" +#include "Algo/Copy.h" +#include "AI/Navigation/NavigationRelevantData.h" + +#include "Components/PrimitiveComponent.h" + +DEFINE_LOG_CATEGORY(LogVRRootComponent); +#define LOCTEXT_NAMESPACE "VRRootComponent" + +DECLARE_CYCLE_STAT(TEXT("VRRootMovement"), STAT_VRRootMovement, STATGROUP_VRRootComponent); +DECLARE_CYCLE_STAT(TEXT("PerformOverlapQueryVR Time"), STAT_PerformOverlapQueryVR, STATGROUP_VRRootComponent); +DECLARE_CYCLE_STAT(TEXT("UpdateOverlapsVRRoot Time"), STAT_UpdateOverlapsVRRoot, STATGROUP_VRRootComponent); + +typedef TArray> TInlineOverlapPointerArray; + +// Helper to see if two components can possibly generate overlaps with each other. +FORCEINLINE_DEBUGGABLE static bool CanComponentsGenerateOverlap(const UPrimitiveComponent* MyComponent, /*const*/ UPrimitiveComponent* OtherComp) +{ + return OtherComp + && OtherComp->GetGenerateOverlapEvents() + && MyComponent + && MyComponent->GetGenerateOverlapEvents() + && MyComponent->GetCollisionResponseToComponent(OtherComp) == ECR_Overlap; +} + +// Predicate to identify components from overlaps array that can overlap +struct FPredicateFilterCanOverlap +{ + FPredicateFilterCanOverlap(const UPrimitiveComponent& OwningComponent) + : MyComponent(OwningComponent) + { + } + + bool operator() (const FOverlapInfo& Info) const + { + return CanComponentsGenerateOverlap(&MyComponent, Info.OverlapInfo.GetComponent()); + } + +private: + const UPrimitiveComponent& MyComponent; +}; + +// Predicate to remove components from overlaps array that can no longer overlap +struct FPredicateFilterCannotOverlap +{ + FPredicateFilterCannotOverlap(const UPrimitiveComponent& OwningComponent) + : MyComponent(OwningComponent) + { + } + + bool operator() (const FOverlapInfo& Info) const + { + return !CanComponentsGenerateOverlap(&MyComponent, Info.OverlapInfo.GetComponent()); + } + +private: + const UPrimitiveComponent& MyComponent; +}; + +// Helper to initialize an array to point to data members in another array. +template +FORCEINLINE_DEBUGGABLE static void GetPointersToArrayData(TArray& Pointers, const TArray& DataArray) +{ + const int32 NumItems = DataArray.Num(); + Pointers.SetNumUninitialized(NumItems); + for (int32 i = 0; i < NumItems; i++) + { + Pointers[i] = &(DataArray[i]); + } +} + +template +FORCEINLINE_DEBUGGABLE static void GetPointersToArrayData(TArray& Pointers, const TArrayView& DataArray) +{ + const int32 NumItems = DataArray.Num(); + Pointers.SetNumUninitialized(NumItems); + for (int32 i = 0; i < NumItems; i++) + { + Pointers[i] = &(DataArray[i]); + } +} + +// Helper to initialize an array to point to data members in another array which satisfy a predicate. +template +FORCEINLINE_DEBUGGABLE static void GetPointersToArrayDataByPredicate(TArray& Pointers, const TArray& DataArray, PredicateT Predicate) +{ + Pointers.Reserve(Pointers.Num() + DataArray.Num()); + for (const ElementType& Item : DataArray) + { + if (Invoke(Predicate, Item)) + { + Pointers.Add(&Item); + } + } +} + +template +FORCEINLINE_DEBUGGABLE static void GetPointersToArrayDataByPredicate(TArray& Pointers, const TArrayView& DataArray, PredicateT Predicate) +{ + Pointers.Reserve(Pointers.Num() + DataArray.Num()); + for (const ElementType& Item : DataArray) + { + if (Invoke(Predicate, Item)) + { + Pointers.Add(&Item); + } + } +} + +// LOOKING_FOR_PERF_ISSUES +#define PERF_MOVECOMPONENT_STATS 0 + +namespace PrimitiveComponentStatics +{ + //static const FText MobilityWarnText = LOCTEXT("InvalidMove", "move"); + static const FName MoveComponentName(TEXT("MoveComponent")); + static const FName UpdateOverlapsName(TEXT("UpdateOverlaps")); +} + +// Helper for finding the index of an FOverlapInfo in an Array using the FFastOverlapInfoCompare predicate, knowing that at least one overlap is valid (non-null). +template +FORCEINLINE_DEBUGGABLE int32 IndexOfOverlapFast(const TArray& OverlapArray, const FOverlapInfo& SearchItem) +{ + return OverlapArray.IndexOfByPredicate(FFastOverlapInfoCompare(SearchItem)); +} + +// Version that works with arrays of pointers and pointers to search items. +template +FORCEINLINE_DEBUGGABLE int32 IndexOfOverlapFast(const TArray& OverlapPtrArray, const FOverlapInfo* SearchItem) +{ + return OverlapPtrArray.IndexOfByPredicate(FFastOverlapInfoCompare(*SearchItem)); +} + +// Helper for adding an FOverlapInfo uniquely to an Array, using IndexOfOverlapFast and knowing that at least one overlap is valid (non-null). +template +FORCEINLINE_DEBUGGABLE void AddUniqueOverlapFast(TArray& OverlapArray, FOverlapInfo& NewOverlap) +{ + if (IndexOfOverlapFast(OverlapArray, NewOverlap) == INDEX_NONE) + { + OverlapArray.Add(NewOverlap); + } +} + +template +FORCEINLINE_DEBUGGABLE void AddUniqueOverlapFast(TArray& OverlapArray, FOverlapInfo&& NewOverlap) +{ + if (IndexOfOverlapFast(OverlapArray, NewOverlap) == INDEX_NONE) + { + OverlapArray.Add(NewOverlap); + } +} + +static void PullBackHit(FHitResult& Hit, const FVector& Start, const FVector& End, const float Dist) +{ + const float DesiredTimeBack = FMath::Clamp(0.1f, 0.1f / Dist, 1.f / Dist) + 0.001f; + Hit.Time = FMath::Clamp(Hit.Time - DesiredTimeBack, 0.f, 1.f); +} + +static bool ShouldIgnoreHitResult(const UWorld* InWorld, bool bAllowSimulatingCollision, FHitResult const& TestHit, FVector const& MovementDirDenormalized, const AActor* MovingActor, EMoveComponentFlags MoveFlags) +{ + if (TestHit.bBlockingHit) + { + // VR Pawns need to totally ignore simulating components with movement to prevent sickness + if (!bAllowSimulatingCollision && TestHit.Component.IsValid() && TestHit.Component->IsSimulatingPhysics()) + return true; + + // check "ignore bases" functionality + if ((MoveFlags & MOVECOMP_IgnoreBases) && MovingActor) //we let overlap components go through because their overlap is still needed and will cause beginOverlap/endOverlap events + { + // ignore if there's a base relationship between moving actor and hit actor + AActor const* const HitActor = TestHit.HitObjectHandle.FetchActor(); + if (HitActor) + { + if (MovingActor->IsBasedOnActor(HitActor) || HitActor->IsBasedOnActor(MovingActor)) + { + return true; + } + } + } + + // If we started penetrating, we may want to ignore it if we are moving out of penetration. + // This helps prevent getting stuck in walls. + static const auto CVarHitDistanceTolerance = IConsoleManager::Get().FindConsoleVariable(TEXT("p.HitDistanceTolerance")); + if ((TestHit.Distance < CVarHitDistanceTolerance->GetFloat() || TestHit.bStartPenetrating) && !(MoveFlags & MOVECOMP_NeverIgnoreBlockingOverlaps)) + { + static const auto CVarInitialOverlapTolerance = IConsoleManager::Get().FindConsoleVariable(TEXT("p.InitialOverlapTolerance")); + const float DotTolerance = CVarInitialOverlapTolerance->GetFloat(); + + // Dot product of movement direction against 'exit' direction + const FVector MovementDir = MovementDirDenormalized.GetSafeNormal(); + const float MoveDot = (TestHit.ImpactNormal | MovementDir); + + const bool bMovingOut = MoveDot > DotTolerance; + +#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) + + static const auto CVarShowInitialOverlaps = IConsoleManager::Get().FindConsoleVariable(TEXT("p.ShowInitialOverlaps")); + if (CVarShowInitialOverlaps->GetInt() != 0) + { + UE_LOG(LogVRRootComponent, Log, TEXT("Overlapping %s Dir %s Dot %f Normal %s Depth %f"), *GetNameSafe(TestHit.Component.Get()), *MovementDir.ToString(), MoveDot, *TestHit.ImpactNormal.ToString(), TestHit.PenetrationDepth); + DrawDebugDirectionalArrow(InWorld, TestHit.TraceStart, TestHit.TraceStart + 30.f * TestHit.ImpactNormal, 5.f, bMovingOut ? FColor(64, 128, 255) : FColor(255, 64, 64), true, 4.f); + if (TestHit.PenetrationDepth > UE_KINDA_SMALL_NUMBER) + { + DrawDebugDirectionalArrow(InWorld, TestHit.TraceStart, TestHit.TraceStart + TestHit.PenetrationDepth * TestHit.Normal, 5.f, FColor(64, 255, 64), true, 4.f); + } + } + // } +#endif + + // If we are moving out, ignore this result! + if (bMovingOut) + { + return true; + } + } + } + + return false; +} +static FORCEINLINE_DEBUGGABLE bool ShouldIgnoreOverlapResult(const UWorld* World, const AActor* ThisActor, const UPrimitiveComponent& ThisComponent, const AActor* OtherActor, const UPrimitiveComponent& OtherComponent, bool bCheckOverlapFlags) +{ + // Don't overlap with self + if (&ThisComponent == &OtherComponent) + { + return true; + } + + if (bCheckOverlapFlags) + { + // Both components must set GetGenerateOverlapEvents() + if (!ThisComponent.GetGenerateOverlapEvents() || !OtherComponent.GetGenerateOverlapEvents()) + { + return true; + } + } + + if (!ThisActor || !OtherActor) + { + return true; + } + + if (!World || OtherActor == (AActor*)World->GetWorldSettings() || !OtherActor->IsActorInitialized()) + { + return true; + } + + return false; +} + + +UVRRootComponent::UVRRootComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + PrimaryComponentTick.bCanEverTick = true; + PrimaryComponentTick.bStartWithTickEnabled = true; + PrimaryComponentTick.TickGroup = TG_PrePhysics; + + bWantsInitializeComponent = true; + + this->SetRelativeScale3D(FVector(1.f)); + this->SetRelativeLocation(FVector::ZeroVector); + + // 2.15f is ((MIN_FLOOR_DIST + MAX_FLOOR_DIST) / 2), same value that walking attempts to retain + // 1.9f is MIN_FLOOR_DIST, this would not go below ledges when hanging off + VRCapsuleOffset = FVector(-8.0f, 0.0f, 2.15f /*0.0f*/); + + bCenterCapsuleOnHMD = false; + bPauseTracking = false; + + + ShapeColor = FColor(223, 149, 157, 255); + + CapsuleRadius = 20.0f; + CapsuleHalfHeight = 96.0f; + bUseEditorCompositing = true; + OffsetComponentToWorld = FTransform(FQuat(0.0f,0.0f,0.0f,1.0f), FVector::ZeroVector, FVector(1.0f)); + + // Fixes a problem where headset stays at 0,0,0 + lastCameraLoc = FVector::ZeroVector; + lastCameraRot = FRotator::ZeroRotator; + curCameraRot = FRotator::ZeroRotator; + curCameraLoc = FVector::ZeroVector; + StoredCameraRotOffset = FRotator::ZeroRotator; + TargetPrimitiveComponent = NULL; + owningVRChar = NULL; + //VRCameraCollider = NULL; + + bAllowSimulatingCollision = false; + bUseWalkingCollisionOverride = false; + WalkingCollisionOverride = ECollisionChannel::ECC_Pawn; + + bCalledUpdateTransform = false; + + CanCharacterStepUpOn = ECB_No; + //bShouldUpdatePhysicsVolume = true; +// bCheckAsyncSceneOnMove = false; + SetCanEverAffectNavigation(false); + bDynamicObstacle = true; + + LineThickness = 1.25f; + //bOffsetByHMD = false; +} + +/** Represents a UVRRootComponent to the scene manager. */ +class FDrawVRCylinderSceneProxy final : public FPrimitiveSceneProxy +{ +public: + SIZE_T GetTypeHash() const override + { + static size_t UniquePointer; + return reinterpret_cast(&UniquePointer); + } + + FDrawVRCylinderSceneProxy(const UVRRootComponent* InComponent) + : FPrimitiveSceneProxy(InComponent) + , bDrawOnlyIfSelected(InComponent->bDrawOnlyIfSelected) + , CapsuleRadius(InComponent->GetScaledCapsuleRadius()) + , CapsuleHalfHeight(InComponent->GetScaledCapsuleHalfHeight()) + , ShapeColor(InComponent->ShapeColor) + , VRCapsuleOffset(InComponent->VRCapsuleOffset) + , bSimulating(false) + //, OffsetComponentToWorld(InComponent->OffsetComponentToWorld) + , LocalToWorld(InComponent->OffsetComponentToWorld.ToMatrixWithScale()) + , LineThickness(InComponent->GetLineThickness()) + { + bWillEverBeLit = false; + } + + virtual void GetDynamicMeshElements(const TArray& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const override + { + QUICK_SCOPE_CYCLE_COUNTER(STAT_GetDynamicMeshElements_DrawDynamicElements); + + //const FMatrix& LocalToWorld = OffsetComponentToWorld.ToMatrixWithScale();//GetLocalToWorld(); + const int32 CapsuleSides = FMath::Clamp(CapsuleRadius / 4.f, 16, 64); + + for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) + { + + if (VisibilityMap & (1 << ViewIndex)) + { + const FSceneView* View = Views[ViewIndex]; + const FLinearColor DrawCapsuleColor = GetViewSelectionColor(ShapeColor, *View, IsSelected(), IsHovered(), false, IsIndividuallySelected()); + + FPrimitiveDrawInterface* PDI = Collector.GetPDI(ViewIndex); + + // If in editor views, lets offset the capsule upwards so that it views correctly + if (bSimulating) + { + DrawWireCapsule(PDI, LocalToWorld.GetOrigin() - FVector(0.f, 0.f, CapsuleHalfHeight), LocalToWorld.GetUnitAxis(EAxis::X), LocalToWorld.GetUnitAxis(EAxis::Y), LocalToWorld.GetUnitAxis(EAxis::Z), DrawCapsuleColor, CapsuleRadius, CapsuleHalfHeight, CapsuleSides, SDPG_World, LineThickness); + } + else if (UseEditorCompositing(View)) + { + DrawWireCapsule(PDI, LocalToWorld.GetOrigin() /*+ FVector(0.f, 0.f, CapsuleHalfHeight)*/, LocalToWorld.GetUnitAxis(EAxis::X), LocalToWorld.GetUnitAxis(EAxis::Y), LocalToWorld.GetUnitAxis(EAxis::Z), DrawCapsuleColor, CapsuleRadius, CapsuleHalfHeight, CapsuleSides, SDPG_World, LineThickness); + } + else + DrawWireCapsule(PDI, LocalToWorld.GetOrigin(), LocalToWorld.GetUnitAxis(EAxis::X), LocalToWorld.GetUnitAxis(EAxis::Y), LocalToWorld.GetUnitAxis(EAxis::Z), DrawCapsuleColor, CapsuleRadius, CapsuleHalfHeight, CapsuleSides, SDPG_World, LineThickness); + } + } + } + + /** Called on render thread to assign new dynamic data */ + void UpdateTransform_RenderThread(const FTransform &NewTransform, float NewHalfHeight, bool bIsSimulating) + { + check(IsInRenderingThread()); + LocalToWorld = NewTransform.ToMatrixWithScale(); + //OffsetComponentToWorld = NewTransform; + CapsuleHalfHeight = NewHalfHeight; + bSimulating = bIsSimulating; + } + + virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView* View) const override + { + const bool bProxyVisible = !bDrawOnlyIfSelected || IsSelected(); + + // Should we draw this because collision drawing is enabled, and we have collision + const bool bShowForCollision = View->Family->EngineShowFlags.Collision && IsCollisionEnabled(); + + FPrimitiveViewRelevance Result; + Result.bDrawRelevance = (IsShown(View) && bProxyVisible) || bShowForCollision; + Result.bDynamicRelevance = true; + Result.bShadowRelevance = IsShadowCast(View); + Result.bEditorPrimitiveRelevance = UseEditorCompositing(View); + return Result; + } + virtual uint32 GetMemoryFootprint(void) const override { return(sizeof(*this) + GetAllocatedSize()); } + uint32 GetAllocatedSize(void) const { return(FPrimitiveSceneProxy::GetAllocatedSize()); } + +private: + const uint32 bDrawOnlyIfSelected : 1; + const float CapsuleRadius; + float CapsuleHalfHeight; + FColor ShapeColor; + const FVector VRCapsuleOffset; + bool bSimulating = false; + //FTransform OffsetComponentToWorld; + FMatrix LocalToWorld; + const float LineThickness; +}; + +FPrimitiveSceneProxy* UVRRootComponent::CreateSceneProxy() +{ + return new FDrawVRCylinderSceneProxy(this); +} + +void UVRRootComponent::InitializeComponent() +{ + Super::InitializeComponent(); + GenerateOffsetToWorld(); +} + +void UVRRootComponent::BeginPlay() +{ + Super::BeginPlay(); + + if(AVRBaseCharacter * vrOwner = Cast(this->GetOwner())) + { + if (vrOwner->VRReplicatedCamera) + { + TargetPrimitiveComponent = vrOwner->VRReplicatedCamera; + owningVRChar = vrOwner; + //VRCameraCollider = vrOwner->VRCameraCollider; + return; + } + } + else + { + TArray children = this->GetAttachChildren(); + + for (int i = 0; i < children.Num(); i++) + { + if (children[i]->IsA(UCameraComponent::StaticClass())) + { + TargetPrimitiveComponent = children[i]; + owningVRChar = NULL; + return; + } + } + } + + //VRCameraCollider = NULL; + TargetPrimitiveComponent = NULL; + owningVRChar = NULL; +} + +void UVRRootComponent::SetTrackingPaused(bool bPaused) +{ + bPauseTracking = bPaused; +} + +void UVRRootComponent::UpdateCharacterCapsuleOffset() +{ + if (owningVRChar && !owningVRChar->bRetainRoomscale && owningVRChar->NetSmoother) + { + if (!FMath::IsNearlyEqual(LastCapsuleHalfHeight, CapsuleHalfHeight)) + { + owningVRChar->NetSmoother->SetRelativeLocation(GetTargetHeightOffset(), false, nullptr, ETeleportType::TeleportPhysics); + + // Update our last sample value + LastCapsuleHalfHeight = CapsuleHalfHeight; + } + } +} + +void UVRRootComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) +{ + + if (this->IsSimulatingPhysics()) + { + return Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + } + + // Skip updates and stay in place if we have paused tracking to the HMD + if (bPauseTracking) + { + bHadRelativeMovement = false; + DifferenceFromLastFrame = FVector::ZeroVector; + return; + } + + UVRBaseCharacterMovementComponent * CharMove = nullptr; + bool bRetainRoomscale = true; + + // Need these for passing physics updates to character movement + if (IsValid(owningVRChar)) + { + CharMove = Cast(owningVRChar->GetCharacterMovement()); + bRetainRoomscale = owningVRChar->bRetainRoomscale; + } + + if (IsLocallyControlled()) + { + if (owningVRChar && owningVRChar->bTrackingPaused) + { + curCameraLoc = owningVRChar->PausedTrackingLoc; + curCameraRot = FRotator(0.f, owningVRChar->PausedTrackingRot, 0.f); + } + else if (OptionalWaistTrackingParent.IsValid()) + { + FTransform NewTrans = IVRTrackedParentInterface::Default_GetWaistOrientationAndPosition(OptionalWaistTrackingParent); + curCameraLoc = NewTrans.GetTranslation(); + curCameraRot = NewTrans.Rotator(); + } + else if (GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowedForWorld(*GetWorld())) + { + FQuat curRot; + if (!GEngine->XRSystem->GetCurrentPose(IXRTrackingSystem::HMDDeviceId, curRot, curCameraLoc)) + { + curCameraLoc = lastCameraLoc; + curCameraRot = lastCameraRot; + } + else + { + if (owningVRChar && owningVRChar->VRReplicatedCamera) + { + owningVRChar->VRReplicatedCamera->ApplyTrackingParameters(curCameraLoc, true); + } + + curCameraRot = curRot.Rotator(); + } + } + else if (TargetPrimitiveComponent) + { + curCameraRot = TargetPrimitiveComponent->GetRelativeRotation(); + curCameraLoc = TargetPrimitiveComponent->GetRelativeLocation(); + } + else + { + curCameraRot = FRotator::ZeroRotator; + curCameraLoc = FVector::ZeroVector; + } + + // Store a leveled yaw value here so it is only calculated once + StoredCameraRotOffset = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(curCameraRot); + + // Skip this if not retaining roomscale as we use higher initial fidelity + // And we can rep the values at full precision if we want too + if (bRetainRoomscale) + { + // Pre-Process this for network sends + UE::Net::QuantizeVector(100, curCameraLoc); + //curCameraLoc.X = FMath::RoundToFloat(curCameraLoc.X * 100.f) / 100.f; + //curCameraLoc.Y = FMath::RoundToFloat(curCameraLoc.Y * 100.f) / 100.f; + //curCameraLoc.Z = FMath::RoundToFloat(curCameraLoc.Z * 100.f) / 100.f; + } + + + // Can adjust the relative tolerances to remove jitter and some update processing + if (!bRetainRoomscale || (!curCameraLoc.Equals(lastCameraLoc, 0.01f) || !curCameraRot.Equals(lastCameraRot, 0.01f))) + { + // Also calculate vector of movement for the movement component + FVector LastPosition = OffsetComponentToWorld.GetLocation(); + + bCalledUpdateTransform = false; + + if (bRetainRoomscale) + { + // If the character movement doesn't exist or is not active/ticking + if (!CharMove || !CharMove->IsComponentTickEnabled() || !CharMove->IsActive()) + { + OnUpdateTransform(EUpdateTransformFlags::None, ETeleportType::None); + } + else // Let the character movement move the capsule instead + { + // Skip physics update, let the movement component handle it instead + OnUpdateTransform(EUpdateTransformFlags::SkipPhysicsUpdate, ETeleportType::None); + } + } + + FHitResult OutHit; + FCollisionQueryParams Params("RelativeMovementSweep", false, GetOwner()); + FCollisionResponseParams ResponseParam; + + InitSweepCollisionParams(Params, ResponseParam); + Params.bFindInitialOverlaps = true; + bool bBlockingHit = false; + + if (bUseWalkingCollisionOverride && bRetainRoomscale) + { + FVector TargetWorldLocation = OffsetComponentToWorld.GetLocation(); + bool bAllowWalkingCollision = false; + if (CharMove != nullptr) + { + if (CharMove->MovementMode == EMovementMode::MOVE_Walking || CharMove->MovementMode == EMovementMode::MOVE_NavWalking) + bAllowWalkingCollision = true; + } + + // TODO: Needs not retained roomscale version that uses movement diff instead of offset to world + if (bAllowWalkingCollision) + { + bBlockingHit = GetWorld()->SweepSingleByChannel(OutHit, LastPosition, TargetWorldLocation, FQuat::Identity, WalkingCollisionOverride, GetCollisionShape(), Params, ResponseParam); + } + + if (bBlockingHit && OutHit.Component.IsValid()) + { + if (CharMove != nullptr && CharMove->bIgnoreSimulatingComponentsInFloorCheck && OutHit.Component->IsSimulatingPhysics()) + bHadRelativeMovement = false; + else + bHadRelativeMovement = true; + } + else + bHadRelativeMovement = false; + } + else + bHadRelativeMovement = true; + + // Not supporting walking collision override currently with new pawn setup + if (bHadRelativeMovement || (owningVRChar && !owningVRChar->bRetainRoomscale)) + { + if (bRetainRoomscale) + { + DifferenceFromLastFrame = OffsetComponentToWorld.GetLocation() - LastPosition; + lastCameraLoc = curCameraLoc; + lastCameraRot = curCameraRot; + + //DifferenceFromLastFrame = (NextTransform.GetLocation() - LastPosition);// .GetSafeNormal2D(); + UE::Net::QuantizeVector(100, DifferenceFromLastFrame); + //DifferenceFromLastFrame.X = FMath::RoundToFloat(DifferenceFromLastFrame.X * 100.f) / 100.f; + //DifferenceFromLastFrame.Y = FMath::RoundToFloat(DifferenceFromLastFrame.Y * 100.f) / 100.f; + //DifferenceFromLastFrame.Z = FMath::RoundToFloat(DifferenceFromLastFrame.Z * 100.f) / 100.f; + //DifferenceFromLastFrame.Z = 0.0f; // Reset Z to zero, its not used anyway and this lets me reuse the Z component for capsule half height + } + else + { + + // Run this first so we get full fidelity on the relative space calculation + FVector NewLocation = StoredCameraRotOffset.RotateVector(FVector(VRCapsuleOffset.X, VRCapsuleOffset.Y, 0.0f)) + curCameraLoc; + FVector PlanerLocation = NewLocation - lastCameraLoc; + PlanerLocation.Z = 0.0f; + DifferenceFromLastFrame = GetComponentTransform().TransformVector(PlanerLocation); + lastCameraLoc = NewLocation; + lastCameraRot = curCameraRot; + + // Skip routing the delta if this is the first tick, prevents an initial jump in position + if (!bTickedOnce) + { + DifferenceFromLastFrame = FVector::ZeroVector; + bTickedOnce = true; + } + else + { + // I'm limiting it to a -100 - 100 unit range in case people somehow skip tracking so far that this multiplication + // Would overflow the max/min values of a float. It shouldn't ever be harmful as that is a loooot of travel in one tick + DifferenceFromLastFrame.X = FMath::Clamp(DifferenceFromLastFrame.X, -100.0f, 100.0f); + DifferenceFromLastFrame.Y = FMath::Clamp(DifferenceFromLastFrame.Y, -100.0f, 100.0f); + DifferenceFromLastFrame.Z = FMath::Clamp(DifferenceFromLastFrame.Z, -100.0f, 100.0f); + UE::Net::QuantizeVector(10000, DifferenceFromLastFrame); + //DifferenceFromLastFrame.X = FMath::RoundToFloat(FMath::Clamp(DifferenceFromLastFrame.X, -100.0f, 100.0f) * 10000.f) / 10000.f; + //DifferenceFromLastFrame.Y = FMath::RoundToFloat(FMath::Clamp(DifferenceFromLastFrame.Y, -100.0f, 100.0f) * 10000.f) / 10000.f; + //DifferenceFromLastFrame.Z = FMath::RoundToFloat(FMath::Clamp(DifferenceFromLastFrame.Z, -100.0f, 100.0f) * 10000.f) / 10000.f; + //DifferenceFromLastFrame.Z = 0.0f; // Reset Z to zero, its not used anyway and this lets me reuse the Z component for capsule half height + } + } + + } + else // Zero it out so we don't process off of the change (multiplayer sends this) + { + DifferenceFromLastFrame = FVector::ZeroVector; + lastCameraLoc = curCameraLoc; + lastCameraRot = curCameraRot; + } + } + else + { + bHadRelativeMovement = false; + DifferenceFromLastFrame = FVector::ZeroVector; + lastCameraLoc = curCameraLoc; + lastCameraRot = curCameraRot; + } + + //lastCameraLoc = curCameraLoc; + //lastCameraRot = curCameraRot; + } + else + { + if (owningVRChar && owningVRChar->bTrackingPaused) + { + curCameraLoc = owningVRChar->PausedTrackingLoc; + curCameraRot = FRotator(0.f, owningVRChar->PausedTrackingRot, 0.f); + } + else if (TargetPrimitiveComponent) + { + curCameraRot = TargetPrimitiveComponent->GetRelativeRotation(); + curCameraLoc = TargetPrimitiveComponent->GetRelativeLocation(); + } + else + { + curCameraRot = FRotator(0.0f, 0.0f, 0.0f);// = FRotator::ZeroRotator; + curCameraLoc = FVector(0.0f, 0.0f, 0.0f);//FVector::ZeroVector; + } + + // Store a leveled yaw value here so it is only calculated once + StoredCameraRotOffset = UVRExpansionFunctionLibrary::GetHMDPureYaw_I(curCameraRot); + + // Can adjust the relative tolerances to remove jitter and some update processing + if (!curCameraLoc.Equals(lastCameraLoc, 0.01f) || !curCameraRot.Equals(lastCameraRot, 0.01f)) + { + bCalledUpdateTransform = false; + + // If the character movement doesn't exist or is not active/ticking + if (!CharMove || !CharMove->IsActive()) + { + OnUpdateTransform(EUpdateTransformFlags::None, ETeleportType::None); + if (bNavigationRelevant && bRegistered) + { + UpdateNavigationData(); + PostUpdateNavigationData(); + } + } + else // Let the character movement move the capsule instead + { + // Skip physics update, let the movement component handle it instead + OnUpdateTransform(EUpdateTransformFlags::SkipPhysicsUpdate, ETeleportType::None); + + // This is an edge case, need to check if the nav data needs updated client side + if (this->GetOwner()->GetLocalRole() == ENetRole::ROLE_SimulatedProxy) + { + if (bNavigationRelevant && bRegistered) + { + UpdateNavigationData(); + PostUpdateNavigationData(); + } + } + } + + + lastCameraRot = curCameraRot; + lastCameraLoc = curCameraLoc; + } + } + + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); +} + + +void UVRRootComponent::SendPhysicsTransform(ETeleportType Teleport) +{ + /*if (owningVRChar && !owningVRChar->bRetainRoomscale) + { + Super::SendPhysicsTransform(Teleport); + return; + }*/ + + BodyInstance.SetBodyTransform(OffsetComponentToWorld, Teleport); + BodyInstance.UpdateBodyScale(OffsetComponentToWorld.GetScale3D()); +} + +void UVRRootComponent::SetSimulatePhysics(bool bSimulate) +{ + Super::SetSimulatePhysics(bSimulate); + + if (owningVRChar && !owningVRChar->bRetainRoomscale) + { + return Super::SetSimulatePhysics(bSimulate); + } + + if (bSimulate) + { + if (AVRCharacter* OwningCharacter = Cast(GetOwner())) + { + if (OwningCharacter->NetSmoother) + { + OwningCharacter->NetSmoother->SetRelativeLocation(FVector(0.f,0.f, -this->GetUnscaledCapsuleHalfHeight())); + } + } + this->AddWorldOffset(this->GetComponentRotation().RotateVector(FVector(0.f, 0.f, this->GetScaledCapsuleHalfHeight())), false, nullptr, ETeleportType::TeleportPhysics); + } + else + { + if (AVRCharacter* OwningCharacter = Cast(GetOwner())) + { + if (OwningCharacter->NetSmoother) + { + OwningCharacter->NetSmoother->SetRelativeLocation(FVector(0.f, 0.f, 0)); + } + } + this->AddWorldOffset(this->GetComponentRotation().RotateVector(FVector(0.f, 0.f, -this->GetScaledCapsuleHalfHeight())), false, nullptr, ETeleportType::TeleportPhysics); + } +} + +// Override this so that the physics representation is in the correct location +void UVRRootComponent::OnUpdateTransform(EUpdateTransformFlags UpdateTransformFlags, ETeleportType Teleport) +{ + if (this->IsSimulatingPhysics()) + { + if (this->ShouldRender() && this->SceneProxy) + { + FTransform lOffsetComponentToWorld = OffsetComponentToWorld; + float lCapsuleHalfHeight = CapsuleHalfHeight; + bool bIsSimulating = this->IsSimulatingPhysics(); + FDrawVRCylinderSceneProxy* CylinderSceneProxy = (FDrawVRCylinderSceneProxy*)SceneProxy; + ENQUEUE_RENDER_COMMAND(VRRootComponent_SendNewDebugTransform)( + [CylinderSceneProxy, lOffsetComponentToWorld, lCapsuleHalfHeight, bIsSimulating](FRHICommandList& RHICmdList) + { + CylinderSceneProxy->UpdateTransform_RenderThread(lOffsetComponentToWorld, lCapsuleHalfHeight, bIsSimulating); + }); + } + + return Super::OnUpdateTransform(UpdateTransformFlags, Teleport); + } + + GenerateOffsetToWorld(); + // Using the physics flag for all of this anyway, no reason for a custom flag, it handles it fine + if (!(UpdateTransformFlags & EUpdateTransformFlags::SkipPhysicsUpdate)) + { + bCalledUpdateTransform = true; + + // Just using the + if (this->ShouldRender() && this->SceneProxy) + { + /*ENQUEUE_UNIQUE_RENDER_COMMAND_THREEPARAMETER( + FDrawCylinderTransformUpdate, + FDrawVRCylinderSceneProxy*, CylinderSceneProxy, (FDrawVRCylinderSceneProxy*)SceneProxy, + FTransform, OffsetComponentToWorld, OffsetComponentToWorld, float, CapsuleHalfHeight, CapsuleHalfHeight, + { + CylinderSceneProxy->UpdateTransform_RenderThread(OffsetComponentToWorld, CapsuleHalfHeight); + } + );*/ + + FTransform lOffsetComponentToWorld = OffsetComponentToWorld; + float lCapsuleHalfHeight = CapsuleHalfHeight; + bool bIsSimulating = this->IsSimulatingPhysics(); + FDrawVRCylinderSceneProxy* CylinderSceneProxy = (FDrawVRCylinderSceneProxy*)SceneProxy; + ENQUEUE_RENDER_COMMAND(VRRootComponent_SendNewDebugTransform)( + [CylinderSceneProxy, lOffsetComponentToWorld, lCapsuleHalfHeight, bIsSimulating](FRHICommandList& RHICmdList) + { + CylinderSceneProxy->UpdateTransform_RenderThread(lOffsetComponentToWorld, lCapsuleHalfHeight, bIsSimulating); + }); + + } + + // Don't want to call primitives version, and the scenecomponents version does nothing + //Super::OnUpdateTransform(UpdateTransformFlags, Teleport); + + // Always send new transform to physics + if (bPhysicsStateCreated) + { + //If we update transform of welded bodies directly (i.e. on the actual component) we need to update the shape transforms of the parent. + //If the parent is updated, any welded shapes are automatically updated so we don't need to do this physx update. + //If the parent is updated and we are NOT welded, the child still needs to update physics + const bool bTransformSetDirectly = !(UpdateTransformFlags & EUpdateTransformFlags::PropagateFromParent); + if (bTransformSetDirectly || !IsWelded()) + { + SendPhysicsTransform(Teleport); + } + } + } +} + +FBoxSphereBounds UVRRootComponent::CalcBounds(const FTransform& LocalToWorld) const +{ + + if (owningVRChar && !owningVRChar->bRetainRoomscale) + { + return Super::CalcBounds(LocalToWorld); + } + + FVector BoxPoint = FVector(CapsuleRadius, CapsuleRadius, CapsuleHalfHeight); + //FRotator CamRotOffset(0.0f, curCameraRot.Yaw, 0.0f); + + //FRotator CamRotOffset = UVRExpansionFunctionLibrary::GetHMDPureYaw(curCameraRot); + /*if(bOffsetByHMD) + return FBoxSphereBounds(FVector(0, 0, CapsuleHalfHeight) + StoredCameraRotOffset.RotateVector(VRCapsuleOffset), BoxPoint, BoxPoint.Size()).TransformBy(LocalToWorld); + else*/ + + return FBoxSphereBounds(FVector(curCameraLoc.X, curCameraLoc.Y, CapsuleHalfHeight) + StoredCameraRotOffset.RotateVector(VRCapsuleOffset), BoxPoint, BoxPoint.Size()).TransformBy(LocalToWorld); +} + +void UVRRootComponent::GetNavigationData(FNavigationRelevantData& Data) const +{ + if (bDynamicObstacle) + { + Data.Modifiers.CreateAreaModifiers(this, GetDesiredAreaClass()); + } +} + +#if WITH_EDITOR +void UVRRootComponent::PreEditChange(FProperty* PropertyThatWillChange) +{ + // This is technically not correct at all to do...however when overloading a root component the preedit gets called twice for some reason. + // Calling it twice attempts to double register it in the list and causes an assert to be thrown. + if (this->GetOwner()->IsA(AVRCharacter::StaticClass())) + return; + else + Super::PreEditChange(PropertyThatWillChange); +} + +void UVRRootComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) +{ + const FName PropertyName = PropertyChangedEvent.Property ? PropertyChangedEvent.Property->GetFName() : NAME_None; + + // We only want to modify the property that was changed at this point + // things like propagation from CDO to instances don't work correctly if changing one property causes a different property to change + if (PropertyName == GET_MEMBER_NAME_CHECKED(UVRRootComponent, CapsuleHalfHeight)) + { + CapsuleHalfHeight = FMath::Max3(0.f, CapsuleHalfHeight, CapsuleRadius); + } + else if (PropertyName == GET_MEMBER_NAME_CHECKED(UVRRootComponent, CapsuleRadius)) + { + CapsuleRadius = FMath::Clamp(CapsuleRadius, 0.f, CapsuleHalfHeight); + } + else if (PropertyName == GET_MEMBER_NAME_CHECKED(UVRRootComponent, VRCapsuleOffset)) + { + } + + if (!IsTemplate()) + { + //UpdateBodySetup(); // do this before reregistering components so that new values are used for collision + } + + return; + + // Overrode the defaults for this, don't call the parent + //Super::PostEditChangeProperty(PropertyChangedEvent); +} +#endif // WITH_EDITOR + + +// This overrides the movement logic to use the offset location instead of the default location for sweeps. +bool UVRRootComponent::MoveComponentImpl(const FVector& Delta, const FQuat& NewRotationQuat, bool bSweep, FHitResult* OutHit, EMoveComponentFlags MoveFlags, ETeleportType Teleport) +{ + + /*if (owningVRChar && !owningVRChar->bRetainRoomscale) + { + return Super::MoveComponentImpl(Delta, NewRotationQuat, bSweep, OutHit, MoveFlags, Teleport); + GenerateOffsetToWorld(); + }*/ + + SCOPE_CYCLE_COUNTER(STAT_VRRootMovement); + //CSV_SCOPED_TIMING_STAT(PrimitiveComponent, MoveComponentTime); + + // static things can move before they are registered (e.g. immediately after streaming), but not after. + if (!IsValid(this) || (this->Mobility == EComponentMobility::Static && IsRegistered()))//|| CheckStaticMobilityAndWarn(PrimitiveComponentStatics::MobilityWarnText)) + { + if (OutHit) + { + OutHit->Init(); + } + return false; + } + + const bool bSkipPhysicsMove = ((MoveFlags & MOVECOMP_SkipPhysicsMove) != MOVECOMP_NoFlags); + + if (!this->IsSimulatingPhysics() && bSkipPhysicsMove) + { + // Phys thread is updating this when we don't want it to, stop it chaos! + return false; + } + + ConditionalUpdateComponentToWorld(); + + // Init HitResult + //FHitResult BlockingHit(1.f); + const FVector TraceStart = OffsetComponentToWorld.GetLocation();// .GetLocation();//GetComponentLocation(); + const FVector TraceEnd = TraceStart + Delta; + //BlockingHit.TraceStart = TraceStart; + //BlockingHit.TraceEnd = TraceEnd; + float DeltaSizeSq = (TraceEnd - TraceStart).SizeSquared(); // Recalc here to account for precision loss of float addition + + // Set up. +// float DeltaSizeSq = Delta.SizeSquared(); + const FQuat InitialRotationQuat = GetComponentTransform().GetRotation();//ComponentToWorld.GetRotation(); + + // ComponentSweepMulti does nothing if moving < UE_KINDA_SMALL_NUMBER in distance, so it's important to not try to sweep distances smaller than that. + const float MinMovementDistSq = (bSweep ? FMath::Square(4.f*UE_KINDA_SMALL_NUMBER) : 0.f); + if (DeltaSizeSq <= MinMovementDistSq) + { + // Skip if no vector or rotation. + if (NewRotationQuat.Equals(InitialRotationQuat, SCENECOMPONENT_QUAT_TOLERANCE)) + { + // copy to optional output param + if (OutHit) + { + OutHit->Init(TraceStart, TraceEnd); + } + return true; + } + DeltaSizeSq = 0.f; + } + + //const bool bSkipPhysicsMove = ((MoveFlags & MOVECOMP_SkipPhysicsMove) != MOVECOMP_NoFlags); + + // WARNING: HitResult is only partially initialized in some paths. All data is valid only if bFilledHitResult is true. + FHitResult BlockingHit(NoInit); + BlockingHit.bBlockingHit = false; + BlockingHit.Time = 1.f; + bool bFilledHitResult = false; + bool bMoved = false; + bool bIncludesOverlapsAtEnd = false; + bool bRotationOnly = false; + TInlineOverlapInfoArray PendingOverlaps; + AActor* const Actor = GetOwner(); + FVector OrigLocation = GetComponentLocation(); + + if (!bSweep) + { + // not sweeping, just go directly to the new transform + bMoved = InternalSetWorldLocationAndRotation(/*TraceEnd*/OrigLocation + Delta, NewRotationQuat, bSkipPhysicsMove, Teleport); + GenerateOffsetToWorld(); + bRotationOnly = (DeltaSizeSq == 0); + bIncludesOverlapsAtEnd = bRotationOnly && (AreSymmetricRotations(InitialRotationQuat, NewRotationQuat, GetComponentScale())) && IsCollisionEnabled(); + } + else + { + TArray Hits; + FVector NewLocation = OrigLocation;//TraceStart; + // Perform movement collision checking if needed for this actor. + const bool bCollisionEnabled = IsQueryCollisionEnabled(); + UWorld* const MyWorld = GetWorld(); + if (MyWorld && bCollisionEnabled && (DeltaSizeSq > 0.f)) + { +#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) + if (!IsRegistered() && !MyWorld->bIsTearingDown) + { + if (Actor) + { + ensureMsgf(IsRegistered(), TEXT("%s MovedComponent %s not registered during sweep (IsValid %d)"), *Actor->GetName(), *GetName(), IsValid(Actor)); + } + else + { //-V523 + ensureMsgf(IsRegistered(), TEXT("Non-actor MovedComponent %s not registered during sweep"), *GetFullName()); + } + } +#endif +#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) && PERF_MOVECOMPONENT_STATS + MoveTimer.bDidLineCheck = true; +#endif + static const FName TraceTagName = TEXT("MoveComponent"); + const bool bForceGatherOverlaps = !ShouldCheckOverlapFlagToQueueOverlaps(*this); + FComponentQueryParams Params(/*PrimitiveComponentStatics::MoveComponentName*//*"MoveComponent"*/SCENE_QUERY_STAT(MoveComponent), Actor); + FCollisionResponseParams ResponseParam; + InitSweepCollisionParams(Params, ResponseParam); + Params.bIgnoreTouches |= !(GetGenerateOverlapEvents() || bForceGatherOverlaps); + Params.TraceTag = TraceTagName; + bool const bHadBlockingHit = MyWorld->ComponentSweepMulti(Hits, this, TraceStart, TraceEnd, InitialRotationQuat, Params); + //bool const bHadBlockingHit = MyWorld->SweepMultiByChannel(Hits, TraceStart, TraceEnd, InitialRotationQuat, this->GetCollisionObjectType(), this->GetCollisionShape(), Params, ResponseParam); + + if (Hits.Num() > 0) + { + const float DeltaSize = FMath::Sqrt(DeltaSizeSq); + for (int32 HitIdx = 0; HitIdx < Hits.Num(); HitIdx++) + { + PullBackHit(Hits[HitIdx], TraceStart, TraceEnd, DeltaSize); + } + } + + // If we had a valid blocking hit, store it. + // If we are looking for overlaps, store those as well. + int32 FirstNonInitialOverlapIdx = INDEX_NONE; + if (bHadBlockingHit || (GetGenerateOverlapEvents() || bForceGatherOverlaps)) + { + int32 BlockingHitIndex = INDEX_NONE; + float BlockingHitNormalDotDelta = UE_BIG_NUMBER; + for (int32 HitIdx = 0; HitIdx < Hits.Num(); HitIdx++) + { + const FHitResult& TestHit = Hits[HitIdx]; + + if (TestHit.bBlockingHit) + { + if (!ShouldIgnoreHitResult(MyWorld, bAllowSimulatingCollision, TestHit, Delta, Actor, MoveFlags) && !ShouldComponentIgnoreHitResult(TestHit, MoveFlags)) + { + if (TestHit.bStartPenetrating) + { + // We may have multiple initial hits, and want to choose the one with the normal most opposed to our movement. + const float NormalDotDelta = (TestHit.ImpactNormal | Delta); + if (NormalDotDelta < BlockingHitNormalDotDelta) + { + BlockingHitNormalDotDelta = NormalDotDelta; + BlockingHitIndex = HitIdx; + } + } + else if (BlockingHitIndex == INDEX_NONE) + { + // First non-overlapping blocking hit should be used, if an overlapping hit was not. + // This should be the only non-overlapping blocking hit, and last in the results. + BlockingHitIndex = HitIdx; + break; + } + } + } + else if (GetGenerateOverlapEvents() || bForceGatherOverlaps) + { + UPrimitiveComponent* OverlapComponent = TestHit.Component.Get(); + if (OverlapComponent && (OverlapComponent->GetGenerateOverlapEvents() || bForceGatherOverlaps)) + { + if (!ShouldIgnoreOverlapResult(MyWorld, Actor, *this, TestHit.HitObjectHandle.FetchActor(), *OverlapComponent,!bForceGatherOverlaps)) + { + // don't process touch events after initial blocking hits + if (BlockingHitIndex >= 0 && TestHit.Time > Hits[BlockingHitIndex].Time) + { + break; + } + + if (FirstNonInitialOverlapIdx == INDEX_NONE && TestHit.Time > 0.f) + { + // We are about to add the first non-initial overlap. + FirstNonInitialOverlapIdx = PendingOverlaps.Num(); + } + + // cache touches + AddUniqueOverlapFast(PendingOverlaps, FOverlapInfo(TestHit)); + } + } + } + } + + // Update blocking hit, if there was a valid one. + if (BlockingHitIndex >= 0) + { + BlockingHit = Hits[BlockingHitIndex]; + bFilledHitResult = true; + } + } + + // Update NewLocation based on the hit result + if (!BlockingHit.bBlockingHit) + { + NewLocation += (TraceEnd - TraceStart); + } + else + { + check(bFilledHitResult); + NewLocation += (BlockingHit.Time * (TraceEnd - TraceStart)); + + // Sanity check + const FVector ToNewLocation = (NewLocation - OrigLocation/*TraceStart*/); + if (ToNewLocation.SizeSquared() <= MinMovementDistSq) + { + // We don't want really small movements to put us on or inside a surface. + NewLocation = OrigLocation;//TraceStart; + BlockingHit.Time = 0.f; + + // Remove any pending overlaps after this point, we are not going as far as we swept. + if (FirstNonInitialOverlapIdx != INDEX_NONE) + { + PendingOverlaps.SetNum(FirstNonInitialOverlapIdx, EAllowShrinking::No); + } + } + } + + bIncludesOverlapsAtEnd = AreSymmetricRotations(InitialRotationQuat, NewRotationQuat, GetComponentScale()); + } + else if (DeltaSizeSq > 0.f) + { + // apply move delta even if components has collisions disabled + NewLocation += Delta; + bIncludesOverlapsAtEnd = false; + } + else if (DeltaSizeSq == 0.f && bCollisionEnabled) + { + bIncludesOverlapsAtEnd = AreSymmetricRotations(InitialRotationQuat, NewRotationQuat, GetComponentScale()); + bRotationOnly = true; + } + + // Update the location. This will teleport any child components as well (not sweep). + bMoved = InternalSetWorldLocationAndRotation(NewLocation, NewRotationQuat, bSkipPhysicsMove, Teleport); + GenerateOffsetToWorld(); + } + + // Handle overlap notifications. + if (bMoved) + { + if (IsDeferringMovementUpdates()) + { + // Defer UpdateOverlaps until the scoped move ends. + FScopedMovementUpdate* ScopedUpdate = GetCurrentScopedMovement(); + if (bRotationOnly && bIncludesOverlapsAtEnd) + { + ScopedUpdate->KeepCurrentOverlapsAfterRotation(bSweep); + } + else + { + ScopedUpdate->AppendOverlapsAfterMove(PendingOverlaps, bSweep, bIncludesOverlapsAtEnd); + } + } + else + { + if (bIncludesOverlapsAtEnd) + { + TInlineOverlapInfoArray OverlapsAtEndLocation; + bool bHasEndOverlaps = false; + if (bRotationOnly) + { + // bHasEndOverlaps = ConvertRotationOverlapsToCurrentOverlaps(OverlapsAtEndLocation, OverlappingComponents); + } + else + { + // bHasEndOverlaps = ConvertSweptOverlapsToCurrentOverlaps(OverlapsAtEndLocation, PendingOverlaps, 0, OffsetComponentToWorld.GetLocation(), GetComponentQuat()); + } + TOverlapArrayView PendingOverlapsView(PendingOverlaps); + TOverlapArrayView OverlapsAtEndView(OverlapsAtEndLocation); + UpdateOverlaps(&PendingOverlapsView, true, bHasEndOverlaps ? &OverlapsAtEndView : nullptr); + } + else + { + TOverlapArrayView PendingOverlapsView(PendingOverlaps); + UpdateOverlaps(&PendingOverlapsView, true, nullptr); + } + } + } + + // Handle blocking hit notifications. Avoid if pending kill (which could happen after overlaps). + const bool bAllowHitDispatch = !BlockingHit.bStartPenetrating || !(MoveFlags & MOVECOMP_DisableBlockingOverlapDispatch); + if (BlockingHit.bBlockingHit && bAllowHitDispatch && IsValid(this)) + { + check(bFilledHitResult); + if (IsDeferringMovementUpdates()) + { + FScopedMovementUpdate* ScopedUpdate = GetCurrentScopedMovement(); + ScopedUpdate->AppendBlockingHitAfterMove(BlockingHit); + } + else + { + DispatchBlockingHit(*Actor, BlockingHit); + } + } + + // copy to optional output param + if (OutHit) + { + if (bFilledHitResult) + { + *OutHit = BlockingHit; + } + else + { + OutHit->Init(TraceStart, TraceEnd); + } + } + + // Return whether we moved at all. + return bMoved; +} + +bool UVRRootComponent::UpdateOverlapsImpl(const TOverlapArrayView* NewPendingOverlaps, bool bDoNotifies, const TOverlapArrayView* OverlapsAtEndLocation) +{ + /*if (owningVRChar && !owningVRChar->bRetainRoomscale) + { + return Super::UpdateOverlaps(NewPendingOverlaps, bDoNotifies, OverlapsAtEndLocation); + }*/ + + //SCOPE_CYCLE_COUNTER(STAT_UpdateOverlaps); + SCOPE_CYCLE_COUNTER(STAT_UpdateOverlapsVRRoot); + SCOPE_CYCLE_UOBJECT(ComponentScope, this); + + // if we haven't begun play, we're still setting things up (e.g. we might be inside one of the construction scripts) + // so we don't want to generate overlaps yet. There is no need to update children yet either, they will update once we are allowed to as well. + const AActor* const MyActor = GetOwner(); + if (MyActor && !MyActor->HasActorBegunPlay() && !MyActor->IsActorBeginningPlay()) + { + return false; + } + + bool bCanSkipUpdateOverlaps = true; + + // first, dispatch any pending overlaps + if (GetGenerateOverlapEvents() && IsQueryCollisionEnabled()) //TODO: should modifying query collision remove from mayoverlapevents? + { + bCanSkipUpdateOverlaps = false; + + if (MyActor) + { + const FTransform PrevTransform = GetComponentTransform(); + // If we are the root component we ignore child components. Those children will update their overlaps when we descend into the child tree. + // This aids an optimization in MoveComponent. + const bool bIgnoreChildren = (MyActor->GetRootComponent() == this); + + if (NewPendingOverlaps) + { + // Note: BeginComponentOverlap() only triggers overlaps where GetGenerateOverlapEvents() is true on both components. + const int32 NumNewPendingOverlaps = NewPendingOverlaps->Num(); + for (int32 Idx = 0; Idx < NumNewPendingOverlaps; ++Idx) + { + BeginComponentOverlap((*NewPendingOverlaps)[Idx], bDoNotifies); + } + } + + const TOverlapArrayView* OverlapsAtEndLocationPtr = OverlapsAtEndLocation; + + // #TODO: Filter this better so it runs even less often? + // Its not that bad currently running off of NewPendingOverlaps + // It forces checking for end location overlaps again if none are registered, just in case + // the capsule isn't setting things correctly. + + TArray OverlapsAtEnd; + TOverlapArrayView OverlapsAtEndLoc; + if (/*(!OverlapsAtEndLocation || OverlapsAtEndLocation->Num() < 1) &&*/ NewPendingOverlaps && NewPendingOverlaps->Num() > 0) + { + ConvertSweptOverlapsToCurrentOverlapsVR(OverlapsAtEnd, *NewPendingOverlaps, -1, OffsetComponentToWorld.GetLocation(), GetComponentQuat()); + OverlapsAtEndLoc = TOverlapArrayView(OverlapsAtEnd); + OverlapsAtEndLocationPtr = &OverlapsAtEndLoc; + } + + // now generate full list of new touches, so we can compare to existing list and determine what changed + + TInlineOverlapInfoArray OverlapMultiResult; + TInlineOverlapPointerArray NewOverlappingComponentPtrs; + + // If pending kill, we should not generate any new overlaps. Also not if overlaps were just disabled during BeginComponentOverlap. + if (IsValid(this) && GetGenerateOverlapEvents()) + { + // 4.17 converted to auto cvar + static const auto CVarAllowCachedOverlaps = IConsoleManager::Get().FindConsoleVariable(TEXT("p.AllowCachedOverlaps")); + // Might be able to avoid testing for new overlaps at the end location. + if (OverlapsAtEndLocationPtr != nullptr && CVarAllowCachedOverlaps->GetInt() > 0 && PrevTransform.Equals(GetComponentTransform())) + { + UE_LOG(LogVRRootComponent, VeryVerbose, TEXT("%s->%s Skipping overlap test!"), *GetNameSafe(GetOwner()), *GetName()); + const bool bCheckForInvalid = (NewPendingOverlaps && NewPendingOverlaps->Num() > 0); + if (bCheckForInvalid) + { + // BeginComponentOverlap may have disabled what we thought were valid overlaps at the end (collision response or overlap flags could change). + GetPointersToArrayDataByPredicate(NewOverlappingComponentPtrs, *OverlapsAtEndLocationPtr, FPredicateFilterCanOverlap(*this)); + } + else + { + GetPointersToArrayData(NewOverlappingComponentPtrs, *OverlapsAtEndLocationPtr); + } + } + else + { + SCOPE_CYCLE_COUNTER(STAT_PerformOverlapQueryVR); + UE_LOG(LogVRRootComponent, VeryVerbose, TEXT("%s->%s Performing overlaps!"), *GetNameSafe(GetOwner()), *GetName()); + UWorld* const MyWorld = GetWorld(); + TArray Overlaps; + // note this will optionally include overlaps with components in the same actor (depending on bIgnoreChildren). + + FComponentQueryParams Params(SCENE_QUERY_STAT(UpdateOverlaps), bIgnoreChildren ? MyActor : nullptr); //(PrimitiveComponentStatics::UpdateOverlapsName, bIgnoreChildren ? MyActor : nullptr); + + Params.bIgnoreBlocks = true; //We don't care about blockers since we only route overlap events to real overlaps + FCollisionResponseParams ResponseParam; + InitSweepCollisionParams(Params, ResponseParam); + ComponentOverlapMulti(Overlaps, MyWorld, OffsetComponentToWorld.GetTranslation(), GetComponentQuat(), GetCollisionObjectType(), Params); + + for (int32 ResultIdx = 0; ResultIdx < Overlaps.Num(); ResultIdx++) + { + const FOverlapResult& Result = Overlaps[ResultIdx]; + + UPrimitiveComponent* const HitComp = Result.Component.Get(); + if (HitComp && (HitComp != this) && HitComp->GetGenerateOverlapEvents()) + { + const bool bCheckOverlapFlags = false; // Already checked above + if (!ShouldIgnoreOverlapResult(MyWorld, MyActor, *this, Result.OverlapObjectHandle.FetchActor(), *HitComp, bCheckOverlapFlags)) + { + OverlapMultiResult.Emplace(HitComp, Result.ItemIndex); // don't need to add unique unless the overlap check can return dupes + } + } + } + + // Fill pointers to overlap results. We ensure below that OverlapMultiResult stays in scope so these pointers remain valid. + GetPointersToArrayData(NewOverlappingComponentPtrs, OverlapMultiResult); + } + } + + // If we have any overlaps from BeginComponentOverlap() (from now or in the past), see if anything has changed by filtering NewOverlappingComponents + if (OverlappingComponents.Num() > 0) + { + TInlineOverlapPointerArray OldOverlappingComponentPtrs; + if (bIgnoreChildren) + { + GetPointersToArrayDataByPredicate(OldOverlappingComponentPtrs, OverlappingComponents, FPredicateOverlapHasDifferentActor(*MyActor)); + } + else + { + GetPointersToArrayData(OldOverlappingComponentPtrs, OverlappingComponents); + } + + // Now we want to compare the old and new overlap lists to determine + // what overlaps are in old and not in new (need end overlap notifies), and + // what overlaps are in new and not in old (need begin overlap notifies). + // We do this by removing common entries from both lists, since overlapping status has not changed for them. + // What is left over will be what has changed. + for (int32 CompIdx = 0; CompIdx < OldOverlappingComponentPtrs.Num() && NewOverlappingComponentPtrs.Num() > 0; ++CompIdx) + { + // RemoveAtSwap is ok, since it is not necessary to maintain order + + const FOverlapInfo* SearchItem = OldOverlappingComponentPtrs[CompIdx]; + const int32 NewElementIdx = IndexOfOverlapFast(NewOverlappingComponentPtrs, SearchItem); + if (NewElementIdx != INDEX_NONE) + { + NewOverlappingComponentPtrs.RemoveAtSwap(NewElementIdx, 1, EAllowShrinking::No); + OldOverlappingComponentPtrs.RemoveAtSwap(CompIdx, 1, EAllowShrinking::No); + --CompIdx; + } + } + + const int32 NumOldOverlaps = OldOverlappingComponentPtrs.Num(); + if (NumOldOverlaps > 0) + { + // Now we have to make a copy of the overlaps because we can't keep pointers to them, that list is about to be manipulated in EndComponentOverlap(). + TInlineOverlapInfoArray OldOverlappingComponents; + OldOverlappingComponents.SetNumUninitialized(NumOldOverlaps); + for (int32 i = 0; i < NumOldOverlaps; i++) + { + OldOverlappingComponents[i] = *(OldOverlappingComponentPtrs[i]); + } + + // OldOverlappingComponents now contains only previous overlaps that are confirmed to no longer be valid. + for (const FOverlapInfo& OtherOverlap : OldOverlappingComponents) + { + if (OtherOverlap.OverlapInfo.Component.IsValid()) + { + EndComponentOverlap(OtherOverlap, bDoNotifies, false); + } + else + { + // Remove stale item. Reclaim memory only if it's getting large, to try to avoid churn but avoid bloating component's memory usage. + const bool bAllowShrinking = (OverlappingComponents.Max() >= 24); + const int32 StaleElementIndex = IndexOfOverlapFast(OverlappingComponents, OtherOverlap); + if (StaleElementIndex != INDEX_NONE) + { + OverlappingComponents.RemoveAtSwap(StaleElementIndex, 1, bAllowShrinking ? EAllowShrinking::Yes : EAllowShrinking::No); + } + } + } + } + } + + // Ensure these arrays are still in scope, because we kept pointers to them in NewOverlappingComponentPtrs. + static_assert(sizeof(OverlapMultiResult) != 0, "Variable must be in this scope"); + static_assert(sizeof(*OverlapsAtEndLocation) != 0, "Variable must be in this scope"); + + // NewOverlappingComponents now contains only new overlaps that didn't exist previously. + for (const FOverlapInfo* NewOverlap : NewOverlappingComponentPtrs) + { + BeginComponentOverlap(*NewOverlap, bDoNotifies); + } + } + } + else + { + // GetGenerateOverlapEvents() is false or collision is disabled + // End all overlaps that exist, in case GetGenerateOverlapEvents() was true last tick (i.e. was just turned off) + if (OverlappingComponents.Num() > 0) + { + const bool bSkipNotifySelf = false; + ClearComponentOverlaps(bDoNotifies, bSkipNotifySelf); + } + } + + // now update any children down the chain. + // since on overlap events could manipulate the child array we need to take a copy + // of it to avoid missing any children if one is removed from the middle + TInlineComponentArray AttachedChildren; + AttachedChildren.Append(GetAttachChildren()); + + for (USceneComponent* const ChildComp : AttachedChildren) + { + if (ChildComp) + { + // Do not pass on OverlapsAtEndLocation, it only applied to this component. + bCanSkipUpdateOverlaps &= ChildComp->UpdateOverlaps(nullptr, bDoNotifies, nullptr); + } + } + + // Update physics volume using most current overlaps + if (GetShouldUpdatePhysicsVolume()) + { + UpdatePhysicsVolume(bDoNotifies); + bCanSkipUpdateOverlaps = false; + } + + return bCanSkipUpdateOverlaps; +} + +bool UVRRootComponent::IsLocallyControlled() const +{ + // I like epics implementation better than my own + const AActor* MyOwner = GetOwner(); + return MyOwner->HasLocalNetOwner(); + //const APawn* MyPawn = Cast(MyOwner); + //return MyPawn ? MyPawn->IsLocallyControlled() : (MyOwner->Role == ENetRole::ROLE_Authority); +} + +/*FORCEINLINE*/ void UVRRootComponent::SetCapsuleSizeVR(float NewRadius, float NewHalfHeight, bool bUpdateOverlaps) +{ + SCOPE_CYCLE_COUNTER(STAT_VRRootSetCapsuleSize); + + FScopedMovementUpdate ScopedNetSmootherMovementUpdate(owningVRChar ? owningVRChar->NetSmoother : nullptr, EScopedUpdate::DeferredUpdates); + + if (FMath::IsNearlyEqual(NewRadius, CapsuleRadius) && FMath::IsNearlyEqual(NewHalfHeight, CapsuleHalfHeight)) + { + return; + } + + float OldCapsuleHalfHeight = CapsuleHalfHeight; + + CapsuleHalfHeight = FMath::Max3(0.f, NewHalfHeight, NewRadius); + CapsuleRadius = FMath::Max(0.f, NewRadius); + + UpdateBounds(); + UpdateBodySetup(); + MarkRenderStateDirty(); + GenerateOffsetToWorld(); + + // do this if already created + // otherwise, it hasn't been really created yet + if (bPhysicsStateCreated) + { + // Update physics engine collision shapes + BodyInstance.UpdateBodyScale(GetComponentTransform().GetScale3D(), true); + + if (bUpdateOverlaps && IsCollisionEnabled() && GetOwner()) + { + UpdateOverlaps(); + } + } + + // Make sure that our character parent updates its replicated var as well + if (owningVRChar) + { + if (GetNetMode() < ENetMode::NM_Client) + { + if (owningVRChar->GetVRReplicateCapsuleHeight()) + { + owningVRChar->ReplicatedCapsuleHeight.CapsuleHeight = CapsuleHalfHeight; + } + } + + float Offset = (CapsuleHalfHeight - OldCapsuleHalfHeight); + + // Simulated proxies should already have the new height from the server + if (!owningVRChar->bRetainRoomscale && (owningVRChar->GetNetMode() < ENetMode::NM_Client || IsLocallyControlled())) + { + MoveComponent(this->GetComponentQuat().GetUpVector() * (Offset * this->GetComponentScale().Z), GetComponentQuat(), true, nullptr, EMoveComponentFlags::MOVECOMP_NoFlags, ETeleportType::TeleportPhysics); + } + /*else + { + // Generate final transform + GenerateOffsetToWorld(); + }*/ + + if (!owningVRChar->bRetainRoomscale && !IsLocallyControlled()) + { + // Don't smooth this change in mesh position + FNetworkPredictionData_Client_Character* ClientData = owningVRChar->GetCharacterMovement()->GetPredictionData_Client_Character(); + if (ClientData) + { + ClientData->MeshTranslationOffset.Z += (Offset * this->GetComponentScale().Z);// FVector::ZeroVector;// -= FVector(0.f, 0.f, Offset * this->GetComponentScale().Z); + ClientData->OriginalMeshTranslationOffset.Z = ClientData->MeshTranslationOffset.Z; + } + } + } + /*else + { + // Generate final transform + GenerateOffsetToWorld(); + }*/ +} + +void UVRRootComponent::UpdatePhysicsVolume(bool bTriggerNotifiers) +{ + if (GetShouldUpdatePhysicsVolume() && IsValid(this)) + { + // SCOPE_CYCLE_COUNTER(STAT_UpdatePhysicsVolume); + if (UWorld * MyWorld = GetWorld()) + { + if (MyWorld->GetNonDefaultPhysicsVolumeCount() == 0) + { + SetPhysicsVolume(MyWorld->GetDefaultPhysicsVolume(), bTriggerNotifiers); + } + else if (GetGenerateOverlapEvents() && IsQueryCollisionEnabled()) + { + APhysicsVolume* BestVolume = MyWorld->GetDefaultPhysicsVolume(); + int32 BestPriority = BestVolume->Priority; + + for (auto CompIt = OverlappingComponents.CreateIterator(); CompIt; ++CompIt) + { + const FOverlapInfo& Overlap = *CompIt; + UPrimitiveComponent* OtherComponent = Overlap.OverlapInfo.Component.Get(); + if (OtherComponent && OtherComponent->GetGenerateOverlapEvents()) + { + APhysicsVolume* V = Cast(OtherComponent->GetOwner()); + if (V && V->Priority > BestPriority) + { + //if (V->IsOverlapInVolume(*this)) + if (AreWeOverlappingVolume(V)) + { + BestPriority = V->Priority; + BestVolume = V; + } + } + } + } + + SetPhysicsVolume(BestVolume, bTriggerNotifiers); + } + else + { + Super::UpdatePhysicsVolume(bTriggerNotifiers); + } + } + } +} + +template +bool UVRRootComponent::ConvertSweptOverlapsToCurrentOverlapsVR( + TArray& OverlapsAtEndLocation, const TOverlapArrayView& SweptOverlaps, int32 SweptOverlapsIndex, + const FVector& EndLocation, const FQuat& EndRotationQuat) +{ + if (SweptOverlapsIndex == -1) + { + SweptOverlapsIndex = 0; + } + else + { + return false; + } + + checkSlow(SweptOverlapsIndex >= 0); + + // Override location check with our own + //GenerateOffsetToWorld(); + FVector EndLocationVR = OffsetComponentToWorld.GetLocation(); + + + bool bResult = false; + const bool bForceGatherOverlaps = !ShouldCheckOverlapFlagToQueueOverlaps(*this); + + static const auto CVarAllowCachedOverlaps = IConsoleManager::Get().FindConsoleVariable(TEXT("p.AllowCachedOverlaps")); + if ((GetGenerateOverlapEvents() || bForceGatherOverlaps) && CVarAllowCachedOverlaps->GetInt()) + { + const AActor* Actor = GetOwner(); + if (Actor && Actor->GetRootComponent() == this) + { + + static const auto CVarEnableFastOverlapCheck = IConsoleManager::Get().FindConsoleVariable(TEXT("p.EnableFastOverlapCheck")); + // We know we are not overlapping any new components at the end location. Children are ignored here (see note below). + if (CVarAllowCachedOverlaps->GetInt()) + { + //SCOPE_CYCLE_COUNTER(STAT_MoveComponent_FastOverlap); + + // Check components we hit during the sweep, keep only those still overlapping + const FCollisionQueryParams UnusedQueryParams(NAME_None, FCollisionQueryParams::GetUnknownStatId()); + const int32 NumSweptOverlaps = SweptOverlaps.Num(); + OverlapsAtEndLocation.Reserve(OverlapsAtEndLocation.Num() + NumSweptOverlaps); + for (int32 Index = SweptOverlapsIndex; Index < NumSweptOverlaps; ++Index) + { + const FOverlapInfo& OtherOverlap = SweptOverlaps[Index]; + UPrimitiveComponent* OtherPrimitive = OtherOverlap.OverlapInfo.GetComponent(); + if (OtherPrimitive && (OtherPrimitive->GetGenerateOverlapEvents() || bForceGatherOverlaps)) + { + if (OtherPrimitive->bMultiBodyOverlap) + { + // Not handled yet. We could do it by checking every body explicitly and track each body index in the overlap test, but this seems like a rare need. + return false; + } + else if (Cast(OtherPrimitive) /* || Cast(this)*/) + { + // SkeletalMeshComponent does not support this operation, and would return false in the test when an actual query could return true. + return false; + } + else if (OtherPrimitive->ComponentOverlapComponent(this, EndLocationVR, EndRotationQuat, UnusedQueryParams)) + { + OverlapsAtEndLocation.Add(OtherOverlap); + } + } + } + + // Note: we don't worry about adding any child components here, because they are not included in the sweep results. + // Children test for their own overlaps after we update our own, and we ignore children in our own update. + checkfSlow(OverlapsAtEndLocation.FindByPredicate(FPredicateOverlapHasSameActor(*Actor)) == nullptr, + TEXT("Child overlaps should not be included in the SweptOverlaps() array in UPrimitiveComponent::ConvertSweptOverlapsToCurrentOverlaps().")); + + bResult = true; + } + else + { + if (SweptOverlaps.Num() == 0 && AreAllCollideableDescendantsRelative()) + { + // Add overlaps with components in this actor. + GetOverlapsWithActor_TemplateVR(Actor, OverlapsAtEndLocation); + bResult = true; + } + } + } + } + + return bResult; +} + +template +bool UVRRootComponent::ConvertRotationOverlapsToCurrentOverlapsVR(TArray& OutOverlapsAtEndLocation, const TOverlapArrayView& CurrentOverlaps) +{ + bool bResult = false; + const bool bForceGatherOverlaps = !ShouldCheckOverlapFlagToQueueOverlaps(*this); + + static const auto CVarAllowCachedOverlaps = IConsoleManager::Get().FindConsoleVariable(TEXT("p.AllowCachedOverlaps")); + + if ((GetGenerateOverlapEvents() || bForceGatherOverlaps) && /*bAllowCachedOverlapsCVar*/ CVarAllowCachedOverlaps->GetInt()) + { + const AActor* Actor = GetOwner(); + if (Actor && Actor->GetRootComponent() == this) + { + static const auto CVarEnableFastOverlapCheck = IConsoleManager::Get().FindConsoleVariable(TEXT("p.EnableFastOverlapCheck")); + // We know we are not overlapping any new components at the end location. Children are ignored here (see note below). + if (CVarAllowCachedOverlaps->GetInt()) + { + // Add all current overlaps that are not children. Children test for their own overlaps after we update our own, and we ignore children in our own update. + OutOverlapsAtEndLocation.Reserve(OutOverlapsAtEndLocation.Num() + CurrentOverlaps.Num()); + Algo::CopyIf(CurrentOverlaps, OutOverlapsAtEndLocation, FPredicateOverlapHasDifferentActor(*Actor)); + bResult = true; + } + } + } + + return bResult; +} + +template +bool UVRRootComponent::GetOverlapsWithActor_TemplateVR(const AActor* Actor, TArray& OutOverlaps) const +{ + const int32 InitialCount = OutOverlaps.Num(); + if (Actor) + { + for (int32 OverlapIdx = 0; OverlapIdx < OverlappingComponents.Num(); ++OverlapIdx) + { + UPrimitiveComponent const* const PrimComp = OverlappingComponents[OverlapIdx].OverlapInfo.Component.Get(); + if (PrimComp && (PrimComp->GetOwner() == Actor)) + { + OutOverlaps.Add(OverlappingComponents[OverlapIdx]); + } + } + } + + return InitialCount != OutOverlaps.Num(); +} +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRStereoWidgetComponent.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRStereoWidgetComponent.cpp new file mode 100644 index 0000000..6f03c91 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRStereoWidgetComponent.cpp @@ -0,0 +1,1279 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "VRStereoWidgetComponent.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRStereoWidgetComponent) + +#include "VRExpansionFunctionLibrary.h" +#include "IXRTrackingSystem.h" +#include "IXRCamera.h" +#include "VRBaseCharacter.h" +#include "VRCharacter.h" +#include "VRRootComponent.h" +#include "TextureResource.h" +#include "Engine/Texture.h" +#include "Engine/GameInstance.h" +#include "SceneManagement.h" +#include "Materials/Material.h" +#include "IStereoLayers.h" +#include "IHeadMountedDisplay.h" +#include "PrimitiveViewRelevance.h" +#include "StereoLayerAdditionalFlagsManager.h" +#include "PrimitiveSceneProxy.h" +#include "UObject/ConstructorHelpers.h" +#include "EngineGlobals.h" +#include "MaterialShared.h" +#include "Materials/MaterialInstanceDynamic.h" +#include "Materials/MaterialRenderProxy.h" +#include "Engine/Engine.h" +#include "Engine/GameViewportClient.h" +#include "Engine/TextureRenderTarget2D.h" +//#include "Widgets/SWindow.h" +#include "Framework/Application/SlateApplication.h" +#include "Kismet/KismetSystemLibrary.h" +//#include "Input/HittestGrid.h" +//#include "SceneManagement.h" +#include "DynamicMeshBuilder.h" +//#include "PhysicsEngine/BoxElem.h" +#include "PhysicsEngine/BodySetup.h" +#include "Slate/SGameLayerManager.h" +#include "Slate/SWorldWidgetScreenLayer.h" + +#include "Widgets/SViewport.h" +#include "Widgets/SViewport.h" +#include "Slate/WidgetRenderer.h" +#include "Blueprint/UserWidget.h" +#include "SceneInterface.h" + +#include "StereoLayerShapes.h" + +// CVars +namespace StereoWidgetCvars +{ + static int32 ForceNoStereoWithVRWidgets = 0; + FAutoConsoleVariableRef CVarForceNoStereoWithVRWidgets( + TEXT("vr.ForceNoStereoWithVRWidgets"), + ForceNoStereoWithVRWidgets, + TEXT("When set to 0, will render stereo layer widgets as stereo by default.\n") + TEXT("When set to 1, will not allow stereo widget components to use stereo layers, will instead fall back to default widget rendering.\n") + TEXT("When set to 2, will render stereo layer widgets as both stereo and in game.\n") + TEXT("0: Default, 1: Force no stereo, 2: Render both at once"), + ECVF_Default); +} + +UVRStereoWidgetRenderComponent::UVRStereoWidgetRenderComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + Widget = nullptr; + WidgetRenderScale = 1.0f; + WidgetRenderGamma = 1.0f; + bUseGammaCorrection = false; + WidgetRenderer = nullptr; + RenderTarget = nullptr; + bDrawAtDesiredSize = true; + RenderTargetClearColor = FLinearColor::Black; + bDrawWithoutStereo = false; + DrawRate = 60.0f; + DrawCounter = 0.0f; + bLiveTexture = true; +} + +void UVRStereoWidgetRenderComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) +{ + + IStereoLayers* StereoLayers; + if (!GetVisibleFlag() || (!bDrawWithoutStereo && (!GEngine->StereoRenderingDevice.IsValid() || (StereoLayers = GEngine->StereoRenderingDevice->GetStereoLayers()) == nullptr))) + { + } + else + { + DrawCounter += DeltaTime; + + if (DrawRate > 0.0f && DrawCounter >= (1.0f / DrawRate)) + { + if (!IsRunningDedicatedServer()) + { + RenderWidget(DeltaTime); + } + + if (!bLiveTexture) + { + MarkStereoLayerDirty(); + } + + DrawCounter = 0.0f; + } + } + + if (bDrawWithoutStereo) + { + // Skip the stereo comps setup, we are just drawing to the texture + Super::Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + } + else + { + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + } +} + +void UVRStereoWidgetRenderComponent::BeginPlay() +{ + Super::BeginPlay(); + + if (WidgetClass.Get() != nullptr) + { + InitWidget(); + + IStereoLayers* StereoLayers; + if (!GetVisibleFlag() || (!bDrawWithoutStereo && (!GEngine->StereoRenderingDevice.IsValid() || (StereoLayers = GEngine->StereoRenderingDevice->GetStereoLayers()) == nullptr))) + { + } + else + { + // Initial render + RenderWidget(0.0f); + } + } +} + +void UVRStereoWidgetRenderComponent::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + Super::EndPlay(EndPlayReason); + + ReleaseResources(); +} + +void UVRStereoWidgetRenderComponent::ReleaseResources() +{ + +#if !UE_SERVER + FWorldDelegates::LevelRemovedFromWorld.RemoveAll(this); +#endif + + if (Widget) + { + Widget = nullptr; + } + + if (SlateWidget) + { + SlateWidget = nullptr; + } + + if (WidgetRenderer) + { + BeginCleanup(WidgetRenderer); + WidgetRenderer = nullptr; + } + + Texture = nullptr; + + if (SlateWindow.IsValid()) + { + if (/*!CanReceiveHardwareInput() && */FSlateApplication::IsInitialized()) + { + FSlateApplication::Get().UnregisterVirtualWindow(SlateWindow.ToSharedRef()); + } + + SlateWindow.Reset(); + } +} + +void UVRStereoWidgetRenderComponent::DestroyComponent(bool bPromoteChildren/*= false*/) +{ + Super::DestroyComponent(bPromoteChildren); + + ReleaseResources(); +} + +void UVRStereoWidgetRenderComponent::SetWidgetAndInit(TSubclassOf NewWidgetClass) +{ + WidgetClass = NewWidgetClass; + InitWidget(); +} + +void UVRStereoWidgetRenderComponent::OnLevelRemovedFromWorld(ULevel* InLevel, UWorld* InWorld) +{ + // If the InLevel is null, it's a signal that the entire world is about to disappear, so + // go ahead and remove this widget from the viewport, it could be holding onto too many + // dangerous actor references that won't carry over into the next world. + if (InLevel == nullptr && InWorld == GetWorld()) + { + ReleaseResources(); + } +} + +void UVRStereoWidgetRenderComponent::InitWidget() +{ + if (IsTemplate()) + return; + +#if !UE_SERVER + FWorldDelegates::LevelRemovedFromWorld.AddUObject(this, &ThisClass::OnLevelRemovedFromWorld); +#endif + if (IsRunningDedicatedServer()) + return; + + if (Widget && Widget->GetClass() == WidgetClass) + return; + + if (Widget != nullptr) + { + Widget->MarkAsGarbage(); + Widget = nullptr; + } + + if (SlateWidget) + { + SlateWidget = nullptr; + } + + // Don't do any work if Slate is not initialized + if (FSlateApplication::IsInitialized()) + { + UWorld* World = GetWorld(); + + if (WidgetClass && Widget == nullptr && World && !World->bIsTearingDown) + { + Widget = CreateWidget(GetWorld(), WidgetClass); + Widget->SetRenderScale(FVector2D(1.0f, 1.0f)); + } + +#if WITH_EDITOR + if (Widget && !World->IsGameWorld())// && !bEditTimeUsable) + { + if (!GEnableVREditorHacks) + { + // Prevent native ticking of editor component previews + Widget->SetDesignerFlags(EWidgetDesignFlags::Designing); + } + } +#endif + + if (Widget) + { + SlateWidget = Widget->TakeWidget(); + } + + // Create the SlateWindow if it doesn't exists + if (!SlateWindow.IsValid()) + { + FVector2D DrawSize = this->GetQuadSize(); + SlateWindow = SNew(SVirtualWindow).Size(DrawSize); + SlateWindow->SetIsFocusable(false); + SlateWindow->SetVisibility(EVisibility::Visible); + SlateWindow->SetContentScale(FVector2D(1.0f, 1.0f)); + + if (Widget && !Widget->IsDesignTime()) + { + if (UWorld* LocalWorld = GetWorld()) + { + if (LocalWorld->IsGameWorld()) + { + UGameInstance* GameInstance = LocalWorld->GetGameInstance(); + check(GameInstance); + + UGameViewportClient* GameViewportClient = GameInstance->GetGameViewportClient(); + if (GameViewportClient) + { + SlateWindow->AssignParentWidget(GameViewportClient->GetGameViewportWidget()); + } + } + } + } + + } + + if (SlateWindow) + { + TSharedRef MyWidget = SlateWidget ? SlateWidget.ToSharedRef() : Widget->TakeWidget(); + SlateWindow->SetContent(MyWidget); + } + } +} + +void UVRStereoWidgetRenderComponent::RenderWidget(float DeltaTime) +{ + if (!Widget) + return; + + if (WidgetRenderer == nullptr) + { + WidgetRenderer = new FWidgetRenderer(bUseGammaCorrection); + check(WidgetRenderer); + } + + FVector2D DrawSize = this->GetQuadSize(); + FVector2D TextureSize = DrawSize; + + const int32 MaxAllowedDrawSize = GetMax2DTextureDimension(); + if (DrawSize.X <= 0 || DrawSize.Y <= 0 || DrawSize.X > MaxAllowedDrawSize || DrawSize.Y > MaxAllowedDrawSize) + { + return; + } + + TSharedRef MyWidget = SlateWidget ? SlateWidget.ToSharedRef() : Widget->TakeWidget(); + + if (bDrawAtDesiredSize) + { + SlateWindow->SlatePrepass(WidgetRenderScale); + + FVector2D DesiredSize = SlateWindow->GetDesiredSize(); + DesiredSize.X = FMath::RoundToInt(DesiredSize.X); + DesiredSize.Y = FMath::RoundToInt(DesiredSize.Y); + + if (!DesiredSize.IsNearlyZero()) + { + TextureSize = DesiredSize;// .IntPoint(); + + WidgetRenderer->SetIsPrepassNeeded(false); + + if (SlateWindow->GetSizeInScreen() != DesiredSize) + { + SlateWindow->Resize(TextureSize); + } + } + else + { + WidgetRenderer->SetIsPrepassNeeded(true); + } + } + else + { + WidgetRenderer->SetIsPrepassNeeded(true); + } + + if (RenderTarget == nullptr) + { + const EPixelFormat requestedFormat = FSlateApplication::Get().GetRenderer()->GetSlateRecommendedColorFormat(); + RenderTarget = NewObject(); + check(RenderTarget); + RenderTarget->ClearColor = RenderTargetClearColor; + RenderTarget->TargetGamma = WidgetRenderGamma; + RenderTarget->InitCustomFormat(TextureSize.X, TextureSize.Y, requestedFormat /*PF_B8G8R8A8*/, false); + MarkStereoLayerDirty(); + } + else if (RenderTarget->GetResource()->GetSizeX() != TextureSize.X || RenderTarget->GetResource()->GetSizeY() != TextureSize.Y) + { + const EPixelFormat requestedFormat = FSlateApplication::Get().GetRenderer()->GetSlateRecommendedColorFormat(); + RenderTarget->InitCustomFormat(TextureSize.X, TextureSize.Y, requestedFormat /*PF_B8G8R8A8*/, false); + RenderTarget->UpdateResourceImmediate(); + MarkStereoLayerDirty(); + } + + WidgetRenderer->DrawWidget(RenderTarget, MyWidget, WidgetRenderScale, TextureSize, DeltaTime);//DeltaTime); + + if (Texture != RenderTarget) + { + Texture = RenderTarget; + } +} + + //============================================================================= +UVRStereoWidgetComponent::UVRStereoWidgetComponent(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +// , bLiveTexture(false) + , bSupportsDepth(false) + , bNoAlphaChannel(false) + //, Texture(nullptr) + //, LeftTexture(nullptr) + , bQuadPreserveTextureRatio(false) + //, StereoLayerQuadSize(FVector2D(500.0f, 500.0f)) + , UVRect(FBox2D(FVector2D(0.0f, 0.0f), FVector2D(1.0f, 1.0f))) + //, CylinderRadius(100) + //, CylinderOverlayArc(100)EWidgetGeometryMode + //, CylinderHeight(50) + //, StereoLayerType(SLT_TrackerLocked) + //, StereoLayerShape(SLSH_QuadLayer) + , Priority(0) + , LayerId(IStereoLayers::FLayerDesc::INVALID_LAYER_ID) + , bIsDirty(true) + , bTextureNeedsUpdate(false) + , LastTransform(FTransform::Identity) + , bLastVisible(false) +{ + bShouldCreateProxy = true; + bUseEpicsWorldLockedStereo = false; + // Replace quad size with DrawSize instead + //StereoLayerQuadSize = DrawSize; + + PrimaryComponentTick.TickGroup = TG_DuringPhysics; + + bIsDirty = true; + bDirtyRenderTarget = false; + bRenderBothStereoAndWorld = false; + bDrawWithoutStereo = false; + bDelayForRenderThread = false; + bIsSleeping = false; + //Texture = nullptr; +} + +//============================================================================= +UVRStereoWidgetComponent::~UVRStereoWidgetComponent() +{ +} + + +void UVRStereoWidgetComponent::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + if (EndPlayReason == EEndPlayReason::EndPlayInEditor || EndPlayReason == EEndPlayReason::Quit) + { + //FStereoLayerAdditionalFlagsManager::Destroy(); + } +} + + +void UVRStereoWidgetComponent::BeginDestroy() +{ + IStereoLayers* StereoLayers; + if (LayerId && GEngine->StereoRenderingDevice.IsValid() && (StereoLayers = GEngine->StereoRenderingDevice->GetStereoLayers()) != nullptr) + { + StereoLayers->DestroyLayer(LayerId); + LayerId = IStereoLayers::FLayerDesc::INVALID_LAYER_ID; + } + + Super::BeginDestroy(); +} + + +void UVRStereoWidgetComponent::OnUnregister() +{ + IStereoLayers* StereoLayers; + if (LayerId && GEngine->StereoRenderingDevice.IsValid() && (StereoLayers = GEngine->StereoRenderingDevice->GetStereoLayers()) != nullptr) + { + StereoLayers->DestroyLayer(LayerId); + LayerId = IStereoLayers::FLayerDesc::INVALID_LAYER_ID; + } + + Super::OnUnregister(); +} + +void UVRStereoWidgetComponent::DrawWidgetToRenderTarget(float DeltaTime) +{ + Super::DrawWidgetToRenderTarget(DeltaTime); + + bDirtyRenderTarget = true; +} + +void UVRStereoWidgetComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) +{ + + // Precaching what the widget uses for draw time here as it gets modified in the super tick + bool bWidgetDrew = ShouldDrawWidget(); + + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + + if (IsRunningDedicatedServer()) + { + SetTickMode(ETickMode::Disabled); + return; + } + + //bool bIsCurVis = IsWidgetVisible(); + + bool bIsVisible = (bAlwaysVisible && !bIsSleeping) || (IsVisible() && IsWidgetVisible() && !bIsSleeping);// && ((GetWorld()->TimeSince(GetLastRenderTime()) <= 0.5f)); + + // If we are set to not use stereo layers or we don't have a valid stereo layer device + if ( + StereoWidgetCvars::ForceNoStereoWithVRWidgets == 1 || + bDrawWithoutStereo || + !UVRExpansionFunctionLibrary::IsInVREditorPreviewOrGame() || + !GEngine->StereoRenderingDevice.IsValid() || + (GEngine->StereoRenderingDevice->GetStereoLayers() == nullptr) + ) + { + if (!bShouldCreateProxy) + { + bShouldCreateProxy = true; + //MarkRenderStateDirty(); // Recreate + + if (LayerId) + { + if (GEngine->StereoRenderingDevice.IsValid()) + { + IStereoLayers* StereoLayers = GEngine->StereoRenderingDevice->GetStereoLayers(); + if (StereoLayers) + StereoLayers->DestroyLayer(LayerId); + } + LayerId = IStereoLayers::FLayerDesc::INVALID_LAYER_ID; + } + } + + return; + } + else if (bRenderBothStereoAndWorld || StereoWidgetCvars::ForceNoStereoWithVRWidgets == 2) // Forcing both modes at once + { + if (!bShouldCreateProxy) + { + bShouldCreateProxy = true; + MarkRenderStateDirty(); // Recreate + } + } + else // Stereo only + { + if (bShouldCreateProxy) + { + bShouldCreateProxy = false; + MarkRenderStateDirty(); // Recreate + } + } + +#if !UE_SERVER + + // Same check that the widget runs prior to ticking + if (IsRunningDedicatedServer() || !GetSlateWindow() || GetSlateWindow()->GetContent() == SNullWidget::NullWidget) + { + return; + } + + IStereoLayers* StereoLayers; + if (!UVRExpansionFunctionLibrary::IsInVREditorPreviewOrGame() || !GEngine->StereoRenderingDevice.IsValid() || !RenderTarget) + { + return; + } + + StereoLayers = GEngine->StereoRenderingDevice->GetStereoLayers(); + + if (StereoLayers == nullptr) + return; + + FTransform Transform = LastTransform; + // Never true until epic fixes back end code + if (false)//StereoLayerType == SLT_WorldLocked) + { + Transform = GetComponentTransform(); + } + else if (Space == EWidgetSpace::Screen) + { + Transform = GetRelativeTransform(); + } + else if(bIsVisible) // World locked here now + { + + if (bUseEpicsWorldLockedStereo) + { + // Its incorrect......even in 4.17 + Transform = FTransform(FRotator(0.f,-180.f, 0.f)) * GetComponentTransform(); + //Transform.ConcatenateRotation(FRotator(0.0f, -180.0f, 0.0f).Quaternion()); + } + else + { + // Fix this when stereo world locked works again + // Thanks to mitch for the temp work around idea + + APlayerController* PC = nullptr; + if (UWorld * CurWorld = GetWorld()) + { + const ULocalPlayer* FirstPlayer = GEngine->GetFirstGamePlayer(CurWorld); + PC = FirstPlayer ? FirstPlayer->GetPlayerController(CurWorld) : nullptr; + } + + if (PC) + { + APawn * mpawn = PC->GetPawnOrSpectator(); + //bTextureNeedsUpdate = true; + if (mpawn) + { + + // Offset the transform by the widget pivot. + float DeltaY = (Pivot.X - 0.5f) * DrawSize.X; + float DeltaZ = (Pivot.Y - 0.5f) * DrawSize.Y; + FTransform OffsetTransform = FTransform(FVector(0.f, DeltaY, DeltaZ)); + OffsetTransform = OffsetTransform * GetComponentTransform(); + + // Set transform to this relative transform + + bool bHandledTransform = false; + if (AVRBaseCharacter* BaseVRChar = Cast(mpawn)) + { + if (BaseVRChar->VRReplicatedCamera) + { + if (USceneComponent* CameraParent = BaseVRChar->VRReplicatedCamera->GetAttachParent()) + { + FTransform DeltaTrans = FTransform::Identity; + if (!BaseVRChar->bRetainRoomscale) + { + FVector HMDLoc; + FQuat HMDRot; + GEngine->XRSystem->GetCurrentPose(IXRTrackingSystem::HMDDeviceId, HMDRot, HMDLoc); + + HMDLoc.Z = 0.0f; + + if (AVRCharacter* VRChar = Cast(mpawn)) + { + HMDLoc += UVRExpansionFunctionLibrary::GetHMDPureYaw_I(HMDRot.Rotator()).RotateVector(FVector(VRChar->VRRootReference->VRCapsuleOffset.X, VRChar->VRRootReference->VRCapsuleOffset.Y, 0.0f)); + } + + DeltaTrans = FTransform(FQuat::Identity, HMDLoc, FVector(1.0f)); + } + + Transform = OffsetTransform.GetRelativeTransform(CameraParent->GetComponentTransform()); + Transform = (FTransform(FRotator(0.f, -180.f, 0.f)) * Transform) * DeltaTrans; + bHandledTransform = true; + } + } + } + else if (UCameraComponent* Camera = mpawn->FindComponentByClass()) + { + // Look for generic camera comp and use its attach parent + if (USceneComponent* CameraParent = Camera->GetAttachParent()) + { + Transform = OffsetTransform.GetRelativeTransform(CameraParent->GetComponentTransform()); + Transform = FTransform(FRotator(0.f, -180.f, 0.f)) * Transform; + bHandledTransform = true; + } + } + + if(!bHandledTransform) // Just use the pawn as we don't know the heirarchy + { + Transform = OffsetTransform.GetRelativeTransform(mpawn->GetTransform()); + Transform = FTransform(FRotator(0.f, -180.f, 0.f)) * Transform; + } + + // OpenVR y+ Up, +x Right, -z Going away + // UE4 z+ up, +y right, +x forward + + //Transform.ConcatenateRotation(FRotator(0.0f, -180.0f, 0.0f).Quaternion()); + // I might need to inverse X axis here to get it facing the correct way, we'll see + + //Transform = mpawn->GetActorTransform().GetRelativeTransform(GetComponentTransform()); + } + } + else + { + // No PC, destroy the layer and enable drawing it normally. + bShouldCreateProxy = true; + + if (LayerId) + { + StereoLayers->DestroyLayer(LayerId); + LayerId = IStereoLayers::FLayerDesc::INVALID_LAYER_ID; + } + return; + } + // + //Transform = GetRelativeTransform(); + } + } + + // If the transform changed dirty the layer and push the new transform + + if (!bIsDirty) + { + if (bLastVisible != bIsVisible) + { + bIsDirty = true; + } + else if (bDirtyRenderTarget || FMemory::Memcmp(&LastTransform, &Transform, sizeof(Transform)) != 0) + { + bIsDirty = true; + } + } + + bool bCurrVisible = bIsVisible; + if (!RenderTarget || !RenderTarget->GetResource()) + { + bCurrVisible = false; + } + + if (bIsDirty) + { + // OpenXR doesn't take the transforms scale component into account for the stereo layer, so we need to scale the buffer instead + // Fixed? In 5.2, leaving code commented out in case I need to bring it back + /*bool bScaleBuffer = false; + static FName SystemName(TEXT("OpenXR")); + if (GEngine->XRSystem.IsValid() && (GEngine->XRSystem->GetSystemName() == SystemName)) + { + bScaleBuffer = true; + }*/ + + IStereoLayers::FLayerDesc LayerDsec; + LayerDsec.Priority = Priority; + LayerDsec.QuadSize = FVector2D(DrawSize); + LayerDsec.UVRect = UVRect; + + if (bDelayForRenderThread && !LastTransform.Equals(FTransform::Identity)) + { + LayerDsec.Transform = LastTransform; + /*if (bScaleBuffer) + { + LayerDsec.QuadSize = FVector2D(DrawSize) * FVector2D(LastTransform.GetScale3D()); + }*/ + } + else + { + LayerDsec.Transform = Transform; + /*if (bScaleBuffer) + { + LayerDsec.QuadSize = FVector2D(DrawSize) * FVector2D(Transform.GetScale3D()); + }*/ + } + + if (RenderTarget) + { + LayerDsec.Texture = RenderTarget->GetResource()->TextureRHI; + LayerDsec.Flags |= (RenderTarget->GetMaterialType() == MCT_TextureExternal) ? IStereoLayers::LAYER_FLAG_TEX_EXTERNAL : 0; + } + // Forget the left texture implementation + //if (LeftTexture) + //{ + // LayerDsec.LeftTexture = LeftTexture->Resource->TextureRHI; + //} + + LayerDsec.Flags |= IStereoLayers::LAYER_FLAG_TEX_CONTINUOUS_UPDATE;// (/*bLiveTexture*/true) ? IStereoLayers::LAYER_FLAG_TEX_CONTINUOUS_UPDATE : 0; + LayerDsec.Flags |= (bNoAlphaChannel) ? IStereoLayers::LAYER_FLAG_TEX_NO_ALPHA_CHANNEL : 0; + LayerDsec.Flags |= (bQuadPreserveTextureRatio) ? IStereoLayers::LAYER_FLAG_QUAD_PRESERVE_TEX_RATIO : 0; + LayerDsec.Flags |= (bSupportsDepth) ? IStereoLayers::LAYER_FLAG_SUPPORT_DEPTH : 0; + LayerDsec.Flags |= (!bCurrVisible) ? IStereoLayers::LAYER_FLAG_HIDDEN : 0; + + // Would love to implement but they aren't exporting the symbols + /*TSharedPtr FlagsManager = FStereoLayerAdditionalFlagsManager::Get(); + for (FName& Flag : AdditionalFlags) + { + LayerDsec.Flags |= FlagsManager->GetFlagValue(Flag); + }*/ + + // Fix this later when WorldLocked is no longer wrong. + switch (Space) + { + case EWidgetSpace::World: + { + if(bUseEpicsWorldLockedStereo) + LayerDsec.PositionType = IStereoLayers::WorldLocked; + else + LayerDsec.PositionType = IStereoLayers::TrackerLocked; + + //LayerDsec.Flags |= IStereoLayers::LAYER_FLAG_SUPPORT_DEPTH; + }break; + + case EWidgetSpace::Screen: + default: + { + LayerDsec.PositionType = IStereoLayers::FaceLocked; + }break; + } + + switch (GeometryMode) + { + case EWidgetGeometryMode::Cylinder: + { + UStereoLayerShapeCylinder* Cylinder = Cast(Shape); + + if (!Cylinder) + { + if (Shape) + { + Shape->MarkAsGarbage(); + } + + Cylinder = NewObject(this, NAME_None, RF_Public); + Shape = Cylinder; + } + + if (Cylinder) + { + const float ArcAngleRadians = FMath::DegreesToRadians(CylinderArcAngle); + const float Radius = GetDrawSize().X / ArcAngleRadians; + + Cylinder->Height = GetDrawSize().Y;//CylinderHeight_DEPRECATED; + Cylinder->OverlayArc = CylinderArcAngle;// CylinderOverlayArc_DEPRECATED; + Cylinder->Radius = Radius;// CylinderRadius_DEPRECATED; + } + break; + + //LayerDsec.ShapeType = IStereoLayers::CylinderLayer; + + }break; + case EWidgetGeometryMode::Plane: + default: + { + UStereoLayerShapeQuad* Quad = Cast(Shape); + + if (!Quad) + { + if (Shape) + { + Shape->MarkAsGarbage(); + } + Shape = NewObject(this, NAME_None, RF_Public); + } + //LayerDsec.ShapeType = IStereoLayers::QuadLayer; + }break; + } + + if(Shape) + Shape->ApplyShape(LayerDsec); + + if (LayerId) + { + StereoLayers->SetLayerDesc(LayerId, LayerDsec); + } + else + { + LayerId = StereoLayers->CreateLayer(LayerDsec); + } + + } + + LastTransform = Transform; + bLastVisible = bCurrVisible; + bIsDirty = false; + bDirtyRenderTarget = false; +#endif +} + + +void UVRStereoWidgetComponent::SetPriority(int32 InPriority) +{ + if (Priority == InPriority) + { + return; + } + + Priority = InPriority; + bIsDirty = true; +} + +void UVRStereoWidgetComponent::UpdateRenderTarget(FIntPoint DesiredRenderTargetSize) +{ + Super::UpdateRenderTarget(DesiredRenderTargetSize); +} + +/** Represents a billboard sprite to the scene manager. */ +class FStereoWidget3DSceneProxy final : public FPrimitiveSceneProxy +{ +public: + SIZE_T GetTypeHash() const override + { + static size_t UniquePointer; + return reinterpret_cast(&UniquePointer); + } + /** Initialization constructor. */ + FStereoWidget3DSceneProxy(UVRStereoWidgetComponent* InComponent, ISlate3DRenderer& InRenderer) + : FPrimitiveSceneProxy(InComponent) + , Pivot(InComponent->GetPivot()) + , Renderer(InRenderer) + , RenderTarget(InComponent->GetRenderTarget()) + , MaterialInstance(InComponent->GetMaterialInstance()) + , BodySetup(InComponent->GetBodySetup()) + , BlendMode(InComponent->GetBlendMode()) + , GeometryMode(InComponent->GetGeometryMode()) + , ArcAngle(FMath::DegreesToRadians(InComponent->GetCylinderArcAngle())) + { + bWillEverBeLit = false; + bCreateSceneProxy = InComponent->bShouldCreateProxy; + MaterialRelevance = MaterialInstance->GetRelevance(GetScene().GetFeatureLevel()); + } + + // FPrimitiveSceneProxy interface. + virtual void GetDynamicMeshElements(const TArray& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const override + { + if(!bCreateSceneProxy) + return; + +#if WITH_EDITOR + const bool bWireframe = AllowDebugViewmodes() && ViewFamily.EngineShowFlags.Wireframe; + + auto WireframeMaterialInstance = new FColoredMaterialRenderProxy( + GEngine->WireframeMaterial ? GEngine->WireframeMaterial->GetRenderProxy() : nullptr, + FLinearColor(0, 0.5f, 1.f) + ); + + Collector.RegisterOneFrameMaterialProxy(WireframeMaterialInstance); + + FMaterialRenderProxy* ParentMaterialProxy = nullptr; + if (bWireframe) + { + ParentMaterialProxy = WireframeMaterialInstance; + } + else + { + ParentMaterialProxy = MaterialInstance->GetRenderProxy(); + } +#else + FMaterialRenderProxy* ParentMaterialProxy = MaterialInstance->GetRenderProxy(); +#endif + + //FSpriteTextureOverrideRenderProxy* TextureOverrideMaterialProxy = new FSpriteTextureOverrideRenderProxy(ParentMaterialProxy, + + const FMatrix& ViewportLocalToWorld = GetLocalToWorld(); + + FMatrix PreviousLocalToWorld; + + if (!GetScene().GetPreviousLocalToWorld(GetPrimitiveSceneInfo(), PreviousLocalToWorld)) + { + PreviousLocalToWorld = GetLocalToWorld(); + } + + if (RenderTarget) + { + FTextureResource* TextureResource = RenderTarget->GetResource(); + if (TextureResource) + { + if (GeometryMode == EWidgetGeometryMode::Plane) + { + float U = -RenderTarget->SizeX * Pivot.X; + float V = -RenderTarget->SizeY * Pivot.Y; + float UL = RenderTarget->SizeX * (1.0f - Pivot.X); + float VL = RenderTarget->SizeY * (1.0f - Pivot.Y); + + int32 VertexIndices[4]; + + for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) + { + FDynamicMeshBuilder MeshBuilder(Views[ViewIndex]->GetFeatureLevel()); + + if (VisibilityMap & (1 << ViewIndex)) + { + VertexIndices[0] = MeshBuilder.AddVertex(-FVector3f(0, U, V), FVector2f(0, 0), FVector3f(0, -1, 0), FVector3f(0, 0, -1), FVector3f(1, 0, 0), FColor::White); + VertexIndices[1] = MeshBuilder.AddVertex(-FVector3f(0, U, VL), FVector2f(0, 1), FVector3f(0, -1, 0), FVector3f(0, 0, -1), FVector3f(1, 0, 0), FColor::White); + VertexIndices[2] = MeshBuilder.AddVertex(-FVector3f(0, UL, VL), FVector2f(1, 1), FVector3f(0, -1, 0), FVector3f(0, 0, -1), FVector3f(1, 0, 0), FColor::White); + VertexIndices[3] = MeshBuilder.AddVertex(-FVector3f(0, UL, V), FVector2f(1, 0), FVector3f(0, -1, 0), FVector3f(0, 0, -1), FVector3f(1, 0, 0), FColor::White); + + MeshBuilder.AddTriangle(VertexIndices[0], VertexIndices[1], VertexIndices[2]); + MeshBuilder.AddTriangle(VertexIndices[0], VertexIndices[2], VertexIndices[3]); + + FDynamicMeshBuilderSettings Settings; + Settings.bDisableBackfaceCulling = false; + Settings.bReceivesDecals = true; + Settings.bUseSelectionOutline = true; + MeshBuilder.GetMesh(ViewportLocalToWorld, PreviousLocalToWorld, ParentMaterialProxy, SDPG_World, Settings, nullptr, ViewIndex, Collector, FHitProxyId()); + } + } + } + else + { + ensure(GeometryMode == EWidgetGeometryMode::Cylinder); + + const int32 NumSegments = FMath::Lerp(4, 32, ArcAngle / PI); + + + const float Radius = RenderTarget->SizeX / ArcAngle; + const float Apothem = Radius * FMath::Cos(0.5f*ArcAngle); + const float ChordLength = 2.0f * Radius * FMath::Sin(0.5f*ArcAngle); + + const float PivotOffsetX = ChordLength * (0.5 - Pivot.X); + const float V = -RenderTarget->SizeY * Pivot.Y; + const float VL = RenderTarget->SizeY * (1.0f - Pivot.Y); + + int32 VertexIndices[4]; + + for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) + { + FDynamicMeshBuilder MeshBuilder(Views[ViewIndex]->GetFeatureLevel()); + + if (VisibilityMap & (1 << ViewIndex)) + { + const float RadiansPerStep = ArcAngle / NumSegments; + + FVector LastTangentX; + FVector LastTangentY; + FVector LastTangentZ; + + for (int32 Segment = 0; Segment < NumSegments; Segment++) + { + const float Angle = -ArcAngle / 2 + Segment * RadiansPerStep; + const float NextAngle = Angle + RadiansPerStep; + + // Polar to Cartesian + const float X0 = Radius * FMath::Cos(Angle) - Apothem; + const float Y0 = Radius * FMath::Sin(Angle); + const float X1 = Radius * FMath::Cos(NextAngle) - Apothem; + const float Y1 = Radius * FMath::Sin(NextAngle); + + const float U0 = static_cast(Segment) / NumSegments; + const float U1 = static_cast(Segment + 1) / NumSegments; + + const FVector Vertex0 = -FVector(X0, PivotOffsetX + Y0, V); + const FVector Vertex1 = -FVector(X0, PivotOffsetX + Y0, VL); + const FVector Vertex2 = -FVector(X1, PivotOffsetX + Y1, VL); + const FVector Vertex3 = -FVector(X1, PivotOffsetX + Y1, V); + + FVector TangentX = Vertex3 - Vertex0; + TangentX.Normalize(); + FVector TangentY = Vertex1 - Vertex0; + TangentY.Normalize(); + FVector TangentZ = FVector::CrossProduct(TangentX, TangentY); + + if (Segment == 0) + { + LastTangentX = TangentX; + LastTangentY = TangentY; + LastTangentZ = TangentZ; + } + + VertexIndices[0] = MeshBuilder.AddVertex((FVector3f)Vertex0, FVector2f(U0, 0), (FVector3f)LastTangentX, (FVector3f)LastTangentY, (FVector3f)LastTangentZ, FColor::White); + VertexIndices[1] = MeshBuilder.AddVertex((FVector3f)Vertex1, FVector2f(U0, 1), (FVector3f)LastTangentX, (FVector3f)LastTangentY, (FVector3f)LastTangentZ, FColor::White); + VertexIndices[2] = MeshBuilder.AddVertex((FVector3f)Vertex2, FVector2f(U1, 1), (FVector3f)TangentX, (FVector3f)TangentY, (FVector3f)TangentZ, FColor::White); + VertexIndices[3] = MeshBuilder.AddVertex((FVector3f)Vertex3, FVector2f(U1, 0), (FVector3f)TangentX, (FVector3f)TangentY, (FVector3f)TangentZ, FColor::White); + + MeshBuilder.AddTriangle(VertexIndices[0], VertexIndices[1], VertexIndices[2]); + MeshBuilder.AddTriangle(VertexIndices[0], VertexIndices[2], VertexIndices[3]); + + LastTangentX = TangentX; + LastTangentY = TangentY; + LastTangentZ = TangentZ; + } + + FDynamicMeshBuilderSettings Settings; + Settings.bDisableBackfaceCulling = false; + Settings.bReceivesDecals = true; + Settings.bUseSelectionOutline = true; + MeshBuilder.GetMesh(ViewportLocalToWorld, PreviousLocalToWorld, ParentMaterialProxy, SDPG_World, Settings, nullptr, ViewIndex, Collector, FHitProxyId()); + } + } + } + } + } + +#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) + for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) + { + if (VisibilityMap & (1 << ViewIndex)) + { + RenderCollision(BodySetup, Collector, ViewIndex, ViewFamily.EngineShowFlags, GetBounds(), IsSelected()); + RenderBounds(Collector.GetPDI(ViewIndex), ViewFamily.EngineShowFlags, GetBounds(), IsSelected()); + } + } +#endif + } + + void RenderCollision(UBodySetup* InBodySetup, FMeshElementCollector& Collector, int32 ViewIndex, const FEngineShowFlags& EngineShowFlags, const FBoxSphereBounds& InBounds, bool bRenderInEditor) const + { + if (InBodySetup) + { + bool bDrawCollision = EngineShowFlags.Collision && IsCollisionEnabled(); + + if (bDrawCollision && AllowDebugViewmodes()) + { + // Draw simple collision as wireframe if 'show collision', collision is enabled, and we are not using the complex as the simple + const bool bDrawSimpleWireframeCollision = InBodySetup->CollisionTraceFlag != ECollisionTraceFlag::CTF_UseComplexAsSimple; + + if (FMath::Abs(GetLocalToWorld().Determinant()) < UE_SMALL_NUMBER) + { + // Catch this here or otherwise GeomTransform below will assert + // This spams so commented out + //UE_LOG(LogStaticMesh, Log, TEXT("Zero scaling not supported (%s)"), *StaticMesh->GetPathName()); + } + else + { + const bool bDrawSolid = !bDrawSimpleWireframeCollision; + const bool bProxyIsSelected = IsSelected(); + + if (bDrawSolid) + { + // Make a material for drawing solid collision stuff + auto SolidMaterialInstance = new FColoredMaterialRenderProxy( + GEngine->ShadedLevelColorationUnlitMaterial->GetRenderProxy(), + GetWireframeColor() + ); + + Collector.RegisterOneFrameMaterialProxy(SolidMaterialInstance); + + FTransform GeomTransform(GetLocalToWorld()); + InBodySetup->AggGeom.GetAggGeom(GeomTransform, GetWireframeColor().ToFColor(true), SolidMaterialInstance, false, true, AlwaysHasVelocity(), ViewIndex, Collector); + } + // wireframe + else + { + FColor CollisionColor = FColor(157, 149, 223, 255); + FTransform GeomTransform(GetLocalToWorld()); + InBodySetup->AggGeom.GetAggGeom(GeomTransform, GetSelectionColor(CollisionColor, bProxyIsSelected, IsHovered()).ToFColor(true), nullptr, false, false, AlwaysHasVelocity(), ViewIndex, Collector); + } + } + } + } + } + + virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView* View) const override + { + bool bVisible = true; + + FPrimitiveViewRelevance Result; + + MaterialRelevance.SetPrimitiveViewRelevance(Result); + + Result.bDrawRelevance = IsShown(View) && bVisible && View->Family->EngineShowFlags.WidgetComponents; + Result.bDynamicRelevance = true; + Result.bShadowRelevance = IsShadowCast(View); + Result.bTranslucentSelfShadow = bCastVolumetricTranslucentShadow; + Result.bEditorPrimitiveRelevance = false; + Result.bVelocityRelevance = DrawsVelocity() && Result.bOpaque && Result.bRenderInMainPass; + + return Result; + } + + virtual void GetLightRelevance(const FLightSceneProxy* LightSceneProxy, bool& bDynamic, bool& bRelevant, bool& bLightMapped, bool& bShadowMapped) const override + { + bDynamic = false; + bRelevant = false; + bLightMapped = false; + bShadowMapped = false; + } + + virtual void OnTransformChanged(FRHICommandListBase& RHICmdList) override + { + Origin = GetLocalToWorld().GetOrigin(); + } + + virtual bool CanBeOccluded() const override + { + return !MaterialRelevance.bDisableDepthTest; + } + + virtual uint32 GetMemoryFootprint(void) const override { return(sizeof(*this) + GetAllocatedSize()); } + + uint32 GetAllocatedSize(void) const { return(FPrimitiveSceneProxy::GetAllocatedSize()); } + +private: + FVector Origin; + FVector2D Pivot; + ISlate3DRenderer& Renderer; + UTextureRenderTarget2D* RenderTarget; + UMaterialInstanceDynamic* MaterialInstance; + FMaterialRelevance MaterialRelevance; + UBodySetup* BodySetup; + EWidgetBlendMode BlendMode; + EWidgetGeometryMode GeometryMode; + float ArcAngle; + bool bCreateSceneProxy; +}; + + +FPrimitiveSceneProxy* UVRStereoWidgetComponent::CreateSceneProxy() +{ + if (Space == EWidgetSpace::Screen) + { + return nullptr; + } + + if (WidgetRenderer && GetSlateWindow() && GetSlateWindow()->GetContent() != SNullWidget::NullWidget) + { + RequestRenderUpdate(); + LastWidgetRenderTime = 0; + + return new FStereoWidget3DSceneProxy(this, *WidgetRenderer->GetSlateRenderer()); + } + +#if WITH_EDITOR + // make something so we can see this component in the editor + class FWidgetBoxProxy final : public FPrimitiveSceneProxy + { + public: + SIZE_T GetTypeHash() const override + { + static size_t UniquePointer; + return reinterpret_cast(&UniquePointer); + } + + FWidgetBoxProxy(const UWidgetComponent* InComponent) + : FPrimitiveSceneProxy(InComponent) + , BoxExtents(1.f, InComponent->GetCurrentDrawSize().X / 2.0f, InComponent->GetCurrentDrawSize().Y / 2.0f) + { + bWillEverBeLit = false; + } + + virtual void GetDynamicMeshElements(const TArray& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const override + { + QUICK_SCOPE_CYCLE_COUNTER(STAT_BoxSceneProxy_GetDynamicMeshElements); + + const FMatrix& LocalToWorld = GetLocalToWorld(); + + for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) + { + if (VisibilityMap & (1 << ViewIndex)) + { + const FSceneView* View = Views[ViewIndex]; + + const FLinearColor DrawColor = GetViewSelectionColor(FColor::White, *View, IsSelected(), IsHovered(), false, IsIndividuallySelected()); + + FPrimitiveDrawInterface* PDI = Collector.GetPDI(ViewIndex); + DrawOrientedWireBox(PDI, LocalToWorld.GetOrigin(), LocalToWorld.GetScaledAxis(EAxis::X), LocalToWorld.GetScaledAxis(EAxis::Y), LocalToWorld.GetScaledAxis(EAxis::Z), BoxExtents, DrawColor, SDPG_World); + } + } + } + + virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView* View) const override + { + FPrimitiveViewRelevance Result; + if (!View->bIsGameView) + { + // Should we draw this because collision drawing is enabled, and we have collision + const bool bShowForCollision = View->Family->EngineShowFlags.Collision && IsCollisionEnabled(); + Result.bDrawRelevance = IsShown(View) || bShowForCollision; + Result.bDynamicRelevance = true; + Result.bShadowRelevance = IsShadowCast(View); + Result.bEditorPrimitiveRelevance = UseEditorCompositing(View); + } + return Result; + } + virtual uint32 GetMemoryFootprint(void) const override { return(sizeof(*this) + GetAllocatedSize()); } + uint32 GetAllocatedSize(void) const { return(FPrimitiveSceneProxy::GetAllocatedSize()); } + + private: + const FVector BoxExtents; + }; + + return new FWidgetBoxProxy(this); +#else + return nullptr; +#endif +} + +class FVRStereoWidgetComponentInstanceData : public FActorComponentInstanceData +{ +public: + FVRStereoWidgetComponentInstanceData(const UVRStereoWidgetComponent* SourceComponent) + : FActorComponentInstanceData(SourceComponent) + , RenderTarget(SourceComponent->GetRenderTarget()) + {} + + virtual void ApplyToComponent(UActorComponent* Component, const ECacheApplyPhase CacheApplyPhase) override + { + FActorComponentInstanceData::ApplyToComponent(Component, CacheApplyPhase); + CastChecked(Component)->ApplyVRComponentInstanceData(this); + } + + /*virtual void AddReferencedObjects(FReferenceCollector& Collector) override + { + FActorComponentInstanceData::AddReferencedObjects(Collector); + + UClass* WidgetUClass = *WidgetClass; + Collector.AddReferencedObject(WidgetUClass); + Collector.AddReferencedObject(RenderTarget); + }*/ + +public: + UTextureRenderTarget2D* RenderTarget; +}; + +TStructOnScope UVRStereoWidgetComponent::GetComponentInstanceData() const +{ + return MakeStructOnScope(this); +} + +void UVRStereoWidgetComponent::ApplyVRComponentInstanceData(FVRStereoWidgetComponentInstanceData* WidgetInstanceData) +{ + check(WidgetInstanceData); + + // Note: ApplyComponentInstanceData is called while the component is registered so the rendering thread is already using this component + // That means all component state that is modified here must be mirrored on the scene proxy, which will be recreated to receive the changes later due to MarkRenderStateDirty. + + if (GetWidgetClass() != WidgetClass) + { + return; + } + + RenderTarget = WidgetInstanceData->RenderTarget; + + // Also set the texture + //Texture = RenderTarget; + // Not needed anymore, just using the render target directly now + + if (MaterialInstance && RenderTarget) + { + MaterialInstance->SetTextureParameterValue("SlateUI", RenderTarget); + } + + MarkRenderStateDirty(); +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRTrackedParentInterface.cpp b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRTrackedParentInterface.cpp new file mode 100644 index 0000000..f2dffe6 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Private/VRTrackedParentInterface.cpp @@ -0,0 +1,74 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#include "VRTrackedParentInterface.h" +#include UE_INLINE_GENERATED_CPP_BY_NAME(VRTrackedParentInterface) + +#include "UObject/Interface.h" +#include "Components/PrimitiveComponent.h" +#include "Components/SceneComponent.h" +#include "VRBPDatatypes.h" + +UVRTrackedParentInterface::UVRTrackedParentInterface(const class FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + +} + +void IVRTrackedParentInterface::Default_SetTrackedParent_Impl(UPrimitiveComponent * NewParentComponent, float WaistRadius, EBPVRWaistTrackingMode WaistTrackingMode, FBPVRWaistTracking_Info & OptionalWaistTrackingParent, USceneComponent * Self) +{ + // If had a different original tracked parent + // Moved this to first thing so the pre-res is removed prior to erroring out and clearing this + if (OptionalWaistTrackingParent.IsValid()) + { + // Remove the tick Prerequisite + Self->RemoveTickPrerequisiteComponent(OptionalWaistTrackingParent.TrackedDevice); + } + if (!NewParentComponent || !Self) + { + OptionalWaistTrackingParent.Clear(); + return; + } + // Make other component tick first if possible, waste of time if in wrong tick group + if (NewParentComponent->PrimaryComponentTick.TickGroup == Self->PrimaryComponentTick.TickGroup) + { + // Make sure the other component isn't depending on this one + NewParentComponent->RemoveTickPrerequisiteComponent(Self); + // Add a tick pre-res for ourselves so that we tick after our tracked parent. + Self->AddTickPrerequisiteComponent(NewParentComponent); + } + OptionalWaistTrackingParent.TrackedDevice = NewParentComponent; + OptionalWaistTrackingParent.RestingRotation = NewParentComponent->GetRelativeRotation(); + OptionalWaistTrackingParent.RestingRotation.Yaw = 0.0f; + + OptionalWaistTrackingParent.TrackingMode = WaistTrackingMode; + OptionalWaistTrackingParent.WaistRadius = WaistRadius; +} +FTransform IVRTrackedParentInterface::Default_GetWaistOrientationAndPosition(FBPVRWaistTracking_Info & WaistTrackingInfo) +{ + if (!WaistTrackingInfo.IsValid()) + return FTransform::Identity; + FTransform DeviceTransform = WaistTrackingInfo.TrackedDevice->GetRelativeTransform(); + // Rewind by the initial rotation when the new parent was set, this should be where the tracker rests on the person + DeviceTransform.ConcatenateRotation(WaistTrackingInfo.RestingRotation.Quaternion().Inverse()); + DeviceTransform.SetScale3D(FVector(1, 1, 1)); + // Don't bother if not set + if (WaistTrackingInfo.WaistRadius > 0.0f) + { + DeviceTransform.AddToTranslation(DeviceTransform.GetRotation().RotateVector(FVector(-WaistTrackingInfo.WaistRadius, 0, 0))); + } + // This changes the forward vector to be correct + // I could pre do it by changed the yaw in resting mode to these values, but that had its own problems + // If given an initial forward vector that it should align to I wouldn't have to do this and could auto calculate it. + // But without that I am limited to this. + // #TODO: add optional ForwardVector to initial setup function that auto calculates offset so that the user can pass in HMD forward or something for calibration X+ + // Also would be better overall because slightly offset from right angles in yaw wouldn't matter anymore, it would adjust for it. + switch (WaistTrackingInfo.TrackingMode) + { + case EBPVRWaistTrackingMode::VRWaist_Tracked_Front: DeviceTransform.ConcatenateRotation(FRotator(0, 0, 0).Quaternion()); break; + case EBPVRWaistTrackingMode::VRWaist_Tracked_Rear: DeviceTransform.ConcatenateRotation(FRotator(0, -180, 0).Quaternion()); break; + case EBPVRWaistTrackingMode::VRWaist_Tracked_Left: DeviceTransform.ConcatenateRotation(FRotator(0, 90, 0).Quaternion()); break; + case EBPVRWaistTrackingMode::VRWaist_Tracked_Right: DeviceTransform.ConcatenateRotation(FRotator(0, -90, 0).Quaternion()); break; + } + + return DeviceTransform; +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/CharacterMovementCompTypes.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/CharacterMovementCompTypes.h new file mode 100644 index 0000000..3afc56a --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/CharacterMovementCompTypes.h @@ -0,0 +1,747 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#pragma once +#include "CoreMinimal.h" +#include "VRBPDatatypes.h" +#include "GameFramework/Character.h" +#include "Components/SkeletalMeshComponent.h" +#include "Engine/ScopedMovementUpdate.h" +#include "GameFramework/CharacterMovementComponent.h" +#include "CharacterMovementCompTypes.generated.h" + + +class AVRBaseCharacter; +class UVRBaseCharacterMovementComponent; + +UENUM(Blueprintable) +enum class EVRMoveAction : uint8 +{ + VRMOVEACTION_None = 0x00, + VRMOVEACTION_SnapTurn = 0x01, + VRMOVEACTION_Teleport = 0x02, + VRMOVEACTION_StopAllMovement = 0x03, + VRMOVEACTION_SetRotation = 0x04, + VRMOVEACTION_PauseTracking = 0x14, + VRMOVEACTION_SetGravityDirection = 0x15, // Reserved from here up to 0x40 + VRMOVEACTION_CUSTOM1 = 0x05, + VRMOVEACTION_CUSTOM2 = 0x06, + VRMOVEACTION_CUSTOM3 = 0x07, + VRMOVEACTION_CUSTOM4 = 0x08, + VRMOVEACTION_CUSTOM5 = 0x09, + VRMOVEACTION_CUSTOM6 = 0x0A, + VRMOVEACTION_CUSTOM7 = 0x0B, + VRMOVEACTION_CUSTOM8 = 0x0C, + VRMOVEACTION_CUSTOM9 = 0x0D, + VRMOVEACTION_CUSTOM10 = 0x0E, + VRMOVEACTION_CUSTOM11 = 0x0F, + VRMOVEACTION_CUSTOM12 = 0x10, + VRMOVEACTION_CUSTOM13 = 0x11, + VRMOVEACTION_CUSTOM14 = 0x12, + VRMOVEACTION_CUSTOM15 = 0x13, + // Up to 0x20 currently allowed for +}; + +// What to do with the players velocity when specific move actions are called +// Default of none leaves it as is, for people with 0 ramp up time on acelleration +// This likely won't be that useful. +UENUM(Blueprintable) +enum class EVRMoveActionVelocityRetention : uint8 +{ + // Leaves velocity as is + VRMOVEACTION_Velocity_None = 0x00, + + // Clears velocity entirely + VRMOVEACTION_Velocity_Clear = 0x01, + + // Rotates the velocity to match new heading + VRMOVEACTION_Velocity_Turn = 0x02 +}; + +UENUM(Blueprintable) +enum class EVRMoveActionDataReq : uint8 +{ + VRMOVEACTIONDATA_None = 0x00, + VRMOVEACTIONDATA_LOC = 0x01, + VRMOVEACTIONDATA_ROT = 0x02, + VRMOVEACTIONDATA_LOC_AND_ROT = 0x03 +}; + + + +USTRUCT() +struct VREXPANSIONPLUGIN_API FVRMoveActionContainer +{ + GENERATED_USTRUCT_BODY() +public: + UPROPERTY() + EVRMoveAction MoveAction; + UPROPERTY() + EVRMoveActionDataReq MoveActionDataReq; + UPROPERTY() + FVector MoveActionLoc; + UPROPERTY() + FVector MoveActionVel; + UPROPERTY() + FRotator MoveActionRot; + UPROPERTY() + float MoveActionDeltaYaw; + UPROPERTY() + uint8 MoveActionFlags; + UPROPERTY() + TArray MoveActionObjectReferences; + UPROPERTY() + EVRMoveActionVelocityRetention VelRetentionSetting; + + FVRMoveActionContainer() + { + Clear(); + } + + void Clear() + { + MoveAction = EVRMoveAction::VRMOVEACTION_None; + MoveActionDataReq = EVRMoveActionDataReq::VRMOVEACTIONDATA_None; + MoveActionLoc = FVector::ZeroVector; + MoveActionVel = FVector::ZeroVector; + MoveActionRot = FRotator::ZeroRotator; + MoveActionDeltaYaw = 0.0f; + MoveActionFlags = 0; + VelRetentionSetting = EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_None; + MoveActionObjectReferences.Empty(); + } + + /** Network serialization */ + // Doing a custom NetSerialize here because this is sent via RPCs and should change on every update + bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) + { + bOutSuccess = true; + + Ar.SerializeBits(&MoveAction, 6); // 64 elements, only allowing 1 per frame, they aren't flags + + switch (MoveAction) + { + case EVRMoveAction::VRMOVEACTION_None: break; + case EVRMoveAction::VRMOVEACTION_SetRotation: + case EVRMoveAction::VRMOVEACTION_SnapTurn: + { + uint16 Yaw = 0; + uint16 Pitch = 0; + + if (Ar.IsSaving()) + { + bool bUseLocOnly = MoveActionFlags & 0x04; + Ar.SerializeBits(&bUseLocOnly, 1); + + if (!bUseLocOnly) + { + //Yaw = FRotator::CompressAxisToShort(MoveActionRot.Yaw); + //Ar << Yaw; + Ar << MoveActionRot; + } + else + { + Ar << MoveActionLoc; + } + + bool bTeleportGrips = MoveActionFlags & 0x01;// MoveActionRot.Roll > 0.0f && MoveActionRot.Roll < 1.5f; + Ar.SerializeBits(&bTeleportGrips, 1); + + if (!bTeleportGrips) + { + bool bTeleportCharacter = MoveActionFlags & 0x02;// MoveActionRot.Roll > 1.5f; + Ar.SerializeBits(&bTeleportCharacter, 1); + } + + Ar.SerializeBits(&VelRetentionSetting, 2); + + if (VelRetentionSetting == EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_Turn) + { + bOutSuccess &= SerializePackedVector<100, 30>(MoveActionVel, Ar); + } + + // Always send this in case we are sitting + Pitch = FRotator::CompressAxisToShort(MoveActionDeltaYaw); + Ar << Pitch; + + bool bRotateAroundCapsule = MoveActionFlags & 0x08; + Ar.SerializeBits(&bRotateAroundCapsule, 1); + } + else + { + + bool bUseLocOnly = false; + Ar.SerializeBits(&bUseLocOnly, 1); + MoveActionFlags |= (bUseLocOnly << 2); + + if (!bUseLocOnly) + { + //Ar << Yaw; + //MoveActionRot.Yaw = FRotator::DecompressAxisFromShort(Yaw); + Ar << MoveActionRot; + } + else + { + Ar << MoveActionLoc; + } + + bool bTeleportGrips = false; + Ar.SerializeBits(&bTeleportGrips, 1); + MoveActionFlags |= (uint8)bTeleportGrips; //.Roll = bTeleportGrips ? 1.0f : 0.0f; + + if (!bTeleportGrips) + { + bool bTeleportCharacter = false; + Ar.SerializeBits(&bTeleportCharacter, 1); + MoveActionFlags |= ((uint8)bTeleportCharacter << 1); + //MoveActionRot.Roll = 2.0f; + } + + Ar.SerializeBits(&VelRetentionSetting, 2); + + if (VelRetentionSetting == EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_Turn) + { + bOutSuccess &= SerializePackedVector<100, 30>(MoveActionVel, Ar); + } + + Ar << Pitch; + MoveActionDeltaYaw = FRotator::DecompressAxisFromShort(Pitch); + + bool bRotateAroundCapsule = false; + Ar.SerializeBits(&bRotateAroundCapsule, 1); + MoveActionFlags |= (uint8)(bRotateAroundCapsule << 3); + } + + //bOutSuccess &= SerializePackedVector<100, 30>(MoveActionLoc, Ar); + }break; + case EVRMoveAction::VRMOVEACTION_Teleport: // Not replicating rot as Control rot does that already + { + uint16 Yaw = 0; + uint16 Pitch = 0; + + if (Ar.IsSaving()) + { + Yaw = FRotator::CompressAxisToShort(MoveActionRot.Yaw); + Ar << Yaw; + + bool bSkipEncroachment = MoveActionFlags & 0x01;// MoveActionRot.Roll > 0.0f; + Ar.SerializeBits(&bSkipEncroachment, 1); + Ar.SerializeBits(&VelRetentionSetting, 2); + + if (VelRetentionSetting == EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_Turn) + { + bOutSuccess &= SerializePackedVector<100, 30>(MoveActionVel, Ar); + //Pitch = FRotator::CompressAxisToShort(MoveActionRot.Pitch); + //Ar << Pitch; + } + } + else + { + Ar << Yaw; + MoveActionRot.Yaw = FRotator::DecompressAxisFromShort(Yaw); + + bool bSkipEncroachment = false; + Ar.SerializeBits(&bSkipEncroachment, 1); + MoveActionFlags |= (uint8)bSkipEncroachment; + //MoveActionRot.Roll = bSkipEncroachment ? 1.0f : 0.0f; + Ar.SerializeBits(&VelRetentionSetting, 2); + + if (VelRetentionSetting == EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_Turn) + { + bOutSuccess &= SerializePackedVector<100, 30>(MoveActionVel, Ar); + //Ar << Pitch; + //MoveActionRot.Pitch = FRotator::DecompressAxisFromShort(Pitch); + } + } + + bOutSuccess &= SerializePackedVector<100, 30>(MoveActionLoc, Ar); + }break; + case EVRMoveAction::VRMOVEACTION_StopAllMovement: + {}break; + case EVRMoveAction::VRMOVEACTION_SetGravityDirection: + { + bOutSuccess = SerializeFixedVector<1, 16>(MoveActionVel, Ar); + if (Ar.IsSaving()) + { + bool bOrientToGravity = MoveActionFlags > 0; + Ar.SerializeBits(&bOrientToGravity, 1); + } + else + { + bool bOrientToGravity = false; + Ar.SerializeBits(&bOrientToGravity, 1); + MoveActionFlags |= (uint8)bOrientToGravity; + } + + }break; + case EVRMoveAction::VRMOVEACTION_PauseTracking: + { + + Ar.SerializeBits(&MoveActionFlags, 1); + bOutSuccess &= SerializePackedVector<100, 30>(MoveActionLoc, Ar); + + uint16 Yaw = 0; + // Loc and rot for capsule should also be sent here + if (Ar.IsSaving()) + { + Yaw = FRotator::CompressAxisToShort(MoveActionRot.Yaw); + Ar << Yaw; + } + else + { + Ar << Yaw; + MoveActionRot.Yaw = FRotator::DecompressAxisFromShort(Yaw); + } + + }break; + default: // Everything else + { + // Defines how much to replicate - only 4 possible values, 0 - 3 so only send 2 bits + Ar.SerializeBits(&MoveActionDataReq, 2); + + if (((uint8)MoveActionDataReq & (uint8)EVRMoveActionDataReq::VRMOVEACTIONDATA_LOC) != 0) + bOutSuccess &= SerializePackedVector<100, 30>(MoveActionLoc, Ar); + + if (((uint8)MoveActionDataReq & (uint8)EVRMoveActionDataReq::VRMOVEACTIONDATA_ROT) != 0) + MoveActionRot.SerializeCompressedShort(Ar); + + bool bSerializeObjects = MoveActionObjectReferences.Num() > 0; + Ar.SerializeBits(&bSerializeObjects, 1); + if (bSerializeObjects) + { + Ar << MoveActionObjectReferences; + } + + bool bSerializeFlags = MoveActionFlags != 0x00; + Ar.SerializeBits(&bSerializeFlags, 1); + if (bSerializeFlags) + { + Ar << MoveActionFlags; + } + + }break; + } + + return bOutSuccess; + } +}; +template<> +struct TStructOpsTypeTraits< FVRMoveActionContainer > : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithNetSerializer = true + }; +}; + +USTRUCT() +struct VREXPANSIONPLUGIN_API FVRMoveActionArray +{ + GENERATED_USTRUCT_BODY() +public: + UPROPERTY() + TArray MoveActions; + + bool CanCombine() const + { + return !MoveActions.Num(); + /*if (!MoveActions.Num()) + { + return true; + } + + for (const FVRMoveActionContainer& MoveAction : MoveActions) + { + if (MoveAction.MoveAction != EVRMoveAction::VRMOVEACTION_SnapTurn) + return false; + } + + return true;*/ + } + + void Clear() + { + MoveActions.Empty(); + } + + /** Network serialization */ + // Doing a custom NetSerialize here because this is sent via RPCs and should change on every update + bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) + { + bOutSuccess = true; + uint8 MoveActionCount = (uint8)MoveActions.Num(); + bool bHasAMoveAction = MoveActionCount > 0; + Ar.SerializeBits(&bHasAMoveAction, 1); + + if (bHasAMoveAction) + { + bool bHasMoreThanOneMoveAction = MoveActionCount > 1; + Ar.SerializeBits(&bHasMoreThanOneMoveAction, 1); + + if (Ar.IsSaving()) + { + if (bHasMoreThanOneMoveAction) + { + Ar << MoveActionCount; + + for (int i = 0; i < MoveActionCount; i++) + { + bOutSuccess &= MoveActions[i].NetSerialize(Ar, Map, bOutSuccess); + } + } + else + { + bOutSuccess &= MoveActions[0].NetSerialize(Ar, Map, bOutSuccess); + } + } + else + { + if (bHasMoreThanOneMoveAction) + { + Ar << MoveActionCount; + } + else + MoveActionCount = 1; + + for (int i = 0; i < MoveActionCount; i++) + { + FVRMoveActionContainer MoveAction; + bOutSuccess &= MoveAction.NetSerialize(Ar, Map, bOutSuccess); + MoveActions.Add(MoveAction); + } + } + } + + return bOutSuccess; + } +}; +template<> +struct TStructOpsTypeTraits< FVRMoveActionArray > : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithNetSerializer = true + }; +}; + + +USTRUCT() +struct VREXPANSIONPLUGIN_API FVRConditionalMoveRep +{ + GENERATED_USTRUCT_BODY() +public: + + UPROPERTY(Transient) + FVector CustomVRInputVector; + UPROPERTY(Transient) + FVector RequestedVelocity; + UPROPERTY(Transient) + FVRMoveActionArray MoveActionArray; + //FVRMoveActionContainer MoveAction; + + FVRConditionalMoveRep() + { + CustomVRInputVector = FVector::ZeroVector; + RequestedVelocity = FVector::ZeroVector; + } + + /** Network serialization */ + // Doing a custom NetSerialize here because this is sent via RPCs and should change on every update + bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) + { + bOutSuccess = true; + + bool bIsLoading = Ar.IsLoading(); + + bool bHasVRinput = !CustomVRInputVector.IsZero(); + bool bHasRequestedVelocity = !RequestedVelocity.IsZero(); + bool bHasMoveAction = MoveActionArray.MoveActions.Num() > 0;//MoveAction.MoveAction != EVRMoveAction::VRMOVEACTION_None; + + bool bHasAnyProperties = bHasVRinput || bHasRequestedVelocity || bHasMoveAction; + Ar.SerializeBits(&bHasAnyProperties, 1); + + if (bHasAnyProperties) + { + Ar.SerializeBits(&bHasVRinput, 1); + Ar.SerializeBits(&bHasRequestedVelocity, 1); + //Ar.SerializeBits(&bHasMoveAction, 1); + + if (bHasVRinput) + { + bOutSuccess &= SerializePackedVector<100, 22/*30*/>(CustomVRInputVector, Ar); + } + else if (bIsLoading) + { + CustomVRInputVector = FVector::ZeroVector; + } + + if (bHasRequestedVelocity) + { + bOutSuccess &= SerializePackedVector<100, 22/*30*/>(RequestedVelocity, Ar); + } + else if (bIsLoading) + { + RequestedVelocity = FVector::ZeroVector; + } + + //if (bHasMoveAction) + MoveActionArray.NetSerialize(Ar, Map, bOutSuccess); + } + else if (bIsLoading) + { + CustomVRInputVector = FVector::ZeroVector; + RequestedVelocity = FVector::ZeroVector; + MoveActionArray.Clear(); + } + + return bOutSuccess; + } + +}; + +template<> +struct TStructOpsTypeTraits< FVRConditionalMoveRep > : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithNetSerializer = true + }; +}; + +// #TODO: DELETE THIS +USTRUCT() +struct VREXPANSIONPLUGIN_API FVRConditionalMoveRep2 +{ + GENERATED_USTRUCT_BODY() +public: + + // Moved these here to avoid having to duplicate tons of properties + UPROPERTY(Transient) + UPrimitiveComponent* ClientMovementBase; + UPROPERTY(Transient) + FName ClientBaseBoneName; + + UPROPERTY(Transient) + uint16 ClientYaw; + + UPROPERTY(Transient) + uint16 ClientPitch; + + UPROPERTY(Transient) + uint8 ClientRoll; + + FVRConditionalMoveRep2() + { + ClientMovementBase = nullptr; + ClientBaseBoneName = NAME_None; + ClientRoll = 0; + ClientPitch = 0; + ClientYaw = 0; + } + + void UnpackAndSetINTRotations(uint32 Rotation32) + { + // Reversed the order of these so it costs less to replicate + ClientYaw = (Rotation32 & 65535); + ClientPitch = (Rotation32 >> 16); + } + + /** Network serialization */ + // Doing a custom NetSerialize here because this is sent via RPCs and should change on every update + bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) + { + bOutSuccess = true; + + bool bRepRollAndPitch = (ClientRoll != 0 || ClientPitch != 0); + Ar.SerializeBits(&bRepRollAndPitch, 1); + + if (bRepRollAndPitch) + { + // Reversed the order of these + uint32 Rotation32 = (((uint32)ClientPitch) << 16) | ((uint32)ClientYaw); + Ar.SerializeIntPacked(Rotation32); + Ar << ClientRoll; + + if (Ar.IsLoading()) + { + UnpackAndSetINTRotations(Rotation32); + } + } + else + { + uint32 Yaw32 = ClientYaw; + Ar.SerializeIntPacked(Yaw32); + ClientYaw = (uint16)Yaw32; + } + + bool bHasMovementBase = MovementBaseUtility::IsDynamicBase(ClientMovementBase); + Ar.SerializeBits(&bHasMovementBase, 1); + + if (bHasMovementBase) + { + Ar << ClientMovementBase; + + bool bValidName = ClientBaseBoneName != NAME_None; + Ar.SerializeBits(&bValidName, 1); + + // This saves 9 bits on average, we almost never have a valid bone name and default rep goes to 9 bits for hardcoded + // total of 6 bits savings as we use 3 extra for our flags in here. + if (bValidName) + { + Ar << ClientBaseBoneName; + } + } + + return bOutSuccess; + } + +}; + +template<> +struct TStructOpsTypeTraits< FVRConditionalMoveRep2 > : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithNetSerializer = true + }; +}; + +/** +* Helper to change mesh bone updates within a scope. +* Example usage: +* { +* FScopedPreventMeshBoneUpdate ScopedNoMeshBoneUpdate(CharacterOwner->GetMesh(), EKinematicBonesUpdateToPhysics::SkipAllBones); +* // Do something to move mesh, bones will not update +* } +* // Movement of mesh at this point will use previous setting. +*/ +struct FScopedMeshBoneUpdateOverrideVR +{ + FScopedMeshBoneUpdateOverrideVR(USkeletalMeshComponent* Mesh, EKinematicBonesUpdateToPhysics::Type OverrideSetting); + + ~FScopedMeshBoneUpdateOverrideVR(); + +private: + USkeletalMeshComponent* MeshRef; + EKinematicBonesUpdateToPhysics::Type SavedUpdateSetting; +}; + + +class VREXPANSIONPLUGIN_API FSavedMove_VRBaseCharacter : public FSavedMove_Character +{ + +public: + + EVRConjoinedMovementModes VRReplicatedMovementMode; + + FVector VRCapsuleLocation; + FVector LFDiff; + FRotator VRCapsuleRotation; + float CapsuleHeight; + FVRConditionalMoveRep ConditionalValues; + + void Clear(); + virtual void SetInitialPosition(ACharacter* C); + virtual void PrepMoveFor(ACharacter* Character) override; + virtual void CombineWith(const FSavedMove_Character* OldMove, ACharacter* InCharacter, APlayerController* PC, const FVector& OldStartLocation) override; + + /** Set the properties describing the final position, etc. of the moved pawn. */ + virtual void PostUpdate(ACharacter* C, EPostUpdateMode PostUpdateMode) override; + + FSavedMove_VRBaseCharacter(); + + virtual uint8 GetCompressedFlags() const override; + virtual bool CanCombineWith(const FSavedMovePtr& NewMove, ACharacter* Character, float MaxDelta) const override; + virtual bool IsImportantMove(const FSavedMovePtr& LastAckedMove) const override; +}; + +// Using this fixes the problem where the character capsule isn't reset after a scoped movement update revert (pretty much just in StepUp operations) +class VREXPANSIONPLUGIN_API FVRCharacterScopedMovementUpdate : public FScopedMovementUpdate +{ +public: + + FVRCharacterScopedMovementUpdate(USceneComponent* Component, EScopedUpdate::Type ScopeBehavior = EScopedUpdate::DeferredUpdates, bool bRequireOverlapsEventFlagToQueueOverlaps = true); + + FTransform InitialVRTransform; + + /** Revert movement to the initial location of the Component at the start of the scoped update. Also clears pending overlaps and sets bHasMoved to false. */ + void RevertMove(); +}; + + +/** Shared pointer for easy memory management of FSavedMove_Character, for accumulating and replaying network moves. */ +//typedef TSharedPtr FSavedMovePtr; +struct VREXPANSIONPLUGIN_API FVRCharacterNetworkMoveData : public FCharacterNetworkMoveData +{ +public: + + FVector_NetQuantize100 VRCapsuleLocation; + FVector/*_NetQuantize100*/ LFDiff; + float CapsuleHeight; + uint16 VRCapsuleRotation; + EVRConjoinedMovementModes ReplicatedMovementMode; + FVRConditionalMoveRep ConditionalMoveReps; + + FVRCharacterNetworkMoveData(); + + virtual ~FVRCharacterNetworkMoveData(); + virtual void ClientFillNetworkMoveData(const FSavedMove_Character& ClientMove, ENetworkMoveType MoveType) override; + virtual bool Serialize(UCharacterMovementComponent& CharacterMovement, FArchive& Ar, UPackageMap* PackageMap, ENetworkMoveType MoveType) override; +}; + +struct VREXPANSIONPLUGIN_API FVRCharacterNetworkMoveDataContainer : public FCharacterNetworkMoveDataContainer +{ +public: + + /** + * Default constructor. Sets data storage (NewMoveData, PendingMoveData, OldMoveData) to point to default data members. Override those pointers to instead point to custom data if you want to use derived classes. + */ + FVRCharacterNetworkMoveDataContainer() : FCharacterNetworkMoveDataContainer() + { + NewMoveData = &VRBaseDefaultMoveData[0]; + PendingMoveData = &VRBaseDefaultMoveData[1]; + OldMoveData = &VRBaseDefaultMoveData[2]; + } + + virtual ~FVRCharacterNetworkMoveDataContainer() + { + } + + /** + * Passes through calls to ClientFillNetworkMoveData on each FCharacterNetworkMoveData matching the client moves. Note that ClientNewMove will never be null, but others may be. + */ + //virtual void ClientFillNetworkMoveData(const FSavedMove_Character* ClientNewMove, const FSavedMove_Character* ClientPendingMove, const FSavedMove_Character* ClientOldMove); + + /** + * Serialize movement data. Passes Serialize calls to each FCharacterNetworkMoveData as applicable, based on bHasPendingMove and bHasOldMove. + */ + //virtual bool Serialize(UCharacterMovementComponent& CharacterMovement, FArchive& Ar, UPackageMap* PackageMap); + + + +protected: + + + FVRCharacterNetworkMoveData VRBaseDefaultMoveData[3]; + +}; + +struct VREXPANSIONPLUGIN_API FVRCharacterMoveResponseDataContainer : public FCharacterMoveResponseDataContainer +{ +public: + + FVRCharacterMoveResponseDataContainer() : FCharacterMoveResponseDataContainer() + { + } + + virtual ~FVRCharacterMoveResponseDataContainer() + { + } + + /** + * Copy the FClientAdjustment and set a few flags relevant to that data. + */ + virtual void ServerFillResponseData(const UCharacterMovementComponent& CharacterMovement, const FClientAdjustment& PendingAdjustment) override; + + //bool bHasRotation; // By default ClientAdjustment.NewRot is not serialized. Set this to true after base ServerFillResponseData if you want Rotation to be serialized. + +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripMotionControllerComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripMotionControllerComponent.h new file mode 100644 index 0000000..3fec2f2 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripMotionControllerComponent.h @@ -0,0 +1,1581 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +//#include "Engine/Engine.h" +//#include "Engine/EngineBaseTypes.h" +#include "SceneViewExtension.h" +#include "VRBPDatatypes.h" +#include "MotionControllerComponent.h" +#include "VRGripInterface.h" +#include "GripScripts/VRGripScriptBase.h" +#include "GripMotionControllerComponent.generated.h" + +class AVRBaseCharacter; +class AVRCharacter; +struct FXRDeviceId; + +/** +* +*/ + +/** Override replication control variable for inherited properties that are private. Be careful since it removes a compile-time error when the variable doesn't exist */ +// This is a temp macro until epic adds their own equivalent +// #UE5.2 - Epic seems to allow the std override macro to work on private properties now, commented this out in case its needed later +/*#define DOREPLIFETIME_ACTIVE_OVERRIDE_PRIVATE_PROPERTY(c,v,active) \ +{ \ + static FProperty* sp##v = GetReplicatedProperty(StaticClass(), c::StaticClass(),FName(TEXT(#v))); \ + for (int32 i = 0; i < sp##v->ArrayDim; i++) \ + { \ + UE::Net::Private::FNetPropertyConditionManager::SetPropertyActiveOverride(ChangedPropertyTracker, this, (int32)c::ENetFields_Private::v, active); \ + } \ +}*/ + +#define RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(c,v,cond) ResetReplicatedLifetimeProperty(StaticClass(), c::StaticClass(), FName(TEXT(#v)), cond, OutLifetimeProps); + +DECLARE_LOG_CATEGORY_EXTERN(LogVRMotionController, Log, All); +//For UE4 Profiler ~ Stat Group +DECLARE_STATS_GROUP(TEXT("TICKGrip"), STATGROUP_TickGrip, STATCAT_Advanced); + +/** Delegate for notification when the controllers tracking changes. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FVRGripControllerOnTrackingEventSignature, const ETrackingStatus &, NewTrackingStatus); + +/** Delegate for notification when the controller grips a new object. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FVROnControllerGripSignature, const FBPActorGripInformation &, GripInformation); + +/** Delegate for notification when the controller drops a gripped object. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FVROnControllerDropSignature, const FBPActorGripInformation &, GripInformation, bool, bWasSocketed); + +/** Delegate for notification when the controller sockets a gripped object. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams(FVROnControllerSocketSignature, const FBPActorGripInformation&, GripInformation, const USceneComponent*, NewParentComp, FName, OptionalSocketName, FTransform, RelativeTransformToParent, bool, bWeldingBodies); + +/** Delegate for notification when the controller teleports its grips. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE(FVROnControllerTeleportedGripsSignature); + +/** Delegate for notification when an interactive grip goes out of range and isn't set to auto handle it. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FVRGripControllerOnGripOutOfRange, const FBPActorGripInformation &, GripInformation, float, Distance); + +/** Delegate for notification when the controller profile transform changes. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FVRGripControllerOnProfileTransformChanged, const FTransform &, NewRelTransForProcComps, const FTransform &, NewProfileTransform); + +/** Delegate for notification when the controller handled a local auth grip conflict. Only called on the server. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FVROnClientAuthGripConflict, UObject *, Object, EVRClientAuthConflictResolutionMode, ResolutionMethod); + +/** +* Utility class for applying an offset to a hierarchy of components in the renderer thread. +*/ +class VREXPANSIONPLUGIN_API FExpandedLateUpdateManager +{ +public: + FExpandedLateUpdateManager(); + + virtual ~FExpandedLateUpdateManager() {} + + /** Setup state for applying the render thread late update */ + void Setup(const FTransform& ParentToWorld, UGripMotionControllerComponent* Component, bool bSkipLateUpdate); + + /** Apply the late update delta to the cached components */ + void Apply_RenderThread(FSceneInterface* Scene, const FTransform& OldRelativeTransform, const FTransform& NewRelativeTransform); + // #TODO: UE5 is missing this pull + //void Apply_RenderThread(FSceneInterface* Scene, const int32 FrameNumber, const FTransform& OldRelativeTransform, const FTransform& NewRelativeTransform); + + /** Returns true if the LateUpdateSetup data is stale. */ + bool GetSkipLateUpdate_RenderThread() const { return UpdateStates[LateUpdateRenderReadIndex].bSkip; } + +public: + + /** A utility method that calls CacheSceneInfo on ParentComponent and all of its descendants */ + void GatherLateUpdatePrimitives(USceneComponent* ParentComponent); + void ProcessGripArrayLateUpdatePrimitives(UGripMotionControllerComponent* MotionController, TArray & GripArray); + + /** Generates a LateUpdatePrimitiveInfo for the given component if it has a SceneProxy and appends it to the current LateUpdatePrimitives array */ + void CacheSceneInfo(USceneComponent* Component); + + struct FLateUpdateState + { + FLateUpdateState() + : ParentToWorld(FTransform::Identity) + , bSkip(false) + , TrackingNumber(-1) + {} + + /** Parent world transform used to reconstruct new world transforms for late update scene proxies */ + FTransform ParentToWorld; + /** Primitives that need late update before rendering */ + TMap Primitives; + /** Late Update Info Stale, if this is found true do not late update */ + bool bSkip; + /** Frame tracking number - used to flag if the game and render threads get badly out of sync */ + int64 TrackingNumber; + }; + + FLateUpdateState UpdateStates[2]; + int32 LateUpdateGameWriteIndex; + int32 LateUpdateRenderReadIndex; +}; + +/** +* Tick function that does post physics work. This executes in EndPhysics (after physics is done) +**/ +USTRUCT() +struct FGripComponentEndPhysicsTickFunction : public FTickFunction +{ + GENERATED_USTRUCT_BODY() + + UGripMotionControllerComponent* Target; + + /** + * Abstract function to execute the tick. + * @param DeltaTime - frame time to advance, in seconds. + * @param TickType - kind of tick for this frame. + * @param CurrentThread - thread we are executing on, useful to pass along as new tasks are created. + * @param MyCompletionGraphEvent - completion event for this task. Useful for holding the completetion of this task until certain child tasks are complete. + */ + virtual void ExecuteTick(float DeltaTime, enum ELevelTick TickType, ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent) override; + /** Abstract function to describe this tick. Used to print messages about illegal cycles in the dependency graph. */ + virtual FString DiagnosticMessage() override; + /** Function used to describe this tick for active tick reporting. **/ + virtual FName DiagnosticContext(bool bDetailed) override; +}; + +template<> +struct TStructOpsTypeTraits : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithCopy = false + }; +}; + +/** +* An override of the MotionControllerComponent that implements position replication and Gripping with grip replication and controllable late updates per object. +*/ +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = MotionController) +class VREXPANSIONPLUGIN_API UGripMotionControllerComponent : public UMotionControllerComponent//PrimitiveComponent +{ + +public: + + FGripComponentEndPhysicsTickFunction EndPhysicsTickFunction; + friend struct FGripComponentEndPhysicsTickFunction; + + /** Update systems after physics sim is done */ + void EndPhysicsTickComponent(FGripComponentEndPhysicsTickFunction& ThisTickFunction); + void RegisterEndPhysicsTick(bool bRegister); + + // If true then we will sample the post physics scene to get the relative location of this object. + // This lets us reproject that relative position prior to running the grip logic. + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "GripMotionController|Advanced") + bool bProjectNonSimulatingGrips; + + // If true then we will sweep grip teleport operations so that they stop when they will be colliding with something. + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "GripMotionController|Advanced") + bool bSweepGripTeleports = false; + + + // The grip script that defines the default behaviors of grips + // Don't edit this unless you really know what you are doing, leave it empty + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "GripMotionController|Advanced") + TSubclassOf DefaultGripScriptClass; + + // This is the pointer to the default grip script + // It is here to access so if you want to set some variables on your override then you can + // Due to a bug with instanced variables and parent classes you can't directly edit this in subclass in the details panel + UPROPERTY(VisibleDefaultsOnly, Transient, BlueprintReadOnly, Category = "GripMotionController|Advanced") + TObjectPtr DefaultGripScript; + + // This is a pointer to be able to access the display component directly in c++ + //TWeakObjectPtr DisplayComponentReference; + + // Lerping functions and events + void InitializeLerpToHand(FBPActorGripInformation& GripInfo); + void HandleGlobalLerpToHand(FBPActorGripInformation& GripInformation, FTransform& WorldTransform, float DeltaTime); + + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + void CancelGlobalLerpToHand(uint8 GripID); + + //UPROPERTY(BlueprintAssignable, Category = "Grip Events") + // FVROnControllerGripSignature OnLerpToHandBegin; + + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnControllerGripSignature OnLerpToHandFinished; + + + // If true we will scale the tracking of the motion controller by the TrackingScaler value + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|Advanced|Tracking") + bool bScaleTracking; + + // A scale to be applied to the tracked positions of the controller if bScaleTracking is true + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|Advanced|Tracking", meta = (ClampMin = "0.1", UIMin = "0.1", EditCondition = "bScaleTracking")) + FVector TrackingScaler; + + // If true we will use the minimum height value to clamp the Z too + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|Advanced|Tracking") + bool bLimitMinHeight; + + // The minimum height to allow for this controller + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|Advanced|Tracking", meta = (ClampMin = "0.0", UIMin = "0.0", EditCondition = "bLimitMinHeight")) + float MinimumHeight; + + // If true we will use the maximum height value to clamp the Z too + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|Advanced|Tracking") + bool bLimitMaxHeight; + + // The maximum height to allow for this controller + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|Advanced|Tracking", meta = (ClampMin = "0.1", UIMin = "0.1", EditCondition = "bLimitMinHeight")) + float MaximumHeight; + + // If true will subtract the HMD's location from the position, useful for if the actors base is set to the HMD location always (simple character). + //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|Advanced|Tracking") + //bool bOffsetByHMD; + + // If true this controller will attempt to stay within its LeashRange distance from the HMD + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|Advanced|Tracking") + bool bLeashToHMD; + + // How far away from the HMD the controller should stay max (vector distance) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|Advanced|Tracking", meta = (ClampMin = "0.1", UIMin = "0.1", EditCondition = "bLeashToHMD")) + float LeashRange; + + void ApplyTrackingParameters(FVector& OriginalPosition, bool bIsInGameThread, bool bApplyZeroing = true); + bool HasTrackingParameters(); + + // When true any physics constraints will be attached to the grip pivot instead of a new kinematic actor in the scene + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|Advanced") + bool bConstrainToPivot; + + UPROPERTY() + TObjectPtr AttachChar; + void UpdateTracking(float DeltaTime); + virtual void OnAttachmentChanged() override; + + FVector LastLocationForLateUpdate; + FTransform LastRelativePosition; + + // If true will smooth the hand tracking data with a TInterp function + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|Smoothing") + bool bSmoothHandTracking; + + bool bWasSmoothingHand; + + // If true will smooth hand tracking with the Linear and Rotational 1 Euro low pass settings instead + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|Smoothing") + bool bSmoothWithEuroLowPassFunction; + + // The interp speed to use if smoothing is enabled and not using the 1 Euro smoothing + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|Smoothing") + float SmoothingSpeed; + + // Smoothing parameters when using the 1 Euro low pass option + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|Smoothing") + FBPEuroLowPassFilterTrans EuroSmoothingParams; + + FTransform LastSmoothRelativeTransform; + + // Type of velocity calculation to use for the motion controller + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|ComponentVelocity") + EVRVelocityType VelocityCalculationType; + + // If we should sample the velocity in world or local space + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|ComponentVelocity") + bool bSampleVelocityInWorldSpace; + + // If not using velocity mode "default" this is the number of sample to keep + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|ComponentVelocity") + int32 VelocitySamples; + + FBPLowPassPeakFilter PeakFilter; + + virtual FVector GetComponentVelocity() const override; + + // If true will offset the tracked location of the controller by the controller profile that is currently loaded. + // Thows the event OnControllerProfileTransformChanged when it happens so that you can adjust specific components + // Like procedural ones for the offset (procedural meshes are already correctly offset for the controller and + // need rewound. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController") + bool bOffsetByControllerProfile; + + // Stores current transform so we don't have to keep casting + FTransform CurrentControllerProfileTransform; + + // Called when the controller profile changed and we have a new transform (only if bOffsetByControllerProfile is true) + UPROPERTY(BlueprintAssignable, Category = "GripMotionController") + FVRGripControllerOnProfileTransformChanged OnControllerProfileTransformChanged; + + // Called when the controller profile changed and we have a new transform (only if bOffsetByControllerProfile is true) + UPROPERTY(BlueprintAssignable, Category = "GripMotionController") + FVRGripControllerOnGripOutOfRange OnGripOutOfRange; + +private: + + GENERATED_BODY() + +public: + UGripMotionControllerComponent(const FObjectInitializer& ObjectInitializer); + + ~UGripMotionControllerComponent(); + + // TMP until physics velocity bug is fixed #TODO: Remove + void CalculateGripVelocity(FBPActorGripInformation &GripToFill, UPrimitiveComponent* ComponentToSample, float DeltaTime); + + + // Custom version of the component sweep function to remove that aggravating warning epic is throwing about skeletal mesh components. + void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; + virtual void InitializeComponent() override; + virtual void OnUnregister() override; + //virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; + virtual void Deactivate() override; + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + virtual void BeginDestroy() override; + virtual void BeginPlay() override; + + /** Post-physics tick function for this character */ + //UPROPERTY() + // FTickFunction PostPhysicsTickFunction; + +protected: + //~ Begin UActorComponent Interface. + virtual void CreateRenderState_Concurrent(FRegisterComponentContext* Context) override; + virtual void SendRenderTransform_Concurrent() override; + //~ End UActorComponent Interface. + + void OnModularFeatureUnregistered(const FName& Type, class IModularFeature* ModularFeature); + + //IMotionController* GripPolledMotionController_GameThread; + //IMotionController* GripPolledMotionController_RenderThread; + //FCriticalSection GripPolledMotionControllerMutex; + + // Late update control variables (should likely struct these soon) + struct FRenderTrackingParams + { + FTransform GripRenderThreadRelativeTransform = FTransform::Identity; + FVector GripRenderThreadComponentScale = FVector::ZeroVector; + FTransform GripRenderThreadProfileTransform = FTransform::Identity; + FVector GripRenderThreadLastLocationForLateUpdate = FVector::ZeroVector; + + // Smoothing info + bool bRenderSmoothHandTracking = false; + bool bRenderSmoothWithEuroLowPassFunction = false; + float RenderSmoothingSpeed = 0.0f; + FBPEuroLowPassFilterTrans RenderEuroSmoothingParams; + FTransform RenderLastSmoothRelativeTransform = FTransform::Identity; + float RenderLastDeltaTime = 0.0f; + }LateUpdateParams; + + + FDelegateHandle NewControllerProfileEvent_Handle; + UFUNCTION() + void NewControllerProfileLoaded(); + void GetCurrentProfileTransform(bool bBindToNoticationDelegate); + +public: + + // Called when a controller first gets a valid tracked frame + UPROPERTY(BlueprintAssignable, Category = "GripMotionController") + FVRGripControllerOnTrackingEventSignature OnTrackingChanged; + + // Called when a object is gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnControllerGripSignature OnGrippedObject; + + // Called when a object is dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnControllerDropSignature OnDroppedObject; + + // Called when a object is being socketed, prior to OnDrop being called and prior to the actual socketing being performed + // Generally an early entry to detach hands and handle pre-socketing logic + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnControllerSocketSignature OnSocketingObject; + + // Called when a gripped object has been teleported + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnControllerTeleportedGripsSignature OnTeleportedGrips; + + // Called when an object we hold is secondary gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnControllerGripSignature OnSecondaryGripAdded; + + // Called when an object we hold is secondary dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnControllerGripSignature OnSecondaryGripRemoved; + + // Storage for remote players for secondary grips specifically + // Its more than a little hacky, but ordering of drop and the secondaries being + // removed on the rep notify require this in rare cases. If Epic ever fixes the last array state not containing removed + // grips then this would be a lot cleaner. + TArray SecondaryGripIDs; + + + // Called when an object we hold has its grip transform changed + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnControllerGripSignature OnGripTransformChanged; + + // Gets the hand enum + UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true", DisplayName = "HandType", CompactNodeTitle = "HandType")) + void GetHandType(EControllerHand& Hand); + + // The component to use for basing the grip off of instead of the motion controller + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "GripMotionController|CustomPivot") + TObjectPtr CustomPivotComponent; + + // The socket for the component to use for basing the grip off of instead of the motion controller + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "GripMotionController|CustomPivot") + FName CustomPivotComponentSocketName; + + // If true then we will skip the pivot transform adjustment when gripping an object with the custom pivot + // This is here for legacy support for anyone not using "ConvertToControllerRelativeTransform". + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "GripMotionController|CustomPivot") + bool bSkipPivotTransformAdjustment; + + // Set the custom pivot component, allows you to use remote grips easier + UFUNCTION(BlueprintCallable, Category = "GripMotionController|CustomPivot") + void SetCustomPivotComponent(USceneComponent * NewCustomPivotComponent, FName PivotSocketName = NAME_None); + + // Set the custom pivot component, allows you to use remote grips easier + UFUNCTION(BlueprintPure, Category = "GripMotionController", meta = (DisplayName = "GetPivotTransform")) + FTransform GetPivotTransform_BP(); + + // Set the custom pivot component, allows you to use remote grips easier + UFUNCTION(BlueprintPure, Category = "GripMotionController", meta = (DisplayName = "GetPivotLocation")) + FVector GetPivotLocation_BP(); + + FORCEINLINE FTransform GetPivotTransform() + { + return IsValid(CustomPivotComponent) ? CustomPivotComponent->GetSocketTransform(CustomPivotComponentSocketName) : this->GetComponentTransform(); + } + + FORCEINLINE FVector GetPivotLocation() + { + return IsValid(CustomPivotComponent) ? CustomPivotComponent->GetSocketLocation(CustomPivotComponentSocketName) : this->GetComponentLocation(); + } + + // Increments with each grip, wraps back to 0 after max due to modulo operation + // I don't think that a 254 (126 total grips) grip index is going to be used up and allow duplicates unless + // someone does something crazy + uint8 GripIDIncrementer; + + + // INVALID_VRGRIP_ID is 0, so + 1 is 1 + inline uint8 GetNextGripID(bool bIsLocalGrip) + { + // We are skipping index 0 to leave it for INVALID_GRIP_ID index; + + if (!bIsLocalGrip) // We need to split them between 0-126 for gripped objects server side + { + if (GripIDIncrementer < 127) + GripIDIncrementer++; + else + GripIDIncrementer = (INVALID_VRGRIP_ID + 1); + + return GripIDIncrementer; + } + else // And 128 - 254 for local grips client side, with half for server initiated and half for client + { + + if (!IsServer()) + { + if (GripIDIncrementer < 63) + GripIDIncrementer++; + else + GripIDIncrementer = (INVALID_VRGRIP_ID + 1); + + return GripIDIncrementer + 128; + } + else + { + if (GripIDIncrementer < 63) + GripIDIncrementer++; + else + GripIDIncrementer = (INVALID_VRGRIP_ID + 1); + + return GripIDIncrementer + 128 + 64; + } + } + } + + // When possible I suggest that you use GetAllGrips/GetGrippedObjects instead of directly referencing this + UPROPERTY(BlueprintReadOnly, Replicated, Category = "GripMotionController", ReplicatedUsing = OnRep_GrippedObjects) + TArray GrippedObjects; + + // If modifying members in gripped objects directly or a specific grip you need to call this function if you are using Push Networking + void DIRTY_GRIPPED_OBJECTS(); + + // When possible I suggest that you use GetAllGrips/GetGrippedObjects instead of directly referencing this + UPROPERTY(BlueprintReadOnly, Replicated, Category = "GripMotionController", ReplicatedUsing = OnRep_LocallyGrippedObjects) + TArray LocallyGrippedObjects; + + // If modifying members in locally gripped objects directly or a specific grip you need to call this function if you are using Push Networking + void DIRTY_LOCALLY_GRIPPED_OBJECTS(); + + + // Local Grip TransactionalBuffer to store server sided grips that need to be emplaced into the local buffer + UPROPERTY(BlueprintReadOnly, Replicated, Category = "GripMotionController", ReplicatedUsing = OnRep_LocalTransaction) + TArray LocalTransactionBuffer; + + // Locally Gripped Array functions + + // Notify a client that their local grip was bad + UFUNCTION(Reliable, Client, Category = "GripMotionController") + void Client_NotifyInvalidLocalGrip(UObject * LocallyGrippedObject, uint8 GripID, bool bWasAGripConflict = false); + + // Notify the server that we locally gripped something + UFUNCTION(Reliable, Server, WithValidation, Category = "GripMotionController") + void Server_NotifyLocalGripAddedOrChanged(const FBPActorGripInformation & newGrip); + + // Notify the server that we changed some secondary attachment information + UFUNCTION(Reliable, Server, WithValidation) + void Server_NotifySecondaryAttachmentChanged( + uint8 GripID, + const FBPSecondaryGripInfo& SecondaryGripInfo); + + // Notify the server that we changed some secondary attachment information + // This one specifically sends out the new relative location for a retain secondary grip + UFUNCTION(Reliable, Server, WithValidation) + void Server_NotifySecondaryAttachmentChanged_Retain( + uint8 GripID, + const FBPSecondaryGripInfo& SecondaryGripInfo, const FTransform_NetQuantize & NewRelativeTransform); + + // Notify change on relative position editing as well, make RPCS callable in blueprint + // Notify the server that we locally gripped something + UFUNCTION(Reliable, Server, WithValidation) + void Server_NotifyLocalGripRemoved(uint8 GripID, const FTransform_NetQuantize &TransformAtDrop, FVector_NetQuantize100 OptAngularVelocity, FVector_NetQuantize100 OptLinearVelocity); + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController|ClientAuth") + EVRClientAuthConflictResolutionMode ClientAuthConflictResolutionMethod; + + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnClientAuthGripConflict OnClientAuthGripConflict; + + // Handle a server initiated grip + UFUNCTION(Reliable, Server, WithValidation, Category = "GripMotionController") + void Server_NotifyHandledTransaction(uint8 GripID); + + // Enable this to send the TickGrip event every tick even for non custom grip types - has a slight performance hit + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController") + bool bAlwaysSendTickGrip; + + // Clean up a grip that is "bad", object is being destroyed or was a bad destructible mesh + void CleanUpBadGrip(TArray &GrippedObjectsArray, int GripIndex, bool bReplicatedArray); + void CleanUpBadPhysicsHandles(); + + // Recreates a grip physics handle bodies + // If FullRecreate is false then it will only set the COM and actors, otherwise will re-init the entire grip + bool UpdatePhysicsHandle(uint8 GripID, bool bFullyRecreate = true); + bool UpdatePhysicsHandle(const FBPActorGripInformation & GripInfo, bool bFullyRecreate = true); + + inline void NotifyGripTransformChanged(const FBPActorGripInformation & GripInfo) + { + if (OnGripTransformChanged.IsBound()) + { + FBPActorGripInformation CurrentGrip; + EBPVRResultSwitch Result; + GetGripByID(CurrentGrip, GripInfo.GripID, Result); + if (Result == EBPVRResultSwitch::OnSucceeded) + { + OnGripTransformChanged.Broadcast(CurrentGrip); + } + } + } + + // Recreates a grip in situations where the collision type or movement replication type may have been changed + inline void ReCreateGrip(FBPActorGripInformation & GripInfo) + { + int HandleIndex = 0; + if (GetPhysicsGripIndex(GripInfo, HandleIndex)) + { + DestroyPhysicsHandle(GripInfo); + } + + // Grip Type or replication was changed + NotifyGrip(GripInfo, true); + } + + // Handles variable state changes and specific actions on a grip replication + inline bool HandleGripReplication(FBPActorGripInformation & Grip, FBPActorGripInformation * OldGripInfo = nullptr) + { + if (Grip.ValueCache.bWasInitiallyRepped && Grip.GripID != Grip.ValueCache.CachedGripID) + { + // There appears to be a bug with TArray replication where if you replace an index with another value of that + // Index, it doesn't fully re-init the object, this is a workaround to re-zero non replicated variables + // when that happens. + Grip.ClearNonReppingItems(); + } + + // Ignore server down no rep grips, this is kind of unavoidable unless I make yet another list which I don't want to do + if (Grip.GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep) + { + // skip init + Grip.ValueCache.bWasInitiallyRepped = true; + + // null ptr so this doesn't block grip operations + Grip.GrippedObject = nullptr; + + // Set to paused so iteration skips it + Grip.bIsPaused = true; + } + + if (!Grip.ValueCache.bWasInitiallyRepped) // Hasn't already been initialized + { + Grip.ValueCache.bWasInitiallyRepped = NotifyGrip(Grip); // Grip it + + // Tick will keep checking from here on out locally + if (!Grip.ValueCache.bWasInitiallyRepped) + { + //UE_LOG(LogVRMotionController, Warning, TEXT("Replicated grip Notify grip failed, was grip called before the object was replicated to the client?")); + return false; + } + + if(Grip.SecondaryGripInfo.bHasSecondaryAttachment) + { + // Reset the secondary grip distance + Grip.SecondaryGripInfo.SecondaryGripDistance = 0.0f; + + if (FMath::IsNearlyZero(Grip.SecondaryGripInfo.LerpToRate)) // Zero, could use IsNearlyZero instead + Grip.SecondaryGripInfo.GripLerpState = EGripLerpState::NotLerping; + else + { + Grip.SecondaryGripInfo.curLerp = Grip.SecondaryGripInfo.LerpToRate; + Grip.SecondaryGripInfo.GripLerpState = EGripLerpState::StartLerp; + } + + if (Grip.GrippedObject && Grip.GrippedObject->IsValidLowLevelFast() && Grip.GrippedObject->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + SecondaryGripIDs.Add(Grip.GripID); + IVRGripInterface::Execute_OnSecondaryGrip(Grip.GrippedObject, this, Grip.SecondaryGripInfo.SecondaryAttachment, Grip); + + TArray GripScripts; + if (IVRGripInterface::Execute_GetGripScripts(Grip.GrippedObject, GripScripts)) + { + for (UVRGripScriptBase* Script : GripScripts) + { + if (Script) + { + Script->OnSecondaryGrip(this, Grip.SecondaryGripInfo.SecondaryAttachment, Grip); + } + } + } + } + + OnSecondaryGripAdded.Broadcast(Grip); + } + //Grip.ValueCache.bWasInitiallyRepped = true; // Set has been initialized + } + else if(OldGripInfo != nullptr) // Check for changes from cached information if we aren't skipping the delta check + { + // Manage lerp states + if ((OldGripInfo->SecondaryGripInfo.bHasSecondaryAttachment != Grip.SecondaryGripInfo.bHasSecondaryAttachment) || + (OldGripInfo->SecondaryGripInfo.SecondaryAttachment != Grip.SecondaryGripInfo.SecondaryAttachment) || + (!OldGripInfo->SecondaryGripInfo.SecondaryRelativeTransform.Equals(Grip.SecondaryGripInfo.SecondaryRelativeTransform))) + { + // Reset the secondary grip distance + Grip.SecondaryGripInfo.SecondaryGripDistance = 0.0f; + + if (FMath::IsNearlyZero(Grip.SecondaryGripInfo.LerpToRate)) // Zero, could use IsNearlyZero instead + Grip.SecondaryGripInfo.GripLerpState = EGripLerpState::NotLerping; + else + { + // New lerp + if (Grip.SecondaryGripInfo.bHasSecondaryAttachment) + { + Grip.SecondaryGripInfo.curLerp = Grip.SecondaryGripInfo.LerpToRate; + Grip.SecondaryGripInfo.GripLerpState = EGripLerpState::StartLerp; + } + else // Post Lerp + { + Grip.SecondaryGripInfo.curLerp = Grip.SecondaryGripInfo.LerpToRate; + Grip.SecondaryGripInfo.GripLerpState = EGripLerpState::EndLerp; + } + } + + bool bSendReleaseEvent = ((!Grip.SecondaryGripInfo.bHasSecondaryAttachment && OldGripInfo->SecondaryGripInfo.bHasSecondaryAttachment) || + ((Grip.SecondaryGripInfo.bHasSecondaryAttachment && OldGripInfo->SecondaryGripInfo.bHasSecondaryAttachment) && + (OldGripInfo->SecondaryGripInfo.SecondaryAttachment != Grip.SecondaryGripInfo.SecondaryAttachment))); + + bool bSendGripEvent = (Grip.SecondaryGripInfo.bHasSecondaryAttachment && + (!OldGripInfo->SecondaryGripInfo.bHasSecondaryAttachment || (OldGripInfo->SecondaryGripInfo.SecondaryAttachment != Grip.SecondaryGripInfo.SecondaryAttachment))); + + if (bSendReleaseEvent) + { + if (Grip.GrippedObject && Grip.GrippedObject->IsValidLowLevelFast() && Grip.GrippedObject->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + IVRGripInterface::Execute_OnSecondaryGripRelease(Grip.GrippedObject, this, OldGripInfo->SecondaryGripInfo.SecondaryAttachment, Grip); + + TArray GripScripts; + if (IVRGripInterface::Execute_GetGripScripts(Grip.GrippedObject, GripScripts)) + { + for (UVRGripScriptBase* Script : GripScripts) + { + if (Script) + { + Script->OnSecondaryGripRelease(this, OldGripInfo->SecondaryGripInfo.SecondaryAttachment, Grip); + } + } + } + } + + SecondaryGripIDs.Remove(Grip.GripID); + OnSecondaryGripRemoved.Broadcast(Grip); + } + + if (bSendGripEvent) + { + if (Grip.GrippedObject && Grip.GrippedObject->IsValidLowLevelFast() && Grip.GrippedObject->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass())) + { + SecondaryGripIDs.Add(Grip.GripID); + IVRGripInterface::Execute_OnSecondaryGrip(Grip.GrippedObject, this, Grip.SecondaryGripInfo.SecondaryAttachment, Grip); + + TArray GripScripts; + if (IVRGripInterface::Execute_GetGripScripts(Grip.GrippedObject, GripScripts)) + { + for (UVRGripScriptBase* Script : GripScripts) + { + if (Script) + { + Script->OnSecondaryGrip(this, Grip.SecondaryGripInfo.SecondaryAttachment, Grip); + } + } + } + } + + OnSecondaryGripAdded.Broadcast(Grip); + } + } + + if (OldGripInfo->GripCollisionType != Grip.GripCollisionType || + OldGripInfo->GripMovementReplicationSetting != Grip.GripMovementReplicationSetting || + OldGripInfo->GrippedBoneName != Grip.GrippedBoneName || + OldGripInfo->AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings != Grip.AdvancedGripSettings.PhysicsSettings.bUsePhysicsSettings + ) + { + ReCreateGrip(Grip); // Need to re-create grip + } + else // If re-creating the grip anyway we don't need to do the below + { + bool bTransformChanged = !OldGripInfo->RelativeTransform.Equals(Grip.RelativeTransform); + + // If physics settings got changed server side + if (!FMath::IsNearlyEqual(OldGripInfo->Stiffness, Grip.Stiffness) || + !FMath::IsNearlyEqual(OldGripInfo->Damping, Grip.Damping) || + OldGripInfo->AdvancedGripSettings.PhysicsSettings != Grip.AdvancedGripSettings.PhysicsSettings || + bTransformChanged + ) + { + UpdatePhysicsHandle(Grip); + + if (bTransformChanged) + { + NotifyGripTransformChanged(Grip); + } + } + } + } + + // Set caches now for next rep + Grip.ValueCache.CachedGripID = Grip.GripID; + + return true; + } + + // Check the local transaction buffer + void CheckTransactionBuffer(); + + UFUNCTION() + virtual void OnRep_LocalTransaction(TArray OriginalArrayState) // Original array state is useless without full serialize, it just hold last delta + { + CheckTransactionBuffer(); + } + + UFUNCTION() + virtual void OnRep_GrippedObjects(TArray OriginalArrayState) // Original array state is useless without full serialize, it just hold last delta + { + // Need to think about how best to handle the simulating flag here, don't handle for now + // Check for removed gripped actors + // This might actually be better left as an RPC multicast + + for (int i = GrippedObjects.Num() - 1; i >= 0; --i) + { + HandleGripReplication(GrippedObjects[i], OriginalArrayState.FindByKey(GrippedObjects[i].GripID)); + } + } + + UFUNCTION() + virtual void OnRep_LocallyGrippedObjects(TArray OriginalArrayState) + { + for (int i = LocallyGrippedObjects.Num() - 1; i >= 0; --i) + { + HandleGripReplication(LocallyGrippedObjects[i], OriginalArrayState.FindByKey(LocallyGrippedObjects[i].GripID)); + } + } + + UPROPERTY(BlueprintReadWrite, Category = "GripMotionController") + TArray AdditionalLateUpdateComponents; + + // Movement Replication + // Actor needs to be replicated for this to work + + UPROPERTY(EditDefaultsOnly, ReplicatedUsing = OnRep_ReplicatedControllerTransform, Category = "GripMotionController|Networking") + FBPVRComponentPosRep ReplicatedControllerTransform; + + FVector LastUpdatesRelativePosition; + FRotator LastUpdatesRelativeRotation; + + bool bLerpingPosition; + bool bReppedOnce; + + UFUNCTION() + virtual void OnRep_ReplicatedControllerTransform(); + + + // Run the smoothing step + void RunNetworkedSmoothing(float DeltaTime); + +protected: + + // Rate to update the position to the server, 100htz is default (same as replication rate, should also hit every tick). + // On dedicated servers the update rate should be at or lower than the server tick rate for smoothing to work + UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "GripMotionController|Networking", meta = (ClampMin = "0", UIMin = "0")) + float ControllerNetUpdateRate; + +public: + void SetControllerNetUpdateRate(float NewControllerNetUpdateRate); + inline float GetControllerNetUpdateRate() { return ControllerNetUpdateRate; }; + + // Used in Tick() to accumulate before sending updates, didn't want to use a timer in this case, also used for remotes to lerp position + float ControllerNetUpdateCount; + + protected: + // Whether to smooth (lerp) between ticks for the replicated motion, DOES NOTHING if update rate is larger than FPS! + UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "GripMotionController|Networking") + bool bSmoothReplicatedMotion; + + public: + void SetSmoothReplicatedMotion(bool NewSmoothReplicatedMotion); + inline bool GetSmoothReplicatedMotion() { return bSmoothReplicatedMotion; }; + + // If true then we will use exponential smoothing with buffered correction + UPROPERTY(EditAnywhere, Category = "GripMotionController|Networking|Smoothing", meta = (editcondition = "bSmoothReplicatedMotion")) + bool bUseExponentialSmoothing = true; + + // Timestep of smoothing translation + UPROPERTY(EditAnywhere, Category = "GripMotionController|Networking|Smoothing", meta = (editcondition = "bUseExponentialSmoothing")) + float InterpolationSpeed = 25.0f; + + // Max distance to allow smoothing before snapping the remainder + UPROPERTY(EditAnywhere, Category = "GripMotionController|Networking|Smoothing", meta = (editcondition = "bUseExponentialSmoothing")) + float NetworkMaxSmoothUpdateDistance = 50.f; + + // Max distance to allow smoothing before snapping entirely to the new position + UPROPERTY(EditAnywhere, Category = "GripMotionController|Networking|Smoothing", meta = (editcondition = "bUseExponentialSmoothing")) + float NetworkNoSmoothUpdateDistance = 100.f; + + protected: + + // Whether to replicate even if no tracking (FPS or test characters) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "GripMotionController|Networking") + bool bReplicateWithoutTracking; + + public: + void SetReplicateWithoutTracking(bool NewReplicateWithoutTracking); + inline bool GetReplicateWithoutTracking() { return bReplicateWithoutTracking; }; + + // I'm sending it unreliable because it is being resent pretty often + UFUNCTION(Unreliable, Server, WithValidation) + void Server_SendControllerTransform(FBPVRComponentPosRep NewTransform); + + // Pointer to an override to call from the owning character - this saves 7 bits a rep avoiding component IDs on the RPC + typedef void (AVRBaseCharacter::*VRBaseCharTransformRPC_Pointer)(FBPVRComponentPosRep NewTransform); + VRBaseCharTransformRPC_Pointer OverrideSendTransform; + + // Need this as I can't think of another way for an actor component to make sure it isn't on the server + inline bool IsLocallyControlled() const + { + // I like epics new authority check more than mine + const AActor* MyOwner = GetOwner(); + return MyOwner->HasLocalNetOwner(); + //const APawn* MyPawn = Cast(MyOwner); + //return MyPawn ? MyPawn->IsLocallyControlled() : (MyOwner && MyOwner->Role == ENetRole::ROLE_Authority); + } + + // Shorthand for checking if we are in seamless travel + inline bool IsTravelingOrNullWorld() const + { + UWorld* myWorld = GetWorld(); + if (IsValid(myWorld)) + { + return myWorld->IsInSeamlessTravel(); + } + + // We don't have a valid world we are part of, don't do anything. + return true; + } + + // Returns if this is the owning connection for the motion controller + UFUNCTION(BlueprintPure, Category = "GripMotionController", meta = (DisplayName = "IsLocallyControlled")) + bool BP_IsLocallyControlled(); + + // Checks if the controllers own is torn off on the network, used to skip some RPCS + inline bool IsTornOff() const + { + const AActor* MyOwner = GetOwner(); + return MyOwner ? MyOwner->GetTearOff() : false; + } + + + inline bool IsServer() const + { + if (GEngine != nullptr && GWorld != nullptr) + { + return GEngine->GetNetMode(GWorld) < NM_Client; + } + + return false; + } + + // Drops a gripped object and sockets it to the given component at the given relative transform. + // *Note*: If both the parent and the child are simulating it also delays a single tick and then re-applies the relative transform. + // This is to avoid a race condition where we need to wait for the next physics update. + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool DropAndSocketObject(const FTransform_NetQuantize & RelativeTransformToParent, UObject * ObjectToDrop = nullptr, uint8 GripIDToDrop = 0, USceneComponent * SocketingParent = nullptr, FName OptionalSocketName = NAME_None, bool bWeldBodies = true); + + // Drops a grip and sockets it to the given component at the given relative transform. + // *Note*: If both the parent and the child are simulating it also delays a single tick and then re-applies the relative transform. + // This is to avoid a race condition where we need to wait for the next physics update. + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool DropAndSocketGrip(const FBPActorGripInformation &GripToDrop, USceneComponent * SocketingParent, FName OptionalSocketName, const FTransform_NetQuantize & RelativeTransformToParent, bool bWeldBodies = true); + bool DropAndSocketGrip_Implementation(const FBPActorGripInformation& GripToDrop, USceneComponent* SocketingParent, FName OptionalSocketName, const FTransform_NetQuantize& RelativeTransformToParent, bool bWeldBodies = true, bool bSkipServerNotify = false); + + // Notify the server about a new drop and socket + UFUNCTION(Reliable, Server, WithValidation, Category = "GripMotionController") + void Server_NotifyDropAndSocketGrip(uint8 GripID, USceneComponent * SocketingParent, FName OptionalSocketName, const FTransform_NetQuantize & RelativeTransformToParent, bool bWeldBodies = true); + + UFUNCTION(Reliable, NetMulticast) + void NotifyDropAndSocket(const FBPActorGripInformation &NewDrop, USceneComponent* SocketingParent, FName OptionalSocketName, const FTransform_NetQuantize& RelativeTransformToParent, bool bWeldBodies = true); + + void DropAndSocket_Implementation(const FBPActorGripInformation &NewDrop); + void Socket_Implementation(UObject * ObjectToSocket, bool bWasSimulating, USceneComponent * SocketingParent, FName OptionalSocketName, const FTransform_NetQuantize & RelativeTransformToParent, bool bWeldBodies = true); + + // Keep a hard reference to the drop to avoid deletion errors + UPROPERTY() + TArray> ObjectsWaitingForSocketUpdate; + + // Resets the transform of a socketed grip 1 tick later, this is to avoid a race condition with simulating grips. + // Their constraint can change the transform before or after the attachment happens if the parent and the child are both simulating. + UFUNCTION() + void SetSocketTransform(UObject* ObjectToSocket, /*USceneComponent * SocketingParent,*/ const FTransform_NetQuantize RelativeTransformToParent/*, FName OptionalSocketName, bool bWeldBodies*/); + + /* Auto grip any uobject that is/root is a primitive component and has the VR Grip Interface + these are stored in a Tarray that will prevent destruction of the object, you MUST ungrip an actor if you want to kill it + The WorldOffset is the transform that it will remain away from the controller, if you use the world position of the actor then it will grab + at the point of intersection. + + If WorldOffsetIsRelative is true then it will not convert the transform from world space but will instead use that offset directly. + You could pass in a socket relative transform with this set for snapping or an empty transform to snap the object at its 0,0,0 point. + + If you declare a valid OptionSnapToSocketName then it will instead snap the actor to the relative offset + location that the socket is to its parent actor. + + It will only do this if the WorldOffset value is left default, if it is not, then it will treat this as the name of the slot + that you already have the transform for. + + If you declare a valid OptionalBoneToGripName then it will grip that physics body with physics grips (It will expect a bone worldspace transform then, + if you pass in the normal actor/root component world space transform then the grip will not be positioned correctly). + */ + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool GripObject( + UObject * ObjectToGrip, + const FTransform &WorldOffset, + bool bWorldOffsetIsRelative = false, + FName OptionalSnapToSocketName = NAME_None, + FName OptionalBoneToGripName = NAME_None, + EGripCollisionType GripCollisionType = EGripCollisionType::InteractiveCollisionWithPhysics, + EGripLateUpdateSettings GripLateUpdateSetting = EGripLateUpdateSettings::NotWhenCollidingOrDoubleGripping, + EGripMovementReplicationSettings GripMovementReplicationSetting = EGripMovementReplicationSettings::ForceClientSideMovement, + float GripStiffness = 2250.0f, + float GripDamping = 140.0f, bool bIsSlotGrip = false); + + + // Auto drop any uobject that is/root is a primitive component and has the VR Grip Interface + // If an object is passed in it will attempt to drop it, otherwise it will attempt to find and drop the given grip id + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool DropObject( + UObject* ObjectToDrop = nullptr, + uint8 GripIdToDrop = 0, + bool bSimulate = false, + FVector OptionalAngularVelocity = FVector::ZeroVector, + FVector OptionalLinearVelocity = FVector::ZeroVector); + + // Auto grip any uobject that is/root is a primitive component + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool GripObjectByInterface(UObject* ObjectToGrip, const FTransform &WorldOffset, bool bWorldOffsetIsRelative = false, FName OptionalBoneToGripName = NAME_None, FName OptionalSnapToSocketName = NAME_None, bool bIsSlotGrip = false); + + // Auto drop any uobject that is/root is a primitive component and has the VR Grip Interface + // If an object is passed in it will attempt to drop it, otherwise it will attempt to find and drop the given grip id + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool DropObjectByInterface(UObject* ObjectToDrop = nullptr, uint8 GripIDToDrop = 0, FVector OptionalAngularVelocity = FVector::ZeroVector, FVector OptionalLinearVelocity = FVector::ZeroVector); + + bool DropObjectByInterface_Implementation(UObject* ObjectToDrop = nullptr, uint8 GripIDToDrop = 0, FVector OptionalAngularVelocity = FVector::ZeroVector, FVector OptionalLinearVelocity = FVector::ZeroVector, bool bSkipNotify = false); + + /* Grip an actor, these are stored in a Tarray that will prevent destruction of the object, you MUST ungrip an actor if you want to kill it + The WorldOffset is the transform that it will remain away from the controller, if you use the world position of the actor then it will grab + at the point of intersection. + + If WorldOffsetIsRelative is true then it will not convert the transform from world space but will instead use that offset directly. + You could pass in a socket relative transform with this set for snapping or an empty transform to snap the object at its 0,0,0 point. + + If you declare a valid OptionSnapToSocketName then it will instead snap the actor to the relative offset + location that the socket is to its parent actor. + + It will only do this if the WorldOffset value is left default, if it is not, then it will treat this as the name of the slot + that you already have the transform for. + + If you declare a valid OptionalBoneToGripName then it will grip that physics body with physics grips (It will expect a bone worldspace transform then, + if you pass in the normal actor/root component world space transform then the grip will not be positioned correctly). + */ + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool GripActor( + AActor* ActorToGrip, + const FTransform &WorldOffset, + bool bWorldOffsetIsRelative = false, + FName OptionalSnapToSocketName = NAME_None, + FName OptionalBoneToGripName = NAME_None, + EGripCollisionType GripCollisionType = EGripCollisionType::InteractiveCollisionWithPhysics, + EGripLateUpdateSettings GripLateUpdateSetting = EGripLateUpdateSettings::NotWhenCollidingOrDoubleGripping, + EGripMovementReplicationSettings GripMovementReplicationSetting = EGripMovementReplicationSettings::ForceClientSideMovement, + float GripStiffness = 1500.0f, + float GripDamping = 200.0f, + bool bIsSlotGrip = false); + + // Drop a gripped actor + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool DropActor( + AActor* ActorToDrop, + bool bSimulate, + FVector OptionalAngularVelocity = FVector::ZeroVector, + FVector OptionalLinearVelocity = FVector::ZeroVector + ); + + // Grip a component + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool GripComponent( + UPrimitiveComponent* ComponentToGrip, + const FTransform &WorldOffset, bool bWorldOffsetIsRelative = false, + FName OptionalsnapToSocketName = NAME_None, + FName OptionalBoneToGripName = NAME_None, + EGripCollisionType GripCollisionType = EGripCollisionType::InteractiveCollisionWithPhysics, + EGripLateUpdateSettings GripLateUpdateSetting = EGripLateUpdateSettings::NotWhenCollidingOrDoubleGripping, + EGripMovementReplicationSettings GripMovementReplicationSetting = EGripMovementReplicationSettings::ForceClientSideMovement, + float GripStiffness = 1500.0f, + float GripDamping = 200.0f, + bool bIsSlotGrip = false); + + // Drop a gripped component + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool DropComponent( + UPrimitiveComponent* ComponentToDrop, + bool bSimulate, + FVector OptionalAngularVelocity = FVector::ZeroVector, + FVector OptionalLinearVelocity = FVector::ZeroVector + ); + + // Master function for dropping a grip + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool DropGrip( + const FBPActorGripInformation &Grip, + bool bSimulate = false, + FVector OptionalAngularVelocity = FVector::ZeroVector, + FVector OptionalLinearVelocity = FVector::ZeroVector); + + bool DropGrip_Implementation( + const FBPActorGripInformation& Grip, + bool bSimulate = false, + FVector OptionalAngularVelocity = FVector::ZeroVector, + FVector OptionalLinearVelocity = FVector::ZeroVector, + bool bSkipNotify = false); + + // No Longer replicated, called via on rep now instead. + //UFUNCTION(Reliable, NetMulticast) + bool NotifyGrip(FBPActorGripInformation &NewGrip, bool bIsReInit = false); + + UFUNCTION(Reliable, NetMulticast) + void NotifyDrop(const FBPActorGripInformation &NewDrop, bool bSimulate); + + // Used so drop logic can be filtered + void Drop_Implementation(const FBPActorGripInformation &NewDrop, bool bSimulate); + + // Get a grip by actor + UFUNCTION(BlueprintCallable, Category = "GripMotionController", meta = (ExpandEnumAsExecs = "Result")) + void GetGripByActor(FBPActorGripInformation &Grip, AActor * ActorToLookForGrip, EBPVRResultSwitch &Result); + + // Get a grip by component + UFUNCTION(BlueprintCallable, Category = "GripMotionController", meta = (ExpandEnumAsExecs = "Result")) + void GetGripByComponent(FBPActorGripInformation &Grip, UPrimitiveComponent * ComponentToLookForGrip, EBPVRResultSwitch &Result); + + // Gets a grip by object, will auto use ByComponent or ByActor + UFUNCTION(BlueprintCallable, Category = "GripMotionController", meta = (ExpandEnumAsExecs = "Result")) + void GetGripByObject(FBPActorGripInformation &Grip, UObject * ObjectToLookForGrip, EBPVRResultSwitch &Result); + + // Gets a grip by its grip ID *NOTE*: Grip IDs are only unique to their controller, do NOT use them as cross controller identifiers + UFUNCTION(BlueprintCallable, Category = "GripMotionController", meta = (ExpandEnumAsExecs = "Result")) + void GetGripByID(FBPActorGripInformation &Grip, uint8 IDToLookForGrip, EBPVRResultSwitch &Result); + + // Gets a grip by its grip ID *NOTE*: Grip IDs are only unique to their controller, do NOT use them as cross controller identifiers + FBPActorGripInformation * GetGripPtrByID(uint8 IDToLookForGrip); + + // Get the physics velocities of a grip + UFUNCTION(BlueprintPure, Category = "GripMotionController") + void GetPhysicsVelocities(const FBPActorGripInformation &Grip, FVector &CurAngularVelocity, FVector &CurLinearVelocity); + + // Get the physics constraint force of a simulating grip + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool GetPhysicsConstraintForce(const FBPActorGripInformation& Grip, FVector& AngularForce, FVector& LinearForce); + + // Get the root components mass of a grip + UFUNCTION(BlueprintPure, Category = "GripMotionController") + static void GetGripMass(const FBPActorGripInformation& Grip, float& Mass); + + /* Returns the world transform of a gripped object from the grip structure */ + UFUNCTION(BlueprintPure, Category = "GripMotionController") + static FTransform GetGrippedObjectTransform(const FBPActorGripInformation& Grip); + + // Sets whether an active grip is paused or not (is not replicated by default as it is likely you will want to pass variables with this setting). + // If you want it server authed you should RPC a bool down with any additional information (ie: attach location). + UFUNCTION(BlueprintCallable, Category = "GripMotionController", meta = (ExpandEnumAsExecs = "Result")) + void SetGripPaused( + const FBPActorGripInformation &Grip, + EBPVRResultSwitch &Result, + bool bIsPaused = false, + bool bNoConstraintWhenPaused = false + ); + + // Sets whether an active hybrid grip is locked to its soft setting (is not replicated by default as it is likely you will want to pass variables with this setting). + UFUNCTION(BlueprintCallable, Category = "GripMotionController", meta = (ExpandEnumAsExecs = "Result")) + void SetGripHybridLock( + const FBPActorGripInformation& Grip, + EBPVRResultSwitch& Result, + bool bIsLocked = false + ); + + // Sets the transform to stay at during pause + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + void SetPausedTransform( + const FBPActorGripInformation &Grip, + const FTransform & PausedTransform, + bool bTeleport = false + ); + + // Set the Grip Collision Type of a grip, call server side if not a local grip + UFUNCTION(BlueprintCallable, Category = "GripMotionController", meta = (ExpandEnumAsExecs = "Result")) + void SetGripCollisionType( + const FBPActorGripInformation &Grip, + EBPVRResultSwitch &Result, + EGripCollisionType NewGripCollisionType = EGripCollisionType::InteractiveCollisionWithPhysics + ); + + + // Set the late update setting of a grip, call server side if not a local grip + UFUNCTION(BlueprintCallable, Category = "GripMotionController", meta = (ExpandEnumAsExecs = "Result")) + void SetGripLateUpdateSetting( + const FBPActorGripInformation &Grip, + EBPVRResultSwitch &Result, + EGripLateUpdateSettings NewGripLateUpdateSetting = EGripLateUpdateSettings::NotWhenCollidingOrDoubleGripping + ); + + // Set the relative transform of a grip, call server side if not a local grip + // Can check HasGripAuthority to decide if callable locally + UFUNCTION(BlueprintCallable, Category = "GripMotionController", meta = (ExpandEnumAsExecs = "Result")) + void SetGripRelativeTransform( + const FBPActorGripInformation &Grip, + EBPVRResultSwitch &Result, + const FTransform & NewRelativeTransform + ); + + // Set the addition transform of a grip, CALL LOCALLY, not server side, Addition transform is not replicated + UFUNCTION(BlueprintCallable, Category = "GripMotionController", meta = (ExpandEnumAsExecs = "Result")) + void SetGripAdditionTransform( + const FBPActorGripInformation &Grip, + EBPVRResultSwitch &Result, + const FTransform & NewAdditionTransform, bool bMakeGripRelative = false + ); + + // Set the constraint stiffness and dampening of a grip, call server side if not a local grip + // Can check HasGripAuthority to decide if callable locally + UFUNCTION(BlueprintCallable, Category = "GripMotionController", meta = (ExpandEnumAsExecs = "Result")) + void SetGripStiffnessAndDamping( + const FBPActorGripInformation &Grip, + EBPVRResultSwitch &Result, + float NewStiffness, float NewDamping, bool bAlsoSetAngularValues = false, float OptionalAngularStiffness = 0.0f, float OptionalAngularDamping = 0.0f + ); + + // Used to convert an offset transform to grip relative, useful for storing an initial offset and then lerping back to 0 without re-calculating every tick + UFUNCTION(BlueprintPure, Category = "GripMotionController", meta = (DisplayName = "CreateGripRelativeAdditionTransform")) + FTransform CreateGripRelativeAdditionTransform_BP( + const FBPActorGripInformation &GripToSample, + const FTransform & AdditionTransform, + bool bGripRelative = false + ); + + inline FTransform CreateGripRelativeAdditionTransform( + const FBPActorGripInformation &GripToSample, + const FTransform & AdditionTransform, + bool bGripRelative = false + ); + + + // Checks if we have grip authority + inline bool HasGripAuthority(const FBPActorGripInformation &Grip); + + // Checks if we have grip authority over a given object + inline bool HasGripAuthority(const UObject * ObjToCheck); + + // Returns if we have grip authority (can call drop / grip on this grip) + // Mostly for networked games as local grips are client authed and all others are server authed + UFUNCTION(BlueprintPure, Category = "GripMotionController", meta = (DisplayName = "HasGripAuthority")) + bool BP_HasGripAuthority(const FBPActorGripInformation & Grip); + + // Returns if we have grip authority (can call drop / grip on this grip) + // Mostly for networked games as local grips are client authed and all others are server authed + UFUNCTION(BlueprintPure, Category = "GripMotionController", meta = (DisplayName = "HasGripAuthorityForObject")) + bool BP_HasGripAuthorityForObject(const UObject* ObjToCheck); + + // Checks if we should be handling the movement of a grip based on settings for it + inline bool HasGripMovementAuthority(const FBPActorGripInformation & Grip); + + // Returns if we have grip movement authority (we handle movement of the grip) + // Mostly for networked games where ClientSide will be true for all and ServerSide will be true for server only + UFUNCTION(BlueprintPure, Category = "GripMotionController", meta = (DisplayName = "HasGripMovementAuthority")) + bool BP_HasGripMovementAuthority(const FBPActorGripInformation & Grip); + + // Running the gripping logic in its own function as the main tick was getting bloated + void TickGrip(float DeltaTime); + + // Splitting logic into separate function + void HandleGripArray(TArray &GrippedObjectsArray, const FTransform & ParentTransform, float DeltaTime, bool bReplicatedArray = false); + + // Gets the world transform of a grip, modified by secondary grips, returns if it has a valid transform, if not then this tick will be skipped for the object + bool GetGripWorldTransform(TArray& GripScripts, float DeltaTime,FTransform & WorldTransform, const FTransform &ParentTransform, FBPActorGripInformation &Grip, AActor * actor, UPrimitiveComponent * root, bool bRootHasInterface, bool bActorHasInterface, bool bIsForTeleport, bool &bForceADrop); + + // Calculate component to world without the protected tag, doesn't set it, just returns it + inline FTransform CalcControllerComponentToWorld(FRotator Orientation, FVector Position) + { + return this->CalcNewComponentToWorld(FTransform(Orientation, Position)); + } + + // Converts a worldspace transform into being relative to this motion controller + UFUNCTION(BlueprintPure, Category = "GripMotionController") + FTransform ConvertToControllerRelativeTransform(const FTransform & InTransform); + + // Creates a secondary grip relative transform + UFUNCTION(BlueprintPure, Category = "GripMotionController") + static FTransform ConvertToGripRelativeTransform(const FTransform& GrippedActorTransform, const FTransform & InTransform); + + // Gets if the given object is held by this controller + UFUNCTION(BlueprintPure, Category = "GripMotionController") + bool GetIsObjectHeld(const UObject * ObjectToCheck); + + // Gets if the given actor is held by this controller + UFUNCTION(BlueprintPure, Category = "GripMotionController") + bool GetIsHeld(const AActor * ActorToCheck); + + // Gets if the given component is held by this controller + UFUNCTION(BlueprintPure, Category = "GripMotionController") + bool GetIsComponentHeld(const UPrimitiveComponent * ComponentToCheck); + + // Gets if the given Component is a secondary attach point to a gripped actor + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool GetIsSecondaryAttachment(const USceneComponent * ComponentToCheck, FBPActorGripInformation & Grip); + + // Get if we have gripped objects, local or replicated + UFUNCTION(BlueprintPure, Category = "GripMotionController") + bool HasGrippedObjects(); + + // Get the first active and valid grip (local and remote auth both, priority remote) + // Returns false is there is none + UFUNCTION(BlueprintCallable, meta = (Keywords = "Grip", DisplayName = "GetFirstActiveGrip", ScriptName = "GetFirstActiveGrip"), Category = "GripMotionController") + bool K2_GetFirstActiveGrip(FBPActorGripInformation& FirstActiveGrip); + + // Get the first active and valid grip (local and remote auth both, priority remote) + // Returns nullptr if there is none + FBPActorGripInformation* GetFirstActiveGrip(); + + // Get list of all gripped objects grip info structures (local and normal both) + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + void GetAllGrips(TArray &GripArray); + + // Get list of all gripped actors + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + void GetGrippedActors(TArray &GrippedActorArray); + + // Get list of all gripped objects + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + void GetGrippedObjects(TArray &GrippedObjectsArray); + + // Get list of all gripped components + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + void GetGrippedComponents(TArray &GrippedComponentsArray); + + // After teleporting a pawn you NEED to call this, otherwise gripped objects will travel with a sweeped move and can get caught on geometry + // The base Teleport() function automatically calls this already, but when you manually set location you should do it yourself. + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + void PostTeleportMoveGrippedObjects(); + + bool bIsPostTeleport; + + // Move a single gripped item back into position ignoring collision in the way + // bTeleportPhysicsGrips says whether we should teleport any physics grips as well + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool TeleportMoveGrippedActor(AActor * GrippedActorToMove, bool bTeleportPhysicsGrips = true); + + // Move a single gripped item back into position ignoring collision in the way + // bTeleportPhysicsGrips says whether we should teleport any physics grips as well + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool TeleportMoveGrippedComponent(UPrimitiveComponent * ComponentToMove, bool bTeleportPhysicsGrips = true); + + // Move a single grip back into position ignoring collision in the way + // bTeleportPhysicsGrips says whether we should teleport any physics grips as well + // bIsForPostTeleport says whether we shuld allow the DropOnTeleport logic to apply or not + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool TeleportMoveGrip(UPARAM(ref)FBPActorGripInformation &Grip, bool bTeleportPhysicsGrips = true, bool bIsForPostTeleport = false); + bool TeleportMoveGrip_Impl(FBPActorGripInformation &Grip, bool bTeleportPhysicsGrips, bool bIsForPostTeleport, FTransform & OptionalTransform); + + // Moves all grips back into position immediately + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + void TeleportMoveGrips(bool bTeleportPhysicsGrips = true, bool bIsForPostTeleport = false); + + // Adds a secondary attachment point to the grip + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool AddSecondaryAttachmentPoint(UObject * GrippedObjectToAddAttachment, USceneComponent * SecondaryPointComponent, const FTransform &OriginalTransform, bool bTransformIsAlreadyRelative = false, float LerpToTime = 0.25f, bool bIsSlotGrip = false, FName SecondarySlotName = NAME_None); + + // Adds a secondary attachment point to the grip + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool AddSecondaryAttachmentToGrip(const FBPActorGripInformation & GripToAddAttachment, USceneComponent * SecondaryPointComponent, const FTransform &OriginalTransform, bool bTransformIsAlreadyRelative = false, float LerpToTime = 0.25f, bool bIsSlotGrip = false, FName SecondarySlotName = NAME_None); + + // Adds a secondary attachment point to the grip + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool AddSecondaryAttachmentToGripByID(const uint8 GripID, USceneComponent* SecondaryPointComponent, const FTransform& OriginalTransform, bool bTransformIsAlreadyRelative = false, float LerpToTime = 0.25f, bool bIsSlotGrip = false, FName SecondarySlotName = NAME_None); + + // Removes a secondary attachment point from a grip + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool RemoveSecondaryAttachmentPoint(UObject * GrippedObjectToRemoveAttachment, float LerpToTime = 0.25f); + + // Removes a secondary attachment point from a grip + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool RemoveSecondaryAttachmentFromGrip(const FBPActorGripInformation & GripToRemoveAttachment, float LerpToTime = 0.25f); + + // Removes a secondary attachment point from a grip + UFUNCTION(BlueprintCallable, Category = "GripMotionController") + bool RemoveSecondaryAttachmentFromGripByID(const uint8 GripID = 0, float LerpToTime = 0.25f); + + // If this is true the controller will always attempt to get the current tracking information, regardless of it TrackingStatus is Untracked or not + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController") + bool bIgnoreTrackingStatus; + + // This is for testing, setting it to true allows you to test grip with a non VR enabled pawn + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripMotionController") + bool bUseWithoutTracking; + + bool CheckComponentWithSweep(UPrimitiveComponent * ComponentToCheck, FVector Move, FRotator newOrientation, bool bSkipSimulatingComponents/*, bool & bHadBlockingHitOut*/); + + // For physics handle operations + void OnGripMassUpdated(FBodyInstance* GripBodyInstance); + bool SetUpPhysicsHandle(const FBPActorGripInformation &NewGrip, TArray * GripScripts = nullptr); + bool DestroyPhysicsHandle(const FBPActorGripInformation &Grip, bool bSkipUnregistering = false); + void UpdatePhysicsHandleTransform(const FBPActorGripInformation &GrippedActor, const FTransform& NewTransform); + bool SetGripConstraintStiffnessAndDamping(const FBPActorGripInformation *Grip, bool bUseHybridMultiplier = false); + bool GetPhysicsJointLength(const FBPActorGripInformation &GrippedActor, UPrimitiveComponent * rootComp, FVector & LocOut); + + TArray PhysicsGrips; + FBPActorPhysicsHandleInformation * GetPhysicsGrip(const FBPActorGripInformation & GripInfo); + FBPActorPhysicsHandleInformation * GetPhysicsGrip(const uint8 GripID); + bool GetPhysicsGripIndex(const FBPActorGripInformation & GripInfo, int & index); + FBPActorPhysicsHandleInformation * CreatePhysicsGrip(const FBPActorGripInformation & GripInfo); + bool DestroyPhysicsHandle(FBPActorPhysicsHandleInformation * HandleInfo); + bool PausePhysicsHandle(FBPActorPhysicsHandleInformation* HandleInfo); + bool UnPausePhysicsHandle(FBPActorGripInformation& GripInfo, FBPActorPhysicsHandleInformation* HandleInfo); + + // Gets the advanced physics handle settings + UFUNCTION(BlueprintCallable, Category = "GripMotionController|Custom", meta = (DisplayName = "GetPhysicsHandleSettings")) + bool GetPhysicsHandleSettings(UPARAM(ref)const FBPActorGripInformation & Grip, FBPAdvancedPhysicsHandleSettings& PhysicsHandleSettingsOut); + + // Sets the advanced physics handle settings, also automatically updates it + UFUNCTION(BlueprintCallable, Category = "GripMotionController|Custom", meta = (DisplayName = "SetPhysicsHandleSettings")) + bool SetPhysicsHandleSettings(UPARAM(ref)const FBPActorGripInformation& Grip, UPARAM(ref) const FBPAdvancedPhysicsHandleSettings& PhysicsHandleSettingsIn); + + // Creates a physics handle for this grip + UFUNCTION(BlueprintCallable, Category = "GripMotionController|Custom", meta = (DisplayName = "SetUpPhysicsHandle")) + bool SetUpPhysicsHandle_BP(UPARAM(ref)const FBPActorGripInformation &Grip); + + // Destroys a physics handle for this grip + UFUNCTION(BlueprintCallable, Category = "GripMotionController|Custom", meta = (DisplayName = "DestroyPhysicsHandle")) + bool DestroyPhysicsHandle_BP(UPARAM(ref)const FBPActorGripInformation &Grip); + + // Re-creates a physics handle for this grip + // If bFullyRecreate is true then it will set all of the handle properties, if not then it will only reset the physics actors and COM positions + UFUNCTION(BlueprintCallable, Category = "GripMotionController|Custom", meta = (DisplayName = "UpdatePhysicsHandle")) + bool UpdatePhysicsHandle_BP(UPARAM(ref)const FBPActorGripInformation& Grip, bool bFullyRecreate = true); + + // Update the location of the physics handle + UFUNCTION(BlueprintCallable, Category = "GripMotionController|Custom", meta = (DisplayName = "UpdatePhysicsHandleTransform")) + void UpdatePhysicsHandleTransform_BP(UPARAM(ref)const FBPActorGripInformation &GrippedActor, UPARAM(ref)const FTransform& NewTransform); + + // Get the grip distance of either the physics handle if there is one, or the difference from the hand to the root component if there isn't + UFUNCTION(BlueprintCallable, Category = "GripMotionController|Custom", meta = (DisplayName = "GetGripDistance")) + bool GetGripDistance_BP(UPARAM(ref)FBPActorGripInformation &Grip, FVector ExpectedLocation, float & CurrentDistance); + + /** If true, the Position and Orientation args will contain the most recent controller state */ + virtual bool GripPollControllerState(FVector& Position, FRotator& Orientation, float WorldToMetersScale); + bool GripPollControllerState_GameThread(FVector& Position, FRotator& Orientation, bool& OutbProvidedLinearVelocity, FVector& OutLinearVelocity, bool& OutbProvidedAngularVelocity, FVector& OutAngularVelocityAsAxisAndLength, bool& OutbProvidedLinearAcceleration, FVector& OutLinearAcceleration, float WorldToMetersScale); + bool GripPollControllerState_RenderThread(FVector& Position, FRotator& Orientation, float WorldToMetersScale); + + /** Whether or not this component had a valid tracked controller associated with it this frame*/ + //bool bTracked; + + /** Whether or not this component had a valid tracked device this frame + * + * Use this instead of the normal IsTracked() for the motion controller which will not return the correct information. + * This is messy but I have no access to the various private members of the motion controller. + */ + UFUNCTION(BlueprintPure, Category = "GripMotionController") + bool GripControllerIsTracked() const; + + /** Returns the first valid device ID for this motion controller (across enabled XR systems) + * + * If bCheckOpenVROnly is true, then it only checks for OpenVR IDs (for use with my openVR nodes). + */ + UFUNCTION(BlueprintCallable, Category = "GripMotionController", meta = (ExpandEnumAsExecs = "Result")) + void GetControllerDeviceID(FXRDeviceId & DeviceID, EBPVRResultSwitch &Result, bool bCheckOpenVROnly = false); + + // Return whether this controller has authority (is locally net owned) + UFUNCTION(BlueprintPure, Category = "GripMotionController") + bool HasAuthority() const; + + /** Whether or not this component has authority within the frame*/ + //bool bHasAuthority; + + /** Whether or not this component has informed the visualization component (if present) to start rendering */ + //bool bHasStartedRendering = false; + +private: + /** Whether or not this component is currently on the network server*/ + //bool bIsServer; + + /** View extension object that can persist on the render thread without the motion controller component */ + class FGripViewExtension : public FSceneViewExtensionBase + { + + // #TODO: 4.18 - Uses an auto register base now, revise declaration and implementation + public: + FGripViewExtension(const FAutoRegister& AutoRegister, UGripMotionControllerComponent* InMotionControllerComponent); + + virtual ~FGripViewExtension() {} + + /** ISceneViewExtension interface */ + virtual void SetupViewFamily(FSceneViewFamily& InViewFamily) override {} + virtual void SetupView(FSceneViewFamily& InViewFamily, FSceneView& InView) override {} + virtual void BeginRenderViewFamily(FSceneViewFamily& InViewFamily) override; + //virtual void PreRenderView_RenderThread(FRHICommandListImmediate& RHICmdList, FSceneView& InView) override {} + //virtual void PreRenderViewFamily_RenderThread(FRHICommandListImmediate& RHICmdList, FSceneViewFamily& InViewFamily) override; + virtual void PreRenderView_RenderThread(FRDGBuilder& GraphBuilder, FSceneView& InView) override {} + virtual void PreRenderViewFamily_RenderThread(FRDGBuilder& GraphBuilder, FSceneViewFamily& InViewFamily) override; + + virtual int32 GetPriority() const override { return -10; } + + private: + friend class UGripMotionControllerComponent; + + /** Motion controller component associated with this view extension */ + UGripMotionControllerComponent* MotionControllerComponent; + + FExpandedLateUpdateManager LateUpdate; + }; + TSharedPtr< FGripViewExtension, ESPMode::ThreadSafe > GripViewExtension; + +}; + +FTransform inline UGripMotionControllerComponent::CreateGripRelativeAdditionTransform( + const FBPActorGripInformation &GripToSample, + const FTransform & AdditionTransform, + bool bGripRelative +) +{ + + FTransform FinalTransform; + + if (bGripRelative) + { + FinalTransform = FTransform(AdditionTransform.GetRotation(), GripToSample.RelativeTransform.GetRotation().RotateVector(AdditionTransform.GetLocation()), AdditionTransform.GetScale3D()); + } + else + { + const FTransform PivotToWorld = FTransform(FQuat::Identity, GripToSample.RelativeTransform.GetLocation()); + const FTransform WorldToPivot = FTransform(FQuat::Identity, -GripToSample.RelativeTransform.GetLocation()); + + // Create a transform from it + FTransform RotationOffsetTransform(AdditionTransform.GetRotation(), FVector::ZeroVector); + FinalTransform = FTransform(FQuat::Identity, AdditionTransform.GetLocation(), AdditionTransform.GetScale3D()) * WorldToPivot * RotationOffsetTransform * PivotToWorld; + } + + return FinalTransform; +} + +bool inline UGripMotionControllerComponent::HasGripAuthority(const FBPActorGripInformation &Grip) +{ + if (((Grip.GripMovementReplicationSetting != EGripMovementReplicationSettings::ClientSide_Authoritive && + Grip.GripMovementReplicationSetting != EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep) && IsServer()) || + ((Grip.GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive || + Grip.GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep) && bHasAuthority)) + { + return true; + } + + return false; +} + +bool inline UGripMotionControllerComponent::HasGripAuthority(const UObject * ObjToCheck) +{ + if (!ObjToCheck) + return false; + + // If it isn't interfaced and we are the server, then allow gripping it + if (!ObjToCheck->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass()) && IsServer()) + return true; + + // I know that it is bad practice to const_cast here, but I want the object to be passed in const + EGripMovementReplicationSettings MovementRepType = IVRGripInterface::Execute_GripMovementReplicationType(const_cast(ObjToCheck)); + + if (((MovementRepType != EGripMovementReplicationSettings::ClientSide_Authoritive && + MovementRepType != EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep) && IsServer()) || + ((MovementRepType == EGripMovementReplicationSettings::ClientSide_Authoritive || + MovementRepType == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep) && bHasAuthority)) + { + return true; + } + + return false; +} + +bool inline UGripMotionControllerComponent::HasGripMovementAuthority(const FBPActorGripInformation &Grip) +{ + if (IsServer()) + { + return true; + } + else + { + if (Grip.GripMovementReplicationSetting == EGripMovementReplicationSettings::ForceClientSideMovement || + Grip.GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive || + Grip.GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep) + { + return true; + } + else if (Grip.GripMovementReplicationSetting == EGripMovementReplicationSettings::ForceServerSideMovement) + { + return false; + } + + // Use original movement type is overridden when initializing the grip and shouldn't happen + check(Grip.GripMovementReplicationSetting != EGripMovementReplicationSettings::KeepOriginalMovement); + } + + return false; +} diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_Default.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_Default.h new file mode 100644 index 0000000..376ede0 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_Default.h @@ -0,0 +1,48 @@ +#pragma once + +#include "CoreMinimal.h" +#include "VRGripScriptBase.h" +#include "GS_Default.generated.h" + + +/** +* The default grip transform logic for the motion controllers +*/ +UCLASS(NotBlueprintable, ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UGS_Default : public UVRGripScriptBase +{ + GENERATED_BODY() +public: + + UGS_Default(const FObjectInitializer& ObjectInitializer); + + //virtual void BeginPlay_Implementation() override; + virtual bool GetWorldTransform_Implementation(UGripMotionControllerComponent * GrippingController, float DeltaTime, FTransform & WorldTransform, const FTransform &ParentTransform, FBPActorGripInformation &Grip, AActor * actor, UPrimitiveComponent * root, bool bRootHasInterface, bool bActorHasInterface, bool bIsForTeleport) override; + + virtual void GetAnyScaling(FVector& Scaler, FBPActorGripInformation& Grip, FVector& frontLoc, FVector& frontLocOrig, ESecondaryGripType SecondaryType, FTransform& SecondaryTransform); + virtual void ApplySmoothingAndLerp(FBPActorGripInformation& Grip, FVector& frontLoc, FVector& frontLocOrig, float DeltaTime); + + virtual void CalculateSecondaryLocation(FVector & frontLoc, const FVector& BasePoint, FBPActorGripInformation& Grip, UGripMotionControllerComponent * GrippingController); +}; + +// An extended default grip script that adds less common grip features that were moved out of the default implementation +UCLASS(BlueprintType, ClassGroup = (VRExpansionPlugin), hideCategories = TickSettings) +class VREXPANSIONPLUGIN_API UGS_ExtendedDefault : public UGS_Default +{ + GENERATED_BODY() +public: + + // Whether clamp the grip scaling in scaling grips + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SecondaryGripSettings") + bool bLimitGripScaling; + + // Minimum size to allow scaling in double grip to reach + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SecondaryGripSettings", meta = (editcondition = "bLimitGripScaling")) + FVector_NetQuantize100 MinimumGripScaling; + + // Maximum size to allow scaling in double grip to reach + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SecondaryGripSettings", meta = (editcondition = "bLimitGripScaling")) + FVector_NetQuantize100 MaximumGripScaling; + + virtual void GetAnyScaling(FVector& Scaler, FBPActorGripInformation& Grip, FVector& frontLoc, FVector& frontLocOrig, ESecondaryGripType SecondaryType, FTransform& SecondaryTransform) override; +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_GunTools.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_GunTools.h new file mode 100644 index 0000000..19d8aee --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_GunTools.h @@ -0,0 +1,318 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +//#include "Engine/Engine.h" +#include "VRGripScriptBase.h" +#include "GripScripts/GS_Default.h" +#include "GS_GunTools.generated.h" + +class UGripMotionControllerComponent; + +// Event thrown when we enter into virtual stock mode +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FVRVirtualStockModeChangedSignature, bool, IsVirtualStockEngaged); + +// Global settings for this player +USTRUCT(BlueprintType, Category = "GunSettings") +struct VREXPANSIONPLUGIN_API FBPVirtualStockSettings +{ + GENERATED_BODY() +public: + + // *Global Value* Should we auto snap to the virtual stock by a set distance + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VirtualStock") + bool bUseDistanceBasedStockSnapping; + + // *Global Value* The distance before snapping to the stock / unsnapping + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VirtualStock") + float StockSnapDistance; + + // *Global Value* The distance from the edge of the stock snap distance where it will be at 100% influence + // Prior to this threshold being hit it will lerp from standard hold to the virtual stock version. + // A value of 0.0f will leave it always off + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VirtualStock", meta = (ClampMin = "0.00", UIMin = "0.00")) + float StockSnapLerpThreshold; + + // Current lerp value of the stock from zero influence to full influence + UPROPERTY(BlueprintReadOnly, Category = "VirtualStock") + float StockLerpValue; + + // *Global Value* An offset to apply to the HMD location to be considered the neck / mount pivot + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VirtualStock") + FVector_NetQuantize100 StockSnapOffset; + + // *Global Value* If we want to have the stock location adjust to follow the primary hands Z value + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VirtualStock") + bool bAdjustZOfStockToPrimaryHand; + + // *Global Value* Whether we should lerp the location of the rearmost (stock side) hand, mostly used for snipers. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VirtualStock|Smoothing") + bool bSmoothStockHand; + + // *Global Value* How much influence the virtual stock smoothing should have, 0.0f is zero smoothing, 1.0f is full smoothing, you should test with full smoothing to get the amount you + // want and then set the smoothing value up until it feels right between the fully smoothed and unsmoothed values. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VirtualStock|Smoothing", meta = (editcondition = "bSmoothStockHand", ClampMin = "0.00", UIMin = "0.00", ClampMax = "1.00", UIMax = "1.00")) + float SmoothingValueForStock; + + // Used to smooth filter the virtual stocks primary hand location + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GunSettings|VirtualStock|Smoothing") + FBPEuroLowPassFilterTrans StockHandSmoothing; + + // Draw debug elements showing the virtual stock location and angles to interacting components + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GunSettings|VirtualStock|Debug") + bool bDebugDrawVirtualStock; + + void CopyFrom(FBPVirtualStockSettings & B) + { + bUseDistanceBasedStockSnapping = B.bUseDistanceBasedStockSnapping; + StockSnapDistance = B.StockSnapDistance; + StockSnapLerpThreshold = B.StockSnapLerpThreshold; + StockSnapOffset = B.StockSnapOffset; + bAdjustZOfStockToPrimaryHand = B.bAdjustZOfStockToPrimaryHand; + bSmoothStockHand = B.bSmoothStockHand; + SmoothingValueForStock = B.SmoothingValueForStock; + StockHandSmoothing = B.StockHandSmoothing; + } + + FBPVirtualStockSettings() + { + StockSnapOffset = FVector(0.f, 0.f, 0.f); + bAdjustZOfStockToPrimaryHand = true; + StockSnapDistance = 35.f; + StockSnapLerpThreshold = 20.0f; + StockLerpValue = 0.0f; + bUseDistanceBasedStockSnapping = true; + SmoothingValueForStock = 0.0f; + bSmoothStockHand = false; + + // Speed up the lerp on fast movements for this + StockHandSmoothing.DeltaCutoff = 20.0f; + StockHandSmoothing.MinCutoff = 5.0f; + + bDebugDrawVirtualStock = false; + } +}; + +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FGunTools_AdvSecondarySettings +{ + GENERATED_BODY() +public: + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AdvSecondarySettings") + bool bUseAdvancedSecondarySettings; + + // Scaler used for handling the smoothing amount, 0.0f is zero smoothing, 1.0f is full smoothing, you should test with full smoothing to get the amount you + // want and then set the smoothing value up until it feels right between the fully smoothed and unsmoothed values. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AdvSecondarySettings|Smoothing", meta = (editcondition = "bUseAdvancedSecondarySettings", ClampMin = "0.00", UIMin = "0.00", ClampMax = "1.00", UIMax = "1.00")) + float SecondaryGripScaler; + + // If true we will constantly be lerping with the grip scaler instead of only sometimes. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AdvSecondarySettings|Smoothing", meta = (editcondition = "bUseAdvancedSecondarySettings")) + bool bUseConstantGripScaler; + + // If true will override custom settings for the smoothing values with the global settings in VRSettings + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AdvSecondarySettings|Smoothing", meta = (editcondition = "bUseAdvancedSecondarySettings")) + bool bUseGlobalSmoothingSettings; + + // Used to smooth filter the secondary influence + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AdvSecondarySettings|Smoothing") + FBPEuroLowPassFilter SecondarySmoothing; + + // Whether to scale the secondary hand influence off of distance from grip point + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AdvSecondarySettings|DistanceInfluence", meta = (editcondition = "bUseAdvancedSecondarySettings")) + bool bUseSecondaryGripDistanceInfluence; + + // If true, will use the GripInfluenceDeadZone as a constant value instead of calculating the distance and lerping, lets you define a static influence amount. + //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SecondaryGripSettings", meta = (editcondition = "bUseSecondaryGripDistanceInfluence")) + // bool bUseGripInfluenceDeadZoneAsConstant; + + // Distance from grip point in local space where there is 100% influence + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AdvSecondarySettings|DistanceInfluence", meta = (editcondition = "bUseSecondaryGripDistanceInfluence", ClampMin = "0.00", UIMin = "0.00", ClampMax = "256.00", UIMax = "256.00")) + float GripInfluenceDeadZone; + + // Distance from grip point in local space before all influence is lost on the secondary grip (1.0f - 0.0f influence over this range) + // this comes into effect outside of the deadzone + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AdvSecondarySettings|DistanceInfluence", meta = (editcondition = "bUseSecondaryGripDistanceInfluence", ClampMin = "1.00", UIMin = "1.00", ClampMax = "256.00", UIMax = "256.00")) + float GripInfluenceDistanceToZero; + + FGunTools_AdvSecondarySettings() + { + bUseAdvancedSecondarySettings = false; + SecondaryGripScaler = 0.0f; + bUseGlobalSmoothingSettings = true; + bUseSecondaryGripDistanceInfluence = false; + //bUseGripInfluenceDeadZoneAsConstant(false), + GripInfluenceDeadZone = 50.0f; + GripInfluenceDistanceToZero = 100.0f; + bUseConstantGripScaler = false; + } +}; + + +// A grip script that adds useful fire-arm related features to grips +// Just adding it to the grippable object provides the features without removing standard +// Grip features. +UCLASS(NotBlueprintable, ClassGroup = (VRExpansionPlugin), hideCategories = TickSettings) +class VREXPANSIONPLUGIN_API UGS_GunTools : public UGS_Default +{ + GENERATED_BODY() +public: + + UGS_GunTools(const FObjectInitializer& ObjectInitializer); + + virtual void OnGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) override; + virtual void OnSecondaryGrip_Implementation(UGripMotionControllerComponent * Controller, USceneComponent * SecondaryGripComponent, const FBPActorGripInformation & GripInformation) override; + virtual void OnBeginPlay_Implementation(UObject* CallingOwner) override; + virtual void HandlePrePhysicsHandle(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation &GripInfo, FBPActorPhysicsHandleInformation* HandleInfo, FTransform& KinPose) override; + //virtual void HandlePostPhysicsHandle(UGripMotionControllerComponent* GrippingController, FBPActorPhysicsHandleInformation* HandleInfo) override; + + + // The name of the component that is used to orient the weapon along its primary axis + // If it does not exist then the weapon is assumed to be X+ facing. + // Also used to perform some calculations, make sure it is parented to the gripped object (root component for actors), + // and that the X+ vector of the orientation component is facing the forward direction of the weapon (gun tip for guns, ect). + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Settings") + FName WeaponRootOrientationComponent; + FTransform OrientationComponentRelativeFacing; + FQuat StoredRootOffset; + + // (default false) If true will run through the entire simulation that the owning client uses for the gun. If false, does a lighter and more performant approximation. + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "GunSettings") + bool bUseHighQualityRemoteSimulation; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GunSettings") + FGunTools_AdvSecondarySettings AdvSecondarySettings; + + // Offset to apply to the pivot (good for centering pivot into the palm ect). + // For this to apply to the physical center of mass as well an OrientationComponent needs to be defined + // So that we have a valid directional vector to work off of, otherwise the pivot will be in component space and you + // will have a harder time aligning it if the weapon is off axis (still works, just less intuitive). + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pivot") + FVector_NetQuantize100 PivotOffset; + + UFUNCTION(BlueprintCallable, Category = "VirtualStock") + void SetVirtualStockComponent(USceneComponent * NewStockComponent) + { + VirtualStockComponent = NewStockComponent; + } + + UFUNCTION(BlueprintCallable, Category = "VirtualStock") + void SetVirtualStockEnabled(bool bAllowVirtualStock) + { + if (!bUseVirtualStock && bAllowVirtualStock) + ResetStockVariables(); + + bUseVirtualStock = bAllowVirtualStock; + } + + void ResetStockVariables() + { + VirtualStockSettings.StockHandSmoothing.ResetSmoothingFilter(); + } + + void GetVirtualStockTarget(UGripMotionControllerComponent * GrippingController); + + // Call to use an object + UPROPERTY(BlueprintAssignable, Category = "VirtualStock") + FVRVirtualStockModeChangedSignature OnVirtualStockModeChanged; + + // Overrides the pivot location to be at this component instead + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VirtualStock") + bool bUseVirtualStock; + + FTransform MountWorldTransform; + bool bIsMounted; + FTransform RelativeTransOnSecondaryRelease; + TObjectPtr CameraComponent; + + // Overrides the default behavior of using the HMD location for the stock and uses this component instead + UPROPERTY(BlueprintReadWrite, Category = "VirtualStock") + TObjectPtr VirtualStockComponent; + + // Loads the global virtual stock settings on grip (only if locally controlled, you need to manually replicate and store the global settings + // In the character if networked). + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VirtualStock") + bool bUseGlobalVirtualStockSettings; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VirtualStock", meta = (editcondition = "!bUseGlobalVirtualStockSettings")) + FBPVirtualStockSettings VirtualStockSettings; + + // If this gun has recoil + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Recoil") + bool bHasRecoil; + + // If true then the recoil will be added as a physical force instead of logical blend + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Recoil") + bool bApplyRecoilAsPhysicalForce; + + // Maximum recoil addition + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Recoil", meta = (editcondition = "bHasRecoil")) + FVector_NetQuantize100 MaxRecoilTranslation; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Recoil", meta = (editcondition = "bHasRecoil")) + FVector_NetQuantize100 MaxRecoilRotation; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Recoil", meta = (editcondition = "bHasRecoil")) + FVector_NetQuantize100 MaxRecoilScale; + + // Recoil decay rate, how fast it decays back to baseline + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Recoil", meta = (editcondition = "bHasRecoil")) + float DecayRate; + + // Recoil lerp rate, how long it takes to lerp to the target recoil amount (0.0f would be instant) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Recoil", meta = (editcondition = "bHasRecoil")) + float LerpRate; + + // Stores the current amount of recoil + FTransform BackEndRecoilStorage; + + // Stores the target amount of recoil + FTransform BackEndRecoilTarget; + + bool bHasActiveRecoil; + + // Adds a recoil instance to the gun tools, the option location is for if using the physical recoil mode + // Physical recoil is in world space and positional only, logical recoil is in relative space to the mesh itself and uses all + // of the transforms properties. + UFUNCTION(BlueprintCallable, Category = "Recoil") + void AddRecoilInstance(const FTransform & RecoilAddition, FVector Optional_Location = FVector::ZeroVector); + + UFUNCTION(BlueprintCallable, Category = "Recoil") + void ResetRecoil(); + + virtual bool GetWorldTransform_Implementation(UGripMotionControllerComponent * GrippingController, float DeltaTime, FTransform & WorldTransform, const FTransform &ParentTransform, FBPActorGripInformation &Grip, AActor * actor, UPrimitiveComponent * root, bool bRootHasInterface, bool bActorHasInterface, bool bIsForTeleport) override; + + // Applies the two hand modifier, broke this out into a function so that we can handle late updates + static void ApplyTwoHandModifier(FTransform & OriginalTransform) + { + + + } + + // Returns the smoothed value now + inline FVector GunTools_ApplySmoothingAndLerp(FBPActorGripInformation & Grip, FVector &frontLoc, FVector & frontLocOrig, float DeltaTime, bool bSkipHighQualitySimulations) + { + FVector SmoothedValue = frontLoc; + + if (Grip.SecondaryGripInfo.GripLerpState == EGripLerpState::StartLerp) // Lerp into the new grip to smooth the transition + { + if (!bSkipHighQualitySimulations && AdvSecondarySettings.SecondaryGripScaler < 1.0f) + { + SmoothedValue = AdvSecondarySettings.SecondarySmoothing.RunFilterSmoothing(frontLoc, DeltaTime); + frontLoc = FMath::Lerp(frontLoc, SmoothedValue, AdvSecondarySettings.SecondaryGripScaler); + + } + //Default_ApplySmoothingAndLerp(Grip, frontLoc, frontLocOrig, DeltaTime); + } + else if (!bSkipHighQualitySimulations && AdvSecondarySettings.bUseAdvancedSecondarySettings && AdvSecondarySettings.bUseConstantGripScaler) // If there is a frame by frame lerp + { + SmoothedValue = AdvSecondarySettings.SecondarySmoothing.RunFilterSmoothing(frontLoc, DeltaTime); + frontLoc = FMath::Lerp(frontLoc, SmoothedValue, AdvSecondarySettings.SecondaryGripScaler); + } + + return SmoothedValue; + } +}; + diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_InteractibleSettings.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_InteractibleSettings.h new file mode 100644 index 0000000..ca62911 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_InteractibleSettings.h @@ -0,0 +1,114 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "VRGripScriptBase.h" +#include "GS_InteractibleSettings.generated.h" + +class UGripMotionControllerComponent; + +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPGS_InteractionSettings +{ + GENERATED_BODY() +public: + + bool bHasValidBaseTransform; // So we don't have to equals the transform + FTransform BaseTransform; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings") + uint32 bLimitsInLocalSpace : 1; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings") + uint32 bGetInitialPositionsOnBeginPlay : 1; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|Linear") + uint32 bLimitX : 1; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|Linear") + uint32 bLimitY : 1; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|Linear") + uint32 bLimitZ : 1; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|Angular") + uint32 bLimitPitch : 1; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|Angular") + uint32 bLimitYaw : 1; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|Angular") + uint32 bLimitRoll : 1; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|Angular") + uint32 bIgnoreHandRotation : 1; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|Linear", meta = (editcondition = "!bGetInitialPositionsOnBeginPlay")) + FVector_NetQuantize100 InitialLinearTranslation; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|Linear") + FVector_NetQuantize100 MinLinearTranslation; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|Linear") + FVector_NetQuantize100 MaxLinearTranslation; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|Angular", meta = (editcondition = "!bGetInitialPositionsOnBeginPlay")) + FRotator InitialAngularTranslation; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|Angular") + FRotator MinAngularTranslation; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|Angular") + FRotator MaxAngularTranslation; + + FBPGS_InteractionSettings() : + bLimitsInLocalSpace(true), + bGetInitialPositionsOnBeginPlay(true), + bLimitX(false), + bLimitY(false), + bLimitZ(false), + bLimitPitch(false), + bLimitYaw(false), + bLimitRoll(false), + bIgnoreHandRotation(false), + InitialLinearTranslation(FVector::ZeroVector), + MinLinearTranslation(FVector::ZeroVector), + MaxLinearTranslation(FVector::ZeroVector), + InitialAngularTranslation(FRotator::ZeroRotator), + MinAngularTranslation(FRotator::ZeroRotator), + MaxAngularTranslation(FRotator::ZeroRotator) + { + BaseTransform = FTransform::Identity; + bHasValidBaseTransform = false; + } +}; + +// A Grip script that overrides the default grip behavior and adds custom clamping logic instead, +UCLASS(NotBlueprintable, ClassGroup = (VRExpansionPlugin), hideCategories = TickSettings) +class VREXPANSIONPLUGIN_API UGS_InteractibleSettings : public UVRGripScriptBase +{ + GENERATED_BODY() +public: + + UGS_InteractibleSettings(const FObjectInitializer& ObjectInitializer); + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "InteractionSettings") + FBPGS_InteractionSettings InteractionSettings; + + virtual void OnBeginPlay_Implementation(UObject * CallingOwner) override; + virtual bool GetWorldTransform_Implementation(UGripMotionControllerComponent * GrippingController, float DeltaTime, FTransform & WorldTransform, const FTransform &ParentTransform, FBPActorGripInformation &Grip, AActor * actor, UPrimitiveComponent * root, bool bRootHasInterface, bool bActorHasInterface, bool bIsForTeleport) override; + virtual void OnGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) override; + virtual void OnGripRelease_Implementation(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed = false) override; + + // Flags the the interaction settings so that it will regenerate removing the hand rotation. + // Use this if you just changed the relative hand transform. + UFUNCTION(BlueprintCallable, Category = "InteractionSettings") + void RemoveHandRotation() + { + // Flag the base transform to be re-applied + InteractionSettings.bHasValidBaseTransform = false; + } + + void RemoveRelativeRotation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation); +}; diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_LerpToHand.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_LerpToHand.h new file mode 100644 index 0000000..78d83c2 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_LerpToHand.h @@ -0,0 +1,69 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "VRGripScriptBase.h" +#include "VRBPDatatypes.h" +#include "Curves/CurveFloat.h" +#include "GS_LerpToHand.generated.h" + +DECLARE_DYNAMIC_MULTICAST_DELEGATE(FVRLerpToHandFinishedSignature); + + +// A grip script that causes new grips to lerp to the hand (from their current position to where they are supposed to sit). +// It turns off when the lerp is complete. +UCLASS(NotBlueprintable, ClassGroup = (VRExpansionPlugin), hideCategories = TickSettings) +class VREXPANSIONPLUGIN_API UGS_LerpToHand : public UVRGripScriptBase +{ + GENERATED_BODY() +public: + + UGS_LerpToHand(const FObjectInitializer& ObjectInitializer); + + float CurrentLerpTime; + float LerpSpeed; + + // If the initial grip distance is closer than this value then the lerping will not be performed. + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "LerpSettings") + float MinDistanceForLerp; + + // How many seconds the lerp should take + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "LerpSettings") + float LerpDuration; + + // The minimum speed (in UU per second) that that the lerp should have across the initial grip distance + // Will speed the LerpSpeed up to try and maintain this initial speed if required + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "LerpSettings") + float MinSpeedForLerp; + + // The maximum speed (in UU per second) that the lerp should have across the initial grip distance + // Will slow the LerpSpeed down to try and maintain this initial speed if required + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "LerpSettings") + float MaxSpeedForLerp; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "LerpSettings") + EVRLerpInterpolationMode LerpInterpolationMode; + + UPROPERTY(BlueprintAssignable, Category = "LerpEvents") + FVRLerpToHandFinishedSignature OnLerpToHandBegin; + + UPROPERTY(BlueprintAssignable, Category = "LerpEvents") + FVRLerpToHandFinishedSignature OnLerpToHandFinished; + + // Whether to use a curve map to map the lerp to + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "LerpCurve") + bool bUseCurve; + + // The curve to follow when using a curve map, only uses from 0.0 - 1.0 of the curve timeline and maps it across the entire duration + UPROPERTY(Category = "LerpCurve", EditAnywhere, meta = (editcondition = "bUseCurve")) + FRuntimeFloatCurve OptionalCurveToFollow; + + FTransform OnGripTransform; + uint8 TargetGrip; + + //virtual void BeginPlay_Implementation() override; + virtual bool GetWorldTransform_Implementation(UGripMotionControllerComponent * OwningController, float DeltaTime, FTransform & WorldTransform, const FTransform &ParentTransform, FBPActorGripInformation &Grip, AActor * actor, UPrimitiveComponent * root, bool bRootHasInterface, bool bActorHasInterface, bool bIsForTeleport) override; + virtual void OnGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) override; + virtual void OnGripRelease_Implementation(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed) override; +}; diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_Melee.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_Melee.h new file mode 100644 index 0000000..8691b53 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_Melee.h @@ -0,0 +1,316 @@ +#pragma once + +#include "CoreMinimal.h" +#include "Engine/Engine.h" +#include "VRGripScriptBase.h" +#include "GripScripts/GS_Default.h" +#include "GS_Melee.generated.h" + + +// The type of melee hit zone we are +UENUM(BlueprintType) +enum class EVRMeleeZoneType : uint8 +{ + // This zone is only valid for stabs + VRPMELLE_ZONETYPE_Stab UMETA(DisplayName = "Stab"), + + // This zone is only valid for hits + VRPMELLE_ZONETYPE_Hit UMETA(DisplayName = "Hit"), + + // This zone is valid for both stabs and hits + VRPMELLE_ZONETYPE_StabAndHit UMETA(DisplayName = "StabAndHit") + +}; + +// The type of COM selection to use +UENUM(BlueprintType) +enum class EVRMeleeComType : uint8 +{ + // Does not set COM + VRPMELEECOM_Normal UMETA(DisplayName = "Normal"), + + // Sets COM to between hands + VRPMELEECOM_BetweenHands UMETA(DisplayName = "BetweenHands"), + + // Uses the primary hand as com location + VRPMELEECOM_PrimaryHand UMETA(DisplayName = "PrimaryHand") +}; + +// The type of primary hand selection to use +UENUM(BlueprintType) +enum class EVRMeleePrimaryHandType : uint8 +{ + // Uses the rearmost hand as the primary hand + VRPHAND_Rear UMETA(DisplayName = "Rear"), + + // Uses the foremost hand as the primary hand + VRPHAND_Front UMETA(DisplayName = "Front"), + + // Uses the first slotted hand as the primary hand + // If neither are slotted then its first come first serve and both hannds load the secondary settings + VRPHAND_Slotted UMETA(DisplayName = "Slotted") +}; + +// A Lodge component data struct +USTRUCT(BlueprintType, Category = "Lodging") +struct VREXPANSIONPLUGIN_API FBPHitSurfaceProperties +{ + GENERATED_BODY() +public: + + // Does this surface type allow penetration + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Surface Property") + bool bSurfaceAllowsPenetration; + + // Scaler to damage applied from hitting this surface with blunt damage + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Surface Property") + float BluntDamageScaler; + + // Scaler to damage applied from hitting this surface with sharp damage + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Surface Property") + float SharpDamageScaler; + + // Alters the stab velocity to let you make it harder or easier to stab this surface + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Surface Property") + float StabVelocityScaler; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Surface Property") + TEnumAsByte SurfaceType; + + FBPHitSurfaceProperties() + { + // Default to true on this + bSurfaceAllowsPenetration = true; + BluntDamageScaler = 1.f; + SharpDamageScaler = 1.f; + StabVelocityScaler = 1.f; + SurfaceType = EPhysicalSurface::SurfaceType_Default; + } +}; + +// A Lodge component data struct +USTRUCT(BlueprintType, Category = "Lodging") +struct VREXPANSIONPLUGIN_API FBPLodgeComponentInfo +{ + GENERATED_BODY() +public: + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "LodgeComponentInfo") + FName ComponentName; + + // Type of collision zone we are + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "LodgeComponentInfo") + EVRMeleeZoneType ZoneType; + + // If true than we will calculate hit impulse off of its total value and not just off of it axially aligned to the forward of this body + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "LodgeComponentInfo") + bool bIgnoreForwardVectorForHitImpulse; + + // For end users to provide a base damage per zone if they want + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "LodgeComponentInfo") + float DamageScaler; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "LodgeComponentInfo") + float PenetrationDepth; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "LodgeComponentInfo") + bool bAllowPenetrationInReverseAsWell; + + // This is the impulse velocity (along forward axis of component) required to throw an OnPenetrated event from a PenetrationNotifierComponent + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Settings") + float PenetrationVelocity; + + // This is the impulse velocity required to throw an OnHit event from a PenetrationNotifierComponent (If a stab didn't take place) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Settings") + float MinimumHitVelocity; + + // The acceptable range of the dot product of the forward vector and the impact normal to define a valid facing + // Subtracted from the 1.0f forward facing value + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Settings") + float AcceptableForwardProductRange; + + // The acceptable range of the dot product of the forward vector and the impact normal to define a valid facing + // Subtracted from the 1.0f forward facing value + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Settings") + float AcceptableForwardProductRangeForHits; + + FBPLodgeComponentInfo() + { + ComponentName = NAME_None; + ZoneType = EVRMeleeZoneType::VRPMELLE_ZONETYPE_StabAndHit; + bIgnoreForwardVectorForHitImpulse = false; + DamageScaler = 0.f; + PenetrationDepth = 100.f; + bAllowPenetrationInReverseAsWell = false; + PenetrationVelocity = 8000.f; + MinimumHitVelocity = 1000.f; + AcceptableForwardProductRange = 0.1f; + AcceptableForwardProductRangeForHits = 0.1f; + TargetComponent = nullptr; + } + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "LodgeComponentInfo") + TObjectPtr TargetComponent; + + FORCEINLINE bool operator==(const FName& Other) const + { + return (ComponentName == Other); + } + +}; + + +// Event thrown when we the melee weapon becomes lodged +DECLARE_DYNAMIC_MULTICAST_DELEGATE_SevenParams(FVROnMeleeShouldLodgeSignature, FBPLodgeComponentInfo, LogComponent, AActor *, OtherActor, UPrimitiveComponent *, OtherComp, ECollisionChannel, OtherCompCollisionChannel, FBPHitSurfaceProperties, HitSurfaceProperties, FVector, NormalImpulse, const FHitResult&, Hit); +DECLARE_DYNAMIC_MULTICAST_DELEGATE_SevenParams(FVROnMeleeOnHit, FBPLodgeComponentInfo, LogComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, ECollisionChannel, OtherCompCollisionChannel, FBPHitSurfaceProperties, HitSurfaceProperties, FVector, NormalImpulse, const FHitResult&, Hit); +DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FVROnMeleeInvalidHitSignature, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, FVector, NormalImpulse, const FHitResult&, Hit); + +/** +* A Melee grip script that hands multi hand interactions and penetration notifications* +* The per surface damage and penetration options have been moved to the project settings unless the per script override is set +*/ +UCLASS(NotBlueprintable, ClassGroup = (VRExpansionPlugin), hideCategories = TickSettings) +class VREXPANSIONPLUGIN_API UGS_Melee : public UGS_Default +{ + GENERATED_BODY() +public: + + UGS_Melee(const FObjectInitializer& ObjectInitializer); + + UFUNCTION() + virtual void OnLodgeHitCallback(AActor* SelfActor, AActor* OtherActor, FVector NormalImpulse, const FHitResult& Hit); + + UFUNCTION(BlueprintCallable, Category = "Weapon Settings") + void SetIsLodged(bool IsLodged, UPrimitiveComponent* LodgeComponent); + + + bool bIsLodged; + TWeakObjectPtr LodgedComponent; + + //virtual void Tick(float DeltaTime) override; + + // Thrown if we should lodge into a hit object + UPROPERTY(BlueprintAssignable, Category = "Melee|Lodging") + FVROnMeleeShouldLodgeSignature OnShouldLodgeInObject; + + // Thrown if we hit something we can damage + UPROPERTY(BlueprintAssignable, Category = "Melee|Hit") + FVROnMeleeOnHit OnMeleeHit; + + // Fired when a hit is invalid (hit something that isn't flagged for damage or stabbing or was below the damage or stab threshold) + UPROPERTY(BlueprintAssignable, Category = "Melee|Hit") + FVROnMeleeInvalidHitSignature OnMeleeInvalidHit; + + // Always tick for penetration + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Melee|Lodging") + bool bAlwaysTickPenetration; + + // Only penetrate with two hands on the weapon + // Mostly for very large weapons + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Melee|Lodging") + bool bOnlyPenetrateWithTwoHands; + + // A list of surface types that allow penetration and their properties + // If empty then the script will use the global settings, if filled with anything then it will override the global settings + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Melee|Lodging") + TArray OverrideMeleeSurfaceSettings; + +// FVector RollingVelocityAverage; + //FVector RollingAngVelocityAverage; + + // The name of the component that is used to orient the weapon along its primary axis + // If it does not exist then the weapon is assumed to be X+ facing. + // Also used to perform some calculations, make sure it is parented to the gripped object (root component for actors). + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Settings") + FName WeaponRootOrientationComponent; + FTransform OrientationComponentRelativeFacing; + + // UpdateHand location on the shaft in the X axis + // If primary hand is false then it will do the secondary hand + // World location is of the pivot generally, I have it passing in so people can snap + // LocDifference returns the relative distance of the change in position (or zero if there was none). + UFUNCTION(BlueprintCallable, Category = "Weapon Settings") + void UpdateHandPosition(FBPGripPair HandPair, FVector HandWorldPosition, FVector & LocDifference); + + // UpdateHand location and rotation on the shaft in the X axis + // If primary hand is false then it will do the secondary hand + // World location is of the pivot generally, I have it passing in so people can snap + // LocDifference returns the relative distance of the change in position (or zero if there was none). + UFUNCTION(BlueprintCallable, Category = "Weapon Settings") + void UpdateHandPositionAndRotation(FBPGripPair HandPair, FTransform HandWorldTransform, FVector& LocDifference, float& RotDifference, bool bUpdateLocation = true, bool bUpdateRotation = true); + + + // This is a built list of components that act as penetration notifiers, they will have their OnHit bound too and we will handle penetration logic + // off of it. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Settings") + TArray PenetrationNotifierComponents; + + bool bCheckLodge; + bool bIsHeld; + + FVector LastRelativePos; + FVector RelativeBetweenGripsCenterPos; + + // When true, will auto set the primary and secondary hands by the WeaponRootOrientationComponents X Axis distance. + // Smallest value along the X Axis will be considered the primary hand. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Settings") + bool bAutoSetPrimaryAndSecondaryHands; + + // If we couldn't decide on a true valid primary hand then this will be false and we will load secondary settings for both + bool bHasValidPrimaryHand; + + UFUNCTION(BlueprintCallable, Category = "Weapon Settings") + void SetPrimaryAndSecondaryHands(FBPGripPair & PrimaryGrip, FBPGripPair & SecondaryGrip); + + // Which method of primary hand to select + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Settings") + EVRMeleePrimaryHandType PrimaryHandSelectionType; + + UPROPERTY(BlueprintReadOnly, Category = "Weapon Settings") + FBPGripPair PrimaryHand; + + UPROPERTY(BlueprintReadOnly, Category = "Weapon Settings") + FBPGripPair SecondaryHand; + + // If true we will use the primary hands grip settings when we only have one hand gripping instead of the objects VRGripInterfaces settings + UPROPERTY(BlueprintReadOnly, Category = "Weapon Settings") + bool bUsePrimaryHandSettingsWithOneHand; + + // To select the type of com setting to use + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Settings") + EVRMeleeComType COMType; + + FTransform ObjectRelativeGripCenter; + + void SetComBetweenHands(UGripMotionControllerComponent* GrippingController, FBPActorPhysicsHandleInformation * HandleInfo); + + + // Grip settings to use on the primary hand when multiple grips are active + // Falls back to the standard grip settings when only one grip is active + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Settings") + FBPAdvancedPhysicsHandleSettings PrimaryHandPhysicsSettings; + + // Grip settings to use on the secondary hand when multiple grips are active + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Settings") + FBPAdvancedPhysicsHandleSettings SecondaryHandPhysicsSettings; + + + void UpdateDualHandInfo(); + + virtual void HandlePostPhysicsHandle(UGripMotionControllerComponent* GrippingController, FBPActorPhysicsHandleInformation* HandleInfo) override; + virtual void HandlePrePhysicsHandle(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation &GripInfo, FBPActorPhysicsHandleInformation* HandleInfo, FTransform& KinPose) override; + virtual void OnBeginPlay_Implementation(UObject* CallingOwner) override; + virtual void OnEndPlay_Implementation(const EEndPlayReason::Type EndPlayReason) override; + virtual void OnSecondaryGrip_Implementation(UGripMotionControllerComponent* Controller, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + virtual void OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + virtual void OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + virtual bool Wants_DenyTeleport_Implementation(UGripMotionControllerComponent* Controller) override; + + //virtual void BeginPlay_Implementation() override; + virtual bool GetWorldTransform_Implementation(UGripMotionControllerComponent * GrippingController, float DeltaTime, FTransform & WorldTransform, const FTransform &ParentTransform, FBPActorGripInformation &Grip, AActor * actor, UPrimitiveComponent * root, bool bRootHasInterface, bool bActorHasInterface, bool bIsForTeleport) override; + + +}; diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_Physics.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_Physics.h new file mode 100644 index 0000000..c300eee --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/GS_Physics.h @@ -0,0 +1,38 @@ +#pragma once + +#include "CoreMinimal.h" +//#include "Engine/Engine.h" +#include "VRGripScriptBase.h" +#include "GameFramework/WorldSettings.h" +#include "GripScripts/GS_Default.h" +#include "GS_Physics.generated.h" + +/** +* A pure physics multi hand interaction grip script, expects that bAllowMultiGrips is set on the parent object* +*/ +UCLASS(NotBlueprintable, ClassGroup = (VRExpansionPlugin), hideCategories = TickSettings) +class VREXPANSIONPLUGIN_API UGS_Physics : public UGS_Default +{ + GENERATED_BODY() +public: + + UGS_Physics(const FObjectInitializer& ObjectInitializer); + + // Grip settings to use when a single hand is gripping, overrides interface defaults + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Physics Settings") + FBPAdvancedPhysicsHandleSettings SingleHandPhysicsSettings; + + // Grip settings to use when multiple hands are gripping + // Overrides interface defaults + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Physics Settings") + FBPAdvancedPhysicsHandleSettings MultiHandPhysicsSettings; + + + void UpdateDualHandInfo(UGripMotionControllerComponent* GrippingController = nullptr, bool bRecreate = true); + + virtual void HandlePostPhysicsHandle(UGripMotionControllerComponent* GrippingController, FBPActorPhysicsHandleInformation* HandleInfo) override; + //virtual void HandlePrePhysicsHandle(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation &GripInfo, FBPActorPhysicsHandleInformation* HandleInfo, FTransform& KinPose) override; + + virtual void OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + virtual void OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; +}; diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/VRGripScriptBase.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/VRGripScriptBase.h new file mode 100644 index 0000000..8effe62 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/GripScripts/VRGripScriptBase.h @@ -0,0 +1,300 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +//#include "Engine/Engine.h" +#include "UObject/Object.h" +#include "VRBPDatatypes.h" +#include "Tickable.h" + +#include "VRGripScriptBase.generated.h" + +class UGripMotionControllerComponent; +class UVRGripInterface; +class UPrimitiveComponent; +class AActor; + + +UENUM(Blueprintable) +enum class EGSTransformOverrideType : uint8 +{ + /** Does not alter the world transform */ + None, + + /* Overrides the world transform */ + OverridesWorldTransform, + + /* Modifies the world transform*/ + ModifiesWorldTransform +}; + +UCLASS(NotBlueprintable, BlueprintType, EditInlineNew, DefaultToInstanced, Abstract, ClassGroup = (VRExpansionPlugin), HideCategories = DefaultSettings) +class VREXPANSIONPLUGIN_API UVRGripScriptBase : public UObject, public FTickableGameObject +{ + GENERATED_BODY() +public: + + UVRGripScriptBase(const FObjectInitializer& ObjectInitializer); + + // Gets the first grip script of the specified type in this object, do NOT call this on tick, save out and store the reference given + UFUNCTION(BlueprintCallable, Category = "VRGripScript|Functions", meta = (WorldContext = "WorldContextObject", bIgnoreSelf = "true", DisplayName = "GetGripScriptByClass", ExpandEnumAsExecs = "Result")) + static UVRGripScriptBase* GetGripScriptByClass(UObject* WorldContextObject, TSubclassOf GripScriptClass, EBPVRResultSwitch& Result); + + bool IsSupportedForNetworking() const override + { + return true; + //return bRequiresReplicationSupport || Super::IsSupportedForNetworking(); + } + // I don't need to do this, there should be no dynamic script spawning and they are all name stable by default + + // Returns if the script is currently active and should be used + bool IsScriptActive(); + + // Is currently active helper variable, returned from IsScriptActive() + UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "GSSettings") + bool bIsActive; + +private: + // If we should replicate, if false we will never be added to our parents list. + UPROPERTY(Replicated, EditDefaultsOnly, BlueprintReadOnly, Category = "GSSettings|Replication", meta = (AllowPrivateAccess = "true")) + bool bReplicates = false; +public: + + /** Enable or disable replication. This is the equivalent of RemoteRole for actors (only a bool is required for components) */ + UFUNCTION(BlueprintCallable, Category = "Components") + void SetIsReplicated(bool ShouldReplicate); + + /** Returns whether replication is enabled or not. */ + UFUNCTION(BlueprintCallable, Category = "Components") + bool GetIsReplicated() const + { + return bReplicates; + } + + // Replication Condition (If using subobject replication list) + UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "GSSettings|Replication") + TEnumAsByte ReplicationCondition = ELifetimeCondition::COND_None; + + // Returns if the script is going to modify the world transform of the grip + EGSTransformOverrideType GetWorldTransformOverrideType(); + + // Whether this script overrides or modifies the world transform + UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "GSSettings") + EGSTransformOverrideType WorldTransformOverrideType; + + // Returns if the script wants auto drop to be ignored + FORCEINLINE bool Wants_DenyAutoDrop() + { + return bDenyAutoDrop; + } + + // Returns if we want to deny auto dropping + UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "GSSettings") + bool bDenyAutoDrop; + + // Returns if the script wants to force a drop + FORCEINLINE bool Wants_ToForceDrop() + { + return bForceDrop; + } + + // Returns if we want to force a drop + UPROPERTY(BlueprintReadWrite, Category = "GSSettings") + bool bForceDrop; + + // Flags the grip to be dropped as soon as possible + UFUNCTION(BlueprintCallable, Category = "VRGripScript") + void ForceGripToDrop() + { + bForceDrop = true; + } + + // Returns if the script wants to deny late updates + FORCEINLINE bool Wants_DenyLateUpdates() + { + return bDenyLateUpdates; + } + + // Returns if we want to inject changes prior to the physics handle + UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "GSSettings") + bool bDenyLateUpdates; + + // Returns if the script wants auto drop to be ignored + FORCEINLINE bool InjectPrePhysicsHandle() + { + return bInjectPrePhysicsHandle; + } + + // Returns if we want to inject changes prior to the physics handle + UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "GSSettings") + bool bInjectPrePhysicsHandle; + + virtual void HandlePrePhysicsHandle(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation &GripInfo, FBPActorPhysicsHandleInformation * HandleInfo, FTransform & KinPose); + + // Returns if we want to inject changes after the physics handle + FORCEINLINE bool InjectPostPhysicsHandle() + { + return bInjectPostPhysicsHandle; + } + + // Returns if we want to inject changes after the physics handle + UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "GSSettings") + bool bInjectPostPhysicsHandle; + + virtual void HandlePostPhysicsHandle(UGripMotionControllerComponent* GrippingController, FBPActorPhysicsHandleInformation * HandleInfo); + + // Returns if the script is currently active and should be used + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripScript") + bool Wants_DenyTeleport(UGripMotionControllerComponent * Controller); + virtual bool Wants_DenyTeleport_Implementation(UGripMotionControllerComponent* Controller); + +#if UE_WITH_IRIS + /** Register all replication fragments */ + virtual void RegisterReplicationFragments(UE::Net::FFragmentRegistrationContext& Context, UE::Net::EFragmentRegistrationFlags RegistrationFlags) override; +#endif // UE_WITH_IRIS + + virtual void GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const override; + + // doesn't currently compile in editor builds, not sure why the linker is screwing up there but works elsewhere + //virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker); + virtual bool CallRemoteFunction(UFunction * Function, void * Parms, FOutParmRec * OutParms, FFrame * Stack) override; + virtual int32 GetFunctionCallspace(UFunction * Function, FFrame * Stack) override; + + // FTickableGameObject functions + + + // If true then this scrip can tick when bAllowticking is true + UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "TickSettings") + bool bCanEverTick; + + // If true and we bCanEverTick, then will fire off the tick function + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "TickSettings") + bool bAllowTicking; + + // Set whether the grip script can tick or not + UFUNCTION(BlueprintCallable, Category = "TickSettings") + void SetTickEnabled(bool bTickEnabled); + + /** + * Function called every frame on this GripScript. Override this function to implement custom logic to be executed every frame. + * Only executes if bCanEverTick is true and bAllowTicking is true + * + * @param DeltaTime - The time since the last tick. + */ + virtual void Tick(float DeltaTime) override; + virtual bool IsTickable() const override; + virtual UWorld* GetTickableGameObjectWorld() const override; + virtual bool IsTickableInEditor() const; + virtual bool IsTickableWhenPaused() const override; + virtual ETickableTickType GetTickableTickType() const; + virtual TStatId GetStatId() const override; + virtual UWorld* GetWorld() const override; + + // End tickable object information + + + // Returns the expected grip transform (relative * controller + addition) + UFUNCTION(BlueprintPure, Category = "VRGripScript") + FTransform GetGripTransform(const FBPActorGripInformation &Grip, const FTransform & ParentTransform); + + // Returns the current world transform of the owning object (or root comp of if it is an actor) + UFUNCTION(BlueprintPure, Category = "VRGripScript") + FTransform GetParentTransform(bool bGetWorldTransform = true, FName BoneName = NAME_None); + + // Returns the scene component of the parent, either being the parent itself or the root comp of it. + // Nullptr if there is no valid scene component + UFUNCTION(BlueprintCallable, Category = "VRGripScript") + USceneComponent* GetParentSceneComp(); + + // Returns the root body instance of the parent + FBodyInstance * GetParentBodyInstance(FName OptionalBoneName = NAME_None); + + // Returns the parent component or actor to this + UFUNCTION(BlueprintPure, Category = "VRGripScript") + UObject * GetParent(); + + // Returns the owning actor + UFUNCTION(BlueprintPure, Category = "VRGripScript") + AActor * GetOwner(); + + // If the owning actor has authority on this connection + UFUNCTION(BlueprintPure, Category = "VRGripScript") + bool HasAuthority(); + + // If the owning actor is on the server on this connection + UFUNCTION(BlueprintPure, Category = "VRGripScript") + bool IsServer(); + + virtual void BeginDestroy(); + void EndPlay(const EEndPlayReason::Type EndPlayReason); + + // Not all scripts will require this function, specific ones that use things like Lever logic however will. Best to call it. + // Grippables will automatically call this, however if you manually spawn a grip script during play or you make your own + // Interfaced grip object and give it grippables, YOU will be required to call this event on them. + UFUNCTION(BlueprintNativeEvent, Category = "VRGripScript") + void OnEndPlay(const EEndPlayReason::Type EndPlayReason); + virtual void OnEndPlay_Implementation(const EEndPlayReason::Type EndPlayReason); + + void BeginPlay(UObject * CallingOwner); + bool bAlreadyNotifiedPlay = false; + virtual void PostInitProperties() override; + + // Not all scripts will require this function, specific ones that use things like Lever logic however will. Best to call it. + // Grippables will automatically call this, however if you manually spawn a grip script during play or you make your own + // Interfaced grip object and give it grippables, YOU will be required to call this event on them. + UFUNCTION(BlueprintNativeEvent, Category = "VRGripScript") + void OnBeginPlay(UObject * CallingOwner); + virtual void OnBeginPlay_Implementation(UObject * CallingOwner); + + // Overrides or Modifies the world transform with this grip script + UFUNCTION(BlueprintNativeEvent, Category = "VRGripScript") + bool GetWorldTransform(UGripMotionControllerComponent * GrippingController, float DeltaTime, UPARAM(ref) FTransform & WorldTransform, const FTransform &ParentTransform, UPARAM(ref) FBPActorGripInformation &Grip, AActor * actor, UPrimitiveComponent * root, bool bRootHasInterface, bool bActorHasInterface, bool bIsForTeleport); + virtual bool GetWorldTransform_Implementation(UGripMotionControllerComponent * OwningController, float DeltaTime, FTransform & WorldTransform, const FTransform &ParentTransform, FBPActorGripInformation &Grip, AActor * actor, UPrimitiveComponent * root, bool bRootHasInterface, bool bActorHasInterface, bool bIsForTeleport); + + // Event triggered on the interfaced object when gripped + UFUNCTION(BlueprintNativeEvent, Category = "VRGripScript") + void OnGrip(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation); + virtual void OnGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation); + + // Event triggered on the interfaced object when grip is released + UFUNCTION(BlueprintNativeEvent, Category = "VRGripScript") + void OnGripRelease(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed = false); + virtual void OnGripRelease_Implementation(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed = false); + + // Event triggered on the interfaced object when secondary gripped + UFUNCTION(BlueprintNativeEvent, Category = "VRGripInterface") + void OnSecondaryGrip(UGripMotionControllerComponent * Controller, USceneComponent * SecondaryGripComponent, const FBPActorGripInformation & GripInformation); + virtual void OnSecondaryGrip_Implementation(UGripMotionControllerComponent * Controller, USceneComponent * SecondaryGripComponent, const FBPActorGripInformation & GripInformation); + + // Event triggered on the interfaced object when secondary grip is released + UFUNCTION(BlueprintNativeEvent, Category = "VRGripInterface") + void OnSecondaryGripRelease(UGripMotionControllerComponent * Controller, USceneComponent * ReleasingSecondaryGripComponent, const FBPActorGripInformation & GripInformation); + virtual void OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent * Controller, USceneComponent * ReleasingSecondaryGripComponent, const FBPActorGripInformation & GripInformation); + + + + virtual bool CallCorrect_GetWorldTransform(UGripMotionControllerComponent * OwningController, float DeltaTime, FTransform & WorldTransform, const FTransform &ParentTransform, FBPActorGripInformation &Grip, AActor * actor, UPrimitiveComponent * root, bool bRootHasInterface, bool bActorHasInterface, bool bIsForTeleport) + { + return GetWorldTransform_Implementation(OwningController, DeltaTime, WorldTransform, ParentTransform, Grip, actor, root, bRootHasInterface, bActorHasInterface, bIsForTeleport); + } +}; + + +UCLASS(Blueprintable, Abstract, ClassGroup = (VRExpansionPlugin), ShowCategories = DefaultSettings) +class VREXPANSIONPLUGIN_API UVRGripScriptBaseBP : public UVRGripScriptBase +{ + GENERATED_BODY() +public: + + virtual bool CallCorrect_GetWorldTransform(UGripMotionControllerComponent * OwningController, float DeltaTime, FTransform & WorldTransform, const FTransform &ParentTransform, FBPActorGripInformation &Grip, AActor * actor, UPrimitiveComponent * root, bool bRootHasInterface, bool bActorHasInterface, bool bIsForTeleport) override + { + return GetWorldTransform(OwningController, DeltaTime, WorldTransform, ParentTransform, Grip, actor, root, bRootHasInterface, bActorHasInterface, bIsForTeleport); + } + + virtual void Tick(float DeltaTime) override; + + /** Event called every frame if ticking is enabled */ + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Tick")) + void ReceiveTick(float DeltaSeconds); +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableActor.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableActor.h new file mode 100644 index 0000000..75df06f --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableActor.h @@ -0,0 +1,298 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" + +#include "GameFramework/Actor.h" +#include "VRBPDatatypes.h" +#include "VRGripInterface.h" +//#include "Engine/Engine.h" +#include "GameplayTagContainer.h" +#include "GameplayTagAssetInterface.h" +#include "Engine/ActorChannel.h" +#include "Grippables/GrippableDataTypes.h" +#include "Grippables/GrippablePhysicsReplication.h" +#include "GrippableActor.generated.h" + +class UGripMotionControllerComponent; +class UVRGripScriptBase; + +/** +* +*/ +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API AGrippableActor : public AActor, public IVRGripInterface, public IGameplayTagAssetInterface +{ + GENERATED_BODY() + +public: + AGrippableActor(const FObjectInitializer& ObjectInitializer); + + ~AGrippableActor(); + virtual void BeginPlay() override; + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + + UPROPERTY(Replicated, ReplicatedUsing = OnRep_AttachmentReplication) + FRepAttachmentWithWeld AttachmentWeldReplication; + + virtual void GatherCurrentMovement() override; + +protected: + UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface") + TArray> GripLogicScripts; + + // If true then the grip script array will be considered for replication, if false then it will not + // This is an optimization for when you have a lot of grip scripts in use, you can toggle this off in cases + // where the object will never have a replicating script + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + bool bReplicateGripScripts; +public: + + void SetReplicateGripScripts(bool NewReplicateGripScripts); + inline bool GetReplicateGripScripts() { return bReplicateGripScripts; }; + + // Get the grip script array, will automatically dirty it if they are replicated as it is assumed if you are directly accessing it you are altering it + TArray>& GetGripLogicScripts(); + + bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override; + virtual void GetSubobjectsWithStableNamesForNetworking(TArray& ObjList) override; + + // Sets the Deny Gripping variable on the FBPInterfaceSettings struct + UFUNCTION(BlueprintCallable, Category = "VRGripInterface") + void SetDenyGripping(bool bDenyGripping); + + // Sets the grip priority on the FBPInterfaceSettings struct + UFUNCTION(BlueprintCallable, Category = "VRGripInterface") + void SetGripPriority(int NewGripPriority); + + // Called when a object is gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnGripped; + + // Called when a object is dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnDropSignature OnDropped; + + // Called when an object we hold is secondary gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnSecondaryGripAdded; + + // Called when an object we hold is secondary dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnSecondaryGripRemoved; + + // ------------------------------------------------ + // Client Auth Throwing Data and functions + // ------------------------------------------------ + +protected: + // Replication settings for client auth throwing + // Must call MarkClientAuthReplicationDirty if setting the properties of it live + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication") + FVRClientAuthReplicationData ClientAuthReplicationData; +public: + + // If changing this in c++ it is using a getter to make sure it is dirtied + FVRClientAuthReplicationData& GetClientAuthReplicationData(FVRClientAuthReplicationData& ClientAuthData); + + + // Add this to client side physics replication (until coming to rest or timeout period is hit) + UFUNCTION(BlueprintCallable, Category = "Networking") + bool AddToClientReplicationBucket(); + + // Remove this from client side physics replication + UFUNCTION(BlueprintCallable, Category = "Networking") + bool RemoveFromClientReplicationBucket(); + + UFUNCTION() + bool PollReplicationEvent(); + + UFUNCTION(Category = "Networking") + void CeaseReplicationBlocking(); + + // Notify the server that we are no longer trying to run the throwing auth + UFUNCTION(Reliable, Server, WithValidation, Category = "Networking") + void Server_EndClientAuthReplication(); + + // Notify the server about a new movement rep + UFUNCTION(UnReliable, Server, WithValidation, Category = "Networking") + void Server_GetClientAuthReplication(const FRepMovementVR & newMovement); + + // Returns if this object is currently client auth throwing + UFUNCTION(BlueprintPure, Category = "Networking") + FORCEINLINE bool IsCurrentlyClientAuthThrowing() + { + return ClientAuthReplicationData.bIsCurrentlyClientAuth; + } + + // End client auth throwing data and functions // + + // ------------------------------------------------ + // Gameplay tag interface + // ------------------------------------------------ + + /** Overridden to return requirements tags */ + virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override + { + TagContainer = GameplayTags; + } + + protected: + + /** Tags that are set on this object */ + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") + FGameplayTagContainer GameplayTags; + + public: + FGameplayTagContainer& GetGameplayTags(); + + // End Gameplay Tag Interface + + virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; + + protected: + + // Skips the attachment replication if we are locally owned and our grip settings say that we are a client authed grip. + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication") + bool bAllowIgnoringAttachOnOwner; + public: + + void SetAllowIgnoringAttachOnOwner(bool bNewAllowIgnoringAttachOnOwner); + inline bool GetAllowIgnoringAttachOnOwner() { return bAllowIgnoringAttachOnOwner; }; + + // Should we skip attachment replication (vr settings say we are a client auth grip and our owner is locally controlled) + /*inline*/ bool ShouldWeSkipAttachmentReplication(bool bConsiderHeld = true) const; + + // Handle fixing some bugs and issues with ReplicateMovement being off + virtual void OnRep_AttachmentReplication() override; + virtual void OnRep_ReplicateMovement() override; + virtual void OnRep_ReplicatedMovement() override; + virtual void PostNetReceivePhysicState() override; + + // Debug printing of when the object is replication destroyed + /*virtual void OnSubobjectDestroyFromReplication(UObject *Subobject) override + { + Super::OnSubobjectDestroyFromReplication(Subobject); + + GEngine->AddOnScreenDebugMessage(-1, 15.f, FColor::Red, FString::Printf(TEXT("Killed Object On Actor: x: %s"), *Subobject->GetName())); + }*/ + + // This isn't called very many places but it does come up + virtual void MarkComponentsAsGarbage(bool bModify) override; + + /** Called right before being marked for destruction due to network replication */ + // Clean up our objects so that they aren't sitting around for GC + virtual void PreDestroyFromReplication() override; + + // On Destroy clean up our objects + virtual void BeginDestroy() override; + + protected: + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + bool bRepGripSettingsAndGameplayTags; + public: + + void SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags); + inline bool GetRepGripSettingsAndGameplayTags() { return bRepGripSettingsAndGameplayTags; }; + + protected: + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + FBPInterfaceProperties VRGripInterfaceSettings; + public: + + // Get VRGripInterfaceSettings, set MarkDirty if you intend to (or may) modify the values inside of it + FBPInterfaceProperties& GetVRGripInterfaceSettings(bool bMarkDirty); + + // Set up as deny instead of allow so that default allows for gripping + // The GripInitiator is not guaranteed to be valid, check it for validity + virtual bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override; + + // How an interfaced object behaves when teleporting + virtual EGripInterfaceTeleportBehavior TeleportBehavior_Implementation() override; + + // Should this object simulate on drop + virtual bool SimulateOnDrop_Implementation() override; + + // Grip type to use + virtual EGripCollisionType GetPrimaryGripType_Implementation(bool bIsSlot) override; + + // Secondary grip type + virtual ESecondaryGripType SecondaryGripType_Implementation() override; + + // Define which movement repliation setting to use + virtual EGripMovementReplicationSettings GripMovementReplicationType_Implementation() override; + + // Define the late update setting + virtual EGripLateUpdateSettings GripLateUpdateSetting_Implementation() override; + + // What grip stiffness and damping to use if using a physics constraint + virtual void GetGripStiffnessAndDamping_Implementation(float& GripStiffnessOut, float& GripDampingOut) override; + + // Get the advanced physics settings for this grip + virtual FBPAdvGripSettings AdvancedGripSettings_Implementation() override; + + // What distance to break a grip at (only relevent with physics enabled grips + virtual float GripBreakDistance_Implementation() override; + + // Get closest primary slot in range + virtual void ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool& bHadSlotInRange, FTransform& SlotWorldTransform, FName& SlotName, UGripMotionControllerComponent* CallingController = nullptr, FName OverridePrefix = NAME_None) override; + + // Check if an object allows multiple grips at one time + virtual bool AllowsMultipleGrips_Implementation() override; + + // Returns if the object is held and if so, which controllers are holding it + virtual void IsHeld_Implementation(TArray& HoldingControllers, bool& bIsHeld) override; + + // Sets is held, used by the plugin + virtual void SetHeld_Implementation(UGripMotionControllerComponent* HoldingController, uint8 GripID, bool bIsHeld) override; + + // Interface function used to throw the delegates that is invisible to blueprints so that it can't be overridden + virtual void Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Returns if the object wants to be socketed + virtual bool RequestsSocketing_Implementation(USceneComponent*& ParentToSocketTo, FName& OptionalSocketName, FTransform_NetQuantize& RelativeTransform) override; + + // Get grip scripts + virtual bool GetGripScripts_Implementation(TArray& ArrayReference) override; + + // Events // + + // Event triggered each tick on the interfaced object when gripped, can be used for custom movement or grip based logic + virtual void TickGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation, float DeltaTime) override; + + // Event triggered on the interfaced object when gripped + virtual void OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when grip is released + virtual void OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when child component is gripped + virtual void OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when child component is released + virtual void OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when secondary gripped + virtual void OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when secondary grip is released + virtual void OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Interaction Functions + + // Call to use an object + virtual void OnUsed_Implementation() override; + + // Call to stop using an object + virtual void OnEndUsed_Implementation() override; + + // Call to use an object + virtual void OnSecondaryUsed_Implementation() override; + + // Call to stop using an object + virtual void OnEndSecondaryUsed_Implementation() override; + + // Call to send an action event to the object + virtual void OnInput_Implementation(FKey Key, EInputEvent KeyEvent) override; +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableBoxComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableBoxComponent.h new file mode 100644 index 0000000..1b7b3b6 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableBoxComponent.h @@ -0,0 +1,225 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "VRBPDatatypes.h" +#include "VRGripInterface.h" +#include "GameplayTagContainer.h" +#include "Components/BoxComponent.h" +#include "GameplayTagAssetInterface.h" +#include "Engine/ActorChannel.h" +#include "GrippableBoxComponent.generated.h" + +class UVRGripScriptBase; +class UGripMotionControllerComponent; + +/** +* +*/ + +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UGrippableBoxComponent : public UBoxComponent, public IVRGripInterface, public IGameplayTagAssetInterface +{ + GENERATED_BODY() + +public: + UGrippableBoxComponent(const FObjectInitializer& ObjectInitializer); + + + ~UGrippableBoxComponent(); + virtual void BeginPlay() override; + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + +protected: + UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface") + TArray> GripLogicScripts; + + // If true then the grip script array will be considered for replication, if false then it will not + // This is an optimization for when you have a lot of grip scripts in use, you can toggle this off in cases + // where the object will never have a replicating script + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + bool bReplicateGripScripts; +public: + + void SetReplicateGripScripts(bool NewReplicateGripScripts); + inline bool GetReplicateGripScripts() { return bReplicateGripScripts; }; + + // Get the grip script array, will automatically dirty it if they are replicated as it is assumed if you are directly accessing it you are altering it + TArray>& GetGripLogicScripts(); + + bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override; + + // Sets the Deny Gripping variable on the FBPInterfaceSettings struct + UFUNCTION(BlueprintCallable, Category = "VRGripInterface") + void SetDenyGripping(bool bDenyGripping); + + // Sets the grip priority on the FBPInterfaceSettings struct + UFUNCTION(BlueprintCallable, Category = "VRGripInterface") + void SetGripPriority(int NewGripPriority); + + // Called when a object is gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnGripped; + + // Called when a object is dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnDropSignature OnDropped; + + // Called when an object we hold is secondary gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnSecondaryGripAdded; + + // Called when an object we hold is secondary dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnSecondaryGripRemoved; + + // ------------------------------------------------ + // Gameplay tag interface + // ------------------------------------------------ + + /** Overridden to return requirements tags */ + virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override + { + TagContainer = GameplayTags; + } + +protected: + /** Tags that are set on this object */ + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") + FGameplayTagContainer GameplayTags; + +public: + FGameplayTagContainer& GetGameplayTags(); + + // End Gameplay Tag Interface + + virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; + + + /** Called right before being marked for destruction due to network replication */ + // Clean up our objects so that they aren't sitting around for GC + virtual void PreDestroyFromReplication() override; + + virtual void GetSubobjectsWithStableNamesForNetworking(TArray &ObjList) override; + + // This one is for components to clean up + virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override; + +protected: + // Requires bReplicates to be true for the component + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") + bool bRepGripSettingsAndGameplayTags; + + // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") + bool bReplicateMovement; + + bool bOriginalReplicatesMovement; + + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + FBPInterfaceProperties VRGripInterfaceSettings; +public: + + void SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags); + inline bool GetRepGripSettingsAndGameplayTags() { return bRepGripSettingsAndGameplayTags; }; + + // Get VRGripInterfaceSettings, set MarkDirty if you intend to (or may) modify the values inside of it + FBPInterfaceProperties& GetVRGripInterfaceSettings(bool bMarkDirty); + + void SetReplicateMovement(bool bNewReplicateMovement); + inline bool GetReplicateMovement() { return bReplicateMovement; }; + + // Set up as deny instead of allow so that default allows for gripping + // The GripInitiator is not guaranteed to be valid, check it for validity + virtual bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override; + + // How an interfaced object behaves when teleporting + virtual EGripInterfaceTeleportBehavior TeleportBehavior_Implementation() override; + + // Should this object simulate on drop + virtual bool SimulateOnDrop_Implementation() override; + + // Grip type to use + virtual EGripCollisionType GetPrimaryGripType_Implementation(bool bIsSlot) override; + + // Secondary grip type + virtual ESecondaryGripType SecondaryGripType_Implementation() override; + + // Define which movement repliation setting to use + virtual EGripMovementReplicationSettings GripMovementReplicationType_Implementation() override; + + // Define the late update setting + virtual EGripLateUpdateSettings GripLateUpdateSetting_Implementation() override; + + // What grip stiffness and damping to use if using a physics constraint + virtual void GetGripStiffnessAndDamping_Implementation(float& GripStiffnessOut, float& GripDampingOut) override; + + // Get the advanced physics settings for this grip + virtual FBPAdvGripSettings AdvancedGripSettings_Implementation() override; + + // What distance to break a grip at (only relevent with physics enabled grips + virtual float GripBreakDistance_Implementation() override; + + // Get closest primary slot in range + virtual void ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool& bHadSlotInRange, FTransform& SlotWorldTransform, FName& SlotName, UGripMotionControllerComponent* CallingController = nullptr, FName OverridePrefix = NAME_None) override; + + // Check if an object allows multiple grips at one time + virtual bool AllowsMultipleGrips_Implementation() override; + + // Returns if the object is held and if so, which controllers are holding it + virtual void IsHeld_Implementation(TArray& HoldingControllers, bool& bIsHeld) override; + + // Sets is held, used by the plugin + virtual void SetHeld_Implementation(UGripMotionControllerComponent* HoldingController, uint8 GripID, bool bIsHeld) override; + + // Interface function used to throw the delegates that is invisible to blueprints so that it can't be overridden + virtual void Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Returns if the object wants to be socketed + virtual bool RequestsSocketing_Implementation(USceneComponent*& ParentToSocketTo, FName& OptionalSocketName, FTransform_NetQuantize& RelativeTransform) override; + + // Get grip scripts + virtual bool GetGripScripts_Implementation(TArray& ArrayReference) override; + + // Events // + + // Event triggered each tick on the interfaced object when gripped, can be used for custom movement or grip based logic + virtual void TickGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation, float DeltaTime) override; + + // Event triggered on the interfaced object when gripped + virtual void OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when grip is released + virtual void OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when child component is gripped + virtual void OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when child component is released + virtual void OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when secondary gripped + virtual void OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when secondary grip is released + virtual void OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Interaction Functions + + // Call to use an object + virtual void OnUsed_Implementation() override; + + // Call to stop using an object + virtual void OnEndUsed_Implementation() override; + + // Call to use an object + virtual void OnSecondaryUsed_Implementation() override; + + // Call to stop using an object + virtual void OnEndSecondaryUsed_Implementation() override; + + // Call to send an action event to the object + virtual void OnInput_Implementation(FKey Key, EInputEvent KeyEvent) override; + +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableCapsuleComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableCapsuleComponent.h new file mode 100644 index 0000000..b6b9969 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableCapsuleComponent.h @@ -0,0 +1,224 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "VRBPDatatypes.h" +#include "VRGripInterface.h" +#include "GameplayTagContainer.h" +#include "GameplayTagAssetInterface.h" +#include "Components/CapsuleComponent.h" +#include "Engine/ActorChannel.h" +#include "GrippableCapsuleComponent.generated.h" + +class UVRGripScriptBase; +class UGripMotionControllerComponent; + +/** +* +*/ + +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent, ChildCanTick), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UGrippableCapsuleComponent : public UCapsuleComponent, public IVRGripInterface, public IGameplayTagAssetInterface +{ + GENERATED_BODY() + +public: + UGrippableCapsuleComponent(const FObjectInitializer& ObjectInitializer); + + + ~UGrippableCapsuleComponent(); + virtual void BeginPlay() override; + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + +protected: + UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface") + TArray> GripLogicScripts; + + // If true then the grip script array will be considered for replication, if false then it will not + // This is an optimization for when you have a lot of grip scripts in use, you can toggle this off in cases + // where the object will never have a replicating script + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + bool bReplicateGripScripts; + +public: + + void SetReplicateGripScripts(bool NewReplicateGripScripts); + inline bool GetReplicateGripScripts() { return bReplicateGripScripts; }; + + // Get the grip script array, will automatically dirty it if they are replicated as it is assumed if you are directly accessing it you are altering it + TArray>& GetGripLogicScripts(); + + bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override; + + // Sets the Deny Gripping variable on the FBPInterfaceSettings struct + UFUNCTION(BlueprintCallable, Category = "VRGripInterface") + void SetDenyGripping(bool bDenyGripping); + + // Sets the grip priority on the FBPInterfaceSettings struct + UFUNCTION(BlueprintCallable, Category = "VRGripInterface") + void SetGripPriority(int NewGripPriority); + + // Called when a object is gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnGripped; + + // Called when a object is dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnDropSignature OnDropped; + + // Called when an object we hold is secondary gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnSecondaryGripAdded; + + // Called when an object we hold is secondary dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnSecondaryGripRemoved; + + // Gameplay tag interface + // ------------------------------------------------ + + /** Overridden to return requirements tags */ + virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override + { + TagContainer = GameplayTags; + } + +protected: + /** Tags that are set on this object */ + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") + FGameplayTagContainer GameplayTags; +public: + FGameplayTagContainer& GetGameplayTags(); + + // End Gameplay Tag Interface + + virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; + + /** Called right before being marked for destruction due to network replication */ + // Clean up our objects so that they aren't sitting around for GC + virtual void PreDestroyFromReplication() override; + + virtual void GetSubobjectsWithStableNamesForNetworking(TArray &ObjList) override; + + // This one is for components to clean up + virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override; + +protected: + + // Requires bReplicates to be true for the component + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") + bool bRepGripSettingsAndGameplayTags; + + // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") + bool bReplicateMovement; + + bool bOriginalReplicatesMovement; + + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + FBPInterfaceProperties VRGripInterfaceSettings; + +public: + + void SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags); + inline bool GetRepGripSettingsAndGameplayTags() { return bRepGripSettingsAndGameplayTags; }; + + // Get VRGripInterfaceSettings, set MarkDirty if you intend to (or may) modify the values inside of it + FBPInterfaceProperties& GetVRGripInterfaceSettings(bool bMarkDirty); + + void SetReplicateMovement(bool bNewReplicateMovement); + inline bool GetReplicateMovement() { return bReplicateMovement; }; + + // Set up as deny instead of allow so that default allows for gripping + // The GripInitiator is not guaranteed to be valid, check it for validity + virtual bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override; + + // How an interfaced object behaves when teleporting + virtual EGripInterfaceTeleportBehavior TeleportBehavior_Implementation() override; + + // Should this object simulate on drop + virtual bool SimulateOnDrop_Implementation() override; + + // Grip type to use + virtual EGripCollisionType GetPrimaryGripType_Implementation(bool bIsSlot) override; + + // Secondary grip type + virtual ESecondaryGripType SecondaryGripType_Implementation() override; + + // Define which movement repliation setting to use + virtual EGripMovementReplicationSettings GripMovementReplicationType_Implementation() override; + + // Define the late update setting + virtual EGripLateUpdateSettings GripLateUpdateSetting_Implementation() override; + + // What grip stiffness and damping to use if using a physics constraint + virtual void GetGripStiffnessAndDamping_Implementation(float& GripStiffnessOut, float& GripDampingOut) override; + + // Get the advanced physics settings for this grip + virtual FBPAdvGripSettings AdvancedGripSettings_Implementation() override; + + // What distance to break a grip at (only relevent with physics enabled grips + virtual float GripBreakDistance_Implementation() override; + + // Get closest primary slot in range + virtual void ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool& bHadSlotInRange, FTransform& SlotWorldTransform, FName& SlotName, UGripMotionControllerComponent* CallingController = nullptr, FName OverridePrefix = NAME_None) override; + + // Check if an object allows multiple grips at one time + virtual bool AllowsMultipleGrips_Implementation() override; + + // Returns if the object is held and if so, which controllers are holding it + virtual void IsHeld_Implementation(TArray& HoldingControllers, bool& bIsHeld) override; + + // Sets is held, used by the plugin + virtual void SetHeld_Implementation(UGripMotionControllerComponent* HoldingController, uint8 GripID, bool bIsHeld) override; + + // Interface function used to throw the delegates that is invisible to blueprints so that it can't be overridden + virtual void Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Returns if the object wants to be socketed + virtual bool RequestsSocketing_Implementation(USceneComponent*& ParentToSocketTo, FName& OptionalSocketName, FTransform_NetQuantize& RelativeTransform) override; + + // Get grip scripts + virtual bool GetGripScripts_Implementation(TArray& ArrayReference) override; + + // Events // + + // Event triggered each tick on the interfaced object when gripped, can be used for custom movement or grip based logic + virtual void TickGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation, float DeltaTime) override; + + // Event triggered on the interfaced object when gripped + virtual void OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when grip is released + virtual void OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when child component is gripped + virtual void OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when child component is released + virtual void OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when secondary gripped + virtual void OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when secondary grip is released + virtual void OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Interaction Functions + + // Call to use an object + virtual void OnUsed_Implementation() override; + + // Call to stop using an object + virtual void OnEndUsed_Implementation() override; + + // Call to use an object + virtual void OnSecondaryUsed_Implementation() override; + + // Call to stop using an object + virtual void OnEndSecondaryUsed_Implementation() override; + + // Call to send an action event to the object + virtual void OnInput_Implementation(FKey Key, EInputEvent KeyEvent) override; +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableCharacter.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableCharacter.h new file mode 100644 index 0000000..68aaf3b --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableCharacter.h @@ -0,0 +1,28 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "GameFramework/Character.h" +#include "GrippableCharacter.generated.h" + +class UGrippableSkeletalMeshComponent; + +UCLASS() +class VREXPANSIONPLUGIN_API AGrippableCharacter : public ACharacter +{ + GENERATED_BODY() + +public: + AGrippableCharacter(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); + + // A reference to the grippable character that can be used instead of casting the root, BP doesn't like the class override. + UPROPERTY(Category = GrippableCharacter, VisibleAnywhere, Transient, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) + TObjectPtr GrippableMeshReference; + + // A Custom bone to use on the character mesh as the originator for the perception systems sight sense + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AI") + FName ViewOriginationSocket; + + virtual void GetActorEyesViewPoint(FVector& Location, FRotator& Rotation) const override; + +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableDataTypes.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableDataTypes.h new file mode 100644 index 0000000..53d3216 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableDataTypes.h @@ -0,0 +1,33 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +//#include "Engine/EngineTypes.h" +#include "Engine/ReplicatedState.h" +#include "GrippableDataTypes.generated.h" + +// A version of the attachment structure that include welding data +USTRUCT() +struct VREXPANSIONPLUGIN_API FRepAttachmentWithWeld : public FRepAttachment +{ +public: + GENERATED_BODY() + + // Add in the is welded property + UPROPERTY() + bool bIsWelded; + + bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess); + + FRepAttachmentWithWeld(); +}; + +template<> +struct TStructOpsTypeTraits< FRepAttachmentWithWeld > : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithNetSerializer = true//, + //WithNetSharedSerialization = true, + }; +}; diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippablePhysicsReplication.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippablePhysicsReplication.h new file mode 100644 index 0000000..cfb8db2 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippablePhysicsReplication.h @@ -0,0 +1,187 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Physics/PhysicsInterfaceUtils.h" +#include "PhysicsReplication.h" + +#include "Engine/ReplicatedState.h" +#include "PhysicsReplicationInterface.h" +#include "Physics/PhysicsInterfaceDeclares.h" +#include "PhysicsProxy/SingleParticlePhysicsProxyFwd.h" +#include "Chaos/PhysicsObject.h" +#include "Chaos/SimCallbackObject.h" +#include "Physics/NetworkPhysicsSettingsComponent.h" + + +#include "GrippablePhysicsReplication.generated.h" +//#include "GrippablePhysicsReplication.generated.h" + + +//DECLARE_DYNAMIC_MULTICAST_DELEGATE(FVRPhysicsReplicationDelegate, void, Return); + +/*static TAutoConsoleVariable CVarEnableCustomVRPhysicsReplication( + TEXT("vr.VRExpansion.EnableCustomVRPhysicsReplication"), + 0, + TEXT("Enable valves input controller that overrides legacy input.\n") + TEXT(" 0: use the engines default input mapping (default), will also be default if vr.SteamVR.EnableVRInput is enabled\n") + TEXT(" 1: use the valve input controller. You will have to define input bindings for the controllers you want to support."), + ECVF_ReadOnly);*/ + +//#if PHYSICS_INTERFACE_PHYSX +//struct FAsyncPhysicsRepCallbackDataVR; +//class FPhysicsReplicationAsyncCallbackVR; + +#pragma region FPhysicsReplicationAsync + +class FPhysicsReplicationAsyncVR : public Chaos::TSimCallbackObject< + FPhysicsReplicationAsyncInput, + Chaos::FSimCallbackNoOutput, + Chaos::ESimCallbackOptions::Presimulate | Chaos::ESimCallbackOptions::PhysicsObjectUnregister> +{ + virtual FName GetFNameForStatId() const override; + virtual void OnPostInitialize_Internal() override; + virtual void OnPreSimulate_Internal() override; + virtual void OnPhysicsObjectUnregistered_Internal(Chaos::FConstPhysicsObjectHandle PhysicsObject) override; + + virtual void ApplyTargetStatesAsync(const float DeltaSeconds, const FPhysicsRepErrorCorrectionData& ErrorCorrection, const TArray& TargetStates); + + // Replication functions + virtual void DefaultReplication_DEPRECATED(Chaos::FRigidBodyHandle_Internal* Handle, const FPhysicsRepAsyncInputData& State, const float DeltaSeconds, const FPhysicsRepErrorCorrectionData& ErrorCorrection); + virtual bool DefaultReplication(Chaos::FPBDRigidParticleHandle* Handle, FReplicatedPhysicsTargetAsync& Target, const float DeltaSeconds); + virtual bool PredictiveInterpolation(Chaos::FPBDRigidParticleHandle* Handle, FReplicatedPhysicsTargetAsync& Target, const float DeltaSeconds); + virtual bool ResimulationReplication(Chaos::FPBDRigidParticleHandle* Handle, FReplicatedPhysicsTargetAsync& Target, const float DeltaSeconds); + +public: + virtual void RegisterSettings(Chaos::FConstPhysicsObjectHandle PhysicsObject, FNetworkPhysicsSettingsAsync InSettings); + +private: + float LatencyOneWay; + FRigidBodyErrorCorrection ErrorCorrectionDefault; + FNetworkPhysicsSettingsAsync SettingsCurrent; + FNetworkPhysicsSettingsAsync SettingsDefault; + TMap ObjectToTarget; + TMap ObjectToSettings; + TArray ParticlesInResimIslands; + +private: + void UpdateAsyncTarget(const FPhysicsRepAsyncInputData& Input, Chaos::FPBDRigidsSolver* RigidsSolver); + void UpdateRewindDataTarget(const FPhysicsRepAsyncInputData& Input); + void CacheResimInteractions(); + // Sets SettingsCurrent to either the objects custom settings or to the default settings + void FetchObjectSettings(Chaos::FConstPhysicsObjectHandle PhysicsObject); + static void ExtrapolateTarget(FReplicatedPhysicsTargetAsync& Target, const int32 ExtrapolateFrames, const float DeltaSeconds); + +public: + void Setup(FRigidBodyErrorCorrection ErrorCorrection) + { + ErrorCorrectionDefault = ErrorCorrection; + } +}; + +#pragma endregion // FPhysicsReplicationAsync + +class FPhysicsReplicationVR : public FPhysicsReplication +{ +public: + + FPhysScene* PhysSceneVR; + + FPhysicsReplicationVR(FPhysScene* PhysScene); + ~FPhysicsReplicationVR(); + static bool IsInitialized(); + + virtual void OnTick(float DeltaSeconds, TMap, FReplicatedPhysicsTarget>& ComponentsToTargets) override; + + virtual bool ApplyRigidBodyState(float DeltaSeconds, FBodyInstance* BI, FReplicatedPhysicsTarget& PhysicsTarget, const FRigidBodyErrorCorrection& ErrorCorrection, const float PingSecondsOneWay, int32 LocalFrame, int32 NumPredictedFrames) override; + virtual bool ApplyRigidBodyState(float DeltaSeconds, FBodyInstance* BI, FReplicatedPhysicsTarget& PhysicsTarget, const FRigidBodyErrorCorrection& ErrorCorrection, const float PingSecondsOneWay, bool* bDidHardSnap = nullptr) override; + + void SetReplicatedTargetVR(Chaos::FConstPhysicsObjectHandle PhysicsObject, const FRigidBodyState& ReplicatedTarget, int32 ServerFrame, EPhysicsReplicationMode ReplicationMode = EPhysicsReplicationMode::Default); + + + virtual void RemoveReplicatedTarget(UPrimitiveComponent* Component) override; + + TArray ReplicatedTargetsQueueVR; + FPhysicsReplicationAsyncVR* PhysicsReplicationAsyncVR; + FPhysicsReplicationAsyncInput* AsyncInputVR; //async data being written into before we push into callback + + void PrepareAsyncData_ExternalVR(const FRigidBodyErrorCorrection& ErrorCorrection); //prepare async data for writing. Call on external thread (i.e. game thread) +}; + + +class IPhysicsReplicationFactoryVR : public IPhysicsReplicationFactory +{ +public: + + virtual TUniquePtr CreatePhysicsReplication(FPhysScene* OwningPhysScene) override + { + return TUniquePtr(new FPhysicsReplicationVR(OwningPhysScene)); + } + + /*virtual FPhysicsReplication* Create(FPhysScene* OwningPhysScene) + { + return new FPhysicsReplicationVR(OwningPhysScene); + } + + virtual void Destroy(FPhysicsReplication* PhysicsReplication) + { + if (PhysicsReplication) + delete PhysicsReplication; + }*/ +}; + +//#endif + +USTRUCT() +struct VREXPANSIONPLUGIN_API FRepMovementVR : public FRepMovement +{ + GENERATED_USTRUCT_BODY() +public: + + FRepMovementVR(); + FRepMovementVR(FRepMovement& other); + void CopyTo(FRepMovement& other) const; + bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess); + bool GatherActorsMovement(AActor* OwningActor); +}; + +template<> +struct TStructOpsTypeTraits : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithNetSerializer = true, + WithNetSharedSerialization = true, + }; +}; + +USTRUCT(BlueprintType) +struct VREXPANSIONPLUGIN_API FVRClientAuthReplicationData +{ + GENERATED_BODY() +public: + + // If True and we are using a client auth grip type then we will replicate our throws on release + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRReplication") + bool bUseClientAuthThrowing; + + // Rate that we will be sending throwing events to the server, not replicated, only serialized + UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadOnly, Category = "VRReplication", meta = (ClampMin = "0", UIMin = "0", ClampMax = "100", UIMax = "100")) + int32 UpdateRate; + + FTimerHandle ResetReplicationHandle; + FTransform LastActorTransform; + float TimeAtInitialThrow; + bool bIsCurrentlyClientAuth; + + FVRClientAuthReplicationData() : + bUseClientAuthThrowing(false), + UpdateRate(30), + LastActorTransform(FTransform::Identity), + TimeAtInitialThrow(0.0f), + bIsCurrentlyClientAuth(false) + { + + } +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableSkeletalMeshActor.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableSkeletalMeshActor.h new file mode 100644 index 0000000..85e87a6 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableSkeletalMeshActor.h @@ -0,0 +1,322 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +//#include "Engine/Engine.h" +#include "VRBPDatatypes.h" +#include "VRGripInterface.h" +#include "Animation/SkeletalMeshActor.h" +#include "Components/SkeletalMeshComponent.h" +#include "GameplayTagContainer.h" +#include "GameplayTagAssetInterface.h" +#include "Engine/ActorChannel.h" +#include "Grippables/GrippableDataTypes.h" +#include "Grippables/GrippablePhysicsReplication.h" +#include "GrippableSkeletalMeshActor.generated.h" + +class UGripMotionControllerComponent; +class UVRGripScriptBase; + +/** +* A component specifically for being able to turn off movement replication in the component at will +* Has the upside of also being a blueprintable base since UE4 doesn't allow that with std ones +*/ +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent, ChildCanTick), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UOptionalRepSkeletalMeshComponent : public USkeletalMeshComponent +{ + GENERATED_BODY() + +public: + UOptionalRepSkeletalMeshComponent(const FObjectInitializer& ObjectInitializer); + +protected: + // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Component Replication") + bool bReplicateMovement; +public: + bool GetReplicateMovement() { return bReplicateMovement; } + void SetReplicateMovement(bool bNewReplicateMovement); + + virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override; + + // Weld Fix until epic fixes it #TODO: check back in on this and remove and the asset include when epic fixes it + virtual void GetWeldedBodies(TArray& OutWeldedBodies, TArray& OutLabels, bool bIncludingAutoWeld) override; + virtual FBodyInstance* GetBodyInstance(FName BoneName = NAME_None, bool bGetWelded = true, int32 Index = INDEX_NONE) const override; +}; + +/** +* +*/ +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent, ChildCanTick), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API AGrippableSkeletalMeshActor : public ASkeletalMeshActor, public IVRGripInterface, public IGameplayTagAssetInterface +{ + GENERATED_BODY() + +public: + AGrippableSkeletalMeshActor(const FObjectInitializer& ObjectInitializer); + + + ~AGrippableSkeletalMeshActor(); + virtual void BeginPlay() override; + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + + UPROPERTY(Replicated, ReplicatedUsing = OnRep_AttachmentReplication) + FRepAttachmentWithWeld AttachmentWeldReplication; + + virtual void GatherCurrentMovement() override; + +protected: + UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface") + TArray> GripLogicScripts; + + // If true then the grip script array will be considered for replication, if false then it will not + // This is an optimization for when you have a lot of grip scripts in use, you can toggle this off in cases + // where the object will never have a replicating script + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + bool bReplicateGripScripts; +public: + + void SetReplicateGripScripts(bool NewReplicateGripScripts); + inline bool GetReplicateGripScripts() { return bReplicateGripScripts; }; + + // Get the grip script array, will automatically dirty it if they are replicated as it is assumed if you are directly accessing it you are altering it + TArray>& GetGripLogicScripts(); + + bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch* Bunch, FReplicationFlags* RepFlags) override; + virtual void GetSubobjectsWithStableNamesForNetworking(TArray& ObjList) override; + + // Sets the Deny Gripping variable on the FBPInterfaceSettings struct + UFUNCTION(BlueprintCallable, Category = "VRGripInterface") + void SetDenyGripping(bool bDenyGripping); + + // Sets the grip priority on the FBPInterfaceSettings struct + UFUNCTION(BlueprintCallable, Category = "VRGripInterface") + void SetGripPriority(int NewGripPriority); + + // Called when a object is gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnGripped; + + // Called when a object is dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnDropSignature OnDropped; + + // Called when an object we hold is secondary gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnSecondaryGripAdded; + + // Called when an object we hold is secondary dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnSecondaryGripRemoved; + + // ------------------------------------------------ + // Client Auth Throwing Data and functions + // ------------------------------------------------ + +protected: + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication") + FVRClientAuthReplicationData ClientAuthReplicationData; +public: + // If changing this in c++ it is using a getter to make sure it is dirtied + FVRClientAuthReplicationData& GetClientAuthReplicationData(FVRClientAuthReplicationData& ClientAuthData); + + // Add this to client side physics replication (until coming to rest or timeout period is hit) + UFUNCTION(BlueprintCallable, Category = "Networking") + bool AddToClientReplicationBucket(); + + // Remove this from client side physics replication + UFUNCTION(BlueprintCallable, Category = "Networking") + bool RemoveFromClientReplicationBucket(); + + UFUNCTION() + bool PollReplicationEvent(); + + UFUNCTION(Category = "Networking") + void CeaseReplicationBlocking(); + + // Notify the server that we are no longer trying to run the throwing auth + UFUNCTION(Reliable, Server, WithValidation, Category = "Networking") + void Server_EndClientAuthReplication(); + + // Notify the server about a new movement rep + UFUNCTION(UnReliable, Server, WithValidation, Category = "Networking") + void Server_GetClientAuthReplication(const FRepMovementVR& newMovement); + + // Returns if this object is currently client auth throwing + UFUNCTION(BlueprintPure, Category = "Networking") + FORCEINLINE bool IsCurrentlyClientAuthThrowing() + { + return ClientAuthReplicationData.bIsCurrentlyClientAuth; + } + + // End client auth throwing data and functions // + + // ------------------------------------------------ + // Gameplay tag interface + // ------------------------------------------------ + + /** Overridden to return requirements tags */ + virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override + { + TagContainer = GameplayTags; + } + +protected: + + /** Tags that are set on this object */ + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") + FGameplayTagContainer GameplayTags; + +public: + FGameplayTagContainer& GetGameplayTags(); + + // End Gameplay Tag Interface + + virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override; + +protected: + // Skips the attachment replication if we are locally owned and our grip settings say that we are a client authed grip. + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication") + bool bAllowIgnoringAttachOnOwner; + +public: + + void SetAllowIgnoringAttachOnOwner(bool bNewAllowIgnoringAttachOnOwner); + inline bool GetAllowIgnoringAttachOnOwner() { return bAllowIgnoringAttachOnOwner; }; + + // Should we skip attachment replication (vr settings say we are a client auth grip and our owner is locally controlled) + /*inline*/ bool ShouldWeSkipAttachmentReplication(bool bConsiderHeld = true) const; + + // Fix bugs with replication and bReplicateMovement + virtual void OnRep_AttachmentReplication() override; + virtual void OnRep_ReplicateMovement() override; + virtual void OnRep_ReplicatedMovement() override; + virtual void PostNetReceivePhysicState() override; + + // Debug printing of when the object is replication destroyed + /*virtual void OnSubobjectDestroyFromReplication(UObject *Subobject) override + { + Super::OnSubobjectDestroyFromReplication(Subobject); + + GEngine->AddOnScreenDebugMessage(-1, 15.f, FColor::Red, FString::Printf(TEXT("Killed Object On Actor: x: %s"), *Subobject->GetName())); + }*/ + + // This isn't called very many places but it does come up + virtual void MarkComponentsAsGarbage(bool bModify) override; + + /** Called right before being marked for destruction due to network replication */ + // Clean up our objects so that they aren't sitting around for GC + virtual void PreDestroyFromReplication() override; + + // On Destroy clean up our objects + virtual void BeginDestroy() override; + +protected: + + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + bool bRepGripSettingsAndGameplayTags; + + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + FBPInterfaceProperties VRGripInterfaceSettings; + +public: + + void SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags); + inline bool GetRepGripSettingsAndGameplayTags() { return bRepGripSettingsAndGameplayTags; }; + + // Get VRGripInterfaceSettings, set MarkDirty if you intend to (or may) modify the values inside of it + FBPInterfaceProperties& GetVRGripInterfaceSettings(bool bMarkDirty); + + // Set up as deny instead of allow so that default allows for gripping + // The GripInitiator is not guaranteed to be valid, check it for validity + virtual bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override; + + // How an interfaced object behaves when teleporting + virtual EGripInterfaceTeleportBehavior TeleportBehavior_Implementation() override; + + // Should this object simulate on drop + virtual bool SimulateOnDrop_Implementation() override; + + // Grip type to use + virtual EGripCollisionType GetPrimaryGripType_Implementation(bool bIsSlot) override; + + // Secondary grip type + virtual ESecondaryGripType SecondaryGripType_Implementation() override; + + // Define which movement repliation setting to use + virtual EGripMovementReplicationSettings GripMovementReplicationType_Implementation() override; + + // Define the late update setting + virtual EGripLateUpdateSettings GripLateUpdateSetting_Implementation() override; + + // What grip stiffness and damping to use if using a physics constraint + virtual void GetGripStiffnessAndDamping_Implementation(float& GripStiffnessOut, float& GripDampingOut) override; + + // Get the advanced physics settings for this grip + virtual FBPAdvGripSettings AdvancedGripSettings_Implementation() override; + + // What distance to break a grip at (only relevent with physics enabled grips + virtual float GripBreakDistance_Implementation() override; + + // Get closest primary slot in range + virtual void ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool& bHadSlotInRange, FTransform& SlotWorldTransform, FName& SlotName, UGripMotionControllerComponent* CallingController = nullptr, FName OverridePrefix = NAME_None) override; + + // Check if an object allows multiple grips at one time + virtual bool AllowsMultipleGrips_Implementation() override; + + // Returns if the object is held and if so, which controllers are holding it + virtual void IsHeld_Implementation(TArray& HoldingControllers, bool& bIsHeld) override; + + // Sets is held, used by the plugin + virtual void SetHeld_Implementation(UGripMotionControllerComponent* HoldingController, uint8 GripID, bool bIsHeld) override; + + // Interface function used to throw the delegates that is invisible to blueprints so that it can't be overridden + virtual void Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Returns if the object wants to be socketed + virtual bool RequestsSocketing_Implementation(USceneComponent*& ParentToSocketTo, FName& OptionalSocketName, FTransform_NetQuantize& RelativeTransform) override; + + // Get grip scripts + virtual bool GetGripScripts_Implementation(TArray& ArrayReference) override; + + // Events // + + // Event triggered each tick on the interfaced object when gripped, can be used for custom movement or grip based logic + virtual void TickGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation, float DeltaTime) override; + + // Event triggered on the interfaced object when gripped + virtual void OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when grip is released + virtual void OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when child component is gripped + virtual void OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when child component is released + virtual void OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when secondary gripped + virtual void OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when secondary grip is released + virtual void OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Interaction Functions + + // Call to use an object + virtual void OnUsed_Implementation() override; + + // Call to stop using an object + virtual void OnEndUsed_Implementation() override; + + // Call to use an object + virtual void OnSecondaryUsed_Implementation() override; + + // Call to stop using an object + virtual void OnEndSecondaryUsed_Implementation() override; + + // Call to send an action event to the object + virtual void OnInput_Implementation(FKey Key, EInputEvent KeyEvent) override; +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableSkeletalMeshComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableSkeletalMeshComponent.h new file mode 100644 index 0000000..2aec546 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableSkeletalMeshComponent.h @@ -0,0 +1,228 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "VRBPDatatypes.h" +#include "VRGripInterface.h" +#include "GameplayTagContainer.h" +#include "GameplayTagAssetInterface.h" +#include "Components/SkeletalMeshComponent.h" +#include "Engine/ActorChannel.h" +#include "GrippableSkeletalMeshComponent.generated.h" + +class UVRGripScriptBase; +class UGripMotionControllerComponent; + +/** +* +*/ + +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent, ChildCanTick), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UGrippableSkeletalMeshComponent : public USkeletalMeshComponent, public IVRGripInterface, public IGameplayTagAssetInterface +{ + GENERATED_BODY() + +public: + UGrippableSkeletalMeshComponent(const FObjectInitializer& ObjectInitializer); + + + ~UGrippableSkeletalMeshComponent(); + virtual void BeginPlay() override; + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + + // Weld Fix until epic fixes it #TODO: check back in on this and remove and the asset include when epic fixes it + virtual void GetWeldedBodies(TArray& OutWeldedBodies, TArray& OutLabels, bool bIncludingAutoWeld) override; + virtual FBodyInstance* GetBodyInstance(FName BoneName = NAME_None, bool bGetWelded = true, int32 Index = INDEX_NONE) const override; + +protected: + UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface") + TArray> GripLogicScripts; + + // If true then the grip script array will be considered for replication, if false then it will not + // This is an optimization for when you have a lot of grip scripts in use, you can toggle this off in cases + // where the object will never have a replicating script + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + bool bReplicateGripScripts; +public: + void SetReplicateGripScripts(bool NewReplicateGripScripts); + inline bool GetReplicateGripScripts() { return bReplicateGripScripts; }; + + // Get the grip script array, will automatically dirty it if they are replicated as it is assumed if you are directly accessing it you are altering it + TArray>& GetGripLogicScripts(); + + bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override; + + + // Sets the Deny Gripping variable on the FBPInterfaceSettings struct + UFUNCTION(BlueprintCallable, Category = "VRGripInterface") + void SetDenyGripping(bool bDenyGripping); + + // Sets the grip priority on the FBPInterfaceSettings struct + UFUNCTION(BlueprintCallable, Category = "VRGripInterface") + void SetGripPriority(int NewGripPriority); + + // Called when a object is gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnGripped; + + // Called when a object is dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnDropSignature OnDropped; + + // Called when an object we hold is secondary gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnSecondaryGripAdded; + + // Called when an object we hold is secondary dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnSecondaryGripRemoved; + + // ------------------------------------------------ + // Gameplay tag interface + // ------------------------------------------------ + + /** Overridden to return requirements tags */ + virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override + { + TagContainer = GameplayTags; + } + +protected: + + /** Tags that are set on this object */ + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") + FGameplayTagContainer GameplayTags; + +public: + FGameplayTagContainer& GetGameplayTags(); + + // End Gameplay Tag Interface + + virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; + + /** Called right before being marked for destruction due to network replication */ + // Clean up our objects so that they aren't sitting around for GC + virtual void PreDestroyFromReplication() override; + + virtual void GetSubobjectsWithStableNamesForNetworking(TArray &ObjList) override; + + // This one is for components to clean up + virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override; + +protected: + // Requires bReplicates to be true for the component + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") + bool bRepGripSettingsAndGameplayTags; + + // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") + bool bReplicateMovement; + + bool bOriginalReplicatesMovement; + + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + FBPInterfaceProperties VRGripInterfaceSettings; +public: + + void SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags); + inline bool GetRepGripSettingsAndGameplayTags() { return bRepGripSettingsAndGameplayTags; }; + + // Get VRGripInterfaceSettings, set MarkDirty if you intend to (or may) modify the values inside of it + FBPInterfaceProperties& GetVRGripInterfaceSettings(bool bMarkDirty); + + void SetReplicateMovement(bool bNewReplicateMovement); + inline bool GetReplicateMovement() { return bReplicateMovement; }; + + // Set up as deny instead of allow so that default allows for gripping + // The GripInitiator is not guaranteed to be valid, check it for validity + virtual bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override; + + // How an interfaced object behaves when teleporting + virtual EGripInterfaceTeleportBehavior TeleportBehavior_Implementation() override; + + // Should this object simulate on drop + virtual bool SimulateOnDrop_Implementation() override; + + // Grip type to use + virtual EGripCollisionType GetPrimaryGripType_Implementation(bool bIsSlot) override; + + // Secondary grip type + virtual ESecondaryGripType SecondaryGripType_Implementation() override; + + // Define which movement repliation setting to use + virtual EGripMovementReplicationSettings GripMovementReplicationType_Implementation() override; + + // Define the late update setting + virtual EGripLateUpdateSettings GripLateUpdateSetting_Implementation() override; + + // What grip stiffness and damping to use if using a physics constraint + virtual void GetGripStiffnessAndDamping_Implementation(float& GripStiffnessOut, float& GripDampingOut) override; + + // Get the advanced physics settings for this grip + virtual FBPAdvGripSettings AdvancedGripSettings_Implementation() override; + + // What distance to break a grip at (only relevent with physics enabled grips + virtual float GripBreakDistance_Implementation() override; + + // Get closest primary slot in range + virtual void ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool& bHadSlotInRange, FTransform& SlotWorldTransform, FName& SlotName, UGripMotionControllerComponent* CallingController = nullptr, FName OverridePrefix = NAME_None) override; + + // Check if an object allows multiple grips at one time + virtual bool AllowsMultipleGrips_Implementation() override; + + // Returns if the object is held and if so, which controllers are holding it + virtual void IsHeld_Implementation(TArray& HoldingControllers, bool& bIsHeld) override; + + // Sets is held, used by the plugin + virtual void SetHeld_Implementation(UGripMotionControllerComponent* HoldingController, uint8 GripID, bool bIsHeld) override; + + // Interface function used to throw the delegates that is invisible to blueprints so that it can't be overridden + virtual void Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Returns if the object wants to be socketed + virtual bool RequestsSocketing_Implementation(USceneComponent*& ParentToSocketTo, FName& OptionalSocketName, FTransform_NetQuantize& RelativeTransform) override; + + // Get grip scripts + virtual bool GetGripScripts_Implementation(TArray& ArrayReference) override; + + // Events // + + // Event triggered each tick on the interfaced object when gripped, can be used for custom movement or grip based logic + virtual void TickGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation, float DeltaTime) override; + + // Event triggered on the interfaced object when gripped + virtual void OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when grip is released + virtual void OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when child component is gripped + virtual void OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when child component is released + virtual void OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when secondary gripped + virtual void OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when secondary grip is released + virtual void OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Interaction Functions + + // Call to use an object + virtual void OnUsed_Implementation() override; + + // Call to stop using an object + virtual void OnEndUsed_Implementation() override; + + // Call to use an object + virtual void OnSecondaryUsed_Implementation() override; + + // Call to stop using an object + virtual void OnEndSecondaryUsed_Implementation() override; + + // Call to send an action event to the object + virtual void OnInput_Implementation(FKey Key, EInputEvent KeyEvent) override; +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableSphereComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableSphereComponent.h new file mode 100644 index 0000000..ec5058b --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableSphereComponent.h @@ -0,0 +1,223 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "VRBPDatatypes.h" +#include "VRGripInterface.h" +#include "GameplayTagContainer.h" +#include "GameplayTagAssetInterface.h" +#include "Components/SphereComponent.h" +#include "Engine/ActorChannel.h" +#include "GrippableSphereComponent.generated.h" + +class UVRGripScriptBase; +class UGripMotionControllerComponent; + +/** +* +*/ + +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent, ChildCanTick), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UGrippableSphereComponent : public USphereComponent, public IVRGripInterface, public IGameplayTagAssetInterface +{ + GENERATED_BODY() + +public: + UGrippableSphereComponent(const FObjectInitializer& ObjectInitializer); + + + ~UGrippableSphereComponent(); + virtual void BeginPlay() override; + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + +protected: + UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface") + TArray> GripLogicScripts; + + // If true then the grip script array will be considered for replication, if false then it will not + // This is an optimization for when you have a lot of grip scripts in use, you can toggle this off in cases + // where the object will never have a replicating script + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + bool bReplicateGripScripts; +public: + + void SetReplicateGripScripts(bool NewReplicateGripScripts); + inline bool GetReplicateGripScripts() { return bReplicateGripScripts; }; + + // Get the grip script array, will automatically dirty it if they are replicated as it is assumed if you are directly accessing it you are altering it + TArray>& GetGripLogicScripts(); + + bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override; + + + // Sets the Deny Gripping variable on the FBPInterfaceSettings struct + UFUNCTION(BlueprintCallable, Category = "VRGripInterface") + void SetDenyGripping(bool bDenyGripping); + + // Sets the grip priority on the FBPInterfaceSettings struct + UFUNCTION(BlueprintCallable, Category = "VRGripInterface") + void SetGripPriority(int NewGripPriority); + + // Called when a object is gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnGripped; + + // Called when a object is dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnDropSignature OnDropped; + + // Called when an object we hold is secondary gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnSecondaryGripAdded; + + // Called when an object we hold is secondary dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnSecondaryGripRemoved; + + // ------------------------------------------------ + // Gameplay tag interface + // ------------------------------------------------ + + /** Overridden to return requirements tags */ + virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override + { + TagContainer = GameplayTags; + } + +protected: + /** Tags that are set on this object */ + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") + FGameplayTagContainer GameplayTags; +public: + FGameplayTagContainer& GetGameplayTags(); + + // End Gameplay Tag Interface + + virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; + + /** Called right before being marked for destruction due to network replication */ + // Clean up our objects so that they aren't sitting around for GC + virtual void PreDestroyFromReplication() override; + + virtual void GetSubobjectsWithStableNamesForNetworking(TArray &ObjList) override; + + // This one is for components to clean up + virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override; + +protected: + // Requires bReplicates to be true for the component + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") + bool bRepGripSettingsAndGameplayTags; + + // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") + bool bReplicateMovement; + + bool bOriginalReplicatesMovement; + + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + FBPInterfaceProperties VRGripInterfaceSettings; +public: + + void SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags); + inline bool GetRepGripSettingsAndGameplayTags() { return bRepGripSettingsAndGameplayTags; }; + + // Get VRGripInterfaceSettings, set MarkDirty if you intend to (or may) modify the values inside of it + FBPInterfaceProperties& GetVRGripInterfaceSettings(bool bMarkDirty); + + void SetReplicateMovement(bool bNewReplicateMovement); + inline bool GetReplicateMovement() { return bReplicateMovement; }; + + // Set up as deny instead of allow so that default allows for gripping + // The GripInitiator is not guaranteed to be valid, check it for validity + virtual bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override; + + // How an interfaced object behaves when teleporting + virtual EGripInterfaceTeleportBehavior TeleportBehavior_Implementation() override; + + // Should this object simulate on drop + virtual bool SimulateOnDrop_Implementation() override; + + // Grip type to use + virtual EGripCollisionType GetPrimaryGripType_Implementation(bool bIsSlot) override; + + // Secondary grip type + virtual ESecondaryGripType SecondaryGripType_Implementation() override; + + // Define which movement repliation setting to use + virtual EGripMovementReplicationSettings GripMovementReplicationType_Implementation() override; + + // Define the late update setting + virtual EGripLateUpdateSettings GripLateUpdateSetting_Implementation() override; + + // What grip stiffness and damping to use if using a physics constraint + virtual void GetGripStiffnessAndDamping_Implementation(float& GripStiffnessOut, float& GripDampingOut) override; + + // Get the advanced physics settings for this grip + virtual FBPAdvGripSettings AdvancedGripSettings_Implementation() override; + + // What distance to break a grip at (only relevent with physics enabled grips + virtual float GripBreakDistance_Implementation() override; + + // Get closest primary slot in range + virtual void ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool& bHadSlotInRange, FTransform& SlotWorldTransform, FName& SlotName, UGripMotionControllerComponent* CallingController = nullptr, FName OverridePrefix = NAME_None) override; + + // Check if an object allows multiple grips at one time + virtual bool AllowsMultipleGrips_Implementation() override; + + // Returns if the object is held and if so, which controllers are holding it + virtual void IsHeld_Implementation(TArray& HoldingControllers, bool& bIsHeld) override; + + // Sets is held, used by the plugin + virtual void SetHeld_Implementation(UGripMotionControllerComponent* HoldingController, uint8 GripID, bool bIsHeld) override; + + // Interface function used to throw the delegates that is invisible to blueprints so that it can't be overridden + virtual void Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Returns if the object wants to be socketed + virtual bool RequestsSocketing_Implementation(USceneComponent*& ParentToSocketTo, FName& OptionalSocketName, FTransform_NetQuantize& RelativeTransform) override; + + // Get grip scripts + virtual bool GetGripScripts_Implementation(TArray& ArrayReference) override; + + // Events // + + // Event triggered each tick on the interfaced object when gripped, can be used for custom movement or grip based logic + virtual void TickGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation, float DeltaTime) override; + + // Event triggered on the interfaced object when gripped + virtual void OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when grip is released + virtual void OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when child component is gripped + virtual void OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when child component is released + virtual void OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when secondary gripped + virtual void OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when secondary grip is released + virtual void OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Interaction Functions + + // Call to use an object + virtual void OnUsed_Implementation() override; + + // Call to stop using an object + virtual void OnEndUsed_Implementation() override; + + // Call to use an object + virtual void OnSecondaryUsed_Implementation() override; + + // Call to stop using an object + virtual void OnEndSecondaryUsed_Implementation() override; + + // Call to send an action event to the object + virtual void OnInput_Implementation(FKey Key, EInputEvent KeyEvent) override; +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableStaticMeshActor.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableStaticMeshActor.h new file mode 100644 index 0000000..986c521 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableStaticMeshActor.h @@ -0,0 +1,321 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +//#include "Engine/Engine.h" +#include "Engine/StaticMeshActor.h" +#include "Components/StaticMeshComponent.h" +#include "VRBPDatatypes.h" +#include "VRGripInterface.h" +#include "GameplayTagContainer.h" +#include "GameplayTagAssetInterface.h" +#include "Engine/ActorChannel.h" +#include "Grippables/GrippableDataTypes.h" +#include "Grippables/GrippablePhysicsReplication.h" +#include "GrippableStaticMeshActor.generated.h" + +class UGripMotionControllerComponent; +class UVRGripScriptBase; + + +/** +* A component specifically for being able to turn off movement replication in the component at will +* Has the upside of also being a blueprintable base since UE4 doesn't allow that with std ones +*/ +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent,ChildCanTick), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UOptionalRepStaticMeshComponent : public UStaticMeshComponent +{ + GENERATED_BODY() + +public: + UOptionalRepStaticMeshComponent(const FObjectInitializer& ObjectInitializer); + + + // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Component Replication") + bool bReplicateMovement; + + virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; +}; + + +/** +* +*/ +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent, ChildCanTick), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API AGrippableStaticMeshActor : public AStaticMeshActor, public IVRGripInterface, public IGameplayTagAssetInterface +{ + GENERATED_BODY() + +public: + AGrippableStaticMeshActor(const FObjectInitializer& ObjectInitializer); + + ~AGrippableStaticMeshActor(); + virtual void BeginPlay() override; + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + + UPROPERTY(Replicated, ReplicatedUsing = OnRep_AttachmentReplication) + FRepAttachmentWithWeld AttachmentWeldReplication; + + virtual void GatherCurrentMovement() override; + +protected: + + UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface") + TArray> GripLogicScripts; + + // If true then the grip script array will be considered for replication, if false then it will not + // This is an optimization for when you have a lot of grip scripts in use, you can toggle this off in cases + // where the object will never have a replicating script + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + bool bReplicateGripScripts; + +public: + + void SetReplicateGripScripts(bool NewReplicateGripScripts); + inline bool GetReplicateGripScripts() { return bReplicateGripScripts; }; + + // Get the grip script array, will automatically dirty it if they are replicated as it is assumed if you are directly accessing it you are altering it + TArray>& GetGripLogicScripts(); + + bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override; + virtual void GetSubobjectsWithStableNamesForNetworking(TArray& ObjList) override; + + // Sets the Deny Gripping variable on the FBPInterfaceSettings struct + UFUNCTION(BlueprintCallable, Category = "VRGripInterface") + void SetDenyGripping(bool bDenyGripping); + + // Sets the grip priority on the FBPInterfaceSettings struct + UFUNCTION(BlueprintCallable, Category = "VRGripInterface") + void SetGripPriority(int NewGripPriority); + + // Called when a object is gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnGripped; + + // Called when a object is dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnDropSignature OnDropped; + + // Called when an object we hold is secondary gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnSecondaryGripAdded; + + // Called when an object we hold is secondary dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnSecondaryGripRemoved; + + + // ------------------------------------------------ + // Client Auth Throwing Data and functions + // ------------------------------------------------ + +protected: + + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication") + FVRClientAuthReplicationData ClientAuthReplicationData; + +public: + // If changing this in c++ it is using a getter to make sure it is dirtied + FVRClientAuthReplicationData& GetClientAuthReplicationData(FVRClientAuthReplicationData& ClientAuthData); + + // Add this to client side physics replication (until coming to rest or timeout period is hit) + UFUNCTION(BlueprintCallable, Category = "Networking") + bool AddToClientReplicationBucket(); + + // Remove this from client side physics replication + UFUNCTION(BlueprintCallable, Category = "Networking") + bool RemoveFromClientReplicationBucket(); + + // From IVRReplicationInterface + UFUNCTION() + bool PollReplicationEvent(); + + UFUNCTION(Category = "Networking") + void CeaseReplicationBlocking(); + + // Notify the server that we are no longer trying to run the throwing auth + UFUNCTION(Reliable, Server, WithValidation, Category = "Networking") + void Server_EndClientAuthReplication(); + + // Notify the server about a new movement rep + UFUNCTION(UnReliable, Server, WithValidation, Category = "Networking") + void Server_GetClientAuthReplication(const FRepMovementVR & newMovement); + + // Returns if this object is currently client auth throwing + UFUNCTION(BlueprintPure, Category = "Networking") + FORCEINLINE bool IsCurrentlyClientAuthThrowing() + { + return ClientAuthReplicationData.bIsCurrentlyClientAuth; + } + + // End client auth throwing data and functions // + + + // ------------------------------------------------ + // Gameplay tag interface + // ------------------------------------------------ + + /** Overridden to return requirements tags */ + virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override + { + TagContainer = GameplayTags; + } + +protected: + + /** Tags that are set on this object */ + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") + FGameplayTagContainer GameplayTags; +public: + FGameplayTagContainer& GetGameplayTags(); + + // End Gameplay Tag Interface + + virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; + +protected: + // Skips the attachment replication if we are locally owned and our grip settings say that we are a client authed grip. + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication") + bool bAllowIgnoringAttachOnOwner; + +public: + void SetAllowIgnoringAttachOnOwner(bool bNewAllowIgnoringAttachOnOwner); + inline bool GetAllowIgnoringAttachOnOwner() { return bAllowIgnoringAttachOnOwner; }; + + // Should we skip attachment replication (vr settings say we are a client auth grip and our owner is locally controlled) + /*inline*/ bool ShouldWeSkipAttachmentReplication(bool bConsiderHeld = true) const; + + // Fix bugs with replication and bReplicateMovement + virtual void OnRep_AttachmentReplication() override; + virtual void OnRep_ReplicateMovement() override; + virtual void OnRep_ReplicatedMovement() override; + virtual void PostNetReceivePhysicState() override; + + // Debug printing of when the object is replication destroyed + /*virtual void OnSubobjectDestroyFromReplication(UObject *Subobject) override + { + Super::OnSubobjectDestroyFromReplication(Subobject); + + GEngine->AddOnScreenDebugMessage(-1, 15.f, FColor::Red, FString::Printf(TEXT("Killed Object On Actor: x: %s"), *Subobject->GetName())); + }*/ + + // This isn't called very many places but it does come up + virtual void MarkComponentsAsGarbage(bool bModify) override; + + /** Called right before being marked for destruction due to network replication */ + // Clean up our objects so that they aren't sitting around for GC + virtual void PreDestroyFromReplication() override; + + // On Destroy clean up our objects + virtual void BeginDestroy() override; + +protected: + + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + bool bRepGripSettingsAndGameplayTags; + + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + FBPInterfaceProperties VRGripInterfaceSettings; + +public: + + void SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags); + inline bool GetRepGripSettingsAndGameplayTags() { return bRepGripSettingsAndGameplayTags; }; + + // Get VRGripInterfaceSettings, set MarkDirty if you intend to (or may) modify the values inside of it + FBPInterfaceProperties& GetVRGripInterfaceSettings(bool bMarkDirty); + + // Set up as deny instead of allow so that default allows for gripping + // The GripInitiator is not guaranteed to be valid, check it for validity + virtual bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override; + + // How an interfaced object behaves when teleporting + virtual EGripInterfaceTeleportBehavior TeleportBehavior_Implementation() override; + + // Should this object simulate on drop + virtual bool SimulateOnDrop_Implementation() override; + + // Grip type to use + virtual EGripCollisionType GetPrimaryGripType_Implementation(bool bIsSlot) override; + + // Secondary grip type + virtual ESecondaryGripType SecondaryGripType_Implementation() override; + + // Define which movement repliation setting to use + virtual EGripMovementReplicationSettings GripMovementReplicationType_Implementation() override; + + // Define the late update setting + virtual EGripLateUpdateSettings GripLateUpdateSetting_Implementation() override; + + // What grip stiffness and damping to use if using a physics constraint + virtual void GetGripStiffnessAndDamping_Implementation(float& GripStiffnessOut, float& GripDampingOut) override; + + // Get the advanced physics settings for this grip + virtual FBPAdvGripSettings AdvancedGripSettings_Implementation() override; + + // What distance to break a grip at (only relevent with physics enabled grips + virtual float GripBreakDistance_Implementation() override; + + // Get closest primary slot in range + virtual void ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool& bHadSlotInRange, FTransform& SlotWorldTransform, FName& SlotName, UGripMotionControllerComponent* CallingController = nullptr, FName OverridePrefix = NAME_None) override; + + // Check if an object allows multiple grips at one time + virtual bool AllowsMultipleGrips_Implementation() override; + + // Returns if the object is held and if so, which controllers are holding it + virtual void IsHeld_Implementation(TArray& HoldingControllers, bool& bIsHeld) override; + + // Sets is held, used by the plugin + virtual void SetHeld_Implementation(UGripMotionControllerComponent* HoldingController, uint8 GripID, bool bIsHeld) override; + + // Interface function used to throw the delegates that is invisible to blueprints so that it can't be overridden + virtual void Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Returns if the object wants to be socketed + virtual bool RequestsSocketing_Implementation(USceneComponent*& ParentToSocketTo, FName& OptionalSocketName, FTransform_NetQuantize& RelativeTransform) override; + + // Get grip scripts + virtual bool GetGripScripts_Implementation(TArray& ArrayReference) override; + + // Events // + + // Event triggered each tick on the interfaced object when gripped, can be used for custom movement or grip based logic + virtual void TickGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation, float DeltaTime) override; + + // Event triggered on the interfaced object when gripped + virtual void OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when grip is released + virtual void OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when child component is gripped + virtual void OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when child component is released + virtual void OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when secondary gripped + virtual void OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when secondary grip is released + virtual void OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Interaction Functions + + // Call to use an object + virtual void OnUsed_Implementation() override; + + // Call to stop using an object + virtual void OnEndUsed_Implementation() override; + + // Call to use an object + virtual void OnSecondaryUsed_Implementation() override; + + // Call to stop using an object + virtual void OnEndSecondaryUsed_Implementation() override; + + // Call to send an action event to the object + virtual void OnInput_Implementation(FKey Key, EInputEvent KeyEvent) override; +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableStaticMeshComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableStaticMeshComponent.h new file mode 100644 index 0000000..900433e --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/GrippableStaticMeshComponent.h @@ -0,0 +1,225 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "VRBPDatatypes.h" +#include "VRGripInterface.h" +#include "GameplayTagContainer.h" +#include "GameplayTagAssetInterface.h" +#include "Components/StaticMeshComponent.h" +#include "Engine/ActorChannel.h" +#include "GrippableStaticMeshComponent.generated.h" + +class UVRGripScriptBase; +class UGripMotionControllerComponent; + +/** +* +*/ + +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent,ChildCanTick), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UGrippableStaticMeshComponent : public UStaticMeshComponent, public IVRGripInterface, public IGameplayTagAssetInterface +{ + GENERATED_BODY() + +public: + UGrippableStaticMeshComponent(const FObjectInitializer& ObjectInitializer); + + + ~UGrippableStaticMeshComponent(); + virtual void BeginPlay() override; + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + + // ------------------------------------------------ + // Gameplay tag interface + // ------------------------------------------------ + +protected: + + /** Overridden to return requirements tags */ + UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface") + TArray> GripLogicScripts; + + // If true then the grip script array will be considered for replication, if false then it will not + // This is an optimization for when you have a lot of grip scripts in use, you can toggle this off in cases + // where the object will never have a replicating script + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + bool bReplicateGripScripts; + +public: + void SetReplicateGripScripts(bool NewReplicateGripScripts); + inline bool GetReplicateGripScripts() { return bReplicateGripScripts; }; + + // Get the grip script array, will automatically dirty it if they are replicated as it is assumed if you are directly accessing it you are altering it + TArray>& GetGripLogicScripts(); + + bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override; + + // Sets the Deny Gripping variable on the FBPInterfaceSettings struct + UFUNCTION(BlueprintCallable, Category = "VRGripInterface") + void SetDenyGripping(bool bDenyGripping); + + // Sets the grip priority on the FBPInterfaceSettings struct + UFUNCTION(BlueprintCallable, Category = "VRGripInterface") + void SetGripPriority(int NewGripPriority); + + // Called when a object is gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnGripped; + + // Called when a object is dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnDropSignature OnDropped; + + // Called when an object we hold is secondary gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnSecondaryGripAdded; + + // Called when an object we hold is secondary dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnSecondaryGripRemoved; + + virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override + { + TagContainer = GameplayTags; + } + +protected: + + /** Tags that are set on this object */ + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") + FGameplayTagContainer GameplayTags; + +public: + FGameplayTagContainer& GetGameplayTags(); + + // End Gameplay Tag Interface + + virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; + + /** Called right before being marked for destruction due to network replication */ + // Clean up our objects so that they aren't sitting around for GC + virtual void PreDestroyFromReplication() override; + + virtual void GetSubobjectsWithStableNamesForNetworking(TArray &ObjList) override; + + // This one is for components to clean up + virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override; + +protected: + // Requires bReplicates to be true for the component + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") + bool bRepGripSettingsAndGameplayTags; + + // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") + bool bReplicateMovement; + + bool bOriginalReplicatesMovement; + + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + FBPInterfaceProperties VRGripInterfaceSettings; + +public: + void SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags); + inline bool GetRepGripSettingsAndGameplayTags() { return bRepGripSettingsAndGameplayTags; }; + + // Get VRGripInterfaceSettings, set MarkDirty if you intend to (or may) modify the values inside of it + FBPInterfaceProperties& GetVRGripInterfaceSettings(bool bMarkDirty); + + void SetReplicateMovement(bool bNewReplicateMovement); + inline bool GetReplicateMovement() { return bReplicateMovement; }; + + // Set up as deny instead of allow so that default allows for gripping + // The GripInitiator is not guaranteed to be valid, check it for validity + virtual bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override; + + // How an interfaced object behaves when teleporting + virtual EGripInterfaceTeleportBehavior TeleportBehavior_Implementation() override; + + // Should this object simulate on drop + virtual bool SimulateOnDrop_Implementation() override; + + // Grip type to use + virtual EGripCollisionType GetPrimaryGripType_Implementation(bool bIsSlot) override; + + // Secondary grip type + virtual ESecondaryGripType SecondaryGripType_Implementation() override; + + // Define which movement repliation setting to use + virtual EGripMovementReplicationSettings GripMovementReplicationType_Implementation() override; + + // Define the late update setting + virtual EGripLateUpdateSettings GripLateUpdateSetting_Implementation() override; + + // What grip stiffness and damping to use if using a physics constraint + virtual void GetGripStiffnessAndDamping_Implementation(float& GripStiffnessOut, float& GripDampingOut) override; + + // Get the advanced physics settings for this grip + virtual FBPAdvGripSettings AdvancedGripSettings_Implementation() override; + + // What distance to break a grip at (only relevent with physics enabled grips + virtual float GripBreakDistance_Implementation() override; + + // Get closest primary slot in range + virtual void ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool& bHadSlotInRange, FTransform& SlotWorldTransform, FName& SlotName, UGripMotionControllerComponent* CallingController = nullptr, FName OverridePrefix = NAME_None) override; + + // Check if an object allows multiple grips at one time + virtual bool AllowsMultipleGrips_Implementation() override; + + // Returns if the object is held and if so, which controllers are holding it + virtual void IsHeld_Implementation(TArray& HoldingControllers, bool& bIsHeld) override; + + // Sets is held, used by the plugin + virtual void SetHeld_Implementation(UGripMotionControllerComponent* HoldingController, uint8 GripID, bool bIsHeld) override; + + // Interface function used to throw the delegates that is invisible to blueprints so that it can't be overridden + virtual void Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Returns if the object wants to be socketed + virtual bool RequestsSocketing_Implementation(USceneComponent*& ParentToSocketTo, FName& OptionalSocketName, FTransform_NetQuantize& RelativeTransform) override; + + // Get grip scripts + virtual bool GetGripScripts_Implementation(TArray& ArrayReference) override; + + // Events // + + // Event triggered each tick on the interfaced object when gripped, can be used for custom movement or grip based logic + virtual void TickGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation, float DeltaTime) override; + + // Event triggered on the interfaced object when gripped + virtual void OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when grip is released + virtual void OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when child component is gripped + virtual void OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when child component is released + virtual void OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when secondary gripped + virtual void OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when secondary grip is released + virtual void OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Interaction Functions + + // Call to use an object + virtual void OnUsed_Implementation() override; + + // Call to stop using an object + virtual void OnEndUsed_Implementation() override; + + // Call to use an object + virtual void OnSecondaryUsed_Implementation() override; + + // Call to stop using an object + virtual void OnEndSecondaryUsed_Implementation() override; + + // Call to send an action event to the object + virtual void OnInput_Implementation(FKey Key, EInputEvent KeyEvent) override; +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/HandSocketComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/HandSocketComponent.h new file mode 100644 index 0000000..6073e9c --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Grippables/HandSocketComponent.h @@ -0,0 +1,484 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "GameplayTagContainer.h" +#include "GameplayTagAssetInterface.h" +#include "Components/SceneComponent.h" +#include "Animation/AnimInstance.h" +#include "Animation/BoneReference.h" +#include "Misc/Guid.h" + +#include "HandSocketComponent.generated.h" + +class USkeletalMeshComponent; +class UPoseableMeshComponent; +class USkeletalMesh; +class UGripMotionControllerComponent; +class UAnimSequence; +struct FPoseSnapshot; + +DECLARE_LOG_CATEGORY_EXTERN(LogVRHandSocketComponent, Log, All); + +// Custom serialization version for the hand socket component +struct VREXPANSIONPLUGIN_API FVRHandSocketCustomVersion +{ + enum Type + { + // Before any version changes were made in the plugin + BeforeCustomVersionWasAdded = 0, + + // Added a set state tracker to handle in editor construction edge cases + HandSocketStoringSetState = 1, + + // ------------------------------------------------------ + VersionPlusOne, + LatestVersion = VersionPlusOne - 1 + }; + + // The GUID for this custom version number + const static FGuid GUID; + +private: + FVRHandSocketCustomVersion() {} +}; + + +UENUM(BlueprintType) +namespace EVRAxis +{ + enum Type + { + X, + Y, + Z + }; +} + +/** +* A base class for custom hand socket objects +* Not directly blueprint spawnable as you are supposed to subclass this to add on top your own custom data +*/ + +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPVRHandPoseBonePair +{ + GENERATED_BODY() +public: + + // Distance to offset to get center of waist from tracked parent location + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings") + FName BoneName; + + // Initial "Resting" location of the tracker parent, assumed to be the calibration zero + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings") + FQuat DeltaPose; + + FBoneReference ReferenceToConstruct; + + FBPVRHandPoseBonePair() + { + BoneName = NAME_None; + DeltaPose = FQuat::Identity; + } + + FORCEINLINE bool operator==(const FName& Other) const + { + return (BoneName == Other); + } +}; + +UCLASS(Blueprintable, ClassGroup = (VRExpansionPlugin), hideCategories = ("Component Tick", Events, Physics, Lod, "Asset User Data", Collision)) +class VREXPANSIONPLUGIN_API UHandSocketComponent : public USceneComponent, public IGameplayTagAssetInterface +{ + GENERATED_BODY() + +public: + + UHandSocketComponent(const FObjectInitializer& ObjectInitializer); + ~UHandSocketComponent(); + + //static get socket compoonent + + //Axis to mirror on for this socket + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Socket Data|Mirroring|Advanced") + TEnumAsByte MirrorAxis; + + // Axis to flip on when mirroring this socket + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Socket Data|Mirroring|Advanced") + TEnumAsByte FlipAxis; + + // Relative placement of the hand to this socket + UPROPERTY(EditAnywhere, BlueprintReadWrite, /*DuplicateTransient,*/ Category = "Hand Socket Data") + FTransform HandRelativePlacement; + + // Target Slot Prefix + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Socket Data") + FName SlotPrefix; + + + // If true the hand meshes relative transform will be de-coupled from the hand socket + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Hand Socket Data") + bool bDecoupleMeshPlacement; + + // If true we should only be used to snap mesh to us, not for the actual socket transform + // Will act like free gripping but the mesh will snap into position + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Socket Data") + bool bOnlySnapMesh; + + // If true the end user should only pull the hand pose, not its transform from this component + // This is up to the end user to make use of as its part of the query steps. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Socket Data") + bool bOnlyUseHandPose; + + // If true we will not create the mesh relative transform using the attach socket we are attached too + // Useful in cases where you aren't doing per bone gripping but want the socket to follow a bone that is animating + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Socket Data") + bool bIgnoreAttachBone; + + // If true then this socket is left hand dominant and will flip for the right hand instead + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Hand Socket Data") + bool bLeftHandDominant; + + // If true we will mirror ourselves automatically for the off hand + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Socket Data|Mirroring", meta = (DisplayName = "Flip For Off Hand")) + bool bFlipForLeftHand; + + // If true, when we mirror the hand socket it will only mirror rotation, not position + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Socket Data|Mirroring", meta = (editcondition = "bFlipForLeftHand")) + bool bOnlyFlipRotation; + + // If true then this hand socket will always be considered "in range" and checked against others for lowest distance + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Socket Data|Searching") + bool bAlwaysInRange; + + // If true and there are multiple hand socket components in range with this setting + // Then the default behavior will compare closest rotation on them all to pick one + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Socket Data|Searching") + bool bMatchRotation; + + // If true then the hand socket will not be considered for search operations + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Socket Data|Control") + bool bDisabled; + + /*** + // If true then the hand socket will be locked in place during gameplay and not moved with the actor (saving performance) + // Generally you want this unless you are moving a hand socket manually during play for custom grip offsetting logic + // If you need the relative location of the hand socket for game logic, get the LockedRelativeTransform variable if bLockInPlace is enabled. + // Defaulted off currently for bug testing + ***/ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Hand Socket Data|Control") + bool bLockInPlace; + + // Snap distance to use if you want to override the defaults. + // Will be ignored if == 0.0f or bAlwaysInRange is true + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Socket Data|Searching") + float OverrideDistance; + + // If true we are expected to have a list of custom deltas for bones to overlay onto our base pose + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Animation") + bool bUseCustomPoseDeltas; + + // Custom rotations that are added on top of an animations bone rotation to make a final transform + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Animation") + TArray CustomPoseDeltas; + + // Primary hand animation, for both hands if they share animations, right hand if they don't + // If using a custom pose delta this is expected to be the base pose + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Animation") + TObjectPtr HandTargetAnimation; + + // Scale to apply when mirroring the hand, adjust to visualize your off hand correctly + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Socket Data|Mirroring") + FVector MirroredScale; + +#if WITH_EDITORONLY_DATA + // If true we will attempt to only show editing widgets for bones matching the _l or _r postfixes + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Animation|Misc") + bool bFilterBonesByPostfix; + + // The postfix to filter by + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Animation|Misc") + FString FilterPostfix; + + // An array of bones to skip when looking to edit deltas, can help clean up the interaction if you have extra bones in the heirarchy + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Animation|Misc") + TArray BonesToSkip; + + FTransform GetBoneTransformAtTime(UAnimSequence* MyAnimSequence, /*float AnimTime,*/ int BoneIdx, FName BoneName, bool bUseRawDataOnly); +#endif + + // Returns the base target animation of the hand (if there is one) + UFUNCTION(BlueprintCallable, Category = "Hand Socket Data") + UAnimSequence* GetTargetAnimation(); + + /** + * Returns the target animation of the hand blended with the delta rotations if there are any + * @param PoseSnapShot - Snapshot generated by this function + * @param TargetMesh - Targetmesh to check the skeleton of + * @param bSkipRootBone - If true we will skip the root bone (IE: Hand_r) and only apply the children poses (Full body) + * @param bFlipHand - If true we will mirror the pose, this is primarily to apply to a left hand from a right + */ + UFUNCTION(BlueprintCallable, Category = "Hand Socket Data") + bool GetBlendedPoseSnapShot(FPoseSnapshot& PoseSnapShot, USkeletalMeshComponent* TargetMesh = nullptr, bool bSkipRootBone = false, bool bFlipHand = false); + + /** + * Converts an animation sequence into a pose snapshot + * @param InAnimationSequence - Sequence to convert to a pose snapshot + * @param OutPoseSnapShot - Snapshot returned by this function + * @param TargetMesh - Targetmesh to check the skeleton of + * @param bSkipRootBone - If true we will skip the root bone (IE: Hand_r) and only apply the children poses (Full body) + * @param bFlipHand - If true we will mirror the pose, this is primarily to apply to a left hand from a right + */ + UFUNCTION(BlueprintCallable, Category = "Hand Socket Data", meta = (bIgnoreSelf = "true")) + static bool GetAnimationSequenceAsPoseSnapShot(UAnimSequence * InAnimationSequence, FPoseSnapshot& OutPoseSnapShot, USkeletalMeshComponent* TargetMesh = nullptr, bool bSkipRootBone = false, bool bFlipHand = false); + + + /** + * Gets all hand socket components in the entire level (this is a slow operation, DO NOT run this on tick) + */ + UFUNCTION(BlueprintCallable, Category = "Hand Socket Data") + static void GetAllHandSocketComponents(TArray& OutHandSockets); + + /** + * Gets all hand socket components within a set range of a world location (this is a slow operation, DO NOT run this on tick) + */ + UFUNCTION(BlueprintCallable, Category = "Hand Socket Data") + static bool GetAllHandSocketComponentsInRange(FVector SearchFromWorldLocation, float SearchRange, TArray& OutHandSockets); + + /** + * Gets the closest hand socket component within a set range of a world location (this is a slow operation, DO NOT run this on tick) + * Must check the output for validity + */ + UFUNCTION(BlueprintCallable, Category = "Hand Socket Data") + static UHandSocketComponent* GetClosestHandSocketComponentInRange(FVector SearchFromWorldLocation, float SearchRange); + + // Returns the target relative transform of the hand + //UFUNCTION(BlueprintCallable, Category = "Hand Socket Data") + FTransform GetHandRelativePlacement(); + + inline void MirrorHandTransform(FTransform& ReturnTrans, FTransform& relTrans) + { + if (bOnlyFlipRotation) + { + ReturnTrans.SetTranslation(ReturnTrans.GetTranslation() - relTrans.GetTranslation()); + ReturnTrans.Mirror(GetAsEAxis(MirrorAxis), GetCrossAxis()); + ReturnTrans.SetTranslation(ReturnTrans.GetTranslation() + relTrans.GetTranslation()); + } + else + { + ReturnTrans.Mirror(GetAsEAxis(MirrorAxis), GetCrossAxis()); + } + } + + inline TEnumAsByte GetAsEAxis(TEnumAsByte InAxis) + { + switch (InAxis) + { + case EVRAxis::X: + { + return EAxis::X; + }break; + case EVRAxis::Y: + { + return EAxis::Y; + }break; + case EVRAxis::Z: + { + return EAxis::Z; + }break; + } + + return EAxis::X; + } + + + inline FVector GetMirrorVector() + { + switch (MirrorAxis) + { + case EVRAxis::Y: + { + return FVector::RightVector; + }break; + case EVRAxis::Z: + { + return FVector::UpVector; + }break; + case EVRAxis::X: + default: + { + return FVector::ForwardVector; + }break; + } + } + + inline FVector GetFlipVector() + { + switch (FlipAxis) + { + case EVRAxis::Y: + { + return FVector::RightVector; + }break; + case EVRAxis::Z: + { + return FVector::UpVector; + }break; + case EVRAxis::X: + default: + { + return FVector::ForwardVector; + }break; + } + } + + inline TEnumAsByte GetCrossAxis() + { + // Checking against the sign now to avoid possible mobile precision issues + FVector SignVec = MirroredScale.GetSignVector(); + + if (SignVec.X < 0) + { + return EAxis::X; + } + else if (SignVec.Z < 0) + { + return EAxis::Z; + } + else if (SignVec.Y < 0) + { + return EAxis::Y; + } + + return GetAsEAxis(FlipAxis); + + /*if (FlipAxis == EVRAxis::Y) + { + return EAxis::Z; + } + else if (FlipAxis == EVRAxis::Z) + { + return EAxis::X; + } + else if (FlipAxis == EVRAxis::X) + { + return EAxis::Y; + }*/ + + //return EAxis::None; + } + // Returns the target relative transform of the hand to the gripped object + // If you want the transform mirrored you need to pass in which hand is requesting the information + // If UseParentScale is true then we will scale the value by the parent scale (generally only for when not using absolute hand scale) + // If UseMirrorScale is true then we will mirror the scale on the hand by the hand sockets mirror scale when appropriate (not for fully body!) + // if UseMirrorScale is false than the resulting transform will not have mirroring scale added so you may have to break the transform. + UFUNCTION(BlueprintCallable, Category = "Hand Socket Data") + FTransform GetMeshRelativeTransform(bool bIsRightHand, bool bUseParentScale = false, bool bUseMirrorScale = false); + + // Returns the defined hand socket component (if it exists, you need to valid check the return! + // If it is a valid return you can then cast to your projects base socket class and handle whatever logic you want + UFUNCTION(BlueprintCallable, Category = "Hand Socket Data") + static UHandSocketComponent* GetHandSocketComponentFromObject(UObject* ObjectToCheck, FName SocketName); + + virtual FTransform GetHandSocketTransform(UGripMotionControllerComponent* QueryController, bool bIgnoreOnlySnapMesh = false); + +#if WITH_EDITOR + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; +#endif +#if WITH_EDITORONLY_DATA + static void AddReferencedObjects(UObject* InThis, FReferenceCollector& Collector); + virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override; + void PoseVisualizationToAnimation(bool bForceRefresh = false); + bool bTickedPose; + + UPROPERTY() + bool bDecoupled; + +#endif + virtual void Serialize(FArchive& Ar) override; + virtual void OnRegister() override; + virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override; + + // ------------------------------------------------ + // Gameplay tag interface + // ------------------------------------------------ + + /** Overridden to return requirements tags */ + virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override + { + TagContainer = GameplayTags; + } + + protected: + + /** Tags that are set on this object */ + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") + FGameplayTagContainer GameplayTags; + + // End Gameplay Tag Interface + + // Requires bReplicates to be true for the component + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") + bool bRepGameplayTags; + + // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") + bool bReplicateMovement; + + public: + FGameplayTagContainer& GetGameplayTags(); + + void SetRepGameplayTags(bool NewRepGameplayTags); + inline bool GetRepGameplayTags() { return bRepGameplayTags; }; + void SetReplicateMovement(bool NewReplicateMovement); + inline bool GetReplicateMovement() { return bReplicateMovement; }; + + /** mesh component to indicate hand placement */ +#if WITH_EDITORONLY_DATA + + UPROPERTY() + TObjectPtr HandVisualizerComponent; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Transient, Category = "Hand Visualization") + TObjectPtr VisualizationMesh; + + // If we should show the visualization mesh + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Hand Visualization") + bool bShowVisualizationMesh; + + // Show the visualization mirrored + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Hand Visualization") + bool bMirrorVisualizationMesh; + + // If we should show the grip range of this socket (shows text if always in range) + // If override distance is zero then it attempts to infer the value from the parent architecture + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Hand Visualization") + bool bShowRangeVisualization; + + void PositionVisualizationMesh(); + void HideVisualizationMesh(); + +#endif + +#if WITH_EDITORONLY_DATA + // Material to apply to the hand + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hand Visualization") + TObjectPtr HandPreviewMaterial; + +#endif +}; + +UCLASS(transient, Blueprintable, hideCategories = AnimInstance, BlueprintType) +class VREXPANSIONPLUGIN_API UHandSocketAnimInstance : public UAnimInstance +{ + GENERATED_BODY() + +public: + + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, transient, Category = "Socket Data") + TObjectPtr OwningSocket; + + virtual void NativeInitializeAnimation() override; +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRButtonComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRButtonComponent.h new file mode 100644 index 0000000..e462761 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRButtonComponent.h @@ -0,0 +1,203 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Components/StaticMeshComponent.h" +#include "VRInteractibleFunctionLibrary.h" +#include "VRButtonComponent.generated.h" + +/** +* +*/ + +// VR Button Types +UENUM(Blueprintable) +enum class EVRButtonType : uint8 +{ + Btn_Press, + Btn_Toggle_Return, + Btn_Toggle_Stay +}; + +// VR Button SyncOptions +UENUM(Blueprintable) +enum class EVRStateChangeAuthorityType : uint8 +{ + /* Button state can be changed on all connections */ + CanChangeState_All, + /* Button state can be changed only on the server */ + CanChangeState_Server, + /* Button state can be changed only on the owner of the interacting primitive */ + CanChangeState_Owner +}; + +/** Delegate for notification when the button state changes. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FVRButtonStateChangedSignature, bool, ButtonState, AActor *, InteractingActor, UPrimitiveComponent *, InteractingComponent); + +/** Delegate for notification when the begins a new interaction. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FVRButtonStartedInteractionSignature, AActor *, InteractingActor, UPrimitiveComponent *, InteractingComponent); + +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UVRButtonComponent : public UStaticMeshComponent +{ + GENERATED_BODY() + +public: + UVRButtonComponent(const FObjectInitializer& ObjectInitializer); + + + ~UVRButtonComponent(); + + UFUNCTION() + void OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult); + + UFUNCTION() + void OnOverlapEnd(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex); + + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; + virtual void BeginPlay() override; + + UFUNCTION(BlueprintPure, Category = "VRButtonComponent") + bool IsButtonInUse(); + + // Should be called after the button is moved post begin play + UFUNCTION(BlueprintCallable, Category = "VRButtonComponent") + void ResetInitialButtonLocation(); + + // Sets the button state outside of interaction, bSnapIntoPosition is for Toggle_Stay mode, it will lerp into the new position if this is false + UFUNCTION(BlueprintCallable, Category = "VRButtonComponent") + void SetButtonState(bool bNewButtonState, bool bCallButtonChangedEvent = true, bool bSnapIntoPosition = false); + + // Resets the button to its resting location (mostly for Toggle_Stay) + UFUNCTION(BlueprintCallable, Category = "VRButtonComponent") + void SetButtonToRestingPosition(bool bLerpToPosition = false); + + // On the button state changing, keep in mind that InteractingActor can be invalid if manually setting the state + UPROPERTY(BlueprintAssignable, Category = "VRButtonComponent") + FVRButtonStateChangedSignature OnButtonStateChanged; + + // On the button state changing, keep in mind that InteractingActor can be invalid if manually setting the state + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Button State Changed")) + void ReceiveButtonStateChanged(bool bCurButtonState, AActor * LastInteractingActor, UPrimitiveComponent * InteractingComponent); + + // On Button beginning interaction (may spam a bit depending on if overlap is jittering) + UPROPERTY(BlueprintAssignable, Category = "VRButtonComponent") + FVRButtonStartedInteractionSignature OnButtonBeginInteraction; + + // On Button ending interaction (may spam a bit depending on if overlap is jittering) + UPROPERTY(BlueprintAssignable, Category = "VRButtonComponent") + FVRButtonStartedInteractionSignature OnButtonEndInteraction; + + // On Button beginning interaction (may spam a bit depending on if overlap is jittering) + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Button Started Interaction")) + void ReceiveButtonBeginInteraction(AActor * InteractingActor, UPrimitiveComponent * InteractingComponent); + + // On Button ending interaction (may spam a bit depending on if overlap is jittering) + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Button Ended Interaction")) + void ReceiveButtonEndInteraction(AActor * LastInteractingActor, UPrimitiveComponent * LastInteractingComponent); + + // On the button state changing, keep in mind that InteractingActor can be invalid if manually setting the state + UPROPERTY(BlueprintReadOnly, Category = "VRButtonComponent") + TObjectPtr LocalInteractingComponent; + + UPROPERTY(BlueprintReadOnly, Category = "VRButtonComponent") + TObjectPtr LocalLastInteractingActor; + + UPROPERTY(BlueprintReadOnly, Category = "VRButtonComponent") + TObjectPtr LocalLastInteractingComponent; + + // Whether the button is enabled or not (can be interacted with) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRButtonComponent") + bool bIsEnabled; + +protected: + // Current state of the button, writable to set initial value + UPROPERTY(EditAnywhere,BlueprintReadWrite, Replicated, Category = "VRButtonComponent") + bool bButtonState; + + // Who is allowed to change the button state + UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "VRButtonComponent|Replication") + EVRStateChangeAuthorityType StateChangeAuthorityType; +public: + bool GetButtonState() { return bButtonState; } + void SetButtonState(bool bNewButtonState); + EVRStateChangeAuthorityType GetStateChangeAuthorityType() { return StateChangeAuthorityType; } + void SetStateChangeAuthorityType(EVRStateChangeAuthorityType NewStateChangeAuthorityType); + + // Speed that the button de-presses when no longer interacted with + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRButtonComponent") + float DepressSpeed; + + // Distance that the button depresses + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRButtonComponent") + float DepressDistance; + + // Type of button this is + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRButtonComponent") + EVRButtonType ButtonType; + + // Negative on this axis is the depress direction + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRButtonComponent") + EVRInteractibleAxis ButtonAxis; + + // Depth at which the button engages (switches) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRButtonComponent") + float ButtonEngageDepth; + + // Minimum time before the button can be switched again + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRButtonComponent") + float MinTimeBetweenEngaging; + + // Skips filtering overlaps on the button and lets you manage it yourself, this is the alternative to overriding IsValidOverlap + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRButtonComponent") + bool bSkipOverlapFiltering; + + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRButtonComponent") + bool IsValidOverlap(UPrimitiveComponent * OverlapComponent); + + // Sets the Last interacting actor variable + void SetLastInteractingActor(); + + virtual FVector GetTargetRelativeLocation(); + + protected: + // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") + bool bReplicateMovement; + public: + bool GetReplicateMovement() { return bReplicateMovement; } + void SetReplicateMovement(bool bNewReplicateMovement); + + virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; + + // Resetting the initial transform here so that it comes in prior to BeginPlay and save loading. + virtual void OnRegister() override; + + protected: + // Now replicating this so that it works correctly over the network + UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_InitialRelativeTransform, Category = "VRButtonComponent") + FTransform_NetQuantize InitialRelativeTransform; + public: + // Gets the initial relative transform, if you want to set it you should be using ResetInitialButtonLocation + FTransform GetInitialRelativeTransform() { return InitialRelativeTransform; } + + UFUNCTION() + virtual void OnRep_InitialRelativeTransform() + { + SetButtonToRestingPosition(); + } + +protected: + + // Control variables + FVector InitialLocation; + bool bToggledThisTouch; + FVector InitialComponentLoc; + float LastToggleTime; + + float GetAxisValue(FVector CheckLocation); + + FVector SetAxisValue(float SetValue); + +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRDialComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRDialComponent.h new file mode 100644 index 0000000..a5e4d7f --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRDialComponent.h @@ -0,0 +1,315 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "GameplayTagContainer.h" +#include "GameplayTagAssetInterface.h" +#include "VRGripInterface.h" +#include "Components/StaticMeshComponent.h" +#include "Interactibles/VRInteractibleFunctionLibrary.h" +#include "VRDialComponent.generated.h" + +class UGripMotionControllerComponent; + +/** Delegate for notification when the lever state changes. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FVRDialStateChangedSignature, float, DialMilestoneAngle); +DECLARE_DYNAMIC_MULTICAST_DELEGATE(FVRDialFinishedLerpingSignature); + +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UVRDialComponent : public UStaticMeshComponent, public IVRGripInterface, public IGameplayTagAssetInterface +{ + GENERATED_BODY() + +public: + UVRDialComponent(const FObjectInitializer& ObjectInitializer); + + + ~UVRDialComponent(); + + // Call to use an object + UPROPERTY(BlueprintAssignable, Category = "VRDialComponent") + FVRDialStateChangedSignature OnDialHitSnapAngle; + + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Dial Hit Snap Angle")) + void ReceiveDialHitSnapAngle(float DialMilestoneAngle); + + // If true the dial will lerp back to zero on release + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRDialComponent|Lerping") + bool bLerpBackOnRelease; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRDialComponent|Lerping") + bool bSendDialEventsDuringLerp; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRDialComponent|Lerping") + float DialReturnSpeed; + + UPROPERTY(BlueprintReadOnly, Category = "VRDialComponent|Lerping") + bool bIsLerping; + + UPROPERTY(BlueprintAssignable, Category = "VRDialComponent|Lerping") + FVRDialFinishedLerpingSignature OnDialFinishedLerping; + + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Dial Finished Lerping")) + void ReceiveDialFinishedLerping(); + + UPROPERTY(BlueprintReadOnly, Category = "VRDialComponent") + float CurrentDialAngle; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRDialComponent")//, meta = (ClampMin = "0.0", ClampMax = "360.0", UIMin = "0.0", UIMax = "360.0")) + float ClockwiseMaximumDialAngle; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRDialComponent")//, meta = (ClampMin = "0.0", ClampMax = "360.0", UIMin = "0.0", UIMax = "360.0")) + float CClockwiseMaximumDialAngle; + + // If true then the dial can "roll over" past 360/0 degrees in a direction + // Allowing unlimited dial angle values + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRDialComponent") + bool bUseRollover; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRDialComponent") + bool bDialUsesAngleSnap; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRDialComponent") + bool bDialUseSnapAngleList; + + // Optional list of snap angles for the dial + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRDialComponent", meta = (editcondition = "bDialUseSnapAngleList")) + TArray DialSnapAngleList; + + // Angle that the dial snaps to on release and when within the threshold distance + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRDialComponent", meta = (editcondition = "!bDialUseSnapAngleList", ClampMin = "0.0", ClampMax = "180.0", UIMin = "0.0", UIMax = "180.0")) + float SnapAngleIncrement; + + // Threshold distance that when within the dial will stay snapped to its closest snap increment + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRDialComponent", meta = (editcondition = "!bDialUseSnapAngleList", ClampMin = "0.0", ClampMax = "180.0", UIMin = "0.0", UIMax = "180.0")) + float SnapAngleThreshold; + + // Scales rotational input to speed up or slow down the rotation + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRDialComponent", meta = (ClampMin = "0.0", ClampMax = "180.0", UIMin = "0.0", UIMax = "180.0")) + float RotationScaler; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRDialComponent") + EVRInteractibleAxis DialRotationAxis; + + // If true then the dial will directly sample the hands rotation instead of using its movement around it. + // This is good for roll specific dials but is fairly bad elsewhere. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRDialComponent") + bool bDialUseDirectHandRotation; + + float LastGripRot; + float InitialGripRot; + float InitialRotBackEnd; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRDialComponent", meta = (editcondition = "bDialUseDirectHandRotation")) + EVRInteractibleAxis InteractorRotationAxis; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripSettings") + float PrimarySlotRange; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripSettings") + float SecondarySlotRange; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripSettings") + int GripPriority; + + // Sets the grip priority + UFUNCTION(BlueprintCallable, Category = "GripSettings") + void SetGripPriority(int NewGripPriority); + + // Resetting the initial transform here so that it comes in prior to BeginPlay and save loading. + virtual void OnRegister() override; + +protected: + // Now replicating this so that it works correctly over the network + UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_InitialRelativeTransform, Category = "VRDialComponent") + FTransform_NetQuantize InitialRelativeTransform; +public: + // Gets the initial relative transform, if you want to set it you should be using ResetInitialButtonLocation + FTransform GetInitialRelativeTransform() { return InitialRelativeTransform; } + + UFUNCTION() + virtual void OnRep_InitialRelativeTransform() + { + CalculateDialProgress(); + } + + void CalculateDialProgress(); + + //FTransform InitialRelativeTransform; + FVector InitialInteractorLocation; + FVector InitialDropLocation; + float CurRotBackEnd; + FRotator LastRotation; + float LastSnapAngle; + + // Should be called after the dial is moved post begin play + UFUNCTION(BlueprintCallable, Category = "VRDialComponent") + void ResetInitialDialLocation(); + + // Can be called to recalculate the dial angle after you move it if you want different values + UFUNCTION(BlueprintCallable, Category = "VRDialComponent") + void AddDialAngle(float DialAngleDelta, bool bCallEvents = false, bool bSkipSettingRot = false); + + // Directly sets the dial angle, still obeys maximum limits and snapping though + UFUNCTION(BlueprintCallable, Category = "VRDialComponent") + void SetDialAngle(float DialAngle, bool bCallEvents = false); + + // ------------------------------------------------ + // Gameplay tag interface + // ------------------------------------------------ + + /** Overridden to return requirements tags */ + virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override + { + TagContainer = GameplayTags; + } + +protected: + /** Tags that are set on this object */ + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") + FGameplayTagContainer GameplayTags; + // End Gameplay Tag Interface + + // Requires bReplicates to be true for the component + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + bool bRepGameplayTags; + + // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") + bool bReplicateMovement; +public: + FGameplayTagContainer& GetGameplayTags(); + bool GetRepGameplayTags() { return bRepGameplayTags; } + void SetRepGameplayTags(bool bNewRepGameplayTags); + bool GetReplicateMovement() { return bReplicateMovement; } + void SetReplicateMovement(bool bNewReplicateMovement); + + virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override; + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; + virtual void BeginPlay() override; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + EGripMovementReplicationSettings MovementReplicationSetting; + + UPROPERTY(BlueprintReadOnly, Category = "VRGripInterface", meta = (ScriptName = "IsCurrentlyHeld")) + bool bIsHeld; // Set on grip notify, not net serializing + + UPROPERTY(BlueprintReadOnly, Category = "VRGripInterface") + FBPGripPair HoldingGrip; // Set on grip notify, not net serializing + bool bOriginalReplicatesMovement; + + // Called when a object is gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnGripped; + + // Called when a object is dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnDropSignature OnDropped; + + // Distance before the object will break out of the hand, 0.0f == never will + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + float BreakDistance; + + // Should we deny gripping on this object + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface", meta = (ScriptName = "IsDenyGripping")) + bool bDenyGripping; + + // Grip interface setup + + // Set up as deny instead of allow so that default allows for gripping + // The GripInitiator is not guaranteed to be valid, check it for validity + bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override; + + // How an interfaced object behaves when teleporting + EGripInterfaceTeleportBehavior TeleportBehavior_Implementation() override; + + // Should this object simulate on drop + bool SimulateOnDrop_Implementation() override; + + // Grip type to use + EGripCollisionType GetPrimaryGripType_Implementation(bool bIsSlot) override; + + // Secondary grip type + ESecondaryGripType SecondaryGripType_Implementation() override; + + // Define which movement repliation setting to use + EGripMovementReplicationSettings GripMovementReplicationType_Implementation() override; + + // Define the late update setting + EGripLateUpdateSettings GripLateUpdateSetting_Implementation() override; + + // What grip stiffness and damping to use if using a physics constraint + void GetGripStiffnessAndDamping_Implementation(float &GripStiffnessOut, float &GripDampingOut) override; + + // Get the advanced physics settings for this grip + FBPAdvGripSettings AdvancedGripSettings_Implementation() override; + + // What distance to break a grip at (only relevent with physics enabled grips + float GripBreakDistance_Implementation() override; + + // Get grip slot in range + void ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool & bHadSlotInRange, FTransform & SlotWorldTransform, FName & SlotName, UGripMotionControllerComponent * CallingController = nullptr, FName OverridePrefix = NAME_None) override; + + // Check if an object allows multiple grips at one time + bool AllowsMultipleGrips_Implementation() override; + + // Returns if the object is held and if so, which controllers are holding it + void IsHeld_Implementation(TArray& CurHoldingControllers, bool & bCurIsHeld) override; + + // Interface function used to throw the delegates that is invisible to blueprints so that it can't be overridden + virtual void Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Sets is held, used by the plugin + void SetHeld_Implementation(UGripMotionControllerComponent * NewHoldingController, uint8 GripID, bool bNewIsHeld) override; + + // Returns if the object wants to be socketed + bool RequestsSocketing_Implementation(USceneComponent *& ParentToSocketTo, FName & OptionalSocketName, FTransform_NetQuantize & RelativeTransform) override; + + // Get grip scripts + bool GetGripScripts_Implementation(TArray & ArrayReference) override; + + + // Events // + + // Event triggered each tick on the interfaced object when gripped, can be used for custom movement or grip based logic + void TickGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation, float DeltaTime) override; + + // Event triggered on the interfaced object when gripped + void OnGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) override; + + // Event triggered on the interfaced object when grip is released + void OnGripRelease_Implementation(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when child component is gripped + void OnChildGrip_Implementation(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation) override; + + // Event triggered on the interfaced object when child component is released + void OnChildGripRelease_Implementation(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when secondary gripped + void OnSecondaryGrip_Implementation(UGripMotionControllerComponent * GripOwningController, USceneComponent * SecondaryGripComponent, const FBPActorGripInformation & GripInformation) override; + + // Event triggered on the interfaced object when secondary grip is released + void OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent * GripOwningController, USceneComponent * ReleasingSecondaryGripComponent, const FBPActorGripInformation & GripInformation) override; + + // Interaction Functions + + // Call to use an object + void OnUsed_Implementation() override; + + // Call to stop using an object + void OnEndUsed_Implementation() override; + + // Call to use an object + void OnSecondaryUsed_Implementation() override; + + // Call to stop using an object + void OnEndSecondaryUsed_Implementation() override; + + // Call to send an action event to the object + void OnInput_Implementation(FKey Key, EInputEvent KeyEvent) override; + + protected: + +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRInteractibleFunctionLibrary.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRInteractibleFunctionLibrary.h new file mode 100644 index 0000000..9e58d44 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRInteractibleFunctionLibrary.h @@ -0,0 +1,303 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "VRBPDatatypes.h" +//#include "UObject/ObjectMacros.h" +//#include "Engine/EngineTypes.h" +//#include "UObject/ScriptInterface.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "Components/SceneComponent.h" +#include "GameplayTagContainer.h" + +#include "VRInteractibleFunctionLibrary.generated.h" + +//General Advanced Sessions Log +DECLARE_LOG_CATEGORY_EXTERN(VRInteractibleFunctionLibraryLog, Log, All); + +// Declares our interactible axis's +UENUM(Blueprintable) +enum class EVRInteractibleAxis : uint8 +{ + Axis_X, + Axis_Y, + Axis_Z +}; + +// A data structure to hold important interactible data +// Should be init'd in Beginplay with BeginPlayInit as well as OnGrip with OnGripInit. +// Works in "static space", it records the original relative transform of the interactible on begin play +// so that calculations on the actual component can be done based off of it. +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPVRInteractibleBaseData +{ + GENERATED_BODY() +public: + + // Our initial relative transform to our parent "static space" - Set in BeginPlayInit + UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "InteractibleData") + FTransform InitialRelativeTransform; + + // Initial location in "static space" of the interactor on grip - Set in OnGripInit + UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "InteractibleData") + FVector InitialInteractorLocation; + + // Initial location of the interactible in the "static space" - Set in OnGripInit + UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "InteractibleData") + FVector InitialGripLoc; + + // Initial location on the interactible of the grip, used for drop calculations - Set in OnGripInit + UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "InteractibleData") + FVector InitialDropLocation; + + // The initial transform in relative space of the grip to us - Set in OnGripInit + UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "InteractibleData") + FTransform ReversedRelativeTransform; + + FBPVRInteractibleBaseData() + { + InitialInteractorLocation = FVector::ZeroVector; + InitialGripLoc = FVector::ZeroVector; + InitialDropLocation = FVector::ZeroVector; + } +}; + +UCLASS() +class VREXPANSIONPLUGIN_API UVRInteractibleFunctionLibrary : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() +public: + + static float GetAtan2Angle(EVRInteractibleAxis AxisToCalc, FVector CurInteractorLocation, float OptionalInitialRotation = 0.0f) + { + switch (AxisToCalc) + { + case EVRInteractibleAxis::Axis_X: + { + return FMath::RadiansToDegrees(FMath::Atan2(CurInteractorLocation.Y, CurInteractorLocation.Z)) - OptionalInitialRotation; + }break; + case EVRInteractibleAxis::Axis_Y: + { + return FMath::RadiansToDegrees(FMath::Atan2(CurInteractorLocation.Z, CurInteractorLocation.X)) - OptionalInitialRotation; + }break; + case EVRInteractibleAxis::Axis_Z: + { + return FMath::RadiansToDegrees(FMath::Atan2(CurInteractorLocation.Y, CurInteractorLocation.X)) - OptionalInitialRotation; + }break; + default: + {}break; + } + + return 0.0f; + } + + static float GetDeltaAngleFromTransforms(EVRInteractibleAxis RotAxis, FTransform & InitialRelativeTransform, FTransform &CurrentRelativeTransform) + { + return GetDeltaAngle(RotAxis, (CurrentRelativeTransform.GetRelativeTransform(InitialRelativeTransform).GetRotation()).GetNormalized()); + } + + static float GetDeltaAngle(EVRInteractibleAxis RotAxis, FQuat DeltaQuat) + { + FVector Axis; + float Angle; + DeltaQuat.ToAxisAndAngle(Axis, Angle); + + if (RotAxis == EVRInteractibleAxis::Axis_Z) + return FRotator::NormalizeAxis(FMath::RadiansToDegrees(Angle)) * (FMath::Sign(GetAxisValue(RotAxis, Axis))); + else + return FRotator::NormalizeAxis(FMath::RadiansToDegrees(Angle)) * (-FMath::Sign(GetAxisValue(RotAxis, Axis))); + } + + static float GetAxisValue(EVRInteractibleAxis RotAxis, FRotator CheckRotation) + { + switch (RotAxis) + { + case EVRInteractibleAxis::Axis_X: + return CheckRotation.Roll; break; + case EVRInteractibleAxis::Axis_Y: + return CheckRotation.Pitch; break; + case EVRInteractibleAxis::Axis_Z: + return CheckRotation.Yaw; break; + default:return 0.0f; break; + } + } + + static float GetAxisValue(EVRInteractibleAxis RotAxis, FVector CheckAxis) + { + switch (RotAxis) + { + case EVRInteractibleAxis::Axis_X: + return CheckAxis.X; break; + case EVRInteractibleAxis::Axis_Y: + return CheckAxis.Y; break; + case EVRInteractibleAxis::Axis_Z: + return CheckAxis.Z; break; + default:return 0.0f; break; + } + } + + static FVector SetAxisValueVec(EVRInteractibleAxis RotAxis, float SetValue) + { + FVector vec = FVector::ZeroVector; + + switch (RotAxis) + { + case EVRInteractibleAxis::Axis_X: + vec.X = SetValue; break; + case EVRInteractibleAxis::Axis_Y: + vec.Y = SetValue; break; + case EVRInteractibleAxis::Axis_Z: + vec.Z = SetValue; break; + default:break; + } + + return vec; + } + + static FRotator SetAxisValueRot(EVRInteractibleAxis RotAxis, float SetValue) + { + FRotator vec = FRotator::ZeroRotator; + + switch (RotAxis) + { + case EVRInteractibleAxis::Axis_X: + vec.Roll = SetValue; break; + case EVRInteractibleAxis::Axis_Y: + vec.Pitch = SetValue; break; + case EVRInteractibleAxis::Axis_Z: + vec.Yaw = SetValue; break; + default:break; + } + + return vec; + } + + static FRotator SetAxisValueRot(EVRInteractibleAxis RotAxis, float SetValue, FRotator Var) + { + FRotator vec = Var; + switch (RotAxis) + { + case EVRInteractibleAxis::Axis_X: + vec.Roll = SetValue; break; + case EVRInteractibleAxis::Axis_Y: + vec.Pitch = SetValue; break; + case EVRInteractibleAxis::Axis_Z: + vec.Yaw = SetValue; break; + default:break; + } + + return vec; + } + + // Get current parent transform + UFUNCTION(BlueprintPure, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true")) + static FTransform Interactible_GetCurrentParentTransform(USceneComponent * SceneComponentToCheck) + { + if (SceneComponentToCheck) + { + if (USceneComponent * AttachParent = SceneComponentToCheck->GetAttachParent()) + { + return AttachParent->GetComponentTransform(); + } + } + + return FTransform::Identity; + } + + // Get current relative transform (original transform we were at on grip for the current parent transform) + UFUNCTION(BlueprintPure, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true")) + static FTransform Interactible_GetCurrentRelativeTransform(USceneComponent * SceneComponentToCheck, UPARAM(ref)FBPVRInteractibleBaseData & BaseData) + { + FTransform ParentTransform = FTransform::Identity; + if (SceneComponentToCheck) + { + if (USceneComponent * AttachParent = SceneComponentToCheck->GetAttachParent()) + { + // during grip there is no parent so we do this, might as well do it anyway for lerping as well + ParentTransform = AttachParent->GetComponentTransform(); + } + } + + return BaseData.InitialRelativeTransform * ParentTransform; + } + + // Inits the initial relative transform of an interactible on begin play + UFUNCTION(BlueprintCallable, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true")) + static void Interactible_BeginPlayInit(USceneComponent * InteractibleComp, UPARAM(ref) FBPVRInteractibleBaseData & BaseDataToInit) + { + if (!InteractibleComp) + return; + + BaseDataToInit.InitialRelativeTransform = InteractibleComp->GetRelativeTransform(); + } + + // Inits the calculated values of a VR Interactible Base Data Structure on a grip event + UFUNCTION(BlueprintCallable, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true")) + static void Interactible_OnGripInit(USceneComponent * InteractibleComp, UPARAM(ref) FBPActorGripInformation& GripInformation, UPARAM(ref) FBPVRInteractibleBaseData & BaseDataToInit) + { + if (!InteractibleComp) + return; + + BaseDataToInit.ReversedRelativeTransform = FTransform(GripInformation.RelativeTransform.ToInverseMatrixWithScale()); + BaseDataToInit.InitialDropLocation = BaseDataToInit.ReversedRelativeTransform.GetTranslation(); // Technically a duplicate, but will be more clear + + FTransform RelativeToGripTransform = BaseDataToInit.ReversedRelativeTransform * InteractibleComp->GetComponentTransform(); + FTransform CurrentRelativeTransform = BaseDataToInit.InitialRelativeTransform * UVRInteractibleFunctionLibrary::Interactible_GetCurrentParentTransform(InteractibleComp); + BaseDataToInit.InitialInteractorLocation = CurrentRelativeTransform.InverseTransformPosition(RelativeToGripTransform.GetTranslation()); + + BaseDataToInit.InitialGripLoc = BaseDataToInit.InitialRelativeTransform.InverseTransformPosition(InteractibleComp->GetRelativeLocation()); + } + + // Returns (in degrees) the angle around the axis of a location + // Expects the CurInteractorLocation to be in relative space already + UFUNCTION(BlueprintPure, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true")) + static float Interactible_GetAngleAroundAxis(EVRInteractibleAxis AxisToCalc, FVector CurInteractorLocation) + { + float ReturnAxis = 0.0f; + + switch (AxisToCalc) + { + case EVRInteractibleAxis::Axis_X: + { + ReturnAxis = FMath::RadiansToDegrees(FMath::Atan2(CurInteractorLocation.Y, CurInteractorLocation.Z)); + }break; + case EVRInteractibleAxis::Axis_Y: + { + ReturnAxis = FMath::RadiansToDegrees(FMath::Atan2(CurInteractorLocation.Z, CurInteractorLocation.X)); + }break; + case EVRInteractibleAxis::Axis_Z: + { + ReturnAxis = FMath::RadiansToDegrees(FMath::Atan2(CurInteractorLocation.Y, CurInteractorLocation.X)); + }break; + default: + {}break; + } + + return ReturnAxis; + } + + // Returns (in degrees) the delta rotation from the initial angle at grip to the current interactor angle around the axis + // Expects CurInteractorLocation to be in relative space already + // You can add this to an initial rotation and clamp the result to rotate over time based on hand position + UFUNCTION(BlueprintPure, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true")) + static float Interactible_GetAngleAroundAxisDelta(EVRInteractibleAxis AxisToCalc, FVector CurInteractorLocation, float InitialAngle) + { + return FRotator::NormalizeAxis(Interactible_GetAngleAroundAxis(AxisToCalc, CurInteractorLocation) - InitialAngle); + } + + + // Returns a value that is snapped to the given settings, taking into account the threshold and increment + UFUNCTION(BlueprintPure, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true")) + static float Interactible_GetThresholdSnappedValue(float ValueToSnap, float SnapIncrement, float SnapThreshold) + { + if (SnapIncrement > 0.f && FMath::Fmod(ValueToSnap, SnapIncrement) <= FMath::Min(SnapIncrement, SnapThreshold)) + { + return FMath::GridSnap(ValueToSnap, SnapIncrement); + } + + return ValueToSnap; + } + +}; + + diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRLeverComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRLeverComponent.h new file mode 100644 index 0000000..8fbce3a --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRLeverComponent.h @@ -0,0 +1,417 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "GameplayTagContainer.h" +#include "GameplayTagAssetInterface.h" +#include "VRGripInterface.h" +#include "Interactibles/VRInteractibleFunctionLibrary.h" +#include "Components/StaticMeshComponent.h" +#include "VRLeverComponent.generated.h" + +class UGripMotionControllerComponent; + +UENUM(Blueprintable) +enum class EVRInteractibleLeverAxis : uint8 +{ + /* Rotates only towards the X Axis */ + Axis_X, + /* Rotates only towards the Y Axis */ + Axis_Y, + /* Rotates only towards the Z Axis */ + Axis_Z, + /* Rotates freely on the XY Axis' */ + Axis_XY, + /* Acts like a flight stick, with AllCurrentLeverAngles being the positive / negative of the current full angle (yaw based on initial grip delta) */ + FlightStick_XY, +}; + +UENUM(Blueprintable) +enum class EVRInteractibleLeverEventType : uint8 +{ + LeverPositive, + LeverNegative +}; + +UENUM(Blueprintable) +enum class EVRInteractibleLeverReturnType : uint8 +{ + /** Stays in place on drop */ + Stay, + + /** Returns to zero on drop (lerps) */ + ReturnToZero, + + /** Lerps to closest max (only works with X/Y/Z axis levers) */ + LerpToMax, + + /** Lerps to closest max if over the toggle threshold (only works with X/Y/Z axis levers) */ + LerpToMaxIfOverThreshold, + + /** Retains momentum on release (only works with X/Y/Z axis levers) */ + RetainMomentum +}; + +/** Delegate for notification when the lever state changes. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FVRLeverStateChangedSignature, bool, LeverStatus, EVRInteractibleLeverEventType, LeverStatusType, float, LeverAngleAtTime, float, FullLeverAngleAtTime); +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FVRLeverFinishedLerpingSignature, float, FinalAngle); + +/** +* A Lever component, can act like a lever, door, wheel, joystick. +* If set to replicates it will replicate its values to the clients. +*/ +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UVRLeverComponent : public UStaticMeshComponent, public IVRGripInterface, public IGameplayTagAssetInterface +{ + GENERATED_BODY() + +public: + UVRLeverComponent(const FObjectInitializer& ObjectInitializer); + + + ~UVRLeverComponent(); + + // Call to use an object + UPROPERTY(BlueprintAssignable, Category = "VRLeverComponent") + FVRLeverStateChangedSignature OnLeverStateChanged; + + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Lever State Changed")) + void ReceiveLeverStateChanged(bool LeverStatus, EVRInteractibleLeverEventType LeverStatusType, float LeverAngleAtTime, float FullLeverAngleAttime); + + UPROPERTY(BlueprintAssignable, Category = "VRLeverComponent") + FVRLeverFinishedLerpingSignature OnLeverFinishedLerping; + + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Lever Finished Lerping")) + void ReceiveLeverFinishedLerping(float LeverFinalAngle); + + // Primary axis angle only + UPROPERTY(BlueprintReadOnly, Category = "VRLeverComponent") + float CurrentLeverAngle; + + // Writes out all current angles to this rotator, useful mostly for XY and Flight stick modes + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent") + FRotator AllCurrentLeverAngles; + + // Bearing Direction, for X/Y is their signed direction, for XY mode it is an actual 2D directional vector + UPROPERTY(BlueprintReadOnly, Category = "VRLeverComponent") + FVector CurrentLeverForwardVector; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent") + bool bUngripAtTargetRotation; + + // Rotation axis to use, XY is combined X and Y, only LerpToZero and PositiveLimits work with this mode + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent") + EVRInteractibleLeverAxis LeverRotationAxis; + + // The percentage of the angle at witch the lever will toggle + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent", meta = (ClampMin = "0.01", ClampMax = "1.0", UIMin = "0.01", UIMax = "1.0")) + float LeverTogglePercentage; + + // The max angle of the lever in the positive direction + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent", meta = (ClampMin = "0.0", ClampMax = "179.9", UIMin = "0.0", UIMax = "180.0")) + float LeverLimitPositive; + + // The max angle of the lever in the negative direction + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent", meta = (ClampMin = "0.0", ClampMax = "179.9", UIMin = "0.0", UIMax = "180.0")) + float LeverLimitNegative; + + // The max angle of the flightsticks yaw in either direction off of 0 + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent|Flight Stick Settings", meta = (ClampMin = "0.0", ClampMax = "179.9", UIMin = "0.0", UIMax = "180.0")) + float FlightStickYawLimit; + + // If true then this lever is locked in place until unlocked again + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent") + bool bIsLocked; + + // If true then this lever will auto drop even when locked + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent") + bool bAutoDropWhenLocked; + + // Sets if the lever is locked or not + UFUNCTION(BlueprintCallable, Category = "GripSettings") + void SetIsLocked(bool bNewLockedState); + + // Checks and applies auto drop if we need too + bool CheckAutoDrop(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation); + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent") + EVRInteractibleLeverReturnType LeverReturnTypeWhenReleased; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent") + bool bSendLeverEventsDuringLerp; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent") + float LeverReturnSpeed; + + // If true then we will blend the values of the XY axis' by the AngleThreshold, lowering Pitch/Yaw influence based on how far from leaning into the axis that the lever is + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent|Flight Stick Settings") + bool bBlendAxisValuesByAngleThreshold; + + // The angle threshold to blend around, default of 90.0 blends 0.0 to 1.0 smoothly across entire sweep + // A value of 45 would blend it to 0 halfway rotated to the other axis, while 180 would still leave half the influence when fully rotated out of facing + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent|Flight Stick Settings", meta = (ClampMin = "1.0", ClampMax = "360.0", UIMin = "1.0", UIMax = "360.0")) + float AngleThreshold; + + // Number of frames to average momentum across for the release momentum (avoids quick waggles) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent|Momentum Settings", meta = (ClampMin = "0", ClampMax = "12", UIMin = "0", UIMax = "12")) + int FramesToAverage; + + // Units in degrees per second to slow a momentum lerp down + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent|Momentum Settings", meta = (ClampMin = "0.0", ClampMax = "180", UIMin = "0.0", UIMax = "180.0")) + float LeverMomentumFriction; + + // % of elasticity on reaching the end 0 - 1.0 + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent|Momentum Settings", meta = (ClampMin = "0.0", ClampMax = "1.0", UIMin = "0.0", UIMax = "1.0")) + float LeverRestitution; + + // Maximum momentum of the lever in degrees per second + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent|Momentum Settings", meta = (ClampMin = "0.0", UIMin = "0.0")) + float MaxLeverMomentum; + + UPROPERTY(BlueprintReadWrite, Category = "VRLeverComponent") + bool bIsLerping; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripSettings") + float PrimarySlotRange; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripSettings") + float SecondarySlotRange; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripSettings") + int GripPriority; + + // Sets the grip priority + UFUNCTION(BlueprintCallable, Category = "GripSettings") + void SetGripPriority(int NewGripPriority); + + // Full precision current angle + float FullCurrentAngle; + + float LastDeltaAngle; + + // Resetting the initial transform here so that it comes in prior to BeginPlay and save loading. + virtual void OnRegister() override; + +protected: + // Now replicating this so that it works correctly over the network + UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_InitialRelativeTransform, Category = "VRLeverComponent") + FTransform_NetQuantize InitialRelativeTransform; +public: + // Gets the initial relative transform, if you want to set it you should be using ResetInitialButtonLocation + FTransform GetInitialRelativeTransform() { return InitialRelativeTransform; } + + UFUNCTION() + virtual void OnRep_InitialRelativeTransform() + { + ReCalculateCurrentAngle(); + } + + // Flight stick variables + FTransform InteractorOffsetTransform; + + FVector InitialInteractorLocation; + FVector InitialInteractorDropLocation; + float InitialGripRot; + float RotAtGrab; + FQuat qRotAtGrab; + bool bLeverState; + bool bIsInFirstTick; + + // For momentum retention + float MomentumAtDrop; + float LastLeverAngle; + + float CalcAngle(EVRInteractibleLeverAxis AxisToCalc, FVector CurInteractorLocation, bool bSkipLimits = false); + + void LerpAxis(float CurrentAngle, float DeltaTime); + + void CalculateCurrentAngle(FTransform & CurrentTransform); + + // ------------------------------------------------ + // Gameplay tag interface + // ------------------------------------------------ + + /** Overridden to return requirements tags */ + virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override + { + TagContainer = GameplayTags; + } + +protected: + /** Tags that are set on this object */ + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") + FGameplayTagContainer GameplayTags; + // End Gameplay Tag Interface + + // Requires bReplicates to be true for the component + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + bool bRepGameplayTags; + + // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") + bool bReplicateMovement; +public: + FGameplayTagContainer& GetGameplayTags(); + bool GetRepGameplayTags() { return bRepGameplayTags; } + void SetRepGameplayTags(bool bNewRepGameplayTags); + bool GetReplicateMovement() { return bReplicateMovement; } + void SetReplicateMovement(bool bNewReplicateMovement); + + virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override; + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; + virtual void BeginPlay() override; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + EGripMovementReplicationSettings MovementReplicationSetting; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + float Stiffness; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + float Damping; + + // Distance before the object will break out of the hand, 0.0f == never will + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + float BreakDistance; + + // Should we deny gripping on this object + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface", meta = (ScriptName = "IsDenyGripping")) + bool bDenyGripping; + + UPROPERTY(BlueprintReadOnly, Category = "VRGripInterface", meta = (ScriptName = "IsCurrentlyHeld")) + bool bIsHeld; // Set on grip notify, not net serializing + + UPROPERTY(BlueprintReadOnly, Category = "VRGripInterface") + FBPGripPair HoldingGrip; // Set on grip notify, not net serializing + bool bOriginalReplicatesMovement; + + TWeakObjectPtr ParentComponent; + + // Should be called after the lever is moved post begin play + UFUNCTION(BlueprintCallable, Category = "VRLeverComponent") + void ResetInitialLeverLocation(bool bAllowThrowingEvents = true); + + /** + * Sets the angle of the lever forcefully + * @param NewAngle The new angle to use, for single axis levers the sign of the angle will be used + * @param DualAxisForwardVector Only used with dual axis levers, you need to define the forward axis for the angle to apply too + */ + UFUNCTION(BlueprintCallable, Category = "VRLeverComponent") + void SetLeverAngle(float NewAngle, FVector DualAxisForwardVector, bool bAllowThrowingEvents = true); + + // ReCalculates the current angle, sets it on the back end, and returns it + // If allow throwing events is true then it will trigger the callbacks for state changes as well + UFUNCTION(BlueprintCallable, Category = "VRLeverComponent") + float ReCalculateCurrentAngle(bool bAllowThrowingEvents = true); + + void ProccessCurrentState(bool bWasLerping = false, bool bThrowEvents = true, bool bCheckAutoDrop = true); + + virtual void OnUnregister() override; + + // Called when a object is gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnGripped; + + // Called when a object is dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnDropSignature OnDropped; + + // Grip interface setup + + // Set up as deny instead of allow so that default allows for gripping + // The GripInitiator is not guaranteed to be valid, check it for validity + bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override; + + // How an interfaced object behaves when teleporting + EGripInterfaceTeleportBehavior TeleportBehavior_Implementation() override; + + // Should this object simulate on drop + bool SimulateOnDrop_Implementation() override; + + // Grip type to use + EGripCollisionType GetPrimaryGripType_Implementation(bool bIsSlot) override; + + // Secondary grip type + ESecondaryGripType SecondaryGripType_Implementation() override; + + // Define which movement repliation setting to use + EGripMovementReplicationSettings GripMovementReplicationType_Implementation() override; + + // Define the late update setting + EGripLateUpdateSettings GripLateUpdateSetting_Implementation() override; + + // What grip stiffness and damping to use if using a physics constraint + void GetGripStiffnessAndDamping_Implementation(float& GripStiffnessOut, float& GripDampingOut) override; + + // Get the advanced physics settings for this grip + FBPAdvGripSettings AdvancedGripSettings_Implementation() override; + + // What distance to break a grip at (only relevent with physics enabled grips + float GripBreakDistance_Implementation() override; + + // Get grip slot in range + void ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool& bHadSlotInRange, FTransform& SlotWorldTransform, FName& SlotName, UGripMotionControllerComponent* CallingController = nullptr, FName OverridePrefix = NAME_None) override; + + // Check if an object allows multiple grips at one time + bool AllowsMultipleGrips_Implementation() override; + + // Returns if the object is held and if so, which controllers are holding it + void IsHeld_Implementation(TArray& CurHoldingControllers, bool& bCurIsHeld) override; + + // Interface function used to throw the delegates that is invisible to blueprints so that it can't be overridden + virtual void Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Sets is held, used by the plugin + void SetHeld_Implementation(UGripMotionControllerComponent* NewHoldingController, uint8 GripID, bool bNewIsHeld) override; + + // Returns if the object wants to be socketed + bool RequestsSocketing_Implementation(USceneComponent*& ParentToSocketTo, FName& OptionalSocketName, FTransform_NetQuantize& RelativeTransform) override; + + // Get grip scripts + bool GetGripScripts_Implementation(TArray& ArrayReference) override; + + + // Events // + + // Event triggered each tick on the interfaced object when gripped, can be used for custom movement or grip based logic + void TickGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation, float DeltaTime) override; + + // Event triggered on the interfaced object when gripped + void OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when grip is released + void OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when child component is gripped + void OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when child component is released + void OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when secondary gripped + void OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when secondary grip is released + void OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Interaction Functions + + // Call to use an object + void OnUsed_Implementation() override; + + // Call to stop using an object + void OnEndUsed_Implementation() override; + + // Call to use an object + void OnSecondaryUsed_Implementation() override; + + // Call to stop using an object + void OnEndSecondaryUsed_Implementation() override; + + // Call to send an action event to the object + void OnInput_Implementation(FKey Key, EInputEvent KeyEvent) override; + + protected: + +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRMountComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRMountComponent.h new file mode 100644 index 0000000..97d2a78 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRMountComponent.h @@ -0,0 +1,254 @@ + +#pragma once + +#include "CoreMinimal.h" +#include "GameplayTagContainer.h" +#include "GameplayTagAssetInterface.h" +#include "Components/StaticMeshComponent.h" +#include "Interactibles/VRInteractibleFunctionLibrary.h" +#include "VRGripInterface.h" +#include "VRMountComponent.generated.h" + +class UGripMotionControllerComponent; + + +UENUM(Blueprintable) +enum class EVRInteractibleMountAxis : uint8 +{ + /** Limit Rotation to Yaw and Roll */ + Axis_XZ +}; + +// A mounted lever/interactible implementation - Created by SpaceHarry - Merged into the plugin 01/29/2018 +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UVRMountComponent : public UStaticMeshComponent, public IVRGripInterface, public IGameplayTagAssetInterface +{ + GENERATED_BODY() + +public: + UVRMountComponent(const FObjectInitializer& ObjectInitializer); + + + ~UVRMountComponent(); + + + // Rotation axis to use, XY is combined X and Y, only LerpToZero and PositiveLimits work with this mode + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMountComponent") + EVRInteractibleMountAxis MountRotationAxis; + + // Resetting the initial transform here so that it comes in prior to BeginPlay and save loading. + virtual void OnRegister() override; + + FTransform InitialRelativeTransform; + FVector InitialInteractorLocation; + FVector InitialInteractorDropLocation; + float InitialGripRot; + FQuat qRotAtGrab; + + // If the mount is swirling around a 90 degree pitch increase this number by 0.1 steps. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMountComponent") + float FlipingZone; + + // If the mount feels lagging behind in yaw at some point after 90 degree pitch increase this number by 0.1 steps + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMountComponent") + float FlipReajustYawSpeed; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripSettings") + int GripPriority; + + // Sets the grip priority + UFUNCTION(BlueprintCallable, Category = "GripSettings") + void SetGripPriority(int NewGripPriority); + + bool GrippedOnBack; + + bool bIsInsideFrontFlipingZone; + bool bIsInsideBackFlipZone; + FVector CurInterpGripLoc; + + float TwistDiff; + FVector InitialGripToForwardVec; + FVector InitialForwardVector; + FVector EntryUpXYNeg; + FVector EntryUpVec; + FVector EntryRightVec; + + bool bFirstEntryToHalfFlipZone; + bool bLerpingOutOfFlipZone; + bool bIsFlipped; + + FPlane FlipPlane; + FPlane ForwardPullPlane; + FVector LastPointOnForwardPlane; + FVector CurPointOnForwardPlane; + + float LerpOutAlpha; + + // ------------------------------------------------ + // Gameplay tag interface + // ------------------------------------------------ + + /** Overridden to return requirements tags */ + virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override + { + TagContainer = GameplayTags; + } + +protected: + /** Tags that are set on this object */ + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") + FGameplayTagContainer GameplayTags; + // End Gameplay Tag Interface + + // Requires bReplicates to be true for the component + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + bool bRepGameplayTags; + + // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") + bool bReplicateMovement; +public: + FGameplayTagContainer& GetGameplayTags(); + bool GetRepGameplayTags() { return bRepGameplayTags; } + void SetRepGameplayTags(bool bNewRepGameplayTags); + bool GetReplicateMovement() { return bReplicateMovement; } + void SetReplicateMovement(bool bNewReplicateMovement); + + virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override; + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; + virtual void BeginPlay() override; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + EGripMovementReplicationSettings MovementReplicationSetting; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + float Stiffness; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + float Damping; + + // Distance before the object will break out of the hand, 0.0f == never will + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + float BreakDistance; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripSettings") + float PrimarySlotRange; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripSettings") + float SecondarySlotRange; + + // Should we deny gripping on this object + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface", meta = (ScriptName = "IsDenyGripping")) + bool bDenyGripping; + + UPROPERTY(BlueprintReadOnly, Category = "VRGripInterface", meta = (ScriptName = "IsCurrentlyHeld")) + bool bIsHeld; // Set on grip notify, not net serializing + + UPROPERTY(BlueprintReadOnly, Category = "VRGripInterface") + FBPGripPair HoldingGrip; // Set on grip notify, not net serializing + bool bOriginalReplicatesMovement; + + // Should be called after the Mount is moved post begin play + UFUNCTION(BlueprintCallable, Category = "VRMountComponent") + void ResetInitialMountLocation(); + + virtual void OnUnregister() override;; + + // Grip interface setup + + // Set up as deny instead of allow so that default allows for gripping + // The GripInitiator is not guaranteed to be valid, check it for validity + bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override; + + // How an interfaced object behaves when teleporting + EGripInterfaceTeleportBehavior TeleportBehavior_Implementation() override; + + // Should this object simulate on drop + bool SimulateOnDrop_Implementation() override; + + // Grip type to use + EGripCollisionType GetPrimaryGripType_Implementation(bool bIsSlot) override; + + // Secondary grip type + ESecondaryGripType SecondaryGripType_Implementation() override; + + // Define which movement repliation setting to use + EGripMovementReplicationSettings GripMovementReplicationType_Implementation() override; + + // Define the late update setting + EGripLateUpdateSettings GripLateUpdateSetting_Implementation() override; + + // What grip stiffness and damping to use if using a physics constraint + void GetGripStiffnessAndDamping_Implementation(float& GripStiffnessOut, float& GripDampingOut) override; + + // Get the advanced physics settings for this grip + FBPAdvGripSettings AdvancedGripSettings_Implementation() override; + + // What distance to break a grip at (only relevent with physics enabled grips + float GripBreakDistance_Implementation() override; + + // Get grip slot in range + void ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool& bHadSlotInRange, FTransform& SlotWorldTransform, FName& SlotName, UGripMotionControllerComponent* CallingController = nullptr, FName OverridePrefix = NAME_None) override; + + // Check if an object allows multiple grips at one time + bool AllowsMultipleGrips_Implementation() override; + + // Returns if the object is held and if so, which controllers are holding it + void IsHeld_Implementation(TArray& CurHoldingControllers, bool& bCurIsHeld) override; + + // Sets is held, used by the plugin + void SetHeld_Implementation(UGripMotionControllerComponent* NewHoldingController, uint8 GripID, bool bNewIsHeld) override; + + // Returns if the object wants to be socketed + bool RequestsSocketing_Implementation(USceneComponent*& ParentToSocketTo, FName& OptionalSocketName, FTransform_NetQuantize& RelativeTransform) override; + + // Get grip scripts + bool GetGripScripts_Implementation(TArray& ArrayReference) override; + + + // Events // + + // Event triggered each tick on the interfaced object when gripped, can be used for custom movement or grip based logic + void TickGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation, float DeltaTime) override; + + // Event triggered on the interfaced object when gripped + void OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when grip is released + void OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when child component is gripped + void OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when child component is released + void OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when secondary gripped + void OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when secondary grip is released + void OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Interaction Functions + + // Call to use an object + void OnUsed_Implementation() override; + + // Call to stop using an object + void OnEndUsed_Implementation() override; + + // Call to use an object + void OnSecondaryUsed_Implementation() override; + + // Call to stop using an object + void OnEndSecondaryUsed_Implementation() override; + + // Call to send an action event to the object + void OnInput_Implementation(FKey Key, EInputEvent KeyEvent) override; + +protected: + + + +}; + diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRSliderComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRSliderComponent.h new file mode 100644 index 0000000..61d5c0b --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Interactibles/VRSliderComponent.h @@ -0,0 +1,423 @@ +// Fill out your copyright notice in the Description page of Project Settings. +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "GameplayTagContainer.h" +#include "VRGripInterface.h" +#include "GameplayTagAssetInterface.h" +#include "Interactibles/VRInteractibleFunctionLibrary.h" +#include "Components/StaticMeshComponent.h" +#include "VRSliderComponent.generated.h" + +class UGripMotionControllerComponent; +class USplineComponent; + +UENUM(Blueprintable) +enum class EVRInteractibleSliderLerpType : uint8 +{ + Lerp_None, + Lerp_Interp, + Lerp_InterpConstantTo +}; + +UENUM(Blueprintable) +enum class EVRInteractibleSliderDropBehavior : uint8 +{ + /** Stays in place on drop */ + Stay, + + /** Retains momentum on release*/ + RetainMomentum +}; + +/** Delegate for notification when the slider state changes. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FVRSliderHitPointSignature, float, SliderProgressPoint); +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FVRSliderFinishedLerpingSignature, float, FinalProgress); + +/** +* A slider component, can act like a scroll bar, or gun bolt, or spline following component +*/ +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UVRSliderComponent : public UStaticMeshComponent, public IVRGripInterface, public IGameplayTagAssetInterface +{ + GENERATED_BODY() + +public: + UVRSliderComponent(const FObjectInitializer& ObjectInitializer); + + + ~UVRSliderComponent(); + + // Call to use an object + UPROPERTY(BlueprintAssignable, Category = "VRSliderComponent") + FVRSliderHitPointSignature OnSliderHitPoint; + + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Slider State Changed")) + void ReceiveSliderHitPoint(float SliderProgressPoint); + + UPROPERTY(BlueprintAssignable, Category = "VRSliderComponent") + FVRSliderFinishedLerpingSignature OnSliderFinishedLerping; + + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Slider Finished Lerping")) + void ReceiveSliderFinishedLerping(float FinalProgress); + + // If true then this slider will only update in its tick event instead of normally using the controllers update event + // Keep in mind that you then must adjust the tick group in order to make sure it happens after the gripping controller + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent") + bool bUpdateInTick; + bool bPassThrough; + + float LastSliderProgressState; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent") + FVector MaxSlideDistance; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent") + FVector MinSlideDistance; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent") + EVRInteractibleSliderDropBehavior SliderBehaviorWhenReleased; + + // Number of frames to average momentum across for the release momentum (avoids quick waggles) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent|Momentum Settings", meta = (ClampMin = "0", ClampMax = "12", UIMin = "0", UIMax = "12")) + int FramesToAverage; + + // Units in % of total length per second to slow a momentum lerp down + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent|Momentum Settings", meta = (ClampMin = "0.0", ClampMax = "10.0", UIMin = "0.0", UIMax = "10.0")) + float SliderMomentumFriction; + + // % of elasticity on reaching the end 0 - 1.0 + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent|Momentum Settings", meta = (ClampMin = "0.0", ClampMax = "1.0", UIMin = "0.0", UIMax = "1.0")) + float SliderRestitution; + + // Maximum momentum of the slider in units of the total distance per second (0.0 - 1.0) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent|Momentum Settings", meta = (ClampMin = "0.0", UIMin = "0.0")) + float MaxSliderMomentum; + + UPROPERTY(BlueprintReadOnly, Category = "VRSliderComponent") + bool bIsLerping; + + // For momentum retention + FVector MomentumAtDrop; + FVector LastSliderProgress; + float SplineMomentumAtDrop; + float SplineLastSliderProgress; + + // Gets filled in with the current slider location progress + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "VRSliderComponent") + float CurrentSliderProgress; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent") + bool bSlideDistanceIsInParentSpace; + + // If true then this slider is locked in place until unlocked again + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent") + bool bIsLocked; + + // If true then this slider will auto drop even when locked + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent") + bool bAutoDropWhenLocked; + + // Sets if the slider is locked or not + UFUNCTION(BlueprintCallable, Category = "GripSettings") + void SetIsLocked(bool bNewLockedState); + + // Uses the legacy slider logic that doesn't ABS the min and max values + // Retains compatibility with some older projects + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent") + bool bUseLegacyLogic; + + // How far away from an event state before the slider allows throwing the same state again, default of 1.0 means it takes a full toggle + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent", meta = (ClampMin = "0.0", ClampMax = "1.0", UIMin = "0.0", UIMax = "1.0")) + float EventThrowThreshold; + bool bHitEventThreshold; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripSettings") + float PrimarySlotRange; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripSettings") + float SecondarySlotRange; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripSettings") + int GripPriority; + + // Sets the grip priority + UFUNCTION(BlueprintCallable, Category = "GripSettings") + void SetGripPriority(int NewGripPriority); + +protected: + // Set this to assign a spline component to the slider + UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Replicated/*Using = OnRep_SplineComponentToFollow*/, Category = "VRSliderComponent") + TObjectPtr SplineComponentToFollow; +public: + // Gets the initial relative transform, if you want to set it you should be using ResetInitialButtonLocation + TObjectPtr GetSplineComponentToFollow() { return SplineComponentToFollow; } + + /*UFUNCTION() + virtual void OnRep_SplineComponentToFollow() + { + CalculateSliderProgress(); + }*/ + + // Where the slider should follow the rotation and scale of the spline as well + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent") + bool bFollowSplineRotationAndScale; + + // Does not allow the slider to skip past nodes on the spline, it requires it to progress from node to node + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent") + bool bEnforceSplineLinearity; + float LastInputKey; + float LerpedKey; + + // Type of lerp to use when following a spline + // For lerping I would suggest using ConstantTo in general as it will be the smoothest. + // Normal Interp will change speed based on distance, that may also have its uses. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent") + EVRInteractibleSliderLerpType SplineLerpType; + + // Lerp Value for the spline, when in InterpMode it is the speed of interpolation + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent", meta = (ClampMin = "0", UIMin = "0")) + float SplineLerpValue; + + // Uses snap increments to move between, not compatible with retain momentum. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent") + bool bSliderUsesSnapPoints; + + // Portion of the slider that the slider snaps to on release and when within the threshold distance + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent", meta = (editcondition = "bSliderUsesSnapPoints", ClampMin = "0.0", ClampMax = "1.0", UIMin = "0.0", UIMax = "1.0")) + float SnapIncrement; + + // Threshold distance that when within the slider will stay snapped to its current snap increment + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent", meta = (editcondition = "bSliderUsesSnapPoints", ClampMin = "0.0", ClampMax = "1.0", UIMin = "0.0", UIMax = "1.0")) + float SnapThreshold; + + // If true then the slider progress will keep incrementing between snap points if outside of the threshold + // However events will not be thrown + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRSliderComponent", meta = (editcondition = "bSliderUsesSnapPoints") ) + bool bIncrementProgressBetweenSnapPoints; + + + // Resetting the initial transform here so that it comes in prior to BeginPlay and save loading. + virtual void OnRegister() override; + +protected: + // Now replicating this so that it works correctly over the network + UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_InitialRelativeTransform, Category = "VRSliderComponent") + FTransform_NetQuantize InitialRelativeTransform; +public: + // Gets the initial relative transform, if you want to set it you should be using ResetInitialButtonLocation + FTransform GetInitialRelativeTransform() { return InitialRelativeTransform; } + + UFUNCTION() + virtual void OnRep_InitialRelativeTransform() + { + CalculateSliderProgress(); + } + + FVector InitialInteractorLocation; + FVector InitialGripLoc; + FVector InitialDropLocation; + + // Checks if we should throw some events + void CheckSliderProgress(); + + /* + Credit to: + https://github.com/Seurabimn + + Who had this function in an engine pull request: + https://github.com/EpicGames/UnrealEngine/pull/6646 + */ + float GetDistanceAlongSplineAtSplineInputKey(float InKey) const; + + // Calculates the current slider progress + UFUNCTION(BlueprintCallable, Category = "VRSliderComponent") + float CalculateSliderProgress(); + + // Forcefully sets the slider progress to the defined value + UFUNCTION(BlueprintCallable, Category = "VRSliderComponent") + void SetSliderProgress(float NewSliderProgress); + + // Should be called after the slider is moved post begin play + UFUNCTION(BlueprintCallable, Category = "VRSliderComponent") + void ResetInitialSliderLocation(); + + // Sets the spline component to follow, if empty, just reinitializes the transform and removes the follow component + UFUNCTION(BlueprintCallable, Category = "VRSliderComponent") + void SetSplineComponentToFollow(USplineComponent * SplineToFollow); + + void ResetToParentSplineLocation(); + + void GetLerpedKey(float &ClosestKey, float DeltaTime); + float GetCurrentSliderProgress(FVector CurLocation, bool bUseKeyInstead = false, float CurKey = 0.f); + + // Returns the slider progress as it is currently per axis (not the total progress, just the amount per axis that has a min/max) + UFUNCTION(BlueprintCallable, Category = "VRSliderComponent") + FVector GetPerAxisSliderProgress(); + + FVector ClampSlideVector(FVector ValueToClamp); + + // ------------------------------------------------ + // Gameplay tag interface + // ------------------------------------------------ + + /** Overridden to return requirements tags */ + virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override + { + TagContainer = GameplayTags; + } + +protected: + + /** Tags that are set on this object */ + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") + FGameplayTagContainer GameplayTags; + // End Gameplay Tag Interface + + // Requires bReplicates to be true for the component + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") + bool bRepGameplayTags; + + // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") + bool bReplicateMovement; +public: + FGameplayTagContainer& GetGameplayTags(); + bool GetRepGameplayTags() { return bRepGameplayTags; } + void SetRepGameplayTags(bool bNewRepGameplayTags); + bool GetReplicateMovement() { return bReplicateMovement; } + void SetReplicateMovement(bool bNewReplicateMovement); + + virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override; + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; + virtual void BeginPlay() override; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + EGripMovementReplicationSettings MovementReplicationSetting; + + // Distance before the object will break out of the hand, 0.0f == never will + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + float BreakDistance; + + // Checks and applies auto drop if we need too + bool CheckAutoDrop(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation); + + // Should we deny gripping on this object + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface", meta = (ScriptName = "IsDenyGripping")) + bool bDenyGripping; + + UPROPERTY(BlueprintReadOnly, Category = "VRGripInterface", meta = (ScriptName = "IsCurrentlyHeld")) + bool bIsHeld; // Set on grip notify, not net serializing + + UPROPERTY(BlueprintReadOnly, Category = "VRGripInterface") + FBPGripPair HoldingGrip; // Set on grip notify, not net serializing + bool bOriginalReplicatesMovement; + + // Called when a object is gripped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnGripSignature OnGripped; + + // Called when a object is dropped + UPROPERTY(BlueprintAssignable, Category = "Grip Events") + FVROnDropSignature OnDropped; + + // Grip interface setup + + // Set up as deny instead of allow so that default allows for gripping + // The GripInitiator is not guaranteed to be valid, check it for validity + bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override; + + // How an interfaced object behaves when teleporting + EGripInterfaceTeleportBehavior TeleportBehavior_Implementation() override; + + // Should this object simulate on drop + bool SimulateOnDrop_Implementation() override; + + // Grip type to use + EGripCollisionType GetPrimaryGripType_Implementation(bool bIsSlot) override; + + // Secondary grip type + ESecondaryGripType SecondaryGripType_Implementation() override; + + // Define which movement repliation setting to use + EGripMovementReplicationSettings GripMovementReplicationType_Implementation() override; + + // Define the late update setting + EGripLateUpdateSettings GripLateUpdateSetting_Implementation() override; + + // What grip stiffness and damping to use if using a physics constraint + void GetGripStiffnessAndDamping_Implementation(float& GripStiffnessOut, float& GripDampingOut) override; + + // Get the advanced physics settings for this grip + FBPAdvGripSettings AdvancedGripSettings_Implementation() override; + + // What distance to break a grip at (only relevent with physics enabled grips + float GripBreakDistance_Implementation() override; + + // Get grip slot in range + void ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool& bHadSlotInRange, FTransform& SlotWorldTransform, FName& SlotName, UGripMotionControllerComponent* CallingController = nullptr, FName OverridePrefix = NAME_None) override; + + // Check if an object allows multiple grips at one time + bool AllowsMultipleGrips_Implementation() override; + + // Returns if the object is held and if so, which controllers are holding it + void IsHeld_Implementation(TArray& CurHoldingControllers, bool& bCurIsHeld) override; + + // Interface function used to throw the delegates that is invisible to blueprints so that it can't be overridden + virtual void Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Sets is held, used by the plugin + void SetHeld_Implementation(UGripMotionControllerComponent* NewHoldingController, uint8 GripID, bool bNewIsHeld) override; + + // Returns if the object wants to be socketed + bool RequestsSocketing_Implementation(USceneComponent*& ParentToSocketTo, FName& OptionalSocketName, FTransform_NetQuantize& RelativeTransform) override; + + // Get grip scripts + bool GetGripScripts_Implementation(TArray& ArrayReference) override; + + + // Events // + + // Event triggered each tick on the interfaced object when gripped, can be used for custom movement or grip based logic + void TickGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation, float DeltaTime) override; + + // Event triggered on the interfaced object when gripped + void OnGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when grip is released + void OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when child component is gripped + void OnChildGrip_Implementation(UGripMotionControllerComponent* GrippingController, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when child component is released + void OnChildGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false) override; + + // Event triggered on the interfaced object when secondary gripped + void OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Event triggered on the interfaced object when secondary grip is released + void OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) override; + + // Interaction Functions + + // Call to use an object + void OnUsed_Implementation() override; + + // Call to stop using an object + void OnEndUsed_Implementation() override; + + // Call to use an object + void OnSecondaryUsed_Implementation() override; + + // Call to stop using an object + void OnEndSecondaryUsed_Implementation() override; + + // Call to send an action event to the object + void OnInput_Implementation(FKey Key, EInputEvent KeyEvent) override; + + protected: + +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/BucketUpdateSubsystem.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/BucketUpdateSubsystem.h new file mode 100644 index 0000000..4dacd14 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/BucketUpdateSubsystem.h @@ -0,0 +1,169 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Subsystems/WorldSubsystem.h" +#include "Tickable.h" +#include "BucketUpdateSubsystem.generated.h" +//#include "GrippablePhysicsReplication.generated.h" + + +//DECLARE_DYNAMIC_MULTICAST_DELEGATE(FVRPhysicsReplicationDelegate, void, Return); + + +DECLARE_DELEGATE_RetVal(bool, FBucketUpdateTickSignature); +DECLARE_DYNAMIC_DELEGATE(FDynamicBucketUpdateTickSignature); + +USTRUCT() +struct VREXPANSIONPLUGIN_API FUpdateBucketDrop +{ + GENERATED_BODY() +public: + FBucketUpdateTickSignature NativeCallback; + FDynamicBucketUpdateTickSignature DynamicCallback; + + FName FunctionName; + + bool ExecuteBoundCallback(); + bool IsBoundToObjectFunction(UObject * Obj, FName & FuncName); + bool IsBoundToObjectDelegate(FDynamicBucketUpdateTickSignature & DynEvent); + bool IsBoundToObject(UObject * Obj); + FUpdateBucketDrop(); + FUpdateBucketDrop(FDynamicBucketUpdateTickSignature & DynCallback); + FUpdateBucketDrop(UObject * Obj, FName FuncName); +}; + + +USTRUCT() +struct VREXPANSIONPLUGIN_API FUpdateBucket +{ + GENERATED_BODY() + +public: + + float nUpdateRate; + float nUpdateCount; + + TArray Callbacks; + + bool Update(float DeltaTime); + + FUpdateBucket() {} + + FUpdateBucket(uint32 UpdateHTZ) : + nUpdateRate(1.0f / UpdateHTZ), + nUpdateCount(0.0f) + { + } +}; + +USTRUCT() +struct VREXPANSIONPLUGIN_API FUpdateBucketContainer +{ + GENERATED_BODY() +public: + + + bool bNeedsUpdate; + TMap ReplicationBuckets; + + void UpdateBuckets(float DeltaTime); + + bool AddBucketObject(uint32 UpdateHTZ, UObject* InObject, FName FunctionName); + bool AddBucketObject(uint32 UpdateHTZ, FDynamicBucketUpdateTickSignature &Delegate); + + /* + template + bool AddReplicatingObject(uint32 UpdateHTZ, classType* InObject, void(classType::* _Func)()) + { + } + */ + + bool RemoveBucketObject(UObject * ObjectToRemove, FName FunctionName); + bool RemoveBucketObject(FDynamicBucketUpdateTickSignature &DynEvent); + bool RemoveObjectFromAllBuckets(UObject * ObjectToRemove); + + bool IsObjectInBucket(UObject * ObjectToRemove); + bool IsObjectFunctionInBucket(UObject * ObjectToRemove, FName FunctionName); + bool IsObjectDelegateInBucket(FDynamicBucketUpdateTickSignature &DynEvent); + + FUpdateBucketContainer() + { + bNeedsUpdate = false; + }; + +}; + +UCLASS() +class VREXPANSIONPLUGIN_API UBucketUpdateSubsystem : public UTickableWorldSubsystem +{ + GENERATED_BODY() + +public: + UBucketUpdateSubsystem() : + Super() + { + + } + + virtual bool DoesSupportWorldType(EWorldType::Type WorldType) const override + { + return WorldType == EWorldType::Game || WorldType == EWorldType::PIE; + // Not allowing for editor type as this is a replication subsystem + } + + //UPROPERTY() + FUpdateBucketContainer BucketContainer; + + // Adds an object to an update bucket with the set HTZ, calls the passed in UFUNCTION name + // If one of the bucket contains an entry with the function already then the existing one is removed and the new one is added + bool AddObjectToBucket(int32 UpdateHTZ, UObject* InObject, FName FunctionName); + + // Adds an object to an update bucket with the set HTZ, calls the passed in UFUNCTION name + // If one of the bucket contains an entry with the function already then the existing one is removed and the new one is added + UFUNCTION(BlueprintCallable, meta = (DisplayName = "Add Object to Bucket Updates", ScriptName = "AddObjectToBucket"), Category = "BucketUpdateSubsystem") + bool K2_AddObjectToBucket(int32 UpdateHTZ = 100, UObject* InObject = nullptr, FName FunctionName = NAME_None); + + UFUNCTION(BlueprintCallable, meta = (DisplayName = "Add Object to Bucket Updates by Event", ScriptName = "AddBucketObjectEvent"), Category = "BucketUpdateSubsystem") + bool K2_AddObjectEventToBucket(UPARAM(DisplayName = "Event") FDynamicBucketUpdateTickSignature Delegate, int32 UpdateHTZ = 100); + + // Remove the entry in the bucket updates with the passed in UFUNCTION name + UFUNCTION(BlueprintCallable, meta = (DisplayName = "Remove Object From Bucket Updates By Function", ScriptName = "RemoveObjectFromBucketByFunction"), Category = "BucketUpdateSubsystem") + bool RemoveObjectFromBucketByFunctionName(UObject* InObject = nullptr, FName FunctionName = NAME_None); + + // Remove the entry in the bucket updates with the passed in UFUNCTION name + UFUNCTION(BlueprintCallable, meta = (DisplayName = "Remove Object From Bucket Updates By Event", ScriptName = "RemoveObjectFromBucketByEvent"), Category = "BucketUpdateSubsystem") + bool RemoveObjectFromBucketByEvent(UPARAM(DisplayName = "Event") FDynamicBucketUpdateTickSignature Delegate); + + // Removes ALL entries in the bucket update system with the specified object + UFUNCTION(BlueprintCallable, meta = (DisplayName = "Remove Object From All Bucket Updates", ScriptName = "RemoveObjectFromAllBuckets"), Category = "BucketUpdateSubsystem") + bool RemoveObjectFromAllBuckets(UObject* InObject = nullptr); + + // Returns if an update bucket contains an entry with the passed in function + UFUNCTION(BlueprintCallable, meta = (DisplayName = "Is Object In Bucket", ScriptName = "IsObjectInBucket"), Category = "BucketUpdateSubsystem") + bool IsObjectFunctionInBucket(UObject* InObject = nullptr, FName FunctionName = NAME_None); + + // Returns if an update bucket contains an entry with the passed in function + UFUNCTION(BlueprintPure, Category = "BucketUpdateSubsystem") + bool IsActive(); + + // FTickableGameObject functions + /** + * Function called every frame on this GripScript. Override this function to implement custom logic to be executed every frame. + * Only executes if bCanEverTick is true and bAllowTicking is true + * + * @param DeltaTime - The time since the last tick. + */ + + virtual void Tick(float DeltaTime) override; + virtual bool IsTickable() const override; + virtual UWorld* GetTickableGameObjectWorld() const override; + virtual bool IsTickableInEditor() const; + virtual bool IsTickableWhenPaused() const override; + virtual ETickableTickType GetTickableTickType() const; + virtual TStatId GetStatId() const override; + + // End tickable object information + +}; diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/CollisionIgnoreSubsystem.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/CollisionIgnoreSubsystem.h new file mode 100644 index 0000000..d9d9c60 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/CollisionIgnoreSubsystem.h @@ -0,0 +1,247 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Subsystems/WorldSubsystem.h" +#include "TimerManager.h" +#include "Components/PrimitiveComponent.h" +//#include "Grippables/GrippablePhysicsReplication.h" + +// For async physics scene callback modifications +// Some of these can be moved out to the cpp +#include "Chaos/SimCallbackObject.h" +#include "Chaos/SimCallbackInput.h" +#include "Chaos/ParticleHandle.h" +//#include "Chaos/ContactModification.h" +//#include "PBDRigidsSolver.h" + + +#include "CollisionIgnoreSubsystem.generated.h" +//#include "GrippablePhysicsReplication.generated.h" + + + + +DECLARE_LOG_CATEGORY_EXTERN(VRE_CollisionIgnoreLog, Log, All); + + +USTRUCT() +struct FChaosParticlePair +{ + GENERATED_BODY() + + Chaos::TPBDRigidParticleHandle* ParticleHandle0; + Chaos::TPBDRigidParticleHandle* ParticleHandle1; + + FChaosParticlePair() + { + ParticleHandle0 = nullptr; + ParticleHandle1 = nullptr; + } + + FChaosParticlePair(Chaos::TPBDRigidParticleHandle* pH1, Chaos::TPBDRigidParticleHandle* pH2) + { + ParticleHandle0 = pH1; + ParticleHandle1 = pH2; + } + + FORCEINLINE bool operator==(const FChaosParticlePair& Other) const + { + return( + (ParticleHandle0 == Other.ParticleHandle0 || ParticleHandle0 == Other.ParticleHandle1) && + (ParticleHandle1 == Other.ParticleHandle1 || ParticleHandle1 == Other.ParticleHandle0) + ); + } +}; + +/* +* All input is const, non-const data goes in output. 'AsyncSimState' points to non-const sim state. +*/ +struct FSimCallbackInputVR : public Chaos::FSimCallbackInput +{ + virtual ~FSimCallbackInputVR() {} + void Reset() + { + ParticlePairs.Empty(); + } + + TArray ParticlePairs; + + bool bIsInitialized; +}; + +struct FSimCallbackNoOutputVR : public Chaos::FSimCallbackOutput +{ + void Reset() {} +}; + +class FCollisionIgnoreSubsystemAsyncCallback : public Chaos::TSimCallbackObject +{ + +private: + + virtual void OnPreSimulate_Internal() override + { + // Copy paired bodies here? + + // Actually use input data to input our paired bodies and copy over here + } + + /** + * Called once per simulation step. Allows user to modify contacts + * + * NOTE: you must explicitly request contact modification when registering the callback for this to be called + */ + virtual void OnContactModification_Internal(Chaos::FCollisionContactModifier& Modifier) override; + +}; + + +USTRUCT() +struct FCollisionPrimPair +{ + GENERATED_BODY() +public: + + UPROPERTY() + TObjectPtr Prim1; + UPROPERTY() + TObjectPtr Prim2; + + FCollisionPrimPair() + { + Prim1 = nullptr; + Prim2 = nullptr; + } + + FORCEINLINE bool operator==(const FCollisionPrimPair& Other) const + { + if (!IsValid(Prim1) || !IsValid(Prim2)) + return false; + + if (!IsValid(Other.Prim1) || !IsValid(Other.Prim2)) + return false; + + return( + (Prim1.Get() == Other.Prim1.Get() || Prim1.Get() == Other.Prim2.Get()) && + (Prim2.Get() == Other.Prim1.Get() || Prim2.Get() == Other.Prim2.Get()) + ); + } + + friend uint32 GetTypeHash(const FCollisionPrimPair& InKey) + { + return GetTypeHash(InKey.Prim1) ^ GetTypeHash(InKey.Prim2); + } + +}; + +USTRUCT() +struct FCollisionIgnorePair +{ + GENERATED_BODY() +public: + + ///FCollisionPrimPair PrimitivePair; + FPhysicsActorHandle Actor1; + UPROPERTY() + FName BoneName1; + FPhysicsActorHandle Actor2; + UPROPERTY() + FName BoneName2; + + // Flip our elements to retain a default ordering in an array + void FlipElements() + { + FPhysicsActorHandle tH = Actor1; + Actor1 = Actor2; + Actor2 = tH; + + FName tN = BoneName1; + BoneName1 = BoneName2; + BoneName2 = tN; + } + + FORCEINLINE bool operator==(const FCollisionIgnorePair& Other) const + { + return ( + (BoneName1 == Other.BoneName1 || BoneName1 == Other.BoneName2) && + (BoneName2 == Other.BoneName2 || BoneName2 == Other.BoneName1) + ); + } + + FORCEINLINE bool operator==(const FName& Other) const + { + return (BoneName1 == Other || BoneName2 == Other); + } +}; + +USTRUCT() +struct FCollisionIgnorePairArray +{ + GENERATED_BODY() +public: + + UPROPERTY() + TArray PairArray; +}; + +UCLASS() +class VREXPANSIONPLUGIN_API UCollisionIgnoreSubsystem : public UWorldSubsystem +{ + GENERATED_BODY() + +public: + + + UCollisionIgnoreSubsystem() : + Super() + { + ContactModifierCallback = nullptr; + } + + FCollisionIgnoreSubsystemAsyncCallback* ContactModifierCallback; + + void ConstructInput(); + + virtual bool DoesSupportWorldType(EWorldType::Type WorldType) const override + { + return WorldType == EWorldType::Game || WorldType == EWorldType::PIE; + // Not allowing for editor type as this is a replication subsystem + } + + /** Implement this for initialization of instances of the system */ + virtual void Initialize(FSubsystemCollectionBase& Collection) override + { + Super::Initialize(Collection); + } + + virtual void Deinitialize() override; + + UPROPERTY() + TMap CollisionTrackedPairs; + //TArray CollisionTrackedPairs; + + UPROPERTY() + TMap RemovedPairs; + //TArray RemovedPairs; + + // + void UpdateTimer(bool bChangesWereMade); + + UFUNCTION(Category = "Collision") + void CheckActiveFilters(); + + // #TODO implement this, though it should be rare + void InitiateIgnore(); + + void SetComponentCollisionIgnoreState(bool bIterateChildren1, bool bIterateChildren2, UPrimitiveComponent* Prim1, FName OptionalBoneName1, UPrimitiveComponent* Prim2, FName OptionalBoneName2, bool bIgnoreCollision, bool bCheckFilters = false); + void RemoveComponentCollisionIgnoreState(UPrimitiveComponent* Prim1); + bool IsComponentIgnoringCollision(UPrimitiveComponent* Prim1); + bool AreComponentsIgnoringCollisions(UPrimitiveComponent* Prim1, UPrimitiveComponent* Prim2); + bool HasCollisionIgnorePairs(); +private: + + FTimerHandle UpdateHandle; + +}; diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/OptionalRepSkeletalMeshActor.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/OptionalRepSkeletalMeshActor.h new file mode 100644 index 0000000..6204dfb --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/OptionalRepSkeletalMeshActor.h @@ -0,0 +1,139 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "GripMotionControllerComponent.h" +//#include "Engine/Engine.h" +#include "Animation/SkeletalMeshActor.h" +#include "Components/SkeletalMeshComponent.h" +#include "Components/SphereComponent.h" +#include "Engine/ActorChannel.h" +#include "OptionalRepSkeletalMeshActor.generated.h" + +// Temp comp to avoid some engine issues, exists only until a bug fix happens +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent, ChildCanTick), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UNoRepSphereComponent : public USphereComponent +{ + GENERATED_BODY() + +public: + UNoRepSphereComponent(const FObjectInitializer& ObjectInitializer); + +protected: + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Component Replication") + bool bReplicateMovement; +public: + bool GetReplicateMovement() { return bReplicateMovement; } + void SetReplicateMovement(bool bNewReplicateMovement); + + virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override; +}; + +/** +* A component specifically for being able to turn off movement replication in the component at will +* Has the upside of also being a blueprintable base since UE4 doesn't allow that with std ones +*/ + +USTRUCT() +struct FSkeletalMeshComponentEndPhysicsTickFunctionVR : public FTickFunction +{ + GENERATED_USTRUCT_BODY() + + UInversePhysicsSkeletalMeshComponent* TargetVR; + + virtual void ExecuteTick(float DeltaTime, enum ELevelTick TickType, ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent) override; + + virtual FString DiagnosticMessage() override; + + virtual FName DiagnosticContext(bool bDetailed) override; + +}; +template<> +struct TStructOpsTypeTraits : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithCopy = false + }; +}; + +// A base skeletal mesh component that has been added to temp correct an engine bug with inversed scale and physics +UCLASS(Blueprintable, meta = (ChildCanTick, BlueprintSpawnableComponent), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UInversePhysicsSkeletalMeshComponent : public USkeletalMeshComponent +{ + GENERATED_BODY() + +public: + UInversePhysicsSkeletalMeshComponent(const FObjectInitializer& ObjectInitializer); + +protected: + // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Component Replication") + bool bReplicateMovement; +public: + bool GetReplicateMovement() { return bReplicateMovement; } + void SetReplicateMovement(bool bNewReplicateMovement); + + + // This is all overrides to fix the skeletal mesh inverse simulation bug + // WILL BE REMOVED LATER when the engine is fixed + FSkeletalMeshComponentEndPhysicsTickFunctionVR EndPhysicsTickFunctionVR; + friend struct FSkeletalMeshComponentEndPhysicsTickFunctionVR; + void EndPhysicsTickComponentVR(FSkeletalMeshComponentEndPhysicsTickFunctionVR& ThisTickFunction); + void BlendInPhysicsInternalVR(FTickFunction& ThisTickFunction); + void FinalizeAnimationUpdateVR(); + + // Weld Fix until epic fixes it #TODO: check back in on this and remove and the asset include when epic fixes it + virtual void GetWeldedBodies(TArray& OutWeldedBodies, TArray& OutLabels, bool bIncludingAutoWeld) override; + virtual FBodyInstance* GetBodyInstance(FName BoneName = NAME_None, bool bGetWelded = true, int32 Index = INDEX_NONE) const override; + + virtual FBoxSphereBounds CalcBounds(const FTransform& LocalToWorld) const override + { + // Get rid of inverse issues + FTransform newLocalToWorld = LocalToWorld; + newLocalToWorld.SetScale3D(newLocalToWorld.GetScale3D().GetAbs()); + + return Super::CalcBounds(newLocalToWorld); + } + + UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions") + FBoxSphereBounds GetLocalBounds() const + { + return this->GetCachedLocalBounds(); + } + + void PerformBlendPhysicsBonesVR(const TArray& InRequiredBones, TArray& InOutComponentSpaceTransforms, TArray& InOutBoneSpaceTransforms); + virtual void RegisterEndPhysicsTick(bool bRegister) override; + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; + // END INVERSED MESH FIX + + virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; + +}; + +/** +* +* A class specifically for turning off default physics replication with a skeletal mesh and fixing an +* engine bug with inversed scale on skeletal meshes. Generally used for the physical hand setup. +*/ +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent, ChildCanTick), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API AOptionalRepGrippableSkeletalMeshActor : public ASkeletalMeshActor +{ + GENERATED_BODY() + +public: + AOptionalRepGrippableSkeletalMeshActor(const FObjectInitializer& ObjectInitializer); + + // Skips the attachment replication + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication") + bool bIgnoreAttachmentReplication; + + // Skips the physics replication + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication") + bool bIgnorePhysicsReplication; + + // Fix bugs with replication and bReplicateMovement + virtual void OnRep_ReplicateMovement() override; + virtual void PostNetReceivePhysicState() override; +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRAIPerceptionOverrides.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRAIPerceptionOverrides.h new file mode 100644 index 0000000..1006aef --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRAIPerceptionOverrides.h @@ -0,0 +1,400 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "UObject/ObjectMacros.h" +#include "VRBaseCharacter.h" +#include "GenericTeamAgentInterface.h" +#include "Perception/AISense.h" +#include "Perception/AISense_Sight.h" +#include "Perception/AISenseConfig.h" +#include "WorldCollision.h" +#include "Misc/MTAccessDetector.h" + +#include "VRAIPerceptionOverrides.generated.h" + +class IAISightTargetInterface; +class UAISense_Sight_VR; + +class FGameplayDebuggerCategory; +class UAIPerceptionComponent; + +DECLARE_LOG_CATEGORY_EXTERN(LogAIPerceptionVR, Warning, All); + +UCLASS(meta = (DisplayName = "AI Sight VR config")) +class VREXPANSIONPLUGIN_API UAISenseConfig_Sight_VR : public UAISenseConfig +{ + GENERATED_UCLASS_BODY() + +public: + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Sense", NoClear, config) + TSubclassOf Implementation; + + /** Maximum sight distance to notice a target. */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Sense", config, meta = (UIMin = 0.0, ClampMin = 0.0)) + float SightRadius; + + /** Maximum sight distance to see target that has been already seen. */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Sense", config, meta = (UIMin = 0.0, ClampMin = 0.0)) + float LoseSightRadius; + + /** How far to the side AI can see, in degrees. Use SetPeripheralVisionAngle to change the value at runtime. + * The value represents the angle measured in relation to the forward vector, not the whole range. */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Sense", config, meta = (UIMin = 0.0, ClampMin = 0.0, UIMax = 180.0, ClampMax = 180.0, DisplayName = "PeripheralVisionHalfAngleDegrees")) + float PeripheralVisionAngleDegrees; + + /** */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Sense", config) + FAISenseAffiliationFilter DetectionByAffiliation; + + /** If not an InvalidRange (which is the default), we will always be able to see the target that has already been seen if they are within this range of their last seen location. */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Sense", config) + float AutoSuccessRangeFromLastSeenLocation; + + /** Point of view move back distance for cone calculation. In conjunction with near clipping distance, this will act as a close by awareness and peripheral vision. */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Sense", config, meta = (UIMin = 0.0, ClampMin = 0.0)) + float PointOfViewBackwardOffset; + + /** Near clipping distance, to be used with point of view backward offset. Will act as a close by awareness and peripheral vision */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Sense", config, meta = (UIMin = 0.0, ClampMin = 0.0)) + float NearClippingRadius; + + virtual TSubclassOf GetSenseImplementation() const override; + + +#if WITH_EDITOR + virtual void PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent) override; +#endif // WITH_EDITOR + +#if WITH_GAMEPLAY_DEBUGGER + virtual void DescribeSelfToGameplayDebugger(const UAIPerceptionComponent* PerceptionComponent, FGameplayDebuggerCategory* DebuggerCategory) const; +#endif // WITH_GAMEPLAY_DEBUGGER + +}; + + +namespace ESightPerceptionEventNameVR +{ + enum Type + { + Undefined, + GainedSight, + LostSight + }; +} + +USTRUCT() +struct VREXPANSIONPLUGIN_API FAISightEventVR +{ + GENERATED_USTRUCT_BODY() + + typedef UAISense_Sight_VR FSenseClass; + + float Age; + ESightPerceptionEventNameVR::Type EventType; + + UPROPERTY() + TObjectPtr SeenActor; + + UPROPERTY() + TObjectPtr Observer; + + FAISightEventVR() : SeenActor(nullptr), Observer(nullptr) {} + + FAISightEventVR(AActor* InSeenActor, AActor* InObserver, ESightPerceptionEventNameVR::Type InEventType) + : Age(0.f), EventType(InEventType), SeenActor(InSeenActor), Observer(InObserver) + { + } +}; + +struct FAISightTargetVR +{ + typedef uint32 FTargetId; + static const FTargetId InvalidTargetId; + + TWeakObjectPtr Target; + IAISightTargetInterface* SightTargetInterface; + FGenericTeamId TeamId; + FTargetId TargetId; + + FAISightTargetVR(AActor* InTarget = NULL, FGenericTeamId InTeamId = FGenericTeamId::NoTeam); + + FORCEINLINE FVector GetLocationSimple() const + { + // Changed this up to support my VR Characters + const AVRBaseCharacter * VRChar = Cast(Target); + return Target.IsValid() ? (VRChar != nullptr ? VRChar->GetVRLocation_Inline() : Target->GetActorLocation()) : FVector::ZeroVector; + } + + FORCEINLINE const AActor* GetTargetActor() const { return Target.Get(); } +}; + +struct FAISightQueryVR +{ + FPerceptionListenerID ObserverId; + FAISightTargetVR::FTargetId TargetId; + + float Score; + float Importance; + + FVector LastSeenLocation; + + /** User data that can be used inside the IAISightTargetInterface::CanBeSeenFrom method to store a persistence state */ + mutable int32 UserData; + + union + { + /** + * We can share the memory for these values because they aren't used at the same time : + * - The FrameInfo is used when the query is queued for an update at a later frame. It stores the last time the + * query was processed so that we can prioritize it accordingly against the other queries + * - The TraceInfo is used when the query has requested a asynchronous trace and is waiting for the result. + * The engine guarantees that we'll get the info at the next frame, but since we can have multiple queries that + * are pending at the same time, we need to store some information to identify them when receiving the result callback + */ + + struct + { + uint64 bLastResult : 1; + uint64 LastProcessedFrameNumber : 63; + } FrameInfo; + + /** + * The 'FrameNumber' value can increase indefinitely while the 'Index' represents the number of queries that were + * already requested during this frame. So it shouldn't reach high values in the allocated 32 bits. + * Thanks to that we can reliable only use 31 bits for this value and thus have space to keep the bLastResult value + */ + struct + { + uint32 bLastResult : 1; + uint32 Index : 31; + uint32 FrameNumber; + } TraceInfo; + }; + + FAISightQueryVR(FPerceptionListenerID ListenerId = FPerceptionListenerID::InvalidID(), FAISightTargetVR::FTargetId Target = FAISightTargetVR::InvalidTargetId) + : ObserverId(ListenerId), TargetId(Target), Score(0), Importance(0), LastSeenLocation(FAISystem::InvalidLocation), UserData(0) + { + FrameInfo.bLastResult = false; + FrameInfo.LastProcessedFrameNumber = GFrameCounter; + } + + /** + * Note: This should only be called on queries that are queued up for later processing (in SightQueriesOutOfRange or SightQueriesOutOfRange) + */ + float GetAge() const + { + return (float)(GFrameCounter - FrameInfo.LastProcessedFrameNumber); + } + + /** + * Note: This should only be called on queries that are queued up for later processing (in SightQueriesOutOfRange or SightQueriesOutOfRange) + */ + void RecalcScore() + { + Score = GetAge() + Importance; + } + + void OnProcessed() + { + FrameInfo.LastProcessedFrameNumber = GFrameCounter; + } + + void ForgetPreviousResult() + { + LastSeenLocation = FAISystem::InvalidLocation; + SetLastResult(false); + } + + bool GetLastResult() const + { + return FrameInfo.bLastResult; + } + + void SetLastResult(const bool bValue) + { + FrameInfo.bLastResult = bValue; + } + + /** + * Note: This only be called for pending queries because it will erase the LastProcessedFrameNumber value + */ + void SetTraceInfo(const FTraceHandle& TraceHandle) + { + check((TraceHandle._Data.Index & (static_cast(1) << 31)) == 0); + TraceInfo.Index = TraceHandle._Data.Index; + TraceInfo.FrameNumber = TraceHandle._Data.FrameNumber; + } + + class FSortPredicate + { + public: + FSortPredicate() + {} + + bool operator()(const FAISightQueryVR& A, const FAISightQueryVR& B) const + { + return A.Score > B.Score; + } + }; +}; + + +struct FAISightQueryIDVR +{ + FPerceptionListenerID ObserverId; + FAISightTargetVR::FTargetId TargetId; + + FAISightQueryIDVR(FPerceptionListenerID ListenerId = FPerceptionListenerID::InvalidID(), FAISightTargetVR::FTargetId Target = FAISightTargetVR::InvalidTargetId) + : ObserverId(ListenerId), TargetId(Target) + { + } + + FAISightQueryIDVR(const FAISightQueryVR& Query) + : ObserverId(Query.ObserverId), TargetId(Query.TargetId) + { + } +}; + +DECLARE_DELEGATE_FiveParams(FOnPendingVisibilityQueryProcessedDelegateVR, const FAISightQueryID&, const bool, const float, const FVector&, const TOptional&); + + +UCLASS(ClassGroup = AI, config = Game) +class VREXPANSIONPLUGIN_API UAISense_Sight_VR : public UAISense +{ + GENERATED_UCLASS_BODY() + +public: + struct FDigestedSightProperties + { + float PeripheralVisionAngleCos; + float SightRadiusSq; + float AutoSuccessRangeSqFromLastSeenLocation; + float LoseSightRadiusSq; + float PointOfViewBackwardOffset; + float NearClippingRadiusSq; + uint8 AffiliationFlags; + + FDigestedSightProperties(); + FDigestedSightProperties(const UAISenseConfig_Sight_VR& SenseConfig); + }; + + typedef TMap FTargetsContainer; + FTargetsContainer ObservedTargets; + TMap DigestedProperties; + + /** The SightQueries are a n^2 problem and to reduce the sort time, they are now split between in range and out of range */ + /** Since the out of range queries only age as the distance component of the score is always 0, there is few need to sort them */ + /** In the majority of the cases most of the queries are out of range, so the sort time is greatly reduced as we only sort the in range queries */ + int32 NextOutOfRangeIndex = 0; + bool bSightQueriesOutOfRangeDirty = true; + TArray SightQueriesOutOfRange; + TArray SightQueriesInRange; + TArray SightQueriesPending; + +protected: + UPROPERTY(EditDefaultsOnly, Category = "AI Perception", config) + int32 MaxTracesPerTick; + + /** Maximum number of asynchronous traces that can be requested in a single update call*/ + UPROPERTY(EditDefaultsOnly, Category = "AI Perception", config) + int32 MaxAsyncTracesPerTick; + + UPROPERTY(EditDefaultsOnly, Category = "AI Perception", config) + int32 MinQueriesPerTimeSliceCheck; + + UPROPERTY(EditDefaultsOnly, Category = "AI Perception", config) + double MaxTimeSlicePerTick; + + UPROPERTY(EditDefaultsOnly, Category = "AI Perception", config) + float HighImportanceQueryDistanceThreshold; + + float HighImportanceDistanceSquare; + + UPROPERTY(EditDefaultsOnly, Category = "AI Perception", config) + float MaxQueryImportance; + + UPROPERTY(EditDefaultsOnly, Category = "AI Perception", config) + float SightLimitQueryImportance; + + /** Defines the amount of async trace queries to prevent based on the number of pending queries at the start of an update. + * 1 means that the async trace budget is slashed by the pending queries count + * 0 means that the async trace budget is not impacted by the pending queries + */ + UPROPERTY(EditDefaultsOnly, Category = "AI Perception", config) + float PendingQueriesBudgetReductionRatio; + + /** Defines if we are allowed to use asynchronous trace queries when there is no IAISightTargetInterface for a Target */ + UPROPERTY(EditDefaultsOnly, Category = "AI Perception", config) + bool bUseAsynchronousTraceForDefaultSightQueries; + + ECollisionChannel DefaultSightCollisionChannel; + + FOnPendingVisibilityQueryProcessedDelegateVR OnPendingCanBeSeenQueryProcessedDelegate; + FTraceDelegate OnPendingTraceQueryProcessedDelegate; + + UE_MT_DECLARE_RW_ACCESS_DETECTOR(QueriesListAccessDetector); + +public: + + virtual void PostInitProperties() override; + + void RegisterEvent(const FAISightEventVR& Event); + + virtual void RegisterSource(AActor& SourceActors) override; + virtual void UnregisterSource(AActor& SourceActor) override; + + virtual void OnListenerForgetsActor(const FPerceptionListener& Listener, AActor& ActorToForget) override; + virtual void OnListenerForgetsAll(const FPerceptionListener& Listener) override; + +#if WITH_GAMEPLAY_DEBUGGER_MENU + virtual void DescribeSelfToGameplayDebugger(const UAIPerceptionSystem& PerceptionSystem, FGameplayDebuggerCategory& DebuggerCategory) const override; +#endif // WITH_GAMEPLAY_DEBUGGER_MENU + +protected: + virtual float Update() override; + + UAISense_Sight::EVisibilityResult ComputeVisibility(UWorld* World, FAISightQueryVR& SightQuery, FPerceptionListener& Listener, const AActor* ListenerActor, FAISightTargetVR& Target, AActor* TargetActor, const FDigestedSightProperties& PropDigest, float& OutStimulusStrength, FVector& OutSeenLocation, int32& OutNumberOfLoSChecksPerformed, int32& OutNumberOfAsyncLosCheckRequested) const; + virtual bool ShouldAutomaticallySeeTarget(const FDigestedSightProperties& PropDigest, FAISightQueryVR* SightQuery, FPerceptionListener& Listener, AActor* TargetActor, float& OutStimulusStrength) const; + UE_DEPRECATED(5.3, "Please use the UpdateQueryVisibilityStatus version which takes an Actor& instead.") + void UpdateQueryVisibilityStatus(FAISightQueryVR& SightQuery, FPerceptionListener& Listener, const bool bIsVisible, const FVector& SeenLocation, const float StimulusStrength, AActor* TargetActor, const FVector& TargetLocation) const; + + void UpdateQueryVisibilityStatus(FAISightQueryVR& SightQuery, FPerceptionListener& Listener, const bool bIsVisible, const FVector& SeenLocation, const float StimulusStrength, AActor& TargetActor, const FVector& TargetLocation) const; + + + void OnPendingCanBeSeenQueryProcessed(const FAISightQueryID& QueryID, const bool bIsVisible, const float StimulusStrength, const FVector& SeenLocation, const TOptional& UserData); + void OnPendingTraceQueryProcessed(const FTraceHandle& TraceHandle, FTraceDatum& TraceDatum); + void OnPendingQueryProcessed(const int32 SightQueryIndex, const bool bIsVisible, const float StimulusStrength, const FVector& SeenLocation, const TOptional& UserData, const TOptional InTargetActor = NullOpt); + + + void OnNewListenerImpl(const FPerceptionListener& NewListener); + void OnListenerUpdateImpl(const FPerceptionListener& UpdatedListener); + void OnListenerRemovedImpl(const FPerceptionListener& RemovedListener); + virtual void OnListenerConfigUpdated(const FPerceptionListener& UpdatedListener) override; + + void GenerateQueriesForListener(const FPerceptionListener& Listener, const FDigestedSightProperties& PropertyDigest, const TFunction& OnAddedFunc = nullptr); + + + void RemoveAllQueriesByListener(const FPerceptionListener& Listener, const TFunction& OnRemoveFunc = nullptr); + void RemoveAllQueriesToTarget(const FAISightTargetVR::FTargetId& TargetId, const TFunction& OnRemoveFunc = nullptr); + /** RemoveAllQueriesToTarget version that need to already have a write access on QueriesListAccessDetector*/ + void RemoveAllQueriesToTarget_Internal(const FAISightTargetVR::FTargetId& TargetId, const TFunction& OnRemoveFunc = nullptr); + + /** returns information whether new LoS queries have been added */ + bool RegisterTarget(AActor& TargetActor, const TFunction& OnAddedFunc = nullptr); + + float CalcQueryImportance(const FPerceptionListener& Listener, const FVector& TargetLocation, const float SightRadiusSq) const; + bool RegisterNewQuery(const FPerceptionListener& Listener, const IGenericTeamAgentInterface* ListenersTeamAgent, const AActor& TargetActor, const FAISightTargetVR::FTargetId& TargetId, const FVector& TargetLocation, const FDigestedSightProperties& PropDigest, const TFunction& OnAddedFunc); + + + // Deprecated methods +public: + UE_DEPRECATED(4.25, "Not needed anymore done automatically at the beginning of each update.") + FORCEINLINE void SortQueries() {} + + enum FQueriesOperationPostProcess + { + DontSort, + Sort + }; +}; diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VREPhysicalAnimationComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VREPhysicalAnimationComponent.h new file mode 100644 index 0000000..0600c4b --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VREPhysicalAnimationComponent.h @@ -0,0 +1,106 @@ +#pragma once + +#include "PhysicsEngine/PhysicalAnimationComponent.h" +#include "CoreMinimal.h" +//#include "UObject/ObjectMacros.h" +#include "Components/ActorComponent.h" +#include "EngineDefines.h" +#if UE_ENABLE_DEBUG_DRAWING +//#include "Chaos/DebugDrawQueue.h" +#endif +#include "VREPhysicalAnimationComponent.generated.h" + +struct FReferenceSkeleton; + +USTRUCT() +struct VREXPANSIONPLUGIN_API FWeldedBoneDriverData +{ + GENERATED_BODY() +public: + FTransform RelativeTransform; + FName BoneName; + //FPhysicsShapeHandle ShapeHandle; + + FTransform LastLocal; + + FWeldedBoneDriverData() : + RelativeTransform(FTransform::Identity), + BoneName(NAME_None) + { + } + + /*FORCEINLINE bool operator==(const FPhysicsShapeHandle& Other) const + { + return (ShapeHandle == Other); + }*/ + + FORCEINLINE bool operator==(const FName& Other) const + { + return (BoneName == Other); + } +}; + +UCLASS(meta = (BlueprintSpawnableComponent), ClassGroup = Physics) +class VREXPANSIONPLUGIN_API UVREPhysicalAnimationComponent : public UPhysicalAnimationComponent +{ + GENERATED_UCLASS_BODY() + +public: + + /** Is the welded bone driver paused */ + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = WeldedBoneDriver) + bool bIsPaused; + + /** IF true then we will auto adjust the sleep settings of the body so that it won't rest during welded bone driving */ + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = WeldedBoneDriver) + bool bAutoSetPhysicsSleepSensitivity; + + /** The threshold multiplier to set on the body */ + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = WeldedBoneDriver) + float SleepThresholdMultiplier; + + /** The Base bone to use as the bone driver root */ + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = WeldedBoneDriver) + TArray BaseWeldedBoneDriverNames; + + UPROPERTY() + TArray BoneDriverMap; + + // Call to setup the welded body driver, initializes all mappings and caches shape contexts + // Requires that SetSkeletalMesh be called first + UFUNCTION(BlueprintCallable, Category = PhysicalAnimation) + void SetupWeldedBoneDriver(TArray BaseBoneNames); + + // Refreshes the welded bone driver, use this in cases where the body may have changed (such as welding to another body or switching physics) + UFUNCTION(BlueprintCallable, Category = PhysicalAnimation) + void RefreshWeldedBoneDriver(); + + // Sets the welded bone driver to be paused, you can also stop the component from ticking but that will also stop any physical animations going on + UFUNCTION(BlueprintCallable, Category = PhysicalAnimation) + void SetWeldedBoneDriverPaused(bool bPaused); + + UFUNCTION(BlueprintPure, Category = PhysicalAnimation) + bool IsWeldedBoneDriverPaused(); + + void SetupWeldedBoneDriver_Implementation(bool bReInit = false); + + //void OnWeldedMassUpdated(FBodyInstance* BodyInstance); + void UpdateWeldedBoneDriver(float DeltaTime); + + + /** If true then we will debug draw the mesh collision post shape alterations */ + //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = WeldedBoneDriver) + //bool bDebugDrawCollision = false; + +#if UE_ENABLE_DEBUG_DRAWING + //void DebugDrawMesh(const TArray& DrawCommands); +#endif + + FTransform GetWorldSpaceRefBoneTransform(FReferenceSkeleton& RefSkel, int32 BoneIndex, int32 ParentBoneIndex); + FTransform GetRefPoseBoneRelativeTransform(USkeletalMeshComponent* SkeleMesh, FName BoneName, FName ParentBoneName); + + //FCalculateCustomPhysics OnCalculateCustomPhysics; + //void CustomPhysics(float DeltaTime, FBodyInstance* BodyInstance); + + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; +}; diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VREPhysicsConstraintComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VREPhysicsConstraintComponent.h new file mode 100644 index 0000000..6bf2ef1 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VREPhysicsConstraintComponent.h @@ -0,0 +1,191 @@ +#pragma once + +#include "CoreMinimal.h" +#include "UObject/ObjectMacros.h" +#include "PhysicsEngine/PhysicsConstraintComponent.h" + +// Delete this eventually when the physics interface is fixed +#include "Chaos/ParticleHandle.h" +#include "Chaos/KinematicGeometryParticles.h" +#include "Chaos/PBDJointConstraintTypes.h" +#include "Chaos/PBDJointConstraintData.h" +#include "Chaos/Sphere.h" +#include "PhysicsProxy/SingleParticlePhysicsProxy.h" + +#include "VREPhysicsConstraintComponent.generated.h" + +/** +* A custom constraint component subclass that exposes additional missing functionality from the default one +*/ +UCLASS(ClassGroup = Physics, meta = (BlueprintSpawnableComponent), HideCategories = (Activation, "Components|Activation", Physics, Mobility), ShowCategories = ("Physics|Components|PhysicsConstraint", "VRE Constraint Settings")) +class VREXPANSIONPLUGIN_API UVREPhysicsConstraintComponent : public UPhysicsConstraintComponent +{ + + GENERATED_BODY() +public: + + UFUNCTION(BlueprintCallable, Category = "VRE Physics Constraint Component") + void SetConstraintToForceBased(bool bUseForceConstraint) + { + + if (!ConstraintInstance.ConstraintHandle.IsValid()) + return; + + if (ConstraintInstance.ConstraintHandle->IsType(Chaos::EConstraintType::JointConstraintType)) + { + if (Chaos::FJointConstraint* Constraint = static_cast(ConstraintInstance.ConstraintHandle.Constraint)) + { + Constraint->SetLinearDriveForceMode(bUseForceConstraint ? Chaos::EJointForceMode::Force : Chaos::EJointForceMode::Acceleration); + Constraint->SetAngularDriveForceMode(bUseForceConstraint ? Chaos::EJointForceMode::Force : Chaos::EJointForceMode::Acceleration); + } + } + + //#endif + } + + + UFUNCTION(BlueprintCallable, Category = "VRE Physics Constraint Component") + void GetConstraintReferenceFrame(EConstraintFrame::Type Frame, FTransform& RefFrame) + { + RefFrame = ConstraintInstance.GetRefFrame(Frame); + } + + UFUNCTION(BlueprintCallable, Category = "VRE Physics Constraint Component") + FTransform GetLocalPose(EConstraintFrame::Type ConstraintFrame) + { + if (ConstraintInstance.IsValidConstraintInstance()) + { + if (ConstraintFrame == EConstraintFrame::Frame1) + { + return FTransform(ConstraintInstance.PriAxis1, ConstraintInstance.SecAxis1, ConstraintInstance.PriAxis1 ^ ConstraintInstance.SecAxis1, ConstraintInstance.Pos1); + } + else + { + return FTransform(ConstraintInstance.PriAxis2, ConstraintInstance.SecAxis2, ConstraintInstance.PriAxis2 ^ ConstraintInstance.SecAxis2, ConstraintInstance.Pos2); + } + + } + + return FTransform::Identity; + } + + UFUNCTION(BlueprintCallable, Category = "VRE Physics Constraint Component") + void GetGlobalPose(EConstraintFrame::Type ConstraintFrame, FTransform& GlobalPose) + { + if (ConstraintInstance.IsValidConstraintInstance()) + { + GlobalPose = FPhysicsInterface::GetGlobalPose(ConstraintInstance.ConstraintHandle, ConstraintFrame); + } + else + GlobalPose = FTransform::Identity; + } + + // Gets the current linear distance in world space on the joint in +/- from the initial reference frame + UFUNCTION(BlueprintPure, Category = "VRE Physics Constraint Component") + FVector GetCurrentLinearDistance(EConstraintFrame::Type FrameOfReference) + { + EConstraintFrame::Type Frame2 = FrameOfReference; + EConstraintFrame::Type Frame1 = (FrameOfReference == EConstraintFrame::Frame1) ? EConstraintFrame::Frame2 : EConstraintFrame::Frame1; + + FTransform Frame1Trans = this->GetBodyTransform(Frame1); + FTransform Frame2Trans = this->GetBodyTransform(Frame2); + + FTransform LocalPose = GetLocalPose(Frame1); + FTransform LocalPose2 = GetLocalPose(Frame2); + + Frame1Trans.SetScale3D(FVector(1.f)); + Frame1Trans = LocalPose * Frame1Trans; + + FVector OffsetLoc = Frame1Trans.GetRotation().UnrotateVector(Frame1Trans.GetLocation() - Frame2Trans.GetLocation()); + FVector OffsetLoc2 = LocalPose2.GetRotation().UnrotateVector(LocalPose2.GetLocation()); + FVector FinalVec = OffsetLoc2 - OffsetLoc; + + return FinalVec; + } + + // Gets the angular offset on the constraint + UFUNCTION(BlueprintPure, Category = "VRE Physics Constraint Component") + FRotator GetAngularOffset() + { + return ConstraintInstance.AngularRotationOffset; + } + + // Sets the angular offset on the constraint and re-initializes it + UFUNCTION(BlueprintCallable, Category="VRE Physics Constraint Component") + void SetAngularOffset(FRotator NewAngularOffset) + { + + // If the constraint is broken then there is no reason to do everything below + // Just early out of it. + if (!ConstraintInstance.IsValidConstraintInstance() || ConstraintInstance.IsBroken()) + { + ConstraintInstance.AngularRotationOffset = NewAngularOffset; + return; + } + + // I could remove a full step if I calc delta in Frame2 local and then apply to the new + // Values. However I am keeping it like this for now, would require an extra inverse / relative calc, this may not even be slower + + FVector RefPos = ConstraintInstance.Pos2; + const float RefScale = FMath::Max(GetConstraintScale(), 0.01f); + if (GetBodyInstance(EConstraintFrame::Frame2)) + { + RefPos *= RefScale; + } + + FQuat AngRotOffset = ConstraintInstance.AngularRotationOffset.Quaternion(); + FQuat newAngRotOffset = NewAngularOffset.Quaternion(); + + FTransform A2Transform = GetBodyTransform(EConstraintFrame::Frame2); + A2Transform.RemoveScaling(); + + FTransform CurrentLocalFrame(ConstraintInstance.PriAxis2, ConstraintInstance.SecAxis2, ConstraintInstance.PriAxis2 ^ ConstraintInstance.SecAxis2, ConstraintInstance.Pos2); + FTransform WorldLocalFrame = (CurrentLocalFrame * A2Transform); + + FVector WPri21 = GetComponentTransform().TransformVectorNoScale(AngRotOffset.GetForwardVector()); + FVector WOrth21 = GetComponentTransform().TransformVectorNoScale(AngRotOffset.GetRightVector()); + + FTransform OriginalRotOffset(WPri21, WOrth21, WPri21 ^ WOrth21, FVector::ZeroVector); + FQuat DeltaRot = WorldLocalFrame.GetRotation() * OriginalRotOffset.GetRotation().Inverse(); + DeltaRot.Normalize(); + + FVector WPri2 = GetComponentTransform().TransformVectorNoScale(newAngRotOffset.GetForwardVector()); + FVector WOrth2 = GetComponentTransform().TransformVectorNoScale(newAngRotOffset.GetRightVector()); + + WPri2 = DeltaRot.RotateVector(WPri2); + WOrth2 = DeltaRot.RotateVector(WOrth2); + + ConstraintInstance.PriAxis2 = A2Transform.InverseTransformVectorNoScale(WPri2); + ConstraintInstance.SecAxis2 = A2Transform.InverseTransformVectorNoScale(WOrth2); + ConstraintInstance.AngularRotationOffset = NewAngularOffset; + + FPhysicsInterface::ExecuteOnUnbrokenConstraintReadWrite(ConstraintInstance.ConstraintHandle, [&](const FPhysicsConstraintHandle& InUnbrokenConstraint) + { + FTransform URefTransform = FTransform(ConstraintInstance.PriAxis2, ConstraintInstance.SecAxis2, ConstraintInstance.PriAxis2 ^ ConstraintInstance.SecAxis2, RefPos); + FPhysicsInterface::SetLocalPose(InUnbrokenConstraint, URefTransform, EConstraintFrame::Frame2); + }); + + return; + } + + UFUNCTION(BlueprintPure, Category = "VRE Physics Constraint Component") + void GetLinearLimits(float& LinearLimit) + { + LinearLimit = ConstraintInstance.GetLinearLimit(); + } + + UFUNCTION(BlueprintPure, Category = "VRE Physics Constraint Component") + void GetAngularLimits(float &Swing1Limit, float &Swing2Limit, float &TwistLimit) + { + Swing1Limit = ConstraintInstance.GetAngularSwing1Limit(); + Swing2Limit = ConstraintInstance.GetAngularSwing2Limit(); + TwistLimit = ConstraintInstance.GetAngularTwistLimit(); + } + + + //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRE Constraint Settings") + //bool bSetAndMaintainCOMOnFrame2; + + //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRE Constraint Settings") + // bool bUseForceConstraint; +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRFullScreenUserWidget.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRFullScreenUserWidget.h new file mode 100644 index 0000000..334198b --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRFullScreenUserWidget.h @@ -0,0 +1,451 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Blueprint/UserWidget.h" +#include "GameFramework/Info.h" +#include "Components/WidgetComponent.h" +#include "ISpectatorScreenController.h" +#include "Templates/NonNullPointer.h" +//#include "CompositingElement.h" +#include "VRFullScreenUserWidget.generated.h" + +class FSceneViewport; +class FWidgetRenderer; +class FVRWidgetPostProcessHitTester; +class SConstraintCanvas; +class SVirtualWindow; +class SViewport; +class SWidget; +class ULevel; +class UMaterialInstanceDynamic; +class UMaterialInterface; +class UPostProcessComponent; +class UTextureRenderTarget2D; +class UWorld; + +#if WITH_EDITOR +class SLevelViewport; +#endif + + +UENUM(BlueprintType) +enum class EVRWidgetDisplayType : uint8 +{ + /** Do not display. */ + Inactive, + /** Display on a game viewport. */ + Viewport, + /** Display as a post process. */ + PostProcess, + /** Render to a texture and send to composure. */ + // Composure, +}; + + +USTRUCT() +struct FVRFullScreenUserWidget_Viewport +{ + GENERATED_BODY() + +public: + //FVRFullScreenUserWidget_Viewport(); + bool Display(UWorld* World, UUserWidget* Widget, TAttribute InDPIScale); + void Hide(UWorld* World); + //void Tick(UWorld* World, float DeltaSeconds); + +#if WITH_EDITOR + /** + * The viewport to use for displaying. + * Defaults to GetFirstActiveLevelViewport(). + + */ + TWeakPtr EditorTargetViewport; +#endif + +private: + + /** Constraint widget that contains the widget we want to display. */ + TWeakPtr FullScreenCanvasWidget; + +#if WITH_EDITOR + /** Level viewport the widget was added to. */ + TWeakPtr OverlayWidgetLevelViewport; +#endif +}; + +USTRUCT() +struct FVRFullScreenUserWidget_PostProcess +{ + GENERATED_BODY() + + FVRFullScreenUserWidget_PostProcess(); + void SetCustomPostProcessSettingsSource(TWeakObjectPtr InCustomPostProcessSettingsSource); + bool Display(UWorld* World, UUserWidget* Widget, bool bInRenderToTextureOnly, TAttribute InDPIScale); + void Hide(UWorld* World); + void Tick(UWorld* World, float DeltaSeconds); + + TSharedPtr VREXPANSIONPLUGIN_API GetSlateWindow() const; + +private: + //bool CreatePostProcessComponent(UWorld* World); + //void ReleasePostProcessComponent(); + + bool CreateRenderer(UWorld* World, UUserWidget* Widget, TAttribute InDPIScale); + void ReleaseRenderer(); + void TickRenderer(UWorld* World, float DeltaSeconds); + + FIntPoint CalculateWidgetDrawSize(UWorld* World); + bool IsTextureSizeValid(FIntPoint Size) const; + + void RegisterHitTesterWithViewport(UWorld* World); + void UnRegisterHitTesterWithViewport(); + + TSharedPtr GetViewport(UWorld* World) const; + float GetDPIScaleForPostProcessHitTester(TWeakObjectPtr World) const; + FPostProcessSettings* GetPostProcessSettings() const; + +public: + /** + * Post process material used to display the widget. + * SlateUI [Texture] + * TintColorAndOpacity [Vector] + * OpacityFromTexture [Scalar] + */ + //UPROPERTY(EditAnywhere, Category = PostProcess) + //UMaterialInterface* PostProcessMaterial; + + /** Tint color and opacity for this component. */ + //UPROPERTY(EditAnywhere, Category = PostProcess) + //FLinearColor PostProcessTintColorAndOpacity; + + /** Sets the amount of opacity from the widget's UI texture to use when rendering the translucent or masked UI to the viewport (0.0-1.0). */ + //UPROPERTY(EditAnywhere, Category = PostProcess, meta = (ClampMin = 0.0f, ClampMax = 1.0f)) + //float PostProcessOpacityFromTexture; + + /** The size of the rendered widget. */ + UPROPERTY(EditAnywhere, Category = PostProcess, meta=(InlineEditConditionToggle)) + bool bWidgetDrawSize; + + /** The size of the rendered widget. */ + UPROPERTY(EditAnywhere, Category = PostProcess, meta=(EditCondition= bWidgetDrawSize)) + FIntPoint WidgetDrawSize; + + /** Is the virtual window created to host the widget focusable? */ + UPROPERTY(EditAnywhere, AdvancedDisplay, Category = PostProcess) + bool bWindowFocusable; + + /** The visibility of the virtual window created to host the widget. */ + UPROPERTY(EditAnywhere, AdvancedDisplay, Category = PostProcess) + EWindowVisibility WindowVisibility; + + /** Register with the viewport for hardware input from the mouse and keyboard. It can and will steal focus from the viewport. */ + UPROPERTY(EditAnywhere, AdvancedDisplay, Category= PostProcess) + bool bReceiveHardwareInput; + + /** The background color of the render target */ + UPROPERTY(EditAnywhere, AdvancedDisplay, Category = PostProcess) + FLinearColor RenderTargetBackgroundColor; + + /** The blend mode for the widget. */ + UPROPERTY(EditAnywhere, AdvancedDisplay, Category = PostProcess) + EWidgetBlendMode RenderTargetBlendMode; + + /** List of composure layers that are expecting to use the WidgetRenderTarget. */ + //UPROPERTY(EditAnywhere, Category= PostProcess) + //TArray ComposureLayerTargets; + + /** The target to which the user widget is rendered. */ + UPROPERTY(Transient) + TObjectPtr WidgetRenderTarget; + + /** Only render to the UTextureRenderTarget2D - do not output to the final viewport. Unless DrawtoVRPreview is active */ + UPROPERTY(EditAnywhere, AdvancedDisplay, Category = PostProcess) + bool bRenderToTextureOnly; + + /** If we should automatically try to draw and manage this to the VR Preview */ + UPROPERTY(EditAnywhere, AdvancedDisplay, Category = PostProcess) + bool bDrawToVRPreview; + + // VR Spectator mode to use when active + UPROPERTY(EditAnywhere, Category = "User Interface") + ESpectatorScreenMode VRDisplayType; + + // VR Spectator mode to use when not active + UPROPERTY(EditAnywhere, Category = "User Interface") + ESpectatorScreenMode PostVRDisplayType; + +#if WITH_EDITOR + /** + * The viewport to use for displaying. + * + * Defaults to GetFirstActiveLevelViewport(). + */ + TWeakPtr EditorTargetViewport; +#endif +private: + /** Post process component used to add the material to the post process chain. */ + //UPROPERTY(Transient) + //UPostProcessComponent* PostProcessComponent; + + /** The dynamic instance of the material that the render target is attached to. */ + //UPROPERTY(Transient) + //UMaterialInstanceDynamic* PostProcessMaterialInstance; + + /** The slate window that contains the user widget content. */ + TSharedPtr SlateWindow; + + /** The slate viewport we are registered to. */ + TWeakPtr ViewportWidget; + + /** Helper class for drawing widgets to a render target. */ + FWidgetRenderer* WidgetRenderer; + + /** The size of the rendered widget */ + FIntPoint CurrentWidgetDrawSize; + + /** Hit tester when we want the hardware input. */ + TSharedPtr CustomHitTestPath; + +}; + +/** + * Will set the Widgets on a viewport either by Widgets are first rendered to a render target, then that render target is displayed in the world. + */ +UCLASS(BlueprintType, meta=(ShowOnlyInnerProperties)) +class VREXPANSIONPLUGIN_API UVRFullScreenUserWidget : public UObject +{ + GENERATED_BODY() + +public: + UVRFullScreenUserWidget(const FObjectInitializer& ObjectInitializer); + + //~ Begin UObject interface + virtual void BeginDestroy() override; +#if WITH_EDITOR + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; +#endif + //~ End UObject Interface + + bool ShouldDisplay(UWorld* World) const; + EVRWidgetDisplayType GetDisplayType(UWorld* World) const; + bool IsDisplayed() const; + + UFUNCTION(BlueprintCallable, Category = "FullScreenWidgetComp") + bool IsDisplayRequested() + { + return bDisplayRequested; + } + + UFUNCTION(BlueprintCallable, Category = "FullScreenWidgetComp") + virtual bool Display(UWorld* World); + + UFUNCTION(BlueprintCallable, Category = "FullScreenWidgetComp") + virtual void Hide(); + + UFUNCTION(BlueprintCallable, Category = "FullScreenWidgetComp") + void SetIsHidden(bool bNewHidden) + { + if (bNewHidden) + { + Hide(); + } + else + { + if (World.IsValid()) + { + Display(World.Get()); + } + else + { + UWorld* myWorld = this->GetWorld(); + if (myWorld) + { + Display(myWorld); + } + } + } + } + + virtual void Tick(float DeltaTime); + + void SetDisplayTypes(EVRWidgetDisplayType InEditorDisplayType, EVRWidgetDisplayType InGameDisplayType, EVRWidgetDisplayType InPIEDisplayType); + void SetOverrideWidget(UUserWidget* InWidget); + + /** + * If using EVPWidgetDisplayType::PostProcess, you can specify a custom post process settings that should be modified. + * By default, a new post process component is added to AWorldSettings. + * + * @param InCustomPostProcessSettingsSource An object containing a FPostProcessSettings UPROPERTY() + */ + //void SetCustomPostProcessSettingsSource(TWeakObjectPtr InCustomPostProcessSettingsSource); + +#if WITH_EDITOR + /** + * Sets the TargetViewport to use on both the Viewport and the PostProcess class. + * + * Overrides the viewport to use for displaying. + * Defaults to GetFirstActiveLevelViewport(). + */ + void SetEditorTargetViewport(TWeakPtr InTargetViewport); + /** Resets the TargetViewport */ + void ResetEditorTargetViewport(); +#endif + +protected: + bool InitWidget(); + void ReleaseWidget(); + + FVector2D FindSceneViewportSize(); + float GetViewportDPIScale(); + +private: + void OnLevelRemovedFromWorld(ULevel* InLevel, UWorld* InWorld); + void OnWorldCleanup(UWorld* InWorld, bool bSessionEnded, bool bCleanupResources); + +public: + + /** The display type when the world is an editor world. */ + UPROPERTY(EditAnywhere, Category = "User Interface") + EVRWidgetDisplayType EditorDisplayType; + + /** The display type when the world is a game world. */ + UPROPERTY(EditAnywhere, Category = "User Interface") + EVRWidgetDisplayType GameDisplayType; + + /** The display type when the world is a PIE world. */ + UPROPERTY(EditAnywhere, Category = "User Interface", meta = (DisplayName = "PIE Display Type")) + EVRWidgetDisplayType PIEDisplayType; + + /** Behavior when the widget should be display by the slate attached to the viewport. */ + UPROPERTY(EditAnywhere, Category = "Viewport", meta = (ShowOnlyInnerProperties)) + FVRFullScreenUserWidget_Viewport ViewportDisplayType; + + /** The class of User Widget to create and display an instance of */ + UPROPERTY(EditAnywhere, Category = "User Interface") + TSubclassOf WidgetClass; + + /** Behavior when the widget should be display by a post process. */ + UPROPERTY(EditAnywhere, Category = "Post Process", meta = (ShowOnlyInnerProperties)) + FVRFullScreenUserWidget_PostProcess PostProcessDisplayType; + + // Get a pointer to the inner widget. + // Note: This should not be stored! + UFUNCTION(BlueprintCallable, Category = "FullScreenWidgetComp") + UUserWidget* GetWidget() const { return Widget; }; + + UFUNCTION(BlueprintCallable, Category = "FullScreenWidgetComp") + UTextureRenderTarget2D* GetPostProcessRenderTarget() const { return PostProcessDisplayType.WidgetRenderTarget; }; + +private: + /** The User Widget object displayed and managed by this component */ + UPROPERTY(Transient, DuplicateTransient) + TObjectPtr Widget; + + /** The world the widget is attached to. */ + TWeakObjectPtr World; + + /** How we currently displaying the widget. */ + EVRWidgetDisplayType CurrentDisplayType; + + /** The user requested the widget to be displayed. It's possible that some setting are invalid and the widget will not be displayed. */ + bool bDisplayRequested; + +#if WITH_EDITOR + /** + * The viewport to use for displaying. + * Defaults to GetFirstActiveLevelViewport(). + */ + TWeakPtr EditorTargetViewport; +#endif +}; + +/** + * Widgets are first rendered to a render target, then that render target is displayed in the world. + */ +UCLASS(Blueprintable, ClassGroup = "UserInterface", HideCategories = (Actor, Input, Movement, Collision, Rendering, "Utilities|Transformation", LOD), ShowCategories = ("Input|MouseInput", "Input|TouchInput")) +class VREXPANSIONPLUGIN_API AVRFullScreenUserWidgetActor : public AInfo +{ + GENERATED_BODY() + +public: + AVRFullScreenUserWidgetActor(const FObjectInitializer& ObjectInitializer); + + //~ Begin AActor interface + virtual void PostInitializeComponents() override; + virtual void PostLoad() override; + virtual void PostActorCreated() override; + virtual void Destroyed() override; + + virtual void BeginPlay() override; + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + virtual void Tick(float DeltaSeconds) override; + + /** If true the widget will be shown right away, if false you will need to set SetWidgetVisible(true) to show it */ + UPROPERTY(EditAnywhere, Category = "User Interface") + bool bShowOnInit; + + /** */ + UPROPERTY(VisibleAnywhere, Instanced, NoClear, Category = "User Interface", meta = (ShowOnlyInnerProperties)) + UVRFullScreenUserWidget* ScreenUserWidget; + + UFUNCTION(BlueprintCallable, Category = "FullScreenWidgetActor") + UVRFullScreenUserWidget* GetPreviewWidgetComp(); + + UFUNCTION(BlueprintCallable, Category = "FullScreenWidgetActor") + void SetPIEDisplayType(EVRWidgetDisplayType NewDisplayType) + { + if (IsValid(ScreenUserWidget)) + { + ScreenUserWidget->PIEDisplayType = NewDisplayType; + ScreenUserWidget->Hide(); + RequestGameDisplay(); + } + } + + UFUNCTION(BlueprintCallable, Category = "FullScreenWidgetActor") + void SetGameDisplayType(EVRWidgetDisplayType NewDisplayType) + { + if (IsValid(ScreenUserWidget)) + { + ScreenUserWidget->GameDisplayType = NewDisplayType; + ScreenUserWidget->Hide(); + RequestGameDisplay(); + } + } + + // Set the widget to visible or not, this will be overriden by any changed to the actors hidden state + // IE: Setting actor to hidden will force this hidden as well, also setting the actor to visible will do the opposite + UFUNCTION(BlueprintCallable, Category = "FullScreenWidgetActor") + void SetWidgetVisible(bool bIsVisible); + + virtual void SetActorHiddenInGame(bool bNewHidden) override + { + SetWidgetVisible(bNewHidden); + Super::SetActorHiddenInGame(bNewHidden); + } + + UFUNCTION(BlueprintCallable, Category = "FullScreenWidgetActor") + UUserWidget* GetWidget(); + + UFUNCTION(BlueprintCallable, Category = "FullScreenWidgetActor") + UTextureRenderTarget2D* GetPostProcessRenderTarget(); + +#if WITH_EDITOR + virtual bool ShouldTickIfViewportsOnly() const override { return true; } +#endif //WITH_EDITOR + //~ End AActor Interface + +private: + void RequestEditorDisplay(); + void RequestGameDisplay(); + +protected: + + +#if WITH_EDITORONLY_DATA + /** Display requested and will be executed on the first frame because we can't call BP function in the loading phase */ + bool bEditorDisplayRequested; +#endif +}; diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRGameViewportClient.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRGameViewportClient.h new file mode 100644 index 0000000..61f52fd --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRGameViewportClient.h @@ -0,0 +1,65 @@ +// This class is intended to provide support for Local Mixed play between a mouse and keyboard player +// and a VR player. It is not needed outside of that use. + +#pragma once +#include "Engine/GameViewportClient.h" + +//#include "Engine/Engine.h" +#include "CoreMinimal.h" +#include "InputKeyEventArgs.h" +#include "Engine/World.h" +#include "Engine/GameInstance.h" + +#include "VRGameViewportClient.generated.h" + +UENUM(Blueprintable) +enum class EVRGameInputMethod : uint8 +{ + GameInput_Default, + GameInput_SharedKeyboardAndMouse, + GameInput_KeyboardAndMouseToPlayer2, +}; + +DECLARE_DYNAMIC_MULTICAST_DELEGATE(FVROnWindowCloseRequested); + + +/** +* Subclass this in a blueprint to overwrite how default input is passed around in engine between local characters. +* Generally used for passing keyboard / mouse input to a secondary local player for local mixed gameplay in VR +*/ +UCLASS(Blueprintable) +class VREXPANSIONPLUGIN_API UVRGameViewportClient : public UGameViewportClient +{ + GENERATED_UCLASS_BODY() + +public: + + // Event thrown when the window is closed + UPROPERTY(BlueprintAssignable, Category = "VRExpansionPlugin") + FVROnWindowCloseRequested BPOnWindowCloseRequested; + + // If true then forced window closing will be canceled (alt-f4, ect) + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRExpansionPlugin") + bool bIgnoreWindowCloseCommands; + + // Input Method for the viewport + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRExpansionPlugin") + EVRGameInputMethod GameInputMethod; + + // If true we will also shuffle gamepad input according to the GameInputMethod + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRExpansionPlugin") + bool bAlsoChangeGamepPadInput; + + // A List of input categories to consider as valid gamepad ones if bIsGamepad is true on the input event + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRExpansionPlugin") + TArray GamepadInputCategories; + + bool IsValidGamePadKey(const FKey& InputKey); + + UFUNCTION() + bool EventWindowClosing(); + + virtual void PostInitProperties() override; + virtual bool InputKey(const FInputKeyEventArgs& EventArgs) override; + virtual bool InputAxis(FViewport* tViewport, FInputDeviceId InputDevice, FKey Key, float Delta, float DeltaTime, int32 NumSamples = 1, bool bGamepad = false) override; +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRLogComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRLogComponent.h new file mode 100644 index 0000000..c3e04c3 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRLogComponent.h @@ -0,0 +1,243 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Components/ActorComponent.h" +#include "Engine/Canvas.h" +#include "Engine/TextureRenderTarget2D.h" +#include "Engine/Console.h" +#include "Containers/UnrealString.h" +#include "Misc/OutputDeviceHelper.h" +#include "VRLogComponent.generated.h" + +/** +* +*/ +UENUM(BlueprintType) +enum class EBPVRConsoleDrawType : uint8 +{ + VRConsole_Draw_ConsoleOnly, + VRConsole_Draw_OutputLogOnly +// VRConsole_Draw_ConsoleAndOutputLog +}; + + +/** +* A single log message for the output log, holding a message and +* a style, for color and bolding of the message. +*/ +struct FVRLogMessage +{ + TSharedRef Message; + ELogVerbosity::Type Verbosity; + FName Category; + FName Style; + + FVRLogMessage(const TSharedRef& NewMessage, FName NewCategory, FName NewStyle = NAME_None) + : Message(NewMessage) + , Verbosity(ELogVerbosity::Log) + , Category(NewCategory) + , Style(NewStyle) + { + } + + FVRLogMessage(const TSharedRef& NewMessage, ELogVerbosity::Type NewVerbosity, FName NewCategory, FName NewStyle = NAME_None) + : Message(NewMessage) + , Verbosity(NewVerbosity) + , Category(NewCategory) + , Style(NewStyle) + { + } +}; + +// Custom Log output history class to hold the VR logs. +/** This class is to capture all log output even if the log window is closed */ +class FVROutputLogHistory : public FOutputDevice +{ +public: + + int32 MaxStoredMessages; + bool bIsDirty; + int32 MaxLineLength; + + FVROutputLogHistory() + { + MaxLineLength = 130; + bIsDirty = false; + MaxStoredMessages = 1000; + GLog->AddOutputDevice(this); + GLog->SerializeBacklog(this); + } + + ~FVROutputLogHistory() + { + // At shutdown, GLog may already be null + if (GLog != NULL) + { + GLog->RemoveOutputDevice(this); + } + } + + /** Gets all captured messages */ + const TArray< TSharedPtr >& GetMessages() const + { + return Messages; + } + +protected: + + virtual void Serialize(const TCHAR* V, ELogVerbosity::Type Verbosity, const class FName& Category) override + { + // Capture all incoming messages and store them in history + CreateLogMessages(V, Verbosity, Category, Messages); + } + + bool CreateLogMessages(const TCHAR* V, ELogVerbosity::Type Verbosity, const class FName& Category, TArray< TSharedPtr >& OutMessages) + { + if (Verbosity == ELogVerbosity::SetColor) + { + // Skip Color Events + return false; + } + else + { + FName Style; + if (Category == NAME_Cmd) + { + Style = FName(TEXT("Log.Command")); + } + else if (Verbosity == ELogVerbosity::Error) + { + Style = FName(TEXT("Log.Error")); + } + else if (Verbosity == ELogVerbosity::Warning) + { + Style = FName(TEXT("Log.Warning")); + } + else + { + Style = FName(TEXT("Log.Normal")); + } + + // Forget timestamps, I don't care about them and we have limited texture space to draw too + // Determine how to format timestamps + static ELogTimes::Type LogTimestampMode = ELogTimes::None; + /*if (UObjectInitialized() && !GExitPurge) + { + // Logging can happen very late during shutdown, even after the UObject system has been torn down, hence the init check above + LogTimestampMode = GetDefault()->LogTimestampMode; + }*/ + + const int32 OldNumMessages = OutMessages.Num(); + + // handle multiline strings by breaking them apart by line + TArray LineRanges; + FString CurrentLogDump = V; + FTextRange::CalculateLineRangesFromString(CurrentLogDump, LineRanges); + + bool bIsFirstLineInMessage = true; + for (const FTextRange& LineRange : LineRanges) + { + if (!LineRange.IsEmpty()) + { + FString Line = CurrentLogDump.Mid(LineRange.BeginIndex, LineRange.Len()); + Line = Line.ConvertTabsToSpaces(4); + + // Hard-wrap lines to avoid them being too long + /*static const */int32 HardWrapLen = MaxLineLength; + for (int32 CurrentStartIndex = 0; CurrentStartIndex < Line.Len();) + { + int32 HardWrapLineLen = 0; + if (bIsFirstLineInMessage) + { + FString MessagePrefix = FOutputDeviceHelper::FormatLogLine(Verbosity, Category, nullptr, LogTimestampMode); + + HardWrapLineLen = FMath::Min(HardWrapLen - MessagePrefix.Len(), Line.Len() - CurrentStartIndex); + FString HardWrapLine = Line.Mid(CurrentStartIndex, HardWrapLineLen); + + OutMessages.Add(MakeShareable(new FVRLogMessage(MakeShareable(new FString(MessagePrefix + HardWrapLine)), Verbosity, Category, Style))); + } + else + { + HardWrapLineLen = FMath::Min(HardWrapLen, Line.Len() - CurrentStartIndex); + FString HardWrapLine = Line.Mid(CurrentStartIndex, HardWrapLineLen); + + OutMessages.Add(MakeShareable(new FVRLogMessage(MakeShareable(new FString(MoveTemp(HardWrapLine))), Verbosity, Category, Style))); + } + + bIsFirstLineInMessage = false; + CurrentStartIndex += HardWrapLineLen; + } + } + } + + int numMessages = OutMessages.Num(); + if (numMessages > MaxStoredMessages) + { + OutMessages.RemoveAt(0, numMessages - MaxStoredMessages, true); + } + if (OldNumMessages != numMessages) + bIsDirty = true; + + return OldNumMessages != numMessages;//OutMessages.Num(); + } + } + +private: + + /** All log messages since this module has been started */ + TArray< TSharedPtr > Messages; +}; + +/** +* This class taps into the output log and console and renders them to textures so they can be viewed in levels. +* Generally used for debugging and testing in VR, also allows sending input to the console. +*/ +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UVRLogComponent : public UActorComponent +{ + GENERATED_BODY() + +public: + UVRLogComponent(const FObjectInitializer& ObjectInitializer); + + + ~UVRLogComponent(); + + FVROutputLogHistory OutputLogHistory; + + virtual void PostInitProperties() override + { + Super::PostInitProperties(); + OutputLogHistory.MaxStoredMessages = FMath::Clamp(MaxStoredMessages, 100, 100000); + OutputLogHistory.MaxLineLength = FMath::Clamp(MaxLineLength, 50, 1000); + } + + UPROPERTY(BlueprintReadWrite,EditAnywhere, Category = "VRLogComponent|Console") + int32 MaxLineLength; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRLogComponent|Console") + int32 MaxStoredMessages; + + // Sets the console input text, can be used to clear the console or enter full or partial commands + UFUNCTION(BlueprintCallable, Category = "VRLogComponent|Console", meta = (bIgnoreSelf = "true")) + void SetConsoleText(FString Text); + + // Sends a key to the console - Console considers Released as final, flashes the cursor + UFUNCTION(BlueprintCallable, Category = "VRLogComponent|Console", meta = (bIgnoreSelf = "true")) + void SendKeyEventToConsole(FKey Key, EInputEvent KeyEvent); + + // Sends text to the console - Optionally returns at the end to "enter" the text, end flashes the cursor + UFUNCTION(BlueprintCallable, Category = "VRLogComponent|Console", meta = (bIgnoreSelf = "true")) + void AppendTextToConsole(FString Text, bool bReturnAtEnd = false); + + // Draw the console to a render target 2D + UFUNCTION(BlueprintCallable, Category = "VRLogComponent|Console", meta = (bIgnoreSelf = "true", DisplayName = "DrawConsoleToCanvasRenderTarget2D")) + bool DrawConsoleToRenderTarget2D(EBPVRConsoleDrawType DrawType, UTextureRenderTarget2D * Texture, float ScrollOffset, bool bForceDraw); + + + void DrawConsole(bool bLowerHalfOnly, UCanvas* Canvas); + void DrawOutputLog(bool bUpperHalfOnly, UCanvas* Canvas, float ScrollOffset); + +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRPlayerStart.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRPlayerStart.h new file mode 100644 index 0000000..a401f60 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRPlayerStart.h @@ -0,0 +1,30 @@ +#pragma once + +#include "CoreMinimal.h" +#include "GameFramework/PlayerStart.h" +#include "Components/SceneComponent.h" +#include "VRPlayerStart.generated.h" + +/** +* A normal player start except I replaced the root component with a scene component so that the spawn +* transform will match our VR characters. +*/ +UCLASS(Blueprintable, ClassGroup = Common, hidecategories = Collision) +class VREXPANSIONPLUGIN_API AVRPlayerStart : public APlayerStart +{ + GENERATED_BODY() +private: + UPROPERTY() + TObjectPtr VRRootComp; +public: + + AVRPlayerStart(const FObjectInitializer& ObjectInitializer); + + /** Returns VRRootComp subobject **/ + class USceneComponent* GetVRRootComponent() const { return VRRootComp; } + + // Override this to use capsule even if it isn't the root component + virtual void GetSimpleCollisionCylinder(float& CollisionRadius, float& CollisionHalfHeight) const override; + virtual void FindBase() override; + virtual void Validate() override; +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRRenderTargetManager.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRRenderTargetManager.h new file mode 100644 index 0000000..696817e --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRRenderTargetManager.h @@ -0,0 +1,387 @@ +#pragma once +#include "TimerManager.h" +#include "GameFramework/Actor.h" +#include "Components/ActorComponent.h" +#include "Containers/Queue.h" +#include "VRRenderTargetManager.generated.h" + +class UVRRenderTargetManager; +class UCanvasRenderTarget2D; +class UCanvas; +class UTexture2D; +class UMaterial; +class APlayerController; +class FRenderCommandFence; +enum EPixelFormat : uint8; + + +// #TODO: Dirty rects so don't have to send entire texture? + + +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPVRReplicatedTextureStore +{ + GENERATED_BODY() +public: + + // Not automatically replicated, we are skipping it so that the array isn't checked + // We manually copy the data into the serialization buffer during netserialize and keep + // a flip flop dirty flag + + UPROPERTY(Transient) + TArray PackedData; + + UPROPERTY(Transient) + TArray UnpackedData; + + UPROPERTY(Transient) + uint32 Width; + + UPROPERTY() + uint32 Height; + + UPROPERTY(Transient) + bool bIsZipped; + + //UPROPERTY() + // bool bJPG; + //UPROPERTY(Transient) + EPixelFormat PixelFormat; + + FBPVRReplicatedTextureStore() + { + Width = 0; + Height = 0; + bIsZipped = false; + } + + void Reset() + { + PackedData.Reset(); + UnpackedData.Reset(); + Width = 0; + Height = 0; + PixelFormat = (EPixelFormat)0; + bIsZipped = false; + //bJPG = false; + } + + void PackData(); + void UnPackData(); + + + /** Network serialization */ + // Doing a custom NetSerialize here because this is sent via RPCs and should change on every update + bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess); + +}; + +template<> +struct TStructOpsTypeTraits< FBPVRReplicatedTextureStore > : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithNetSerializer = true, + WithNetSharedSerialization = true, + }; +}; + + +USTRUCT() +struct FRenderDataStore { + GENERATED_BODY() + + TArray ColorData; + FRenderCommandFence RenderFence; + FIntPoint Size2D; + EPixelFormat PixelFormat; + + FRenderDataStore() { + } +}; + +UENUM(BlueprintType) +enum class ERenderManagerOperationType : uint8 +{ + Op_LineDraw = 0x00, + Op_TriDraw = 0x01, + Op_TexDraw = 0x02 +}; + + +USTRUCT() +struct FRenderManagerTri { + GENERATED_BODY() +public: + FVector2D P1; + FVector2D P2; + FVector2D P3; +}; + +USTRUCT() +struct FRenderManagerOperation { + GENERATED_BODY() +public: + + UPROPERTY() + uint32 OwnerID; + + UPROPERTY() + ERenderManagerOperationType OperationType; + + UPROPERTY() + FColor Color; + + UPROPERTY() + FVector2D P1; + + UPROPERTY() + FVector2D P2; + + UPROPERTY() + uint32 Thickness; + + UPROPERTY() + TArray Tris; + + UPROPERTY() + TSoftObjectPtr Texture; + + UPROPERTY() + TSoftObjectPtr Material; + + FRenderManagerOperation() + { + OwnerID = 0; + OperationType = ERenderManagerOperationType::Op_LineDraw; + Color = FColor::White; + P1 = FVector2D::ZeroVector; + P2 = FVector2D::ZeroVector; + Thickness = 0; + } + + bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess); +}; +template<> +struct TStructOpsTypeTraits< FRenderManagerOperation > : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithNetSerializer = true, + WithNetSharedSerialization = true, + }; +}; + +/** +* This class is used as a proxy to send owner only RPCs +*/ +UCLASS(ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API ARenderTargetReplicationProxy : public AActor +{ + GENERATED_BODY() + +public: + ARenderTargetReplicationProxy(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); + + UPROPERTY(Replicated, ReplicatedUsing = OnRep_Manager) + TObjectPtr OwningManager; + + UPROPERTY(Replicated) + uint32 OwnersID; + + UFUNCTION() + void OnRep_Manager(); + + UPROPERTY(Transient) + FBPVRReplicatedTextureStore TextureStore; + + UPROPERTY(Transient) + int32 BlobNum; + + bool bWaitingForManager; + + void SendInitMessage(); + + UFUNCTION() + void SendNextDataBlob(); + + FTimerHandle SendTimer_Handle; + FTimerHandle CheckManager_Handle; + + // Maximum size of texture blobs to use for sending (size of chunks that it gets broken down into) + UPROPERTY() + int32 TextureBlobSize; + + // Maximum bytes per second to send, you will want to play around with this and the + // MaxClientRate settings in config in order to balance the bandwidth and avoid saturation + // If you raise this above the max replication size of a 65k byte size then you will need + // To adjust the max size in engine network settings. + UPROPERTY() + int32 MaxBytesPerSecondRate; + + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + + UFUNCTION(Reliable, Server, WithValidation) + void SendLocalDrawOperations(const TArray& LocalRenderOperationStoreList); + + UFUNCTION(Reliable, Client) + void InitTextureSend(int32 Width, int32 Height, int32 TotalDataCount, int32 BlobCount, EPixelFormat PixelFormat, bool bIsZipped/*, bool bIsJPG*/); + + UFUNCTION(Reliable, Server, WithValidation) + void Ack_InitTextureSend(int32 TotalDataCount); + + UFUNCTION(Reliable, Client) + void ReceiveTextureBlob(const TArray& TextureBlob, int32 LocationInData, int32 BlobCount); + + UFUNCTION(Reliable, Server, WithValidation) + void Ack_ReceiveTextureBlob(int32 BlobCount); + + UFUNCTION(Reliable, Client) + void ReceiveTexture(const FBPVRReplicatedTextureStore&TextureData); + +}; + + + +USTRUCT() +struct FClientRepData { + GENERATED_BODY() + + UPROPERTY() + TObjectPtr PC; + + UPROPERTY() + TObjectPtr ReplicationProxy; + + UPROPERTY() + bool bIsRelevant; + + UPROPERTY() + bool bIsDirty; + + FClientRepData() + { + PC = nullptr; + ReplicationProxy = nullptr; + bIsRelevant = false; + bIsDirty = false; + } +}; + + +/** +* This class stores reading requests for rendertargets and iterates over them +* It returns the pixel data at the end of processing +* It references code from: https://github.com/TimmHess/UnrealImageCapture +*/ +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UVRRenderTargetManager : public UActorComponent +{ + GENERATED_BODY() + +public: + + UVRRenderTargetManager(const FObjectInitializer& ObjectInitializer); + + uint32 OwnerIDCounter; + + UPROPERTY(Transient) + TObjectPtr LocalProxy; + + TArray RenderOperationStore; + TArray LocalRenderOperationStore; + + // Rate to poll for drawing new operations + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "RenderTargetManager") + float DrawRate; + + UFUNCTION(Reliable, NetMultiCast, WithValidation) + void SendDrawOperations(const TArray& RenderOperationStoreList); + + UFUNCTION(BlueprintCallable, Category = "VRRenderTargetManager|DrawingFunctions") + void AddLineDrawOperation(FVector2D Point1, FVector2D Point2, FColor Color, int32 Thickness); + + UFUNCTION(BlueprintCallable, Category = "VRRenderTargetManager|DrawingFunctions") + void AddTextureDrawOperation(FVector2D Position, UTexture2D* TextureToDisplay); + + // Adds a draw operation for a triangle list, only takes the first vertex's color + UFUNCTION(BlueprintCallable, Category = "VRRenderTargetManager|DrawingFunctions") + void AddMaterialTrianglesDrawOperation(TArray Tris, UMaterial* Material); + + void DrawOperation(UCanvas* Canvas, const FRenderManagerOperation& Operation); + + UFUNCTION() + void DrawPoll(); + + void DrawOperations(); + + UPROPERTY() + FTimerHandle DrawHandle; + + UPROPERTY(Transient) + bool bIsStoringImage; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "RenderTargetManager") + bool bInitiallyReplicateTexture; + + UPROPERTY(Transient) + bool bIsLoadingTextureBuffer; + + // Maximum size of texture blobs to use for sending (size of chunks that it gets broken down into) + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "RenderTargetManager") + int32 TextureBlobSize; + + // Maximum bytes per second to send, you will want to play around with this and the + // MaxClientRate settings in config in order to balance the bandwidth and avoid saturation + // If you raise this above the max replication size of a 65k byte size then you will need + // To adjust the max size in engine network settings. + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "RenderTargetManager") + int32 MaxBytesPerSecondRate; + + UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "RenderTargetManager") + TObjectPtr RenderTarget; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "RenderTargetManager") + int32 RenderTargetWidth; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "RenderTargetManager") + int32 RenderTargetHeight; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "RenderTargetManager") + FColor ClearColor; + + UPROPERTY(Transient) + TArray NetRelevancyLog; + + // Rate to poll for actor relevancy + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "RenderTargetManager") + float PollRelevancyTime; + + FTimerHandle NetRelevancyTimer_Handle; + + UPROPERTY(Transient) + FBPVRReplicatedTextureStore RenderTargetStore; + + UFUNCTION(BlueprintCallable, Category = "VRRenderTargetManager|UtilityFunctions") + bool GenerateTrisFromBoxPlaneIntersection(UPrimitiveComponent* PrimToBoxCheck, FTransform WorldTransformOfPlane, const FPlane& LocalProjectionPlane, FVector2D PlaneSize, FColor UVColor, TArray& OutTris); + + // Create the render target that we are managing + void InitRenderTarget(); + + // Update the list of players that we are checking for relevancy + void UpdateRelevancyMap(); + + // Decompress the render target data to a texture and copy it to our managed render target + bool DeCompressRenderTarget2D(); + + // Queues storing the render target image to our buffer + void QueueImageStore(); + + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; + virtual void BeginPlay() override; + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + +protected: + TQueue RenderDataQueue; + +}; diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRVehiclePawn.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRVehiclePawn.h new file mode 100644 index 0000000..83afc09 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRVehiclePawn.h @@ -0,0 +1,158 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "UObject/ObjectMacros.h" +#include "GameFramework/Pawn.h" +#include "Engine/InputDelegateBinding.h" +#include "Components/InputComponent.h" +#include "GameFramework/PlayerController.h" +#include "VRVehiclePawn.generated.h" + + +/** +* This override of the base pawn allows for dual pawn usage in engine. +* It adds two new functions: SetBindToInput to bind input locally to the pawn and ForceSecondaryPossession which fakes possession so the +* player can control the pawn as if they were locally possessed into it in a multiplayer enviroment (no lag). +*/ +UCLASS(config = Game, BlueprintType) +class VREXPANSIONPLUGIN_API AVRVehiclePawn : public APawn +{ + GENERATED_BODY() + +public: + + /** Call this function to detach safely pawn from its controller, knowing that we will be destroyed soon. */ + /*UFUNCTION(BlueprintCallable, Category = "Pawn", meta = (Keywords = "Delete")) + virtual void DetachFromControllerPendingDestroy() override + { + if (Controller != NULL && Controller->GetPawn() == this) + { + Controller->PawnPendingDestroy(this); + if (Controller != NULL) + { + Controller->UnPossess(); + Controller = NULL; + } + } + }*/ + + + //UFUNCTION() + virtual void OnRep_Controller() override + { + if ((Controller != NULL) && (Controller->GetPawn() == NULL)) + { + // This ensures that APawn::OnRep_Pawn is called. Since we cant ensure replication order of APawn::Controller and AController::Pawn, + // if APawn::Controller is repped first, it will set AController::Pawn locally. When AController::Pawn is repped, the rep value will not + // be different from the just set local value, and OnRep_Pawn will not be called. This can cause problems if OnRep_Pawn does anything important. + // + // It would be better to never ever set replicated properties locally, but this is pretty core in the gameplay framework and I think there are + // lots of assumptions made in the code base that the Pawn and Controller will always be linked both ways. + //Controller->SetPawnFromRep(this); + + /*APlayerController* const PC = Cast(Controller); + if ((PC != NULL) && PC->bAutoManageActiveCameraTarget && (PC->PlayerCameraManager->ViewTarget.Target == Controller)) + { + PC->AutoManageActiveCameraTarget(this); + }*/ + } + + /*if (IsLocallyControlled()) + { + SetBindToInput(Controller, true); + }*/ + + } + + + UFUNCTION(BlueprintCallable, Category = "Pawn") + virtual bool SetBindToInput(AController * CController, bool bBindToInput) + { + APlayerController * playe = Cast(CController); + + if (playe != NULL) + { + if(InputComponent) + playe->PopInputComponent(InputComponent); // Make sure it is off the stack + + if (!bBindToInput) + { + // Unregister input component if we created one + DestroyPlayerInputComponent(); + return true; + } + else + { + // Set up player input component, if there isn't one already. + if (InputComponent == NULL) + { + InputComponent = CreatePlayerInputComponent(); + if (InputComponent) + { + SetupPlayerInputComponent(InputComponent); + InputComponent->RegisterComponent(); + + if (UInputDelegateBinding::SupportsInputDelegate(GetClass())) + { + InputComponent->bBlockInput = bBlockInput; + UInputDelegateBinding::BindInputDelegates(GetClass(), InputComponent); + } + } + } + + if (InputComponent) + { + playe->PushInputComponent(InputComponent); // Enforce input as top of stack so it gets input first and can consume it + return true; + } + } + } + else + { + // Unregister input component if we created one + DestroyPlayerInputComponent(); + return false; + } + + return false; + } + + UFUNCTION(BlueprintCallable, Category = "Pawn") + virtual bool ForceSecondaryPossession(AController * NewController) + { + if (NewController) + { + PossessedBy(NewController); + } + else + { + UnPossessed(); + } + + return false; + //INetworkPredictionInterface* NetworkPredictionInterface = GetPawn() ? Cast(GetPawn()->GetMovementComponent()) : NULL; + //if (NetworkPredictionInterface) + //{ + // NetworkPredictionInterface->ResetPredictionData_Server(); + // } + + + // Local PCs will have the Restart() triggered right away in ClientRestart (via PawnClientRestart()), but the server should call Restart() locally for remote PCs. + // We're really just trying to avoid calling Restart() multiple times. + // if (!IsLocalPlayerController()) + // { + // GetPawn()->Restart(); + // } + // ClientRestart(GetPawn()); + + //ChangeState(NAME_Playing); + //if (bAutoManageActiveCameraTarget) + //{ + // AutoManageActiveCameraTarget(GetPawn()); + // ResetCameraMode(); + //} + //UpdateNavigationComponents(); + } + +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRWheeledVehicle.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRWheeledVehicle.h new file mode 100644 index 0000000..d29d88c --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Misc/VRWheeledVehicle.h @@ -0,0 +1,92 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "WheeledVehiclePawn.h" +#include "ChaosWheeledVehicleMovementComponent.h" + +#include "UObject/ObjectMacros.h" +#include "GameFramework/Pawn.h" +#include "Engine/InputDelegateBinding.h" +#include "Components/InputComponent.h" +#include "GameFramework/PlayerController.h" +#include "VRWheeledVehicle.generated.h" + + +/** +* This override of the base wheeled vehicle allows for dual pawn usage in engine. +*/ +UCLASS(config = Game, BlueprintType) +class VREXPANSIONPLUGIN_API AVRWheeledVehicle : public AWheeledVehiclePawn +//#endif +{ + GENERATED_BODY() + +public: + + UFUNCTION(BlueprintCallable, Category = "Pawn") + virtual bool SetBindToInput(AController * CController, bool bBindToInput) + { + APlayerController * playe = Cast(CController); + + if (playe != NULL) + { + if(InputComponent) + playe->PopInputComponent(InputComponent); // Make sure it is off the stack + + if (!bBindToInput) + { + // Unregister input component if we created one + DestroyPlayerInputComponent(); + return true; + } + else + { + // Set up player input component, if there isn't one already. + if (InputComponent == NULL) + { + InputComponent = CreatePlayerInputComponent(); + if (InputComponent) + { + SetupPlayerInputComponent(InputComponent); + InputComponent->RegisterComponent(); + + if (UInputDelegateBinding::SupportsInputDelegate(GetClass())) + { + InputComponent->bBlockInput = bBlockInput; + UInputDelegateBinding::BindInputDelegates(GetClass(), InputComponent); + } + } + } + + if (InputComponent) + { + playe->PushInputComponent(InputComponent); // Enforce input as top of stack so it gets input first and can consume it + return true; + } + } + } + else + { + // Unregister input component if we created one + DestroyPlayerInputComponent(); + return false; + } + + return false; + } + + // Calls the movement components override controller function + UFUNCTION(BlueprintCallable, Category = "Pawn") + virtual bool SetOverrideController(AController * NewController) + { + if (UChaosWheeledVehicleMovementComponent* MoveComp = Cast(this->GetMovementComponent())) + { + MoveComp->SetOverrideController(NewController); + return true; + } + + return false; + } + +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Mover/VRMoverComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Mover/VRMoverComponent.h new file mode 100644 index 0000000..687b613 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/Mover/VRMoverComponent.h @@ -0,0 +1,154 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "MoverComponent.h" +#include "MoverTypes.h" +#include "GameFramework/Pawn.h" +#include "LayeredMove.h" +#include "VRMoverComponent.generated.h" + +class UCurveVector; +class UCurveFloat; + +DECLARE_LOG_CATEGORY_EXTERN(LogVRMoverComponent, Log, All); + +/** Linear Velocity: A method of inducing a straight-line velocity on an actor over time */ +USTRUCT(BlueprintType) +struct VREXPANSIONPLUGIN_API FLayeredMove_VRMovement : public FLayeredMoveBase +{ + GENERATED_USTRUCT_BODY() + + FLayeredMove_VRMovement(); + + virtual ~FLayeredMove_VRMovement() {} + + // Units per second, could be worldspace vs relative depending on Flags + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Mover) + FVector Velocity; + + // Optional curve float for controlling the magnitude of the velocity applied to the actor over the duration of the move + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Mover) + TObjectPtr MagnitudeOverTime; + + // @see ELayeredMove_ConstantVelocitySettingsFlags + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Mover) + uint8 SettingsFlags; + + // Never finish this movement + virtual bool IsFinished(float CurrentSimTimeMs) const; + + // Generate a movement + virtual bool GenerateMove(const FMoverTickStartData& StartState, const FMoverTimeStep& TimeStep, const UMoverComponent* MoverComp, UMoverBlackboard* SimBlackboard, FProposedMove& OutProposedMove) override; + + virtual FLayeredMoveBase* Clone() const override; + + virtual void NetSerialize(FArchive& Ar) override; + + virtual UScriptStruct* GetScriptStruct() const override; + + virtual FString ToSimpleString() const override; + + virtual void AddReferencedObjects(class FReferenceCollector& Collector) override; +}; + +template<> +struct TStructOpsTypeTraits< FLayeredMove_VRMovement > : public TStructOpsTypeTraitsBase2< FLayeredMove_VRMovement > +{ + enum + { + //WithNetSerializer = true, + WithCopy = true + }; +}; + +// Data block containing basic sync state information +USTRUCT(BlueprintType) +struct VREXPANSIONPLUGIN_API FVRMoverHMDSyncState : public FMoverDataStructBase +{ + GENERATED_USTRUCT_BODY() + +public: + // Movement intent direction relative to MovementBase if set, world space otherwise. Magnitude of range (0-1) + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Mover) + FVector MoveDirectionIntent; + +public: + + FVRMoverHMDSyncState() + { + // In constructor list when the actual var is made + MoveDirectionIntent = FVector::ZeroVector; + } + + virtual ~FVRMoverHMDSyncState() {} + + // @return newly allocated copy of this FMoverDefaultSyncState. Must be overridden by child classes + virtual FMoverDataStructBase* Clone() const override; + + virtual bool NetSerialize(FArchive& Ar, UPackageMap* Map, bool& bOutSuccess) override; + + virtual UScriptStruct* GetScriptStruct() const override { return StaticStruct(); } + + // Need implemented (if needed) + virtual bool ShouldReconcile(const FMoverDataStructBase& AuthorityState) const override + { + return false; + } + + // Needs implemented (should we even do this?) + virtual void Interpolate(const FMoverDataStructBase& From, const FMoverDataStructBase& To, float Pct) override + { + return; + } + + +}; + +template<> +struct TStructOpsTypeTraits< FVRMoverHMDSyncState > : public TStructOpsTypeTraitsBase2< FVRMoverHMDSyncState > +{ + enum + { + WithNetSerializer = true, + WithCopy = true + }; +}; + + + +UCLASS() +class VREXPANSIONPLUGIN_API AVRMoverBasePawn : public APawn, public IMoverInputProducerInterface +{ + GENERATED_BODY() + +public: + // Sets default values for this pawn's properties + AVRMoverBasePawn(const FObjectInitializer& ObjectInitializer); + + /** Accessor for the actor's movement component */ + UFUNCTION(BlueprintPure, Category = Mover) + UMoverComponent* GetMoverComponent() const { return CharacterMotionComponent; } + + virtual void BeginPlay() override; + +protected: + + virtual UPrimitiveComponent* GetMovementBase() const override; + + // Entry point for input production. Do not override. To extend in derived character types, override OnProduceInput for native types or implement "Produce Input" blueprint event + virtual void ProduceInput_Implementation(int32 SimTimeMs, FMoverInputCmdContext& InputCmdResult) override; + + // Override this function in native class to author input for the next simulation frame. Consider also calling Super method. + virtual void OnProduceInput(float DeltaMs, FMoverInputCmdContext& InputCmdResult); + + // Implement this event in Blueprints to author input for the next simulation frame. Consider also calling Parent event. + UFUNCTION(BlueprintImplementableEvent, DisplayName = "On Produce Input", meta = (ScriptName = "OnProduceInput")) + FMoverInputCmdContext OnProduceInputInBlueprint(float DeltaMs, FMoverInputCmdContext InputCmd); + +protected: + UPROPERTY(Category = Movement, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) + TObjectPtr CharacterMotionComponent; + + uint8 bHasProduceInputinBpFunc : 1; +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/ParentRelativeAttachmentComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/ParentRelativeAttachmentComponent.h new file mode 100644 index 0000000..e1abb2f --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/ParentRelativeAttachmentComponent.h @@ -0,0 +1,348 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +//#include "Engine/Engine.h" +#include "VRExpansionFunctionLibrary.h" +#include "Components/ShapeComponent.h" +#include "VRTrackedParentInterface.h" +#include "ParentRelativeAttachmentComponent.generated.h" + +class AVRBaseCharacter; +class AVRCharacter; + +/** Delegate for notification when the PRC starts rotating in yaw to match the snap / yaw tolerances. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE(FVRPRCBeginYawRotationEventSignature); + +// Type of rotation sampling to use +UENUM(BlueprintType) +enum class EVR_PRC_RotationMethod : uint8 +{ + // Rotate purely to the HMD yaw, default mode + PRC_ROT_HMD UMETA(DisplayName = "HMD rotation"), + + // Rotate to a blend between the HMD and Controller facing + PRC_ROT_HMDControllerBlend UMETA(DisplayName = "ROT HMD Controller Blend"), + + // Rotate to the controllers with behind the back detection, clamp within neck limit + PRC_ROT_ControllerHMDClamped UMETA(DisplayName = "Controller Clamped to HMD") +}; + + +/** +* A component that will track the HMD/Cameras location and YAW rotation to allow for chest/waist attachements. +* This is intended to be parented to the root component of a pawn, it will then either find and track the camera +* or use the HMD's position if one is connected. This allows it to work in multiplayer since the camera will +* have its position replicated. +*/ +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = VRExpansionLibrary) +class VREXPANSIONPLUGIN_API UParentRelativeAttachmentComponent : public USceneComponent, public IVRTrackedParentInterface +{ + GENERATED_BODY() + +public: + UParentRelativeAttachmentComponent(const FObjectInitializer& ObjectInitializer); + virtual void InitializeComponent() override; + + // Rotation method to use for facing calulations + //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary") + //EVR_PRC_RotationMethod YawRotationMethod; + + // Angle tolerance before we lerp / snap to the new rotation + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary", meta = (ClampMin = "0", UIMin = "0")) + float YawTolerance; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary", meta = (ClampMin = "0", UIMin = "0")) + float LerpSpeed; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary") + bool bLerpTransition; + + float LastRot; + float LastLerpVal; + float LerpTarget; + bool bWasSetOnce; + FTransform LeftControllerTrans; + FTransform RightControllerTrans; + + UPROPERTY(BlueprintAssignable, Category = "PRC Events") + FVRPRCBeginYawRotationEventSignature OnYawToleranceExceeded; + + // If true uses feet/bottom of the capsule as the base Z position for this component instead of the HMD/Camera Z position + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary") + bool bUseFeetLocation = false; + + // If true uses center of capsule as the feet location instead + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary", meta = (EditCondition = "bUseFeetLocation")) + bool bUseCenterAsFeetLocation = false; // Should really be an enum with the above but that would make people change projects + + // An additional value added to the relative position of the PRC + // Can be used to offset the floor, or component heights if needed + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary") + FVector CustomOffset; + + // If true will subtract the HMD's location from the position, useful for if the actors base is set to the HMD location always (simple character). + //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary") + //bool bOffsetByHMD; + + // If true, will not set rotation every frame, only position + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary") + bool bIgnoreRotationFromParent; + + // If true, this component will not perform logic in its tick, it will instead allow the character movement component to move it (unless the CMC is inactive, then it will go back to self managing) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary") + bool bUpdateInCharacterMovement; + +private: + UPROPERTY() + bool bIsPaused; +public: + + // Set the paused state of the PRC, if setting to paused then zero out rotation and zero out location will null out those values + UFUNCTION(BlueprintCallable, Category = "VRExpansionLibrary") + void SetPaused(bool bNewPaused, bool bZeroOutRotation, bool bZeroOutLocation); + + // If valid will use this as the tracked parent instead of the HMD / Parent + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRTrackedParentInterface") + FBPVRWaistTracking_Info OptionalWaistTrackingParent; + + virtual void SetTrackedParent(UPrimitiveComponent * NewParentComponent, float WaistRadius, EBPVRWaistTrackingMode WaistTrackingMode) override + { + IVRTrackedParentInterface::Default_SetTrackedParent_Impl(NewParentComponent, WaistRadius, WaistTrackingMode, OptionalWaistTrackingParent, this); + } + + UPROPERTY() + TObjectPtr AttachChar; + UPROPERTY() + TObjectPtr AttachBaseChar; + + void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; + + virtual void OnAttachmentChanged() override; + void UpdateTracking(float DeltaTime); + + bool IsLocallyControlled() const + { + // I like epics implementation better than my own + const AActor* MyOwner = GetOwner(); + return MyOwner->HasLocalNetOwner(); + //const APawn* MyPawn = Cast(MyOwner); + //return MyPawn ? MyPawn->IsLocallyControlled() : (MyOwner->Role == ENetRole::ROLE_Authority); + } + + // Sets the rotation and location depending on the control variables. Trying to remove some code duplication here + inline void SetRelativeRotAndLoc(FVector NewRelativeLocation, FRotator NewRelativeRotation, float DeltaTime); + + FQuat GetCalculatedRotation(FRotator InverseRot, float DeltaTime) + { + FRotator FinalRot = FRotator::ZeroRotator; + + if (FPlatformMath::Abs(FRotator::ClampAxis(InverseRot.Yaw) - LastRot) < YawTolerance) // This is never true with the default value of 0.0f + { + if (!bWasSetOnce) + { + LastRot = FRotator::ClampAxis(InverseRot.Yaw); + LastLerpVal = LastRot; + LerpTarget = LastRot; + bWasSetOnce = true; + } + + if (bLerpTransition && !FMath::IsNearlyEqual(LastLerpVal, LerpTarget)) + { + LastLerpVal = FMath::FixedTurn(LastLerpVal, LerpTarget, LerpSpeed * DeltaTime); + FinalRot = FRotator(0, LastLerpVal, 0); + } + else + { + FinalRot = FRotator(0, LastRot, 0); + LastLerpVal = LastRot; + } + } + else + { + // If we are using a snap threshold + if (!FMath::IsNearlyZero(YawTolerance)) + { + LerpTarget = FRotator::ClampAxis(InverseRot.Yaw); + LastLerpVal = FMath::FixedTurn(/*LastRot*/LastLerpVal, LerpTarget, LerpSpeed * DeltaTime); + FinalRot = FRotator(0, LastLerpVal, 0); + OnYawToleranceExceeded.Broadcast(); + } + else // If we aren't then just directly set it to the correct rotation + { + FinalRot = FRotator(0, FRotator::ClampAxis(InverseRot.Yaw), 0); + } + + LastRot = FRotator::ClampAxis(InverseRot.Yaw); + } + + return FinalRot.Quaternion(); + } + + + + void RunSampling(FRotator &HMDRotation, FVector &HMDLocation) + { + /*switch(YawRotationMethod) + { + case EVR_PRC_RotationMethod::PRC_ROT_HMD: + { + return; + }break; + + case EVR_PRC_RotationMethod::PRC_ROT_HMDControllerBlend: + { + return; + }break; + + case EVR_PRC_RotationMethod::PRC_ROT_ControllerHMDClamped: + { + GetEstShoulderRotation(HMDRotation, HMDLocation); + return; + }break; + }*/ + + } + + // Get combined direction angle up + void GetEstShoulderRotation(FRotator &InputHMDRotation, FVector &InputHMDLocation) + { + /*float WorldToMeters = GetWorld() ? GetWorld()->GetWorldSettings()->WorldToMeters : 100.0f; + + // Position shoulder (neck) + FTransform shoulder = FTransform::Identity; + FVector headNeckDirectionVector = FVector(-.05f, 0.f, -1.f); + FVector neckShoulderDistance = FVector(-0.02f, 0.f, -.15f) * WorldToMeters; // World To Meters idealy + float headNeckDistance = 0.03f * WorldToMeters; // World To Meters idealy + + FVector headNeckOffset = InputHMDRotation.RotateVector(headNeckDirectionVector); + FVector targetPosition = InputHMDLocation + headNeckOffset * headNeckDistance; + shoulder.SetLocation(targetPosition + InputHMDRotation.RotateVector(neckShoulderDistance)); + + //DrawDebugSphere(GetWorld(), (shoulder * GetAttachParent()->GetComponentTransform()).GetLocation(), 4.0f, 32, FColor::White); + return; + */ + + /*if (IsLocallyControlled() && GEngine->XRSystem.IsValid()) + { + FVector Position = GetRelativeLocation(); + FRotator Orientation = GetRelativeRotation(); + + if (AttachBaseChar.IsValid()) + { + if (AttachBaseChar->LeftMotionController) + { + const bool bNewTrackedState = AttachBaseChar->LeftMotionController->GripPollControllerState(Position, Orientation, WorldToMeters); + bool bTracked = bNewTrackedState && CurrentTrackingStatus != ETrackingStatus::NotTracked; + + if (bTracked) + { + LeftControllerTrans = FTransform(Position, Orientation); + } + } + + if (AttachBaseChar->RightMotionController) + { + const bool bNewTrackedState = AttachBaseChar->RightMotionController->GripPollControllerState(Position, Orientation, WorldToMeters); + bool bTracked = bNewTrackedState && CurrentTrackingStatus != ETrackingStatus::NotTracked; + + if (bTracked) + { + RightControllerTrans = FTransform(Position, Orientation); + } + } + } + } + else if (AttachBaseChar.IsValid()) + { + LeftControllerTrans = AttachBaseChar->LeftMotionController->GetRelativeTransform(); + RightControllerTrans = AttachBaseChar->RightMotionController->GetRelativeTransform(); + } + + FVector LeftHand = LeftControllerTrans.GetLocation(); + FVector RightHand = RightControllerTrans.GetLocation(); + + //FRotator LeveledRel = CurrentTransforms.PureCameraYaw; + + FVector DistLeft = LeftHand - shoulder.Transform.GetLocation(); + FVector DistRight = RightHand - shoulder.Transform.GetLocation(); + + if (bIgnoreZPos) + { + DistLeft.Z = 0.0f; + DistRight.Z = 0.0f; + } + + FVector DirLeft = DistLeft.GetSafeNormal(); + FVector DirRight = DistRight.GetSafeNormal(); + + FVector CombinedDir = DirLeft + DirRight; + float FinalRot = FMath::RadiansToDegrees(FMath::Atan2(CombinedDir.Y, CombinedDir.X)); + + DetectHandsBehindHead(FinalRot, InputHMDRotation); + ClampHeadRotationDelta(FinalRot, InputHMDRotation); + + return FinalRot;*/ + } + + void DetectHandsBehindHead(float& TargetRot, FRotator HMDRotation) + { + /*float delta = FRotator::ClampAxis(FMath::FindDeltaAngleDegrees(TargetRot, LastTargetRot));// FRotator::ClampAxis(TargetRot - LastTargetRot); + + if (delta > 150.f && delta < 210.0f && !FMath::IsNearlyZero(LastTargetRot) && !bClampingHeadRotation) + { + bHandsBehindHead = !bHandsBehindHead; + if (bHandsBehindHead) + { + BehindHeadAngle = TargetRot; + } + else + { + BehindHeadAngle = 0.f; + } + } + else if (bHandsBehindHead) + { + float delta2 = FMath::Abs(FMath::FindDeltaAngleDegrees(TargetRot, BehindHeadAngle)); + + if (delta2 > 90.f) + { + bHandsBehindHead = !bHandsBehindHead; + BehindHeadAngle = 0.f; + } + } + + LastTargetRot = TargetRot; + + if (bHandsBehindHead) + { + TargetRot += 180.f; + }*/ + } + + // Clamp head rotation delta yaw + void ClampHeadRotationDelta(float& TargetRotation, FRotator HMDRotation) + { + /*float HeadRotation = FRotator::ClampAxis(CurrentTransforms.PureCameraYaw.Yaw); + float cTargetRotation = FRotator::ClampAxis(TargetRotation); + + float delta = HeadRotation - cTargetRotation; + + if ((delta > 80.f && delta < 180.f) || (delta < -180.f && delta >= -360.f + 80)) + { + TargetRotation = HeadRotation - 80.f; + bClampingHeadRotation = true; + } + else if ((delta < -80.f && delta > -180.f) || (delta > 180.f && delta < 360.f - 80.f)) + { + TargetRotation = HeadRotation + 80.f; + bClampingHeadRotation = true; + } + else + { + bClampingHeadRotation = false; + }*/ + } +}; + diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/ReplicatedVRCameraComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/ReplicatedVRCameraComponent.h new file mode 100644 index 0000000..74e657d --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/ReplicatedVRCameraComponent.h @@ -0,0 +1,172 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "VRBPDatatypes.h" +//#include "Net/UnrealNetwork.h" +#include "Camera/CameraComponent.h" +#include "ReplicatedVRCameraComponent.generated.h" + +class AVRBaseCharacter; +class AVRCharacter; + +/** +* An overridden camera component that replicates its location in multiplayer +*/ +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = VRExpansionLibrary) +class VREXPANSIONPLUGIN_API UReplicatedVRCameraComponent : public UCameraComponent +{ + GENERATED_BODY() + +public: + UReplicatedVRCameraComponent(const FObjectInitializer& ObjectInitializer); + + + // If true, this component will not perform logic in its tick, it will instead allow the character movement component to move it (unless the CMC is inactive, then it will go back to self managing) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary") + bool bUpdateInCharacterMovement; + + UPROPERTY() + TObjectPtr AttachChar; + void UpdateTracking(float DeltaTime); + + virtual void OnAttachmentChanged() override; + + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; + //virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; + + /** Whether or not this component has authority within the frame*/ + bool bHasAuthority; + + /** Whether or not this component is currently on the network server*/ + bool bIsServer; + + FTransform LastRelativePosition; + bool bHadValidFirstVelocity; + + // If we should sample the velocity in world or local space + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ReplicatedCamera|ComponentVelocity") + bool bSampleVelocityInWorldSpace; + + // If true we will sample relative position for replication instead of the tracked settings + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ReplicatedCamera") + bool bFPSDebugMode = false; + + // For non view target positional updates + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ReplicatedCamera") + bool bSetPositionDuringTick; + + // If true will subtract the HMD's location from the position, useful for if the actors base is set to the HMD location always (simple character). + //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ReplicatedCamera") + //bool bOffsetByHMD; + + // If true will scale the tracking of the camera by TrackingScaler + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ReplicatedCamera|Advanced|Tracking") + bool bScaleTracking; + + // A scale to be applied to the tracking of the camera + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ReplicatedCamera|Advanced|Tracking", meta = (ClampMin = "0.1", UIMin = "0.1", EditCondition = "bScaleTracking")) + FVector TrackingScaler; + + // If true we will use the minimum height value to clamp the Z too + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ReplicatedCamera|Advanced|Tracking") + bool bLimitMinHeight; + + // The minimum height to allow for this camera + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ReplicatedCamera|Advanced|Tracking", meta = (ClampMin = "0.0", UIMin = "0.0", EditCondition = "bLimitMinHeight")) + float MinimumHeightAllowed; + + // If true will limit the max Z height that the camera is capable of reaching + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ReplicatedCamera|Advanced|Tracking") + bool bLimitMaxHeight; + + // If we are limiting the max height, this is the maximum allowed value + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ReplicatedCamera|Advanced|Tracking", meta = (ClampMin = "0.1", UIMin = "0.1", EditCondition = "bLimitMaxHeight")) + float MaxHeightAllowed; + + // If true will limit the maximum offset from center of the players tracked space + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ReplicatedCamera|Advanced|Tracking") + bool bLimitBounds; + + // If we are limiting the maximum bounds, this is the maximum length of the vector from the center of the tracked space + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ReplicatedCamera|Advanced|Tracking", meta = (ClampMin = "0.1", UIMin = "0.1", EditCondition = "bLimitBounds")) + float MaximumTrackedBounds; + + /** Sets lock to hmd automatically based on if the camera is currently locally controlled or not */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ReplicatedCamera|Advanced|Tracking") + uint32 bAutoSetLockToHmd : 1; + + void ApplyTrackingParameters(FVector & OriginalPosition, bool bSkipLocZero = false); + bool HasTrackingParameters(); + + // Get Camera View is no longer required, they finally broke the HMD logic out into its own section!! + //virtual void GetCameraView(float DeltaTime, FMinimalViewInfo& DesiredView) override; + virtual void HandleXRCamera() override; + + UPROPERTY(EditDefaultsOnly, ReplicatedUsing = OnRep_ReplicatedCameraTransform, Category = "ReplicatedCamera|Networking") + FBPVRComponentPosRep ReplicatedCameraTransform; + + // Returns the actual tracked transform of the HMD, as with RetainRoomscale = False we do not set the camera to it + // Can also just use the HMD function library but this is a fast way if you already have a camera reference + UFUNCTION(BlueprintPure, Category = "ReplicatedCamera|Tracking") + FTransform GetHMDTrackingTransform(); + + FVector LastUpdatesRelativePosition = FVector::ZeroVector; + FRotator LastUpdatesRelativeRotation = FRotator::ZeroRotator; + + bool bLerpingPosition; + bool bReppedOnce; + + // Run the smoothing step + void RunNetworkedSmoothing(float DeltaTime); + + + // Whether to smooth (lerp) between ticks for the replicated motion, DOES NOTHING if update rate is larger than FPS! + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ReplicatedCamera|Networking") + bool bSmoothReplicatedMotion = true; + + // If true then we will use exponential smoothing with buffered correction + UPROPERTY(EditAnywhere, Category = "ReplicatedCamera|Networking|Smoothing", meta = (editcondition = "bSmoothReplicatedMotion")) + bool bUseExponentialSmoothing = true; + + // Timestep of smoothing translation + UPROPERTY(EditAnywhere, Category = "ReplicatedCamera|Networking|Smoothing", meta = (editcondition = "bUseExponentialSmoothing")) + float InterpolationSpeed = 25.0f; + + // Max distance to allow smoothing before snapping the remainder + UPROPERTY(EditAnywhere, Category = "ReplicatedCamera|Networking|Smoothing", meta = (editcondition = "bUseExponentialSmoothing")) + float NetworkMaxSmoothUpdateDistance = 50.f; + + // Max distance to allow smoothing before snapping entirely to the new position + UPROPERTY(EditAnywhere, Category = "ReplicatedCamera|Networking|Smoothing", meta = (editcondition = "bUseExponentialSmoothing")) + float NetworkNoSmoothUpdateDistance = 100.f; + + UFUNCTION() + virtual void OnRep_ReplicatedCameraTransform(); + +protected: + // Rate to update the position to the server, 100htz is default (same as replication rate, should also hit every tick). + // On dedicated servers the update rate should be at or lower than the server tick rate for smoothing to work + UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "ReplicatedCamera|Networking") + float NetUpdateRate; +public: + + // Used in Tick() to accumulate before sending updates, didn't want to use a timer in this case. + float NetUpdateCount; + + float GetNetUpdateRate() { return NetUpdateRate; } + void SetNetUpdateRate(float NewNetUpdateRate); + + // I'm sending it unreliable because it is being resent pretty often + UFUNCTION(Unreliable, Server, WithValidation) + void Server_SendCameraTransform(FBPVRComponentPosRep NewTransform); + + // Pointer to an override to call from the owning character - this saves 7 bits a rep avoiding component IDs on the RPC + typedef void (AVRBaseCharacter::*VRBaseCharTransformRPC_Pointer)(FBPVRComponentPosRep NewTransform); + VRBaseCharTransformRPC_Pointer OverrideSendTransform; + + // Need this as I can't think of another way for an actor component to make sure it isn't on the server + bool IsLocallyControlled() const; + + //bool IsServer(); +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRAIController.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRAIController.h new file mode 100644 index 0000000..4405019 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRAIController.h @@ -0,0 +1,36 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "AIController.h" + +#include "VRAIController.generated.h" + + +UCLASS() +class VREXPANSIONPLUGIN_API AVRAIController : public AAIController +{ + GENERATED_BODY() + +public: + virtual FVector GetFocalPointOnActor(const AActor *Actor) const override; + + /** + * Checks line to center and top of other actor + * @param Other is the actor whose visibility is being checked. + * @param ViewPoint is eye position visibility is being checked from. If vect(0,0,0) passed in, uses current viewtarget's eye position. + * @param bAlternateChecks used only in AIController implementation + * @return true if controller's pawn can see Other actor. + */ + virtual bool LineOfSightTo(const AActor* Other, FVector ViewPoint = FVector(ForceInit), bool bAlternateChecks = false) const override; + //~ End AController Interface +}; + + +UCLASS() +class AVRDetourCrowdAIController : public AVRAIController +{ + GENERATED_BODY() +public: + AVRDetourCrowdAIController(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRBPDatatypes.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRBPDatatypes.h new file mode 100644 index 0000000..5196519 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRBPDatatypes.h @@ -0,0 +1,1929 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "Engine/NetSerialization.h" +#include "PhysicsPublic.h" +//#include "EngineMinimal.h" +//#include "Components/PrimitiveComponent.h" + +#include "PhysicsEngine/ConstraintTypes.h" +#include "PhysicsEngine/ConstraintDrives.h" +#include "Physics/PhysicsInterfaceCore.h" +#include "VRBPDatatypes.generated.h" + +class UGripMotionControllerComponent; +class UVRGripScriptBase; +class UPrimitiveComponent; + +// Custom movement modes for the characters +UENUM(BlueprintType) +enum class EVRCustomMovementMode : uint8 +{ + VRMOVE_Climbing UMETA(DisplayName = "Climbing"), + VRMOVE_LowGrav UMETA(DisplayName = "LowGrav"), + VRMOVE_Seated UMETA(DisplayName = "Seated"), + VRMOVE_SplineFollow UMETA(DisplayName = "SplineFollow") +// VRMove_Spider UMETA(DisplayName = "Spider") +}; + +// We use 6 bits for this so a maximum of 64 elements +UENUM(BlueprintType) +enum class EVRConjoinedMovementModes : uint8 +{ + C_MOVE_None = 0x00 UMETA(DisplayName = "None"), + C_MOVE_Walking = 0x01 UMETA(DisplayName = "Walking"), + C_MOVE_NavWalking = 0x02 UMETA(DisplayName = "Navmesh Walking"), + C_MOVE_Falling = 0x03 UMETA(DisplayName = "Falling"), + C_MOVE_Swimming = 0x04 UMETA(DisplayName = "Swimming"), + C_MOVE_Flying = 0x05 UMETA(DisplayName = "Flying"), + //C_MOVE_Custom = 0x06 UMETA(DisplayName = "Custom"), // Skip this, could technically get a Custom7 out of using this slot but who needs 7? + C_MOVE_MAX = 0x07 UMETA(Hidden), + C_VRMOVE_Climbing = 0x08 UMETA(DisplayName = "Climbing"), + C_VRMOVE_LowGrav = 0x09 UMETA(DisplayName = "LowGrav"), + //C_VRMOVE_Spider = 0x0A UMETA(DisplayName = "Spider"), + C_VRMOVE_Seated = 0x0A UMETA(DisplayName = "Seated"), + C_VRMOVE_SplineFollow = 0x0B UMETA(DisplayName = "SplineFollow"), // + // 0x0C + // 0x0D + // 0x0E + // 0x0F + // 0x10 + // 0x11 + // 0x12 + // 0x13 + // 0x14 + // 0x15 + // 0x16 + // 0x17 + // 0x18 + // 0x19 + C_VRMOVE_Custom1 = 0x1A UMETA(DisplayName = "Custom1"), + C_VRMOVE_Custom2 = 0x1B UMETA(DisplayName = "Custom2"), + C_VRMOVE_Custom3 = 0x1C UMETA(DisplayName = "Custom3"), + C_VRMOVE_Custom4 = 0x1D UMETA(DisplayName = "Custom4"), + C_VRMOVE_Custom5 = 0x1E UMETA(DisplayName = "Custom5"), + C_VRMOVE_Custom6 = 0x1F UMETA(DisplayName = "Custom6"), + C_VRMOVE_Custom7 = 0x20 UMETA(DisplayName = "Custom7"), + C_VRMOVE_Custom8 = 0x21 UMETA(DisplayName = "Custom8"), + C_VRMOVE_Custom9 = 0x22 UMETA(DisplayName = "Custom9"), + C_VRMOVE_Custom10 = 0x23 UMETA(DisplayName = "Custom10") +}; + +// This makes a lot of the blueprint functions cleaner +UENUM() +enum class EBPVRResultSwitch : uint8 +{ + // On Success + OnSucceeded, + // On Failure + OnFailed +}; + +// Which method of handling gripping conflict to take with client auth +UENUM(BlueprintType) +enum class EVRClientAuthConflictResolutionMode : uint8 +{ + // Do nothing + VRGRIP_CONFLICT_None, + // Give to the first to arrive + VRGRIP_CONFLICT_First, + // Give to the last to arrive + VRGRIP_CONFLICT_Last, + // Force all ends to drop their grip + VRGRIP_CONFLICT_DropAll +}; + +// Wasn't needed when final setup was realized +// Tracked device waist location +UENUM(Blueprintable) +enum class EBPVRWaistTrackingMode : uint8 +{ + // Waist is tracked from the front + VRWaist_Tracked_Front, + // Waist is tracked from the rear + VRWaist_Tracked_Rear, + // Waist is tracked from the left (self perspective) + VRWaist_Tracked_Left, + // Waist is tracked from the right (self perspective) + VRWaist_Tracked_Right +}; + +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPVRWaistTracking_Info +{ + GENERATED_BODY() +public: + + // Initial "Resting" location of the tracker parent, assumed to be the calibration zero + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings") + FRotator RestingRotation; + + // Distance to offset to get center of waist from tracked parent location + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings") + float WaistRadius; + + // Controls forward vector + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings") + EBPVRWaistTrackingMode TrackingMode; + + // Tracked parent reference + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings") + TObjectPtr TrackedDevice; + + bool IsValid() + { + return TrackedDevice != nullptr; + } + + void Clear() + { + TrackedDevice = nullptr; + } + + FBPVRWaistTracking_Info(): + RestingRotation(FRotator::ZeroRotator), + WaistRadius(0.0f), + TrackingMode(EBPVRWaistTrackingMode::VRWaist_Tracked_Rear), + TrackedDevice(nullptr) + {} + +}; + + +/** Different methods for interpolating rotation between transforms */ +UENUM(BlueprintType) +enum class EVRLerpInterpolationMode : uint8 +{ + /** Shortest Path or Quaternion interpolation for the rotation. */ + QuatInterp, + + /** Rotor or Euler Angle interpolation. */ + EulerInterp, + + /** Dual quaternion interpolation, follows helix or screw-motion path between keyframes. */ + DualQuatInterp +}; + +template +class FBasicLowPassFilter +{ +public: + + /** Default constructor */ + FBasicLowPassFilter(filterType EmptyValueSet) + { + EmptyValue = EmptyValueSet; + Previous = EmptyValue; + PreviousRaw = EmptyValue; + bFirstTime = true; + } + + /** Calculate */ + filterType Filter(const filterType& InValue, const filterType& InAlpha) + { + + filterType Result = InValue; + if (!bFirstTime) + { + // This is unsafe in non float / float array data types, but I am not going to be using any like that + for (int i = 0; i < sizeof(filterType) / sizeof(double); i++) + { + ((double*)&Result)[i] = ((double*)&InAlpha)[i] * ((double*)&InValue)[i] + (1.0f - ((double*)&InAlpha)[i]) * ((double*)&Previous)[i]; + } + } + + bFirstTime = false; + Previous = Result; + PreviousRaw = InValue; + return Result; + } + + filterType EmptyValue; + + /** The previous filtered value */ + filterType Previous; + + /** The previous raw value */ + filterType PreviousRaw; + + /** If this is the first time doing a filter */ + bool bFirstTime; + + //private: + + const filterType CalculateCutoff(const filterType& InValue, double& MinCutoff, double& CutoffSlope) + { + filterType Result; + // This is unsafe in non float / float array data types, but I am not going to be using any like that + for (int i = 0; i < sizeof(filterType) / sizeof(double); i++) + { + ((double*)&Result)[i] = MinCutoff + CutoffSlope * FMath::Abs(((double*)&InValue)[i]); + } + return Result; + } + + const filterType CalculateAlpha(const filterType& InCutoff, const double InDeltaTime) + { + filterType Result; + // This is unsafe in non float / float array data types, but I am not going to be using any like that + for (int i = 0; i < sizeof(filterType) / sizeof(double); i++) + { + ((double*)&Result)[i] = CalculateAlphaTau(((double*)&InCutoff)[i], InDeltaTime); + } + return Result; + } + + inline const double CalculateAlphaTau(const double InCutoff, const double InDeltaTime) + { + const double tau = 1.0 / (2.0 * PI * InCutoff); + return 1.0 / (1.0 + tau / InDeltaTime); + } +}; + + +/************************************************************************/ +/* 1 Euro filter smoothing algorithm */ +/* http://cristal.univ-lille.fr/~casiez/1euro/ */ +/************************************************************************/ +// A re-implementation of the Euro Low Pass Filter that epic uses for the VR Editor, but for blueprints +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPEuroLowPassFilter +{ + GENERATED_BODY() +public: + + /** Default constructor */ + FBPEuroLowPassFilter() : + MinCutoff(0.9), + DeltaCutoff(1.0), + CutoffSlope(0.007), + RawFilter(FVector::ZeroVector), + DeltaFilter(FVector::ZeroVector) + {} + + FBPEuroLowPassFilter(const double InMinCutoff, const double InCutoffSlope, const double InDeltaCutoff) : + MinCutoff(InMinCutoff), + DeltaCutoff(InDeltaCutoff), + CutoffSlope(InCutoffSlope), + RawFilter(FVector::ZeroVector), + DeltaFilter(FVector::ZeroVector) + {} + + // The smaller the value the less jitter and the more lag with micro movements + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") + double MinCutoff; + + // If latency is too high with fast movements increase this value + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") + double DeltaCutoff; + + // This is the magnitude of adjustment + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") + double CutoffSlope; + + + void ResetSmoothingFilter(); + + /** Smooth vector */ + FVector RunFilterSmoothing(const FVector& InRawValue, const float& InDeltaTime); + +private: + + FBasicLowPassFilter RawFilter; + FBasicLowPassFilter DeltaFilter; + +}; + +/************************************************************************/ +/* 1 Euro filter smoothing algorithm */ +/* http://cristal.univ-lille.fr/~casiez/1euro/ */ +/************************************************************************/ +// A re-implementation of the Euro Low Pass Filter that epic uses for the VR Editor, but for blueprints +// This version is for Quaternions +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPEuroLowPassFilterQuat +{ + GENERATED_BODY() +public: + + /** Default constructor */ + FBPEuroLowPassFilterQuat() : + MinCutoff(0.9), + DeltaCutoff(1.0), + CutoffSlope(0.007), + RawFilter(FQuat::Identity), + DeltaFilter(FQuat::Identity) + {} + + FBPEuroLowPassFilterQuat(const double InMinCutoff, const double InCutoffSlope, const double InDeltaCutoff) : + MinCutoff(InMinCutoff), + DeltaCutoff(InDeltaCutoff), + CutoffSlope(InCutoffSlope), + RawFilter(FQuat::Identity), + DeltaFilter(FQuat::Identity) + {} + + // The smaller the value the less jitter and the more lag with micro movements + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") + double MinCutoff; + + // If latency is too high with fast movements increase this value + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") + double DeltaCutoff; + + // This is the magnitude of adjustment + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") + double CutoffSlope; + + void ResetSmoothingFilter(); + + /** Smooth vector */ + FQuat RunFilterSmoothing(const FQuat& InRawValue, const float& InDeltaTime); + +private: + + FBasicLowPassFilter RawFilter; + FBasicLowPassFilter DeltaFilter; + +}; + +/************************************************************************/ +/* 1 Euro filter smoothing algorithm */ +/* http://cristal.univ-lille.fr/~casiez/1euro/ */ +/************************************************************************/ +// A re-implementation of the Euro Low Pass Filter that epic uses for the VR Editor, but for blueprints +// This version is for Transforms +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPEuroLowPassFilterTrans +{ + GENERATED_BODY() +public: + + /** Default constructor */ + FBPEuroLowPassFilterTrans() : + MinCutoff(0.1), + DeltaCutoff(10.0), + CutoffSlope(10.0), + RawFilter(FTransform::Identity), + DeltaFilter(FTransform::Identity) + {} + + FBPEuroLowPassFilterTrans(const double InMinCutoff, const double InCutoffSlope, const double InDeltaCutoff) : + MinCutoff(InMinCutoff), + DeltaCutoff(InDeltaCutoff), + CutoffSlope(InCutoffSlope), + RawFilter(FTransform::Identity), + DeltaFilter(FTransform::Identity) + {} + + // The smaller the value the less jitter and the more lag with micro movements + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") + double MinCutoff; + + // If latency is too high with fast movements increase this value + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") + double DeltaCutoff; + + // This is the magnitude of adjustment + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") + double CutoffSlope; + + void ResetSmoothingFilter(); + + /** Smooth vector */ + FTransform RunFilterSmoothing(const FTransform& InRawValue, const float& InDeltaTime); + +private: + + FBasicLowPassFilter RawFilter; + FBasicLowPassFilter DeltaFilter; + +}; + +// The type of velocity tracking to perform on the motion controllers +UENUM(BlueprintType) +enum class EVRVelocityType : uint8 +{ + // Gets the frame by frame velocity + VRLOCITY_Default UMETA(DisplayName = "Default"), + + // Gets a running average velocity across a sample duration + VRLOCITY_RunningAverage UMETA(DisplayName = "Running Average"), + + // Gets the peak velocity across a sample duration + VRLOCITY_SamplePeak UMETA(DisplayName = "Sampled Peak") +}; + +// A structure used to store and calculate velocities in different ways +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPLowPassPeakFilter +{ + GENERATED_BODY() +public: + + /** Default constructor */ + FBPLowPassPeakFilter() : + VelocitySamples(30), + VelocitySampleLogCounter(0) + {} + + // This is the number of samples to keep active + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Samples") + int32 VelocitySamples; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Samples") + TArrayVelocitySampleLog; + + int32 VelocitySampleLogCounter; + + void Reset() + { + VelocitySampleLog.Reset(VelocitySamples); + } + + void AddSample(FVector NewSample) + { + if (VelocitySamples <= 0) + return; + + if (VelocitySampleLog.Num() != VelocitySamples) + { + VelocitySampleLog.Reset(VelocitySamples); + VelocitySampleLog.AddZeroed(VelocitySamples); + VelocitySampleLogCounter = 0; + } + + VelocitySampleLog[VelocitySampleLogCounter] = NewSample; + ++VelocitySampleLogCounter; + + if (VelocitySampleLogCounter >= VelocitySamples) + VelocitySampleLogCounter = 0; + } + + FVector GetPeak() const + { + FVector MaxValue = FVector::ZeroVector; + float ValueSizeSq = 0.f; + float CurSizeSq = 0.f; + + for (int i = 0; i < VelocitySampleLog.Num(); i++) + { + CurSizeSq = VelocitySampleLog[i].SizeSquared(); + if (CurSizeSq > ValueSizeSq) + { + MaxValue = VelocitySampleLog[i]; + ValueSizeSq = CurSizeSq; + } + } + + return MaxValue; + } +}; + +// Some static vars so we don't have to keep calculating these for our Smallest Three compression +namespace TransNetQuant +{ + static const float MinimumQ = -1.0f / 1.414214f; + static const float MaximumQ = +1.0f / 1.414214f; + static const float MinMaxQDiff = TransNetQuant::MaximumQ - TransNetQuant::MinimumQ; +} + +USTRUCT(/*noexport, */BlueprintType, Category = "VRExpansionLibrary|TransformNetQuantize", meta = (HasNativeMake = "/Script/VRExpansionPlugin.VRExpansionFunctionLibrary.MakeTransform_NetQuantize", HasNativeBreak = "/Script/VRExpansionPlugin.VRExpansionFunctionLibrary.BreakTransform_NetQuantize")) +struct FTransform_NetQuantize : public FTransform +{ + GENERATED_USTRUCT_BODY() + + FORCEINLINE FTransform_NetQuantize() : FTransform() + {} + + FORCEINLINE explicit FTransform_NetQuantize(ENoInit Init) : FTransform(Init) + {} + + FORCEINLINE explicit FTransform_NetQuantize(const FVector& InTranslation) : FTransform(InTranslation) + {} + + FORCEINLINE explicit FTransform_NetQuantize(const FQuat& InRotation) : FTransform(InRotation) + {} + + FORCEINLINE explicit FTransform_NetQuantize(const FRotator& InRotation) : FTransform(InRotation) + {} + + FORCEINLINE FTransform_NetQuantize(const FQuat& InRotation, const FVector& InTranslation, const FVector& InScale3D = FVector::OneVector) + : FTransform(InRotation, InTranslation, InScale3D) + {} + + FORCEINLINE FTransform_NetQuantize(const FRotator& InRotation, const FVector& InTranslation, const FVector& InScale3D = FVector::OneVector) + : FTransform(InRotation, InTranslation, InScale3D) + {} + + FORCEINLINE FTransform_NetQuantize(const FTransform& InTransform) : FTransform(InTransform) + {} + + FORCEINLINE explicit FTransform_NetQuantize(const FMatrix& InMatrix) : FTransform(InMatrix) + {} + + FORCEINLINE FTransform_NetQuantize(const FVector& InX, const FVector& InY, const FVector& InZ, const FVector& InTranslation) + : FTransform(InX, InY, InZ, InTranslation) + {} +public: + + bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess); + + // Serializes a quaternion with the Smallest Three alg + // Referencing the implementation from https://gafferongames.com/post/snapshot_compression/ + // Which appears to be the mostly widely referenced method + // Template variable is number of bits per element (IE: precision), lowest suggested is 9 + // While I wouldn't go to 16 as at that point it is 2 bits more expensive than FRotator::SerializeShort + // Due to the overhead 2 bits of sending out the largest index, a good default is likely 9-10 bits. + template + static bool SerializeQuat_SmallestThree(FArchive& Ar, FQuat &InQuat) + { + check(bits > 1 && bits <= 32); + + uint32 IntegerA = 0, IntegerB = 0, IntegerC = 0, LargestIndex = 0; + + // Get our scaler to not chop off the values + const float scale = float((1 << bits) - 1); + + if (Ar.IsSaving()) + { + InQuat.Normalize(); + const float abs_x = FMath::Abs(InQuat.X); + const float abs_y = FMath::Abs(InQuat.Y); + const float abs_z = FMath::Abs(InQuat.Z); + const float abs_w = FMath::Abs(InQuat.W); + + LargestIndex = 0; + float largest_value = abs_x; + + if (abs_y > largest_value) + { + LargestIndex = 1; + largest_value = abs_y; + } + + if (abs_z > largest_value) + { + LargestIndex = 2; + largest_value = abs_z; + } + + if (abs_w > largest_value) + { + LargestIndex = 3; + largest_value = abs_w; + } + + float a = 0.f; + float b = 0.f; + float c = 0.f; + + switch (LargestIndex) + { + case 0: + if (InQuat.X >= 0) + { + a = InQuat.Y; + b = InQuat.Z; + c = InQuat.W; + } + else + { + a = -InQuat.Y; + b = -InQuat.Z; + c = -InQuat.W; + } + break; + + case 1: + if (InQuat.Y >= 0) + { + a = InQuat.X; + b = InQuat.Z; + c = InQuat.W; + } + else + { + a = -InQuat.X; + b = -InQuat.Z; + c = -InQuat.W; + } + break; + + case 2: + if (InQuat.Z >= 0) + { + a = InQuat.X; + b = InQuat.Y; + c = InQuat.W; + } + else + { + a = -InQuat.X; + b = -InQuat.Y; + c = -InQuat.W; + } + break; + + case 3: + if (InQuat.W >= 0) + { + a = InQuat.X; + b = InQuat.Y; + c = InQuat.Z; + } + else + { + a = -InQuat.X; + b = -InQuat.Y; + c = -InQuat.Z; + } + break; + + default:break; + } + + const float normal_a = (a - TransNetQuant::MinimumQ) / (TransNetQuant::MinMaxQDiff); + const float normal_b = (b - TransNetQuant::MinimumQ) / (TransNetQuant::MinMaxQDiff); + const float normal_c = (c - TransNetQuant::MinimumQ) / (TransNetQuant::MinMaxQDiff); + + IntegerA = FMath::FloorToInt(normal_a * scale + 0.5f); + IntegerB = FMath::FloorToInt(normal_b * scale + 0.5f); + IntegerC = FMath::FloorToInt(normal_c * scale + 0.5f); + } + + // Serialize the bits + Ar.SerializeBits(&LargestIndex, 2); + Ar.SerializeBits(&IntegerA, bits); + Ar.SerializeBits(&IntegerB, bits); + Ar.SerializeBits(&IntegerC, bits); + + if (Ar.IsLoading()) + { + const float inverse_scale = 1.0f / scale; + + const float a = IntegerA * inverse_scale * (TransNetQuant::MinMaxQDiff) + TransNetQuant::MinimumQ; + const float b = IntegerB * inverse_scale * (TransNetQuant::MinMaxQDiff) + TransNetQuant::MinimumQ; + const float c = IntegerC * inverse_scale * (TransNetQuant::MinMaxQDiff) + TransNetQuant::MinimumQ; + + switch (LargestIndex) + { + case 0: + { + InQuat.X = FMath::Sqrt(1.f - a * a - b * b - c * c); + InQuat.Y = a; + InQuat.Z = b; + InQuat.W = c; + } + break; + + case 1: + { + InQuat.X = a; + InQuat.Y = FMath::Sqrt(1.f - a * a - b * b - c * c); + InQuat.Z = b; + InQuat.W = c; + } + break; + + case 2: + { + InQuat.X = a; + InQuat.Y = b; + InQuat.Z = FMath::Sqrt(1.f - a * a - b * b - c * c); + InQuat.W = c; + } + break; + + case 3: + { + InQuat.X = a; + InQuat.Y = b; + InQuat.Z = c; + InQuat.W = FMath::Sqrt(1.f - a * a - b * b - c * c); + } + break; + + default: + { + InQuat.X = 0.f; + InQuat.Y = 0.f; + InQuat.Z = 0.f; + InQuat.W = 1.f; + } + } + + InQuat.Normalize(); + } + + return true; + } +}; + +template<> +struct TStructOpsTypeTraits< FTransform_NetQuantize > : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithNetSerializer = true, + WithNetSharedSerialization = true, + }; +}; + +UENUM() +enum class EVRVectorQuantization : uint8 +{ + /** Each vector component will be rounded, preserving one decimal place. */ + RoundOneDecimal = 0, + /** Each vector component will be rounded, preserving two decimal places. */ + RoundTwoDecimals = 1 +}; + +UENUM() +enum class EVRRotationQuantization : uint8 +{ + /** Each rotation component will be rounded to 10 bits (1024 values). */ + RoundTo10Bits = 0, + /** Each rotation component will be rounded to a short. */ + RoundToShort = 1 +}; + + +USTRUCT() +struct VREXPANSIONPLUGIN_API FBPVRComponentPosRep +{ + GENERATED_USTRUCT_BODY() +public: + + UPROPERTY(Transient) + FVector Position; + UPROPERTY(Transient) + FRotator Rotation; + + // The quantization level to use for the vector components + UPROPERTY(EditDefaultsOnly, Category = Replication, AdvancedDisplay) + EVRVectorQuantization QuantizationLevel; + + // The quantization level to use for the rotation components + // Using 10 bits mode saves approx 2.25 bytes per replication. + UPROPERTY(EditDefaultsOnly, Category = Replication, AdvancedDisplay) + EVRRotationQuantization RotationQuantizationLevel; + + FORCEINLINE uint16 CompressAxisTo10BitShort(float Angle) + { + // map [0->360) to [0->1024) and mask off any winding + return FMath::RoundToInt(Angle * 1024.f / 360.f) & 0xFFFF; + } + + + FORCEINLINE float DecompressAxisFrom10BitShort(uint16 Angle) + { + // map [0->1024) to [0->360) + return (Angle * 360.f / 1024.f); + } + + FBPVRComponentPosRep(): + QuantizationLevel(EVRVectorQuantization::RoundTwoDecimals), + RotationQuantizationLevel(EVRRotationQuantization::RoundToShort) + { + //QuantizationLevel = EVRVectorQuantization::RoundTwoDecimals; + Position = FVector::ZeroVector; + Rotation = FRotator::ZeroRotator; + } + + /** Network serialization */ + // Doing a custom NetSerialize here because this is sent via RPCs and should change on every update + bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) + { + bOutSuccess = true; + + // Defines the level of Quantization + //uint8 Flags = (uint8)QuantizationLevel; + Ar.SerializeBits(&QuantizationLevel, 1); // Only two values 0:1 + Ar.SerializeBits(&RotationQuantizationLevel, 1); // Only two values 0:1 + + // No longer using their built in rotation rep, as controllers will rarely if ever be at 0 rot on an axis and + // so the 1 bit overhead per axis is just that, overhead + //Rotation.SerializeCompressedShort(Ar); + + uint16 ShortPitch = 0; + uint16 ShortYaw = 0; + uint16 ShortRoll = 0; + + /** + * Valid range 100: 2^22 / 100 = +/- 41,943.04 (419.43 meters) + * Valid range 10: 2^18 / 10 = +/- 26,214.4 (262.144 meters) + * Pos rep is assumed to be in relative space for a tracked component, these numbers should be fine + */ + if (Ar.IsSaving()) + { + switch (QuantizationLevel) + { + case EVRVectorQuantization::RoundTwoDecimals: bOutSuccess &= SerializePackedVector<100, 22/*30*/>(Position, Ar); break; + case EVRVectorQuantization::RoundOneDecimal: bOutSuccess &= SerializePackedVector<10, 18/*24*/>(Position, Ar); break; + } + + switch (RotationQuantizationLevel) + { + case EVRRotationQuantization::RoundTo10Bits: + { + ShortPitch = CompressAxisTo10BitShort(Rotation.Pitch); + ShortYaw = CompressAxisTo10BitShort(Rotation.Yaw); + ShortRoll = CompressAxisTo10BitShort(Rotation.Roll); + + Ar.SerializeBits(&ShortPitch, 10); + Ar.SerializeBits(&ShortYaw, 10); + Ar.SerializeBits(&ShortRoll, 10); + }break; + + case EVRRotationQuantization::RoundToShort: + { + ShortPitch = FRotator::CompressAxisToShort(Rotation.Pitch); + ShortYaw = FRotator::CompressAxisToShort(Rotation.Yaw); + ShortRoll = FRotator::CompressAxisToShort(Rotation.Roll); + + Ar << ShortPitch; + Ar << ShortYaw; + Ar << ShortRoll; + }break; + } + } + else // If loading + { + //QuantizationLevel = (EVRVectorQuantization)Flags; + + switch (QuantizationLevel) + { + case EVRVectorQuantization::RoundTwoDecimals: bOutSuccess &= SerializePackedVector<100, 22/*30*/>(Position, Ar); break; + case EVRVectorQuantization::RoundOneDecimal: bOutSuccess &= SerializePackedVector<10, 18/*24*/>(Position, Ar); break; + } + + switch (RotationQuantizationLevel) + { + case EVRRotationQuantization::RoundTo10Bits: + { + Ar.SerializeBits(&ShortPitch, 10); + Ar.SerializeBits(&ShortYaw, 10); + Ar.SerializeBits(&ShortRoll, 10); + + Rotation.Pitch = DecompressAxisFrom10BitShort(ShortPitch); + Rotation.Yaw = DecompressAxisFrom10BitShort(ShortYaw); + Rotation.Roll = DecompressAxisFrom10BitShort(ShortRoll); + }break; + + case EVRRotationQuantization::RoundToShort: + { + Ar << ShortPitch; + Ar << ShortYaw; + Ar << ShortRoll; + + Rotation.Pitch = FRotator::DecompressAxisFromShort(ShortPitch); + Rotation.Yaw = FRotator::DecompressAxisFromShort(ShortYaw); + Rotation.Roll = FRotator::DecompressAxisFromShort(ShortRoll); + }break; + } + } + + return bOutSuccess; + } + +}; + +template<> +struct TStructOpsTypeTraits< FBPVRComponentPosRep > : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithNetSerializer = true, + WithNetSharedSerialization = true, + }; +}; + +UENUM(Blueprintable) +enum class EGripCollisionType : uint8 +{ + /** Held items can be offset by geometry, uses physics for the offset, pushes physics simulating objects with weight taken into account. */ + InteractiveCollisionWithPhysics, + + // InteractiveCollisionWithVelocity, + + /** Held items can be offset by geometry, uses sweep for the offset, pushes physics simulating objects, no weight. */ + InteractiveCollisionWithSweep, + + /** Uses Stiffness and damping settings on collision, on no collision uses stiffness values 10x stronger so it has less play. */ + InteractiveHybridCollisionWithPhysics, + + /** Swaps back and forth between physics grip and a sweep type grip depending on if the held object will be colliding this frame or not. */ + InteractiveHybridCollisionWithSweep, + + /** Only sweeps movement, will not be offset by geomtry, still pushes physics simulating objects, no weight. */ + SweepWithPhysics, + + /** Does not sweep at all (does not trigger OnHitEvents), still pushes physics simulating objects, no weight. */ + PhysicsOnly, + + /** Free constraint to controller base, no rotational drives. */ + ManipulationGrip, + + /** Free constraint to controller base with a twist drive. */ + ManipulationGripWithWristTwist, + + /** Attachment grips use native attachment and only sets location / rotation if they differ, this grip always late updates*/ + AttachmentGrip, + + /** Custom grip is to be handled by the object itself, it just sends the TickGrip event every frame but doesn't move the object. */ + CustomGrip, + + /** A grip that does not tick or move, used for drop / grip events only and uses least amount of processing. */ + EventsOnly, + + /** Uses a hard constraint with no softness to lock them together, best used with ConstrainToPivot enabled and a bone chain. */ + LockedConstraint + +}; + +// This needs to be updated as the original gets changed, that or hope they make the original blueprint accessible. +UENUM(Blueprintable) +enum class EBPHMDDeviceType : uint8 +{ + DT_OculusHMD,//Rift, + DT_PSVR, + //DT_Morpheus, + DT_ES2GenericStereoMesh, + DT_SteamVR, + DT_GearVR, + DT_GoogleVR, + DT_AppleARKit, + DT_GoogleARCore, + DT_Unknown +}; + +// Lerp states +UENUM(Blueprintable) +enum class EGripLerpState : uint8 +{ + StartLerp, + EndLerp, + //ConstantLerp_DEPRECATED, + NotLerping +}; + +// Secondary Grip Type +UENUM(Blueprintable) +enum class ESecondaryGripType : uint8 +{ + // No secondary grip + SG_None, + // Free secondary grip + SG_Free, + // Only secondary grip at a slot + SG_SlotOnly, + // Retain pos on drop + SG_Free_Retain, + // Retain pos on drop, slot only + SG_SlotOnly_Retain, + // Scaling with retain pos on drop + SG_FreeWithScaling_Retain, + // Scaling with retain pos on drop, slot only + SG_SlotOnlyWithScaling_Retain, + // Does nothing, just provides the events for personal use + SG_Custom, + // Does not track the hand, only scales the mesh with it + SG_ScalingOnly, +}; + +// Grip Late Update information +UENUM(Blueprintable) +enum class EGripLateUpdateSettings : uint8 +{ + LateUpdatesAlwaysOn, + LateUpdatesAlwaysOff, + NotWhenColliding, + NotWhenDoubleGripping, + NotWhenCollidingOrDoubleGripping +}; + +// Grip movement replication settings +// LocalOnly_Not_Replicated is useful for instant client grips +// that can be sent to the server and everyone locally grips it (IE: inventories that don't ever leave a player) +// Objects that need to be handled possibly by multiple players should be ran +// non locally gripped instead so that the server can validate grips instead. +// ClientSide_Authoritive will grip on the client instantly without server intervention and then send a notice to the server +// ClientSide_Authoritive_NoRep will grip on the client instantly without server intervention but will not rep the grip to the server +// that the grip was made +UENUM(Blueprintable) +enum class EGripMovementReplicationSettings : uint8 +{ + KeepOriginalMovement, + ForceServerSideMovement, + ForceClientSideMovement, + ClientSide_Authoritive, + ClientSide_Authoritive_NoRep +}; + +// Grip Target Type +UENUM(Blueprintable) +enum class EGripTargetType : uint8 +{ + ActorGrip, + ComponentGrip + //InteractibleActorGrip, + //InteractibleComponentGrip +}; + +// Lerp states +UENUM(Blueprintable) +enum class EGripInterfaceTeleportBehavior : uint8 +{ + /* Teleports entire actor */ + TeleportAllComponents, + /* Teleports by the location delta and not the calculated new position of the grip, useful for rag dolls*/ + DeltaTeleportation, + /* Only teleports an actor if the root component is held */ + OnlyTeleportRootComponent, + /* Just drop the grip on teleport */ + DropOnTeleport, + /* Teleporting is not allowed */ + DontTeleport +}; + +// Type of physics constraint to use +UENUM(Blueprintable) +enum class EPhysicsGripConstraintType : uint8 +{ + AccelerationConstraint = 0, + ForceConstraint = 1 +}; + +UENUM(Blueprintable) +enum class EPhysicsGripCOMType : uint8 +{ + /* Use the default setting for the specified grip type */ + COM_Default = 0, + /* Don't grip at center of mass (generally unstable as it grips at actor zero)*/ + COM_AtPivot = 1, + /* Set center of mass to grip location and grip there (default for interactible with physics) */ + COM_SetAndGripAt = 2, + /* Grip at center of mass but do not set it */ + COM_GripAt = 3, + /* Just grip at the controller location, but don't set COM (default for manipulation grips)*/ + COM_GripAtControllerLoc = 4 +}; + +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPAdvGripPhysicsSettings +{ + GENERATED_BODY() +public: + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PhysicsSettings") + bool bUsePhysicsSettings; + + // Set the constraint force mode + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PhysicsSettings", meta = (editcondition = "bUsePhysicsSettings")) + EPhysicsGripConstraintType PhysicsConstraintType; + + // Set how the grips handle center of mass + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PhysicsSettings", meta = (editcondition = "bUsePhysicsSettings")) + EPhysicsGripCOMType PhysicsGripLocationSettings; + + // Turn off gravity during the grip, resolves the slight downward offset of the object with normal constraint strengths. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PhysicsSettings", meta = (editcondition = "bUsePhysicsSettings")) + bool bTurnOffGravityDuringGrip; + + // Don't automatically (un)simulate the component/root on grip/drop, let the end user set it up instead + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PhysicsSettings", meta = (editcondition = "bUsePhysicsSettings")) + bool bSkipSettingSimulating; + + // A multiplier to add to the stiffness of a grip that is then set as the MaxForce of the grip + // It is clamped between 0.00 and 512.00 to save in replication cost, a value of 0 will mean max force is infinite as it will multiply it to zero (legacy behavior) + // If you want an exact value you can figure it out as a factor of the stiffness, also Max force can be directly edited with SetAdvancedConstraintSettings + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PhysicsSettings", meta = (editcondition = "bUsePhysicsSettings"), meta = (ClampMin = "0.00", UIMin = "0.00", ClampMax = "512.00", UIMax = "512.00")) + float LinearMaxForceCoefficient; + + // A multiplier to add to the stiffness of a grip that is then set as the MaxForce of the grip + // It is clamped between 0.00 and 512.00 to save in replication cost, a value of 0 will mean max force is infinite as it will multiply it to zero (legacy behavior) + // If you want an exact value you can figure it out as a factor of the stiffness, also Max force can be directly edited with SetAdvancedConstraintSettings + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PhysicsSettings", meta = (editcondition = "bUsePhysicsSettings"), meta = (ClampMin = "0.00", UIMin = "0.00", ClampMax = "512.00", UIMax = "512.00")) + float AngularMaxForceCoefficient; + + // Use the custom angular values on this grip + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PhysicsSettings", meta = (editcondition = "bUsePhysicsSettings")) + bool bUseCustomAngularValues; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PhysicsSettings", meta = (editcondition = "bUseCustomAngularValues", ClampMin = "0.000", UIMin = "0.000")) + float AngularStiffness; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PhysicsSettings", meta = (editcondition = "bUseCustomAngularValues", ClampMin = "0.000", UIMin = "0.000")) + float AngularDamping; + + FBPAdvGripPhysicsSettings(): + bUsePhysicsSettings(false), + PhysicsConstraintType(EPhysicsGripConstraintType::AccelerationConstraint), + PhysicsGripLocationSettings(EPhysicsGripCOMType::COM_Default), + bTurnOffGravityDuringGrip(false), + bSkipSettingSimulating(false), + LinearMaxForceCoefficient(0.f), + AngularMaxForceCoefficient(0.f), + bUseCustomAngularValues(false), + AngularStiffness(0.0f), + AngularDamping(0.0f)//, + //MaxForce(0.f) + {} + + FORCEINLINE bool operator==(const FBPAdvGripPhysicsSettings &Other) const + { + return (bUsePhysicsSettings == Other.bUsePhysicsSettings && + PhysicsGripLocationSettings == Other.PhysicsGripLocationSettings && + bTurnOffGravityDuringGrip == Other.bTurnOffGravityDuringGrip && + bSkipSettingSimulating == Other.bSkipSettingSimulating && + bUseCustomAngularValues == Other.bUseCustomAngularValues && + PhysicsConstraintType == Other.PhysicsConstraintType && + FMath::IsNearlyEqual(LinearMaxForceCoefficient, Other.LinearMaxForceCoefficient) && + FMath::IsNearlyEqual(AngularMaxForceCoefficient, Other.AngularMaxForceCoefficient) && + FMath::IsNearlyEqual(AngularStiffness, Other.AngularStiffness) && + FMath::IsNearlyEqual(AngularDamping, Other.AngularDamping) //&& + //FMath::IsNearlyEqual(MaxForce, Other.MaxForce) + ); + } + + FORCEINLINE bool operator!=(const FBPAdvGripPhysicsSettings &Other) const + { + return (bUsePhysicsSettings != Other.bUsePhysicsSettings || + PhysicsGripLocationSettings != Other.PhysicsGripLocationSettings || + bTurnOffGravityDuringGrip != Other.bTurnOffGravityDuringGrip || + bSkipSettingSimulating != Other.bSkipSettingSimulating || + bUseCustomAngularValues != Other.bUseCustomAngularValues || + PhysicsConstraintType != Other.PhysicsConstraintType || + !FMath::IsNearlyEqual(LinearMaxForceCoefficient, Other.LinearMaxForceCoefficient) || + !FMath::IsNearlyEqual(AngularMaxForceCoefficient, Other.AngularMaxForceCoefficient) || + !FMath::IsNearlyEqual(AngularStiffness, Other.AngularStiffness) || + !FMath::IsNearlyEqual(AngularDamping, Other.AngularDamping) //|| + //!FMath::IsNearlyEqual(MaxForce, Other.MaxForce) + ); + } + + /** Network serialization */ + bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) + { + //Ar << bUsePhysicsSettings; + Ar.SerializeBits(&bUsePhysicsSettings, 1); + + if (bUsePhysicsSettings) + { + //Ar << bDoNotSetCOMToGripLocation; + Ar.SerializeBits(&PhysicsGripLocationSettings, 3); // This only has four elements + + //Ar << PhysicsConstraintType; + Ar.SerializeBits(&PhysicsConstraintType, 1); // This only has two elements + + //Ar << bTurnOffGravityDuringGrip; + Ar.SerializeBits(&bTurnOffGravityDuringGrip, 1); + Ar.SerializeBits(&bSkipSettingSimulating, 1); + + + // This is 0.0 - 512.0, using compression to get it smaller, 8 bits = max 256 + 1 bit for sign and 7 bits precision for 128 / full 2 digit precision + if (Ar.IsSaving()) + { + bOutSuccess &= WriteFixedCompressedFloat<512, 17>(LinearMaxForceCoefficient, Ar); + bOutSuccess &= WriteFixedCompressedFloat<512, 17>(AngularMaxForceCoefficient, Ar); + } + else + { + bOutSuccess &= ReadFixedCompressedFloat<512, 17>(LinearMaxForceCoefficient, Ar); + bOutSuccess &= ReadFixedCompressedFloat<512, 17>(AngularMaxForceCoefficient, Ar); + } + + + + //Ar << bUseCustomAngularValues; + Ar.SerializeBits(&bUseCustomAngularValues, 1); + + if (bUseCustomAngularValues) + { + Ar << AngularStiffness; + Ar << AngularDamping; + } + + //Ar << MaxForce; + } + + bOutSuccess = true; + return bOutSuccess; + } +}; + +template<> +struct TStructOpsTypeTraits< FBPAdvGripPhysicsSettings > : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithNetSerializer = true + }; +}; + +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPAdvGripSettings +{ + GENERATED_BODY() +public: + + // Priority of this item when being gripped, (Higher is more priority) + // This lets you prioritize whether an object should be gripped over another one when both + // collide with traces or overlaps. #Note: Currently not implemented in the plugin, here for your use. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AdvancedGripSettings") + uint8 GripPriority; + + // If true, will set the owner of actor grips on grip + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AdvancedGripSettings") + bool bSetOwnerOnGrip; + + // If true, we will be bypassed on global lerp operations + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AdvancedGripSettings") + bool bDisallowLerping; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AdvancedGripSettings") + FBPAdvGripPhysicsSettings PhysicsSettings; + + FBPAdvGripSettings() : + GripPriority(1), + bSetOwnerOnGrip(1), + bDisallowLerping(0) + {} + + FBPAdvGripSettings(int GripPrio) : + GripPriority(GripPrio), + bSetOwnerOnGrip(1), + bDisallowLerping(0) + {} +}; + +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPSecondaryGripInfo +{ + GENERATED_BODY() +public: + + // For multi grip situations + UPROPERTY(BlueprintReadOnly, Category = "SecondaryGripInfo") + bool bHasSecondaryAttachment; + + UPROPERTY(BlueprintReadOnly, Category = "SecondaryGripInfo") + TObjectPtr SecondaryAttachment; + + UPROPERTY(BlueprintReadWrite, Category = "SecondaryGripInfo") + FTransform_NetQuantize SecondaryRelativeTransform; + + UPROPERTY(BlueprintReadWrite, Category = "SecondaryGripInfo") + bool bIsSlotGrip; + + UPROPERTY(BlueprintReadWrite, Category = "SecondaryGripInfo") + FName SecondarySlotName; + + // Lerp transitions + // Max value is 16 seconds with two decimal precision, this is to reduce replication overhead + UPROPERTY() + float LerpToRate; + + // Filled in from the tick code so users can activate and deactivate grips based on this + UPROPERTY(BlueprintReadOnly, NotReplicated, Category = "SecondaryGripInfo") + float SecondaryGripDistance; + + // These are not replicated, they don't need to be + EGripLerpState GripLerpState; + float curLerp; + + // Store values for frame by frame changes of secondary grips + FVector LastRelativeLocation; + + void ClearNonReppingItems() + { + SecondaryGripDistance = 0.0f; + GripLerpState = EGripLerpState::NotLerping; + curLerp = 0.0f; + } + + FBPSecondaryGripInfo(): + bHasSecondaryAttachment(false), + SecondaryAttachment(nullptr), + SecondaryRelativeTransform(FTransform::Identity), + bIsSlotGrip(false), + SecondarySlotName(NAME_None), + LerpToRate(0.0f), + SecondaryGripDistance(0.0f), + GripLerpState(EGripLerpState::NotLerping), + curLerp(0.0f), + LastRelativeLocation(FVector::ZeroVector) + {} + + // Adding this override to handle the fact that repped versions don't send relative loc and slot grip + // We don't want to override relative loc with 0,0,0 when it is in end lerp as otherwise it lerps wrong + FORCEINLINE FBPSecondaryGripInfo& RepCopy(const FBPSecondaryGripInfo& Other) + { + this->bHasSecondaryAttachment = Other.bHasSecondaryAttachment; + this->SecondaryAttachment = Other.SecondaryAttachment; + + if (bHasSecondaryAttachment) + { + this->SecondaryRelativeTransform = Other.SecondaryRelativeTransform; + this->bIsSlotGrip = Other.bIsSlotGrip; + this->SecondarySlotName = Other.SecondarySlotName; + } + + this->LerpToRate = Other.LerpToRate; + return *this; + } + + /** Network serialization */ + bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) + { + bOutSuccess = true; + + //Ar << bHasSecondaryAttachment; + Ar.SerializeBits(&bHasSecondaryAttachment, 1); + + if (bHasSecondaryAttachment) + { + Ar << SecondaryAttachment; + //Ar << SecondaryRelativeLocation; + SecondaryRelativeTransform.NetSerialize(Ar, Map, bOutSuccess); + + //Ar << bIsSlotGrip; + Ar.SerializeBits(&bIsSlotGrip, 1); + + Ar << SecondarySlotName; + } + + // This is 0.0 - 16.0, using compression to get it smaller, 4 bits = max 16 + 1 bit for sign and 7 bits precision for 128 / full 2 digit precision + if (Ar.IsSaving()) + bOutSuccess &= WriteFixedCompressedFloat<16, 12>(LerpToRate, Ar); + else + bOutSuccess &= ReadFixedCompressedFloat<16, 12>(LerpToRate, Ar); + + //Ar << LerpToRate; + return true; + } +}; + +template<> +struct TStructOpsTypeTraits< FBPSecondaryGripInfo > : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithNetSerializer = true + }; +}; + +#define INVALID_VRGRIP_ID 0 + +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPActorGripInformation +{ + GENERATED_BODY() +public: + + // Hashed unique ID to identify this grip instance + UPROPERTY(BlueprintReadOnly, Category = "Settings") + uint8 GripID; + UPROPERTY(BlueprintReadOnly, Category = "Settings") + EGripTargetType GripTargetType; + UPROPERTY(BlueprintReadOnly, Category = "Settings") + TObjectPtr GrippedObject; + UPROPERTY(BlueprintReadOnly, Category = "Settings") + EGripCollisionType GripCollisionType; + UPROPERTY(BlueprintReadWrite, Category = "Settings") + EGripLateUpdateSettings GripLateUpdateSetting; + UPROPERTY(BlueprintReadOnly, NotReplicated, Category = "Settings") + bool bColliding; + UPROPERTY(BlueprintReadWrite, Category = "Settings") + FTransform_NetQuantize RelativeTransform; + UPROPERTY(BlueprintReadWrite, Category = "Settings") + bool bIsSlotGrip; + UPROPERTY(BlueprintReadWrite, Category = "Settings") + FName GrippedBoneName; + UPROPERTY(BlueprintReadWrite, Category = "Settings") + FName SlotName; + UPROPERTY(BlueprintReadOnly, Category = "Settings") + EGripMovementReplicationSettings GripMovementReplicationSetting; + + // Whether the grip is currently paused + UPROPERTY(BlueprintReadWrite, NotReplicated, Category = "Settings") + bool bIsPaused; + + // Only true in one specific circumstance, when you are a simulated client + // and the grip has been dropped but replication on the array hasn't deleted + // the entry yet. We cannot remove the entry as it can corrupt the array. + // this lets end users check against the grip to ignore it. + UPROPERTY(BlueprintReadOnly, NotReplicated, Category = "Settings") + bool bIsPendingKill; + + // When true, will lock a hybrid grip into its collision state + UPROPERTY(BlueprintReadWrite, NotReplicated, Category = "Settings") + bool bLockHybridGrip; + + // I would have loved to have both of these not be replicated (and in normal grips they wouldn't have to be) + // However for serialization purposes and Client_Authority grips they need to be.... + UPROPERTY() + bool bOriginalReplicatesMovement; + UPROPERTY() + bool bOriginalGravity; + + UPROPERTY(BlueprintReadOnly, Category = "Settings") + float Damping; + UPROPERTY(BlueprintReadOnly, Category = "Settings") + float Stiffness; + + UPROPERTY(BlueprintReadOnly, Category = "Settings") + FBPAdvGripSettings AdvancedGripSettings; + + // For multi grip situations + UPROPERTY(BlueprintReadOnly, Category = "Settings") + FBPSecondaryGripInfo SecondaryGripInfo; + + // Optional Additive Transform for programmatic animation + UPROPERTY(BlueprintReadWrite, NotReplicated, Category = "Settings") + FTransform AdditionTransform; + + // Distance from the target point for the grip + UPROPERTY(BlueprintReadOnly, NotReplicated, Category = "Settings") + float GripDistance; + + // Locked transitions for swept movement so they don't just rotate in place on contact + bool bIsLocked; + FQuat LastLockedRotation; + + // For delta teleport and any future calculations we want to do + FTransform LastWorldTransform; + bool bSetLastWorldTransform; + + // Need to skip one frame of length check post teleport with constrained objects, the constraint may have not been updated yet. + bool bSkipNextTeleportCheck; + + // Need to skip one frame of length check post teleport with constrained objects, the constraint may have not been updated yet. + bool bSkipNextConstraintLengthCheck; + + // Lerp settings if we are using global lerping + float CurrentLerpTime; + float LerpSpeed; + FTransform OnGripTransform; + + ///////////////////// + // TMP: Velocity calculation addition for 5.4 #TODO: Remove this when the bug is fixed + FVector LinVel = FVector::ZeroVector; + FVector RotVel = FVector::ZeroVector; + FTransform LastVelWorldTrans; // Identity by default + /////////////////////// + + UPROPERTY(BlueprintReadWrite, NotReplicated, Category = "Settings") + bool bIsLerping; + + bool IsLocalAuthGrip() + { + return GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive || GripMovementReplicationSetting == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep; + } + + // If the grip is valid + bool IsValid() const + { + return (!bIsPendingKill && GripID != INVALID_VRGRIP_ID && GrippedObject && IsValidChecked(GrippedObject)); + } + + // Both valid and is not paused + bool IsActive() const + { + return (!bIsPendingKill && GripID != INVALID_VRGRIP_ID && GrippedObject && IsValidChecked(GrippedObject) && !bIsPaused); + } + + // Cached values - since not using a full serialize now the old array state may not contain what i need to diff + // I set these in On_Rep now and check against them when new replications happen to control some actions. + struct FGripValueCache + { + bool bWasInitiallyRepped; + uint8 CachedGripID; + + FGripValueCache() : + bWasInitiallyRepped(false), + CachedGripID(INVALID_VRGRIP_ID) + {} + + }ValueCache; + + void ClearNonReppingItems() + { + ValueCache = FGripValueCache(); + bColliding = false; + bIsLocked = false; + LastLockedRotation = FQuat::Identity; + LastWorldTransform.SetIdentity(); + bSetLastWorldTransform = false; + bSkipNextTeleportCheck = false; + bSkipNextConstraintLengthCheck = false; + bIsPaused = false; + bIsPendingKill = false; + bLockHybridGrip = false; + AdditionTransform = FTransform::Identity; + GripDistance = 0.0f; + CurrentLerpTime = 0.f; + LerpSpeed = 0.f; + OnGripTransform = FTransform::Identity; + bIsLerping = false; + + // Clear out the secondary grip + SecondaryGripInfo.ClearNonReppingItems(); + } + + // Adding this override to keep un-repped variables from repping over from Client Auth grips + FORCEINLINE FBPActorGripInformation& RepCopy(const FBPActorGripInformation& Other) + { + this->GripID = Other.GripID; + this->GripTargetType = Other.GripTargetType; + this->GrippedObject = Other.GrippedObject; + this->GripCollisionType = Other.GripCollisionType; + this->GripLateUpdateSetting = Other.GripLateUpdateSetting; + this->RelativeTransform = Other.RelativeTransform; + this->bIsSlotGrip = Other.bIsSlotGrip; + this->GrippedBoneName = Other.GrippedBoneName; + this->SlotName = Other.SlotName; + this->GripMovementReplicationSetting = Other.GripMovementReplicationSetting; + //this->bOriginalReplicatesMovement = Other.bOriginalReplicatesMovement; + //this->bOriginalGravity = Other.bOriginalGravity; + this->Damping = Other.Damping; + this->Stiffness = Other.Stiffness; + this->AdvancedGripSettings = Other.AdvancedGripSettings; + this->SecondaryGripInfo.RepCopy(Other.SecondaryGripInfo); // Run the replication copy version so we don't overwrite vars + //this->SecondaryGripInfo = Other.SecondaryGripInfo; + + return *this; + } + + + AActor* GetGrippedActor() const; + + UPrimitiveComponent* GetGrippedComponent() const; + + //Check if a grip is the same as another, the only things I check for are the actor / component + //This is here for the Find() function from TArray + FORCEINLINE bool operator==(const FBPActorGripInformation &Other) const + { + if ((GripID != INVALID_VRGRIP_ID) && (GripID == Other.GripID) ) + return true; + //if (GrippedObject && GrippedObject == Other.GrippedObject) + //return true; + + return false; + } + + FORCEINLINE bool operator==(const AActor * Other) const + { + if (Other && GrippedObject && GrippedObject == (const UObject*)Other) + return true; + + return false; + } + + bool operator==(const UPrimitiveComponent* Other) const; + + FORCEINLINE bool operator==(const UObject * Other) const + { + if (Other && GrippedObject == Other) + return true; + + return false; + } + + FORCEINLINE bool operator==(const uint8& Other) const + { + if ((GripID != INVALID_VRGRIP_ID) && (GripID == Other)) + return true; + + return false; + } + + FBPActorGripInformation() : + GripID(INVALID_VRGRIP_ID), + GripTargetType(EGripTargetType::ActorGrip), + GrippedObject(nullptr), + GripCollisionType(EGripCollisionType::InteractiveCollisionWithPhysics), + GripLateUpdateSetting(EGripLateUpdateSettings::NotWhenCollidingOrDoubleGripping), + bColliding(false), + RelativeTransform(FTransform::Identity), + bIsSlotGrip(false), + GrippedBoneName(NAME_None), + SlotName(NAME_None), + GripMovementReplicationSetting(EGripMovementReplicationSettings::ForceClientSideMovement), + bIsPaused(false), + bIsPendingKill(false), + bLockHybridGrip(false), + bOriginalReplicatesMovement(false), + bOriginalGravity(false), + Damping(200.0f), + Stiffness(1500.0f), + AdditionTransform(FTransform::Identity), + GripDistance(0.0f), + bIsLocked(false), + LastLockedRotation(FRotator::ZeroRotator), + LastWorldTransform(FTransform::Identity), + bSetLastWorldTransform(false), + bSkipNextTeleportCheck(false), + bSkipNextConstraintLengthCheck(false), + CurrentLerpTime(0.f), + LerpSpeed(0.f), + OnGripTransform(FTransform::Identity), + bIsLerping(false) + { + } + +}; + +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPGripPair +{ + GENERATED_BODY() +public: + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripPair") + TObjectPtr HoldingController; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripPair") + uint8 GripID; + + FBPGripPair() : + HoldingController(nullptr), + GripID(INVALID_VRGRIP_ID) + {} + + FBPGripPair(UGripMotionControllerComponent * Controller, uint8 ID) : + HoldingController(Controller), + GripID(ID) + {} + + void Clear() + { + HoldingController = nullptr; + GripID = INVALID_VRGRIP_ID; + } + + bool IsValid() + { + return HoldingController != nullptr && GripID != INVALID_VRGRIP_ID; + } + + FORCEINLINE bool operator==(const FBPGripPair & Other) const + { + return (Other.HoldingController == HoldingController && ((GripID != INVALID_VRGRIP_ID) && (GripID == Other.GripID))); + } + + FORCEINLINE bool operator==(const UGripMotionControllerComponent * Other) const + { + return (Other == HoldingController); + } + + FORCEINLINE bool operator==(const uint8 & Other) const + { + return GripID == Other; + } + +}; + +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPInterfaceProperties +{ + GENERATED_BODY() +public: + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + bool bDenyGripping; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + bool bAllowMultipleGrips; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + EGripInterfaceTeleportBehavior OnTeleportBehavior; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + bool bSimulateOnDrop; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + EGripCollisionType SlotDefaultGripType; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + EGripCollisionType FreeDefaultGripType; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + ESecondaryGripType SecondaryGripType; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + EGripMovementReplicationSettings MovementReplicationType; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + EGripLateUpdateSettings LateUpdateSetting; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + float ConstraintStiffness; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + float ConstraintDamping; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + float ConstraintBreakDistance; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + float SecondarySlotRange; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface") + float PrimarySlotRange; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface|AdvancedGripSettings") + FBPAdvGripSettings AdvancedGripSettings; + + UPROPERTY(BlueprintReadWrite, NotReplicated, Category = "VRGripInterface") + bool bIsHeld; // Set on grip notify, not net serializing + + // If this grip was ever held + bool bWasHeld;; + + UPROPERTY(BlueprintReadWrite, NotReplicated, Category = "VRGripInterface") + TArray HoldingControllers; // Set on grip notify, not net serializing + + FBPInterfaceProperties(): + bDenyGripping(false), + bAllowMultipleGrips(false), + OnTeleportBehavior(EGripInterfaceTeleportBehavior::DropOnTeleport), + bSimulateOnDrop(true), + SlotDefaultGripType(EGripCollisionType::ManipulationGrip), + FreeDefaultGripType(EGripCollisionType::ManipulationGrip), + SecondaryGripType(ESecondaryGripType::SG_None), + MovementReplicationType(EGripMovementReplicationSettings::ForceClientSideMovement), + LateUpdateSetting(EGripLateUpdateSettings::LateUpdatesAlwaysOff), + ConstraintStiffness(1500.0f), + ConstraintDamping(200.0f), + ConstraintBreakDistance(0.0f), + SecondarySlotRange(20.0f), + PrimarySlotRange(20.0f), + bIsHeld(false), + bWasHeld(false) + { + } +}; + + +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPActorPhysicsHandleInformation +{ + GENERATED_BODY() +public: + UPROPERTY(BlueprintReadOnly, Category = "Settings") + TObjectPtr HandledObject; + uint8 GripID; + bool bIsPaused; + + FPhysicsActorHandle KinActorData2; + FPhysicsConstraintHandle HandleData2; + FLinearDriveConstraint LinConstraint; + FAngularDriveConstraint AngConstraint; + + FTransform LastPhysicsTransform; + FTransform COMPosition; + FTransform RootBoneRotation; + + bool bSetCOM; + bool bSkipResettingCom; + bool bSkipDeletingKinematicActor; + bool bInitiallySetup; + + FBPActorPhysicsHandleInformation() + { + HandledObject = nullptr; + LastPhysicsTransform = FTransform::Identity; + COMPosition = FTransform::Identity; + GripID = INVALID_VRGRIP_ID; + bIsPaused = false; + RootBoneRotation = FTransform::Identity; + bSetCOM = false; + bSkipResettingCom = false; + bSkipDeletingKinematicActor = false; + bInitiallySetup = false; + KinActorData2 = nullptr; + } + + FORCEINLINE bool operator==(const FBPActorGripInformation & Other) const + { + return ((GripID != INVALID_VRGRIP_ID) && (GripID == Other.GripID)); + } + + FORCEINLINE bool operator==(const uint8 & Other) const + { + return ((GripID != INVALID_VRGRIP_ID) && (GripID == Other)); + } + +}; + +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPAdvancedPhysicsHandleAxisSettings +{ + GENERATED_BODY() +public: + /** The spring strength of the drive. Force proportional to the position error. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Constraint, meta = (ClampMin = "0.0")) + float Stiffness; + + /** The damping strength of the drive. Force proportional to the velocity error. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Constraint, meta = (ClampMin = "0.0")) + float Damping; + + // A multiplier to add to the stiffness that is then set as the MaxForce + // It is clamped between 0.00 and 256.00 to save in replication cost, a value of 0 will mean max force is infinite as it will multiply it to zero (legacy behavior) + // If you want an exact value you can figure it out as a factor of the stiffness + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PhysicsSettings", meta = (ClampMin = "0.00", UIMin = "0.00", ClampMax = "256.00", UIMax = "256.00")) + float MaxForceCoefficient; + + /** Enables/Disables position drive (orientation if using angular drive)*/ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Constraint) + bool bEnablePositionDrive; + + /** Enables/Disables velocity drive (damping) (angular velocity if using angular drive) */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Constraint) + bool bEnableVelocityDrive; + + FBPAdvancedPhysicsHandleAxisSettings() + { + Stiffness = 0.f; + Damping = 0.f; + MaxForceCoefficient = 0.f; + bEnablePositionDrive = false; + bEnableVelocityDrive = false; + } + + void FillFrom(FConstraintDrive& ConstraintDrive) + { + Damping = ConstraintDrive.Damping; + Stiffness = ConstraintDrive.Stiffness; + MaxForceCoefficient = ConstraintDrive.MaxForce / Stiffness; + bEnablePositionDrive = ConstraintDrive.bEnablePositionDrive; + bEnableVelocityDrive = ConstraintDrive.bEnableVelocityDrive; + } + + void FillTo(FConstraintDrive& ConstraintDrive, float DampingScaler = 1.0f, float StiffnessScaler = 1.0f) const + { + ConstraintDrive.Damping = Damping * DampingScaler; + ConstraintDrive.Stiffness = Stiffness * StiffnessScaler; + ConstraintDrive.MaxForce = (float)FMath::Clamp((double)ConstraintDrive.Stiffness * (double)MaxForceCoefficient, 0, (double)MAX_FLT); + ConstraintDrive.bEnablePositionDrive = bEnablePositionDrive; + ConstraintDrive.bEnableVelocityDrive = bEnableVelocityDrive; + } + +}; + +USTRUCT(BlueprintType, Category = "VRExpansionLibrary") +struct VREXPANSIONPLUGIN_API FBPAdvancedPhysicsHandleSettings +{ + GENERATED_BODY() +public: + + // The settings for the XAxis + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Linear Constraint Settings") + FBPAdvancedPhysicsHandleAxisSettings XAxisSettings; + + // The settings for the YAxis + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Linear Constraint Settings") + FBPAdvancedPhysicsHandleAxisSettings YAxisSettings; + + // The settings for the ZAxis + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Linear Constraint Settings") + FBPAdvancedPhysicsHandleAxisSettings ZAxisSettings; + + // The settings for the Orientation (Slerp only for now) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Angular Constraint Settings") + FBPAdvancedPhysicsHandleAxisSettings SlerpSettings; + + // The settings for the Orientation (Slerp only for now) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Angular Constraint Settings") + FBPAdvancedPhysicsHandleAxisSettings TwistSettings; + + // The settings for the Orientation (Slerp only for now) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Angular Constraint Settings") + FBPAdvancedPhysicsHandleAxisSettings SwingSettings; + + + // FConstraintSettings // settings for various things like distance limits + // Add a deletegate bindable in the motion controller + + bool FillFrom(FBPActorPhysicsHandleInformation* HandleInfo) + { + if (!HandleInfo) + return false; + + XAxisSettings.FillFrom(HandleInfo->LinConstraint.XDrive); + YAxisSettings.FillFrom(HandleInfo->LinConstraint.YDrive); + ZAxisSettings.FillFrom(HandleInfo->LinConstraint.ZDrive); + + SlerpSettings.FillFrom(HandleInfo->AngConstraint.SlerpDrive); + TwistSettings.FillFrom(HandleInfo->AngConstraint.TwistDrive); + SwingSettings.FillFrom(HandleInfo->AngConstraint.SwingDrive); + + return true; + } + + bool FillTo(FBPActorPhysicsHandleInformation* HandleInfo, bool bModifyWithScalers = true) const; +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRBaseCharacter.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRBaseCharacter.h new file mode 100644 index 0000000..7764226 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRBaseCharacter.h @@ -0,0 +1,653 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "VRBPDatatypes.h" +#include "VRBaseCharacterMovementComponent.h" +#include "ReplicatedVRCameraComponent.h" +#include "GameFramework/Character.h" +#include "Navigation/PathFollowingComponent.h" +#include "VRBaseCharacter.generated.h" + +class AVRPlayerController; +class UGripMotionControllerComponent; +class UParentRelativeAttachmentComponent; +class AController; +class UNavigationQueryFilter; + +DECLARE_LOG_CATEGORY_EXTERN(LogBaseVRCharacter, Log, All); + +/** Delegate for notification when the lever state changes. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FVRSeatThresholdChangedSignature, bool, bIsWithinThreshold, float, ToThresholdScaler); +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FVRPlayerStateReplicatedSignature, const APlayerState *, NewPlayerState); +DECLARE_DYNAMIC_MULTICAST_DELEGATE(FVRPlayerTeleportedSignature); +DECLARE_DYNAMIC_MULTICAST_DELEGATE(FVRPlayerNetworkCorrectedSignature); + +USTRUCT() +struct VREXPANSIONPLUGIN_API FRepMovementVRCharacter : public FRepMovement +{ + GENERATED_BODY() + +public: + + FRepMovementVRCharacter(); + + UPROPERTY(Transient) + bool bJustTeleported; + + UPROPERTY(Transient) + bool bJustTeleportedGrips; + + UPROPERTY(Transient) + bool bPausedTracking; + + UPROPERTY(Transient) + FVector_NetQuantize100 PausedTrackingLoc; + + UPROPERTY(Transient) + float PausedTrackingRot; + + UPROPERTY(Transient) + TObjectPtr Owner; + + bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) + { + FRepMovement BaseSettings = Owner ? Owner->GetReplicatedMovement() : FRepMovement(); + + // pack bitfield with flags + uint8 Flags = (bSimulatedPhysicSleep << 0) | (bRepPhysics << 1) | (bJustTeleported << 2) | (bJustTeleportedGrips << 3) | (bPausedTracking << 4); + Ar.SerializeBits(&Flags, 5); + bSimulatedPhysicSleep = (Flags & (1 << 0)) ? 1 : 0; + bRepPhysics = (Flags & (1 << 1)) ? 1 : 0; + bJustTeleported = (Flags & (1 << 2)) ? 1 : 0; + bJustTeleportedGrips = (Flags & (1 << 3)) ? 1 : 0; + bPausedTracking = (Flags & (1 << 4)) ? 1 : 0; + + bOutSuccess = true; + + if (bPausedTracking) + { + bOutSuccess &= PausedTrackingLoc.NetSerialize(Ar, Map, bOutSuccess); + + uint16 Yaw = 0; + if (Ar.IsSaving()) + { + Yaw = FRotator::CompressAxisToShort(PausedTrackingRot); + Ar << Yaw; + } + else + { + Ar << Yaw; + PausedTrackingRot = Yaw; + } + + } + + // update location, rotation, linear velocity + bOutSuccess &= SerializeQuantizedVector(Ar, Location, BaseSettings.LocationQuantizationLevel); + + switch (BaseSettings.RotationQuantizationLevel) + { + case ERotatorQuantization::ByteComponents: + { + Rotation.SerializeCompressed(Ar); + break; + } + + case ERotatorQuantization::ShortComponents: + { + Rotation.SerializeCompressedShort(Ar); + break; + } + } + + bOutSuccess &= SerializeQuantizedVector(Ar, LinearVelocity, BaseSettings.VelocityQuantizationLevel); + + // update angular velocity if required + if (bRepPhysics) + { + bOutSuccess &= SerializeQuantizedVector(Ar, AngularVelocity, BaseSettings.VelocityQuantizationLevel); + } + + return true; + } +}; + +template<> +struct TStructOpsTypeTraits : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithNetSerializer = true, + WithNetSharedSerialization = true, + }; +}; + +USTRUCT(Blueprintable) +struct VREXPANSIONPLUGIN_API FVRSeatedCharacterInfo +{ + GENERATED_USTRUCT_BODY() +public: + UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo") + bool bSitting; + UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo") + bool bZeroToHead; + UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo") + FTransform_NetQuantize StoredTargetTransform; + UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo") + FTransform_NetQuantize InitialRelCameraTransform; + UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo") + TObjectPtr SeatParent; + UPROPERTY(BlueprintReadOnly, Category = "CharacterSeatInfo") + EVRConjoinedMovementModes PostSeatedMovementMode; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, NotReplicated, Category = "CharacterSeatInfo", meta = (ClampMin = "1.000", UIMin = "1.000", ClampMax = "256.000", UIMax = "256.000")) + float AllowedRadius; + UPROPERTY(EditAnywhere, BlueprintReadWrite, NotReplicated, Category = "CharacterSeatInfo", meta = (ClampMin = "1.000", UIMin = "1.000", ClampMax = "256.000", UIMax = "256.000")) + float AllowedRadiusThreshold; + UPROPERTY(BlueprintReadOnly, NotReplicated, Category = "CharacterSeatInfo") + float CurrentThresholdScaler; + UPROPERTY(BlueprintReadOnly, NotReplicated, Category = "CharacterSeatInfo") + bool bIsOverThreshold; + + bool bWasSeated; + bool bOriginalControlRotation; + bool bWasOverLimit; + + FVRSeatedCharacterInfo() + { + Clear(); + } + + void Clear() + { + bSitting = false; + bIsOverThreshold = false; + bWasOverLimit = false; + bZeroToHead = true; + StoredTargetTransform = FTransform::Identity; + InitialRelCameraTransform = FTransform::Identity; + bWasSeated = false; + bOriginalControlRotation = false; + AllowedRadius = 40.0f; + AllowedRadiusThreshold = 20.0f; + CurrentThresholdScaler = 0.0f; + SeatParent = nullptr; + PostSeatedMovementMode = EVRConjoinedMovementModes::C_MOVE_Walking; + } + + void ClearTempVals() + { + bWasOverLimit = false; + bWasSeated = false; + bOriginalControlRotation = false; + CurrentThresholdScaler = 0.0f; + } + + + /** Network serialization */ + // Doing a custom NetSerialize here because this is sent via RPCs and should change on every update + bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) + { + bOutSuccess = true; + + Ar.SerializeBits(&bSitting, 1); + Ar.SerializeBits(&bZeroToHead, 1); + + if (bSitting) + { + InitialRelCameraTransform.NetSerialize(Ar, Map, bOutSuccess); + + // Forcing a maximum value here so that we can compress it by making assumptions + // 256 max value = 8 bits + 1 bit for sign + 7 bits for precision (up to 128 on precision, so full range 2 digit precision). + if (Ar.IsSaving()) + { + bOutSuccess &= WriteFixedCompressedFloat<256, 16>(AllowedRadius, Ar); + bOutSuccess &= WriteFixedCompressedFloat<256, 16>(AllowedRadiusThreshold, Ar); + } + else + { + bOutSuccess &= ReadFixedCompressedFloat<256, 16>(AllowedRadius, Ar); + bOutSuccess &= ReadFixedCompressedFloat<256, 16>(AllowedRadiusThreshold, Ar); + } + } + + StoredTargetTransform.NetSerialize(Ar, Map, bOutSuccess); + Ar << SeatParent; + Ar << PostSeatedMovementMode; + return bOutSuccess; + } +}; +template<> +struct TStructOpsTypeTraits< FVRSeatedCharacterInfo > : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithNetSerializer = true + }; +}; + +USTRUCT() +struct VREXPANSIONPLUGIN_API FVRReplicatedCapsuleHeight +{ + GENERATED_USTRUCT_BODY() +public: + UPROPERTY() + float CapsuleHeight; + + FVRReplicatedCapsuleHeight() : + CapsuleHeight(0.0f) + {} + + /** Network serialization */ + bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) + { + bOutSuccess = true; + // Forcing a maximum value here so that we can compress it by making assumptions + // 1024 max value = 10 bits + 1 bit for sign + 7 bits for precision (up to 128 on precision, so full range 2 digit precision). + if (Ar.IsSaving()) + { + bOutSuccess &= WriteFixedCompressedFloat<1024, 18>(CapsuleHeight, Ar); + } + else + { + bOutSuccess &= ReadFixedCompressedFloat<1024, 18>(CapsuleHeight, Ar); + } + + return bOutSuccess; + } +}; +template<> +struct TStructOpsTypeTraits< FVRReplicatedCapsuleHeight > : public TStructOpsTypeTraitsBase2 +{ + enum + { + WithNetSerializer = true + }; +}; + +UCLASS() +class VREXPANSIONPLUGIN_API AVRBaseCharacter : public ACharacter +{ + GENERATED_BODY() + +public: + AVRBaseCharacter(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); + + /** BaseVR Character movement component belongs to */ + UPROPERTY(Transient, DuplicateTransient) + AVRPlayerController* OwningVRPlayerController; + + // If true then we will retain roomscale tracking in relative space of the character. + // If false than the movement component will offset to the hmd tracking and the tracking will be nulled out + UPROPERTY(Category = VRBaseCharacter, EditAnywhere, BlueprintReadOnly) + bool bRetainRoomscale = false; + + //virtual void CacheInitialMeshOffset(FVector MeshRelativeLocation, FRotator MeshRelativeRotation) override; + virtual void PostInitializeComponents() override; + + virtual void PossessedBy(AController* NewController); + virtual void OnRep_Controller() override; + virtual void OnRep_PlayerState() override; + + /** Used for replication of our RootComponent's position and velocity */ + UPROPERTY(ReplicatedUsing = OnRep_ReplicatedMovement) + struct FRepMovementVRCharacter ReplicatedMovementVR; + + bool bFlagTeleported; + bool bFlagTeleportedGrips; + bool bTrackingPaused; + FVector PausedTrackingLoc; + float PausedTrackingRot; + + + // Injecting our custom teleport notification + virtual void OnRep_ReplicatedMovement() override; + virtual void GatherCurrentMovement() override; + + // Give my users direct access to an event for when the player has teleported + UPROPERTY(BlueprintAssignable, Category = "VRMovement") + FVRPlayerTeleportedSignature OnCharacterTeleported_Bind; + + // Give my users direct access to an event for when the player has been network corrected + UPROPERTY(BlueprintAssignable, Category = "VRMovement") + FVRPlayerNetworkCorrectedSignature OnCharacterNetworkCorrected_Bind; + + // Give my users direct access to an event for when the player state has changed + UPROPERTY(BlueprintAssignable, Category = "VRMovement") + FVRPlayerStateReplicatedSignature OnPlayerStateReplicated_Bind; + + //These functions are now housed in the base character and used when possible, it saves about 7 bits of packet header overhead per send. + + // I'm sending it unreliable because it is being resent pretty often + UFUNCTION(Unreliable, Server, WithValidation) + void Server_SendTransformCamera(FBPVRComponentPosRep NewTransform); + + UFUNCTION(Unreliable, Server, WithValidation) + void Server_SendTransformLeftController(FBPVRComponentPosRep NewTransform); + + UFUNCTION(Unreliable, Server, WithValidation) + void Server_SendTransformRightController(FBPVRComponentPosRep NewTransform); + + virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; + +protected: + // If true will replicate the capsule height on to clients, allows for dynamic capsule height changes in multiplayer + UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRBaseCharacter") + bool VRReplicateCapsuleHeight; +public: + bool GetVRReplicateCapsuleHeight() { return VRReplicateCapsuleHeight; } + void SetVRReplicateCapsuleHeight(bool bNewVRReplicateCapsuleHeight); + + + // OnlyReplicated to simulated clients + UPROPERTY(Replicated, ReplicatedUsing = OnRep_CapsuleHeight) + FVRReplicatedCapsuleHeight ReplicatedCapsuleHeight; + + UFUNCTION() + void OnRep_CapsuleHeight(); + + // Override this in c++ or blueprints to pass in an IK mesh to be used in some optimizations + // May be extended in the future + //UFUNCTION(BlueprintNativeEvent, Category = "BaseVRCharacter") + //USkeletalMeshComponent * GetIKMesh() const; + //virtual USkeletalMeshComponent * GetIKMesh_Implementation() const;1 + // #TODO: Work with the above, can do multiple things with it + + + // Called when the client is in climbing mode and is stepped up onto a platform + // Generally you should drop the climbing at this point and go into falling movement. + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRMovement") + void OnClimbingSteppedUp(); + virtual void OnClimbingSteppedUp_Implementation(); + + /** + * Event for adding to the climbing movement mode. Called by CharacterMovement if MovementMode is set to Climbing. + * @note C++ code should override PhysCustom_Climbing() instead. + */ + UFUNCTION(BlueprintNativeEvent, meta = (DisplayName = "UpdateLowGravMovement", ScriptName = "UpdateLowGravMovement")) + void UpdateLowGravMovement(float DeltaTime); + virtual void UpdateLowGravMovement_Implementation(float DeltaTime) {} // Do nothing by default + + /** + * Event for adding to the climbing movement mode. Called by CharacterMovement if MovementMode is set to Climbing. + * @note C++ code should override PhysCustom_Climbing() instead. + */ + UFUNCTION(BlueprintNativeEvent, meta = (DisplayName = "UpdateClimbingMovement", ScriptName = "UpdateClimbingMovement")) + void UpdateClimbingMovement(float DeltaTime); + virtual void UpdateClimbingMovement_Implementation(float DeltaTime){} // Do nothing by default + + // This is the offset location of the player, use this for when checking against player transform instead of the actors transform + UPROPERTY(BlueprintReadOnly, Transient, Category = "VRExpansionLibrary") + FTransform OffsetComponentToWorld; + + // Gets the forward vector of the HMD offset capsule + UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations") + FVector GetVRForwardVector() const + { + return OffsetComponentToWorld.GetRotation().GetForwardVector(); + } + + // Gets the right vector of the HMD offset capsule + UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations") + FVector GetVRRightVector() const + { + return OffsetComponentToWorld.GetRotation().GetRightVector(); + } + + // Gets the upvector of the HMD offset capsule + UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations") + FVector GetVRUpVector() const + { + return OffsetComponentToWorld.GetRotation().GetUpVector(); + } + + // Gets the location of the HMD offset capsule (this retains the Capsule HalfHeight offset) + UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations") + FVector GetVRLocation() const + { + return OffsetComponentToWorld.GetLocation(); + } + + inline FVector GetVRLocation_Inline() const + { + return OffsetComponentToWorld.GetLocation(); + } + + // Returns the head location projected from the world offset (if applicable) + virtual FVector GetProjectedVRLocation() const; + + // Gets the rotation of the HMD offset capsule + UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations") + FRotator GetVRRotation() const + { + return OffsetComponentToWorld.GetRotation().Rotator(); + } + // Gets the location of the HMD, if the camera is missing then it just returns waist location instead + UFUNCTION(BlueprintPure, Category = "BaseVRCharacter|VRLocations", meta = (DisplayName = "GetVRHeadLocation", ScriptName = "GetVRHeadLocation", Keywords = "position")) + FVector K2_GetVRHeadLocation() const + { + return GetVRHeadLocation(); + } + + inline FVector GetVRHeadLocation() const + { + return VRReplicatedCamera != nullptr ? VRReplicatedCamera->GetComponentLocation() : OffsetComponentToWorld.GetLocation(); + } + + + virtual FVector GetTargetLocation(AActor* RequestedBy) const override + { + return GetVRLocation_Inline(); + } + + // If true will use the experimental method of unseating that clears some movement replication options. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRBaseCharacter") + bool bUseExperimentalUnseatModeFix; + + UPROPERTY(BlueprintReadOnly, Replicated, EditAnywhere, Category = "Seating", ReplicatedUsing = OnRep_SeatedCharInfo) + FVRSeatedCharacterInfo SeatInformation; + + // Called when the seated mode is changed + UFUNCTION(BlueprintNativeEvent, Category = "Seating") + void OnSeatedModeChanged(bool bNewSeatedMode, bool bWasAlreadySeated); + virtual void OnSeatedModeChanged_Implementation(bool bNewSeatedMode, bool bWasAlreadySeated) {} + + // Called when the the player either transitions to/from the threshold boundry or the scaler value of being outside the boundry changes + // Can be used for warnings or screen darkening, ect + UFUNCTION(BlueprintNativeEvent, Category = "Seating") + void OnSeatThreshholdChanged(bool bIsWithinThreshold, float ToThresholdScaler); + virtual void OnSeatThreshholdChanged_Implementation(bool bIsWithinThreshold, float ToThresholdScaler) {} + + // Call to use an object + UPROPERTY(BlueprintAssignable, Category = "Seating") + FVRSeatThresholdChangedSignature OnSeatThreshholdChanged_Bind; + + virtual FVector GetTargetHeightOffset() + { + return FVector::ZeroVector; + } + + void ZeroToSeatInformation() + { + + SetSeatRelativeLocationAndRotationVR(FVector::ZeroVector); + + NotifyOfTeleport(); + //LeftMotionController->PostTeleportMoveGrippedObjects(); + //RightMotionController->PostTeleportMoveGrippedObjects(); + } + + // Called from the movement component + void TickSeatInformation(float DeltaTime); + + UFUNCTION() + virtual void OnRep_SeatedCharInfo(); + + void InitSeatedModeTransition(); + + // Re-zeros the seated settings + UFUNCTION(BlueprintCallable, Server, Reliable, WithValidation, Category = "BaseVRCharacter", meta = (DisplayName = "ReZeroSeating")) + void Server_ReZeroSeating(FTransform_NetQuantize NewTargetTransform, FTransform_NetQuantize NewInitialRelCameraTransform, bool bZeroToHead = true); + + // Snapturn update + UFUNCTION(Reliable, Server, WithValidation) + void Server_SeatedSnapTurn(float Yaw); + + // Sets seated mode on the character and then fires off an event to handle any special setup + // Target Transform is for teleport location if standing up, or relative camera location when sitting down. + // InitialRelCameraTransform is generally the relative transform of the camera at the time of requesting to sit. + // ZeroToHead places central point on head, if false it will use foot location and ignore Z values instead. + // Post Seated movement mode is the movement mode to switch too after seating is canceled, defaults to Walking and only uses it when un-seating. + UFUNCTION(BlueprintCallable, Server, Reliable, WithValidation, Category = "BaseVRCharacter", meta = (DisplayName = "SetSeatedMode")) + void Server_SetSeatedMode(USceneComponent * SeatParent, bool bSetSeatedMode, FTransform_NetQuantize TargetTransform, FTransform_NetQuantize InitialRelCameraTransform, float AllowedRadius = 40.0f, float AllowedRadiusThreshold = 20.0f, bool bZeroToHead = true, EVRConjoinedMovementModes PostSeatedMovementMode = EVRConjoinedMovementModes::C_MOVE_Walking); + + // Sets seated mode on the character and then fires off an event to handle any special setup + // Should only be called on the server / net authority + // If allowed radius is 0.0f then the seated mode does not check for radial distance anymore. + bool SetSeatedMode(USceneComponent * SeatParent, bool bSetSeatedMode, FTransform TargetTransform, FTransform InitialRelCameraTransform, float AllowedRadius = 40.0f, float AllowedRadiusThreshold = 20.0f, bool bZeroToHead = true, EVRConjoinedMovementModes PostSeatedMovementMode = EVRConjoinedMovementModes::C_MOVE_Walking); + + void SetSeatRelativeLocationAndRotationVR(FVector LocDelta); + + // Adds a rotation delta taking into account the HMD as a pivot point (also moves the actor), returns final location difference + // If bRotateAroundCapsule is true then it rotates around the offset capsule, otherwise it rotates around the camera + UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter|VRLocations") + FVector AddActorWorldRotationVR(FRotator DeltaRot, bool bUseYawOnly = true, bool bRotateAroundCapsule = true); + + // Sets the actors rotation taking into account the HMD as a pivot point (also moves the actor), returns the location difference + // bAccountForHMDRotation sets the rot to have the HMD face the given rot, if it is false it ignores the HMD rotation + // If bRotateAroundCapsule is true then it rotates around the offset capsule, otherwise it rotates around the camera + UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter|VRLocations") + FVector SetActorRotationVR(FRotator NewRot, bool bUseYawOnly = true, bool bAccountForHMDRotation = true, bool bRotateAroundCapsule = true); + + // Sets the actors rotation and location taking into account the HMD as a pivot point (also moves the actor), returns the location difference from the rotation + // If bRotateAroundCapsule is true then it rotates around the offset capsule, otherwise it rotates around the camera + UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter|VRLocations") + FVector SetActorLocationAndRotationVR(FVector NewLoc, FRotator NewRot, bool bUseYawOnly = true, bool bAccountForHMDRotation = true, bool bTeleport = false, bool bRotateAroundCapsule = true); + + // Sets the actors location taking into account the HMD as a pivot point, returns the location difference + // If SetCapsuleLocation is true then it offsets the capsule to the location, otherwise it will move the Camera itself to the location + UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter|VRLocations") + FVector SetActorLocationVR(FVector NewLoc, bool bTeleport, bool bSetCapsuleLocation = true); + + // Regenerates the base offsetcomponenttoworld that VR uses + UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter|VRLocations") + virtual void RegenerateOffsetComponentToWorld(bool bUpdateBounds, bool bCalculatePureYaw) + {} + + // This sets the capsules height, but also regenerates the offset transform instantly + UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter") + virtual void SetCharacterSizeVR(float NewRadius, float NewHalfHeight, bool bUpdateOverlaps = true); + + // This sets the capsules half height, but also regenerates the offset transform instantly + UFUNCTION(BlueprintCallable, Category = "BaseVRCharacter") + virtual void SetCharacterHalfHeightVR(float HalfHeight, bool bUpdateOverlaps = true); + + // This component is used with the normal character SkeletalMesh network smoothing system for simulated proxies + // It will lerp the characters components back to zero on simulated proxies after a move is complete. + // The simplest method of doing this was applying the exact same offset as the mesh gets to a base component that + // tracked objects are attached to. + UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) + TObjectPtr NetSmoother; + + // This is just a helper proxy component after the net smoother to make it easier to move tracking around for people + // but still maintain the netsmoothers functionality + UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) + TObjectPtr VRProxyComponent; + + UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, Transient, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) + TObjectPtr VRMovementReference; + + UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) + TObjectPtr VRReplicatedCamera; + + UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) + TObjectPtr ParentRelativeAttachment; + + UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) + TObjectPtr LeftMotionController; + + UPROPERTY(Category = VRBaseCharacter, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) + TObjectPtr RightMotionController; + + /** Name of the LeftMotionController component. Use this name if you want to use a different class (with ObjectInitializer.SetDefaultSubobjectClass). */ + static FName LeftMotionControllerComponentName; + + /** Name of the RightMotionController component. Use this name if you want to use a different class (with ObjectInitializer.SetDefaultSubobjectClass). */ + static FName RightMotionControllerComponentName; + + /** Name of the VRReplicatedCamera component. Use this name if you want to use a different class (with ObjectInitializer.SetDefaultSubobjectClass). */ + static FName ReplicatedCameraComponentName; + + /** Name of the ParentRelativeAttachment component. Use this name if you want to use a different class (with ObjectInitializer.SetDefaultSubobjectClass). */ + static FName ParentRelativeAttachmentComponentName; + + /** Name of the net smoother component. Use this name if you want to use a different class (with ObjectInitializer.SetDefaultSubobjectClass). */ + static FName SmoothingSceneParentComponentName; + + /** Name of the vr proxy component. Use this name if you want to use a different class (with ObjectInitializer.SetDefaultSubobjectClass). */ + static FName VRProxyComponentName; + + /* + A helper function that offsets a given vector by the roots collision location + pass in a teleport location and it provides the correct spot for it to be at your feet + */ + UFUNCTION(BlueprintPure, Category = "VRGrip") + virtual FVector GetTeleportLocation(FVector OriginalLocation); + + // Notifies that we should teleport the both hand grips on next tick + // When called server side will automatically apply to remote clients as well. + // Owning clients get it on server correction automatically already. + UFUNCTION(BlueprintCallable, Category = "VRGrip") + virtual void NotifyOfTeleport(bool bRegisterAsTeleport = true); + + + // Event triggered when a move action is performed, this is ran just prior to PerformMovement in the character tick + UFUNCTION(BlueprintNativeEvent, Category = "VRMovement") + void OnCustomMoveActionPerformed(EVRMoveAction MoveActionType, FVector MoveActionVector, FRotator MoveActionRotator, uint8 MoveActionFlags); + virtual void OnCustomMoveActionPerformed_Implementation(EVRMoveAction MoveActionType, FVector MoveActionVector, FRotator MoveActionRotator, uint8 MoveActionFlags); + + // Event triggered when beginning to be pushed back from a wall + // bHadLocomotionInput means that the character was moving itself + // HmdInput is how much the HMD moved in that tick so you can compare sizes to decide what to do + UFUNCTION(BlueprintNativeEvent, Category = "VRMovement") + void OnBeginWallPushback(FHitResult HitResultOfImpact, bool bHadLocomotionInput, FVector HmdInput); + virtual void OnBeginWallPushback_Implementation(FHitResult HitResultOfImpact, bool bHadLocomotionInput, FVector HmdInput); + + // Event triggered when beginning to be pushed back from a wall + UFUNCTION(BlueprintNativeEvent, Category = "VRMovement") + void OnEndWallPushback(); + virtual void OnEndWallPushback_Implementation(); + + // Event when a navigation pathing operation has completed, auto calls stop movement for VR characters + UFUNCTION(BlueprintImplementableEvent, Category = "VRBaseCharacter|Navigation") + void ReceiveNavigationMoveCompleted(EPathFollowingResult::Type PathingResult); + + virtual void NavigationMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult& Result); + + UFUNCTION(BlueprintCallable, Category = "VRBaseCharacter|Navigation") + EPathFollowingStatus::Type GetMoveStatus() const; + + /** Returns true if the current PathFollowingComponent's path is partial (does not reach desired destination). */ + UFUNCTION(BlueprintCallable, Category = "VRBaseCharacter|Navigation") + bool HasPartialPath() const; + + // Instantly stops pathing + UFUNCTION(BlueprintCallable, Category = "VRBaseCharacter|Navigation") + void StopNavigationMovement(); + + UPROPERTY(BlueprintReadWrite, Category = AI) + TSubclassOf DefaultNavigationFilterClass; + + // An extended simple move to location with additional parameters + UFUNCTION(BlueprintCallable, Category = "VRBaseCharacter|Navigation", Meta = (AdvancedDisplay = "bStopOnOverlap,bCanStrafe,bAllowPartialPath")) + virtual void ExtendedSimpleMoveToLocation(const FVector& GoalLocation, float AcceptanceRadius = -1, bool bStopOnOverlap = false, + bool bUsePathfinding = true, bool bProjectDestinationToNavigation = true, bool bCanStrafe = false, + TSubclassOf FilterClass = NULL, bool bAllowPartialPath = true); + + // Returns the current path points on the active navigation path + // Will return false / an empty result if the path following component is not active yet or the path is empty + UFUNCTION(BlueprintCallable, Category = "VRBaseCharacter|Navigation") + bool GetCurrentNavigationPathPoints(TArray& NavigationPointList); + +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRBaseCharacterMovementComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRBaseCharacterMovementComponent.h new file mode 100644 index 0000000..8b2c057 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRBaseCharacterMovementComponent.h @@ -0,0 +1,449 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#pragma once +#include "CoreMinimal.h" +#include "CharacterMovementCompTypes.h" +#include "GameFramework/CharacterMovementComponent.h" +#include "Components/SkeletalMeshComponent.h" +#include "VRBaseCharacterMovementComponent.generated.h" + +class AVRBaseCharacter; +class AVRCharacter; +struct FAIRequestID; +struct FPathFollowingResult; + +DECLARE_LOG_CATEGORY_EXTERN(LogVRBaseCharacterMovement, Log, All); + +/** Delegate for notification when to handle a climbing step up, will override default step up logic if is bound to. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FVROnPerformClimbingStepUp, FVector, FinalStepUpLocation); + +/* +* The base class for our VR characters, contains common logic across them, not to be used directly +*/ +UCLASS() +class VREXPANSIONPLUGIN_API UVRBaseCharacterMovementComponent : public UCharacterMovementComponent +{ + GENERATED_BODY() +public: + + UVRBaseCharacterMovementComponent(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); + + /** Default client to server move RPC data container. Can be bypassed via SetNetworkMoveDataContainer(). */ + FVRCharacterNetworkMoveDataContainer VRNetworkMoveDataContainer; + FVRCharacterMoveResponseDataContainer VRMoveResponseDataContainer; + + bool bNotifyTeleported; + + /** BaseVR Character movement component belongs to */ + UPROPERTY(Transient, DuplicateTransient) + TObjectPtr BaseVRCharacterOwner; + + virtual void SetUpdatedComponent(USceneComponent* NewUpdatedComponent); + + virtual void MoveAutonomous(float ClientTimeStamp, float DeltaTime, uint8 CompressedFlags, const FVector& NewAccel) override; + virtual void PerformMovement(float DeltaSeconds) override; + //virtual void ReplicateMoveToServer(float DeltaTime, const FVector& NewAcceleration) override; + + virtual bool ClientUpdatePositionAfterServerUpdate() override; + + // Overriding this to run the seated logic + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; + + // Skip force updating position if we are seated. + virtual bool ForcePositionUpdate(float DeltaTime) override; + + // When true will use the default engines behavior of setting rotation to match the clients instead of simulating rotations, this is really only here for FPS test pawns + // And non VRCharacter classes (simple character will use this) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRBaseCharacterMovementComponent") + bool bUseClientControlRotation; + + // When true remote proxies will no longer attempt to estimate player moves when motion smoothing is enabled. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRBaseCharacterMovementComponent|Smoothing") + bool bDisableSimulatedTickWhenSmoothingMovement; + + // When true the hmd movement injection speed is capped to the maximum movement speed + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement") + bool bCapHMDMovementToMaxMovementSpeed; + + // If true then when in walking mode the character will attempt to automatically orient itself to the normal of the floor it is standing on + // Both the rotation and gravity vector will be effected. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Wall Walking") + bool bAutoOrientToFloorNormal = false; + + // If true then we will attempt to blend all gravity based floor changes as long as they are within the max walking angle of the CMC + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Wall Walking") + bool bBlendGravityFloorChanges = true; + + // The rate at which we will blend the change in rotation for wall walking + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Wall Walking") + float FloorOrientationChangeBlendRate = 25.0f; + + // Sets the value of bAutoOrientToFloorNormal in a manner that cleans up when removed + UFUNCTION(BlueprintCallable, Category = "BaseVRCharacterMovementComponent|Wall Walking") + void SetAutoOrientToFloorNormal(bool bAutoOrient, bool bRevertGravityWhenDisabled = true); + + // Store if our current movement was blending rotation + bool bIsBlendingOrientation = false; + + void AutoTraceAndSetCharacterToNewGravity(FHitResult & TargetFloor, float DeltaTime = 1.0f); + + // Directly set new gravity (does not replicate, move action is preferrable) + UFUNCTION(BlueprintCallable, Category = "BaseVRCharacterMovementComponent|Wall Walking") + bool SetCharacterToNewGravity(FVector NewGravityDirection, bool bOrientToNewGravity = true, float Deltatime = 1.0f); + + // Adding seated transition + void OnMovementModeChanged(EMovementMode PreviousMovementMode, uint8 PreviousCustomMode) override; + + // Called when a valid climbing step up movement is found, if bound to the default auto step up is not performed to let custom step up logic happen instead. + UPROPERTY(BlueprintAssignable, Category = "VRMovement") + FVROnPerformClimbingStepUp OnPerformClimbingStepUp; + + virtual void OnMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult& Result); + + // Can't be inline anymore + FVector GetActorFeetLocationVR() const; + + FORCEINLINE bool HasRequestedVelocity() + { + return bHasRequestedVelocity; + } + + void SetHasRequestedVelocity(bool bNewHasRequestedVelocity); + bool IsClimbing() const; + + // Sets the crouching half height since it isn't exposed during runtime to blueprints + //UFUNCTION(BlueprintCallable, Category = "VRMovement") + // void SetCrouchedHalfHeight(float NewCrouchedHalfHeight); + + // Setting this higher will divide the wall slide effect by this value, to reduce collision sliding. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement", meta = (ClampMin = "0.0", UIMin = "0", ClampMax = "5.0", UIMax = "5")) + float VRWallSlideScaler; + + /** Custom version of SlideAlongSurface that handles different movement modes separately; namely during walking physics we might not want to slide up slopes. */ + virtual float SlideAlongSurface(const FVector& Delta, float Time, const FVector& Normal, FHitResult& Hit, bool bHandleImpact) override; + + // Add in the custom replicated movement that climbing mode uses, this is a cutom vector that is applied to character movements + // on the next tick as a movement input.. + UFUNCTION(BlueprintCallable, Category = "BaseVRCharacterMovementComponent|VRLocations") + void AddCustomReplicatedMovement(FVector Movement); + + // Clears the custom replicated movement, can be used to cancel movements if the mode changes + UFUNCTION(BlueprintCallable, Category = "BaseVRCharacterMovementComponent|VRLocations") + void ClearCustomReplicatedMovement(); + + // Called to check if the server is performing a move action on a non controlled character + // If so then we just run the logic right away as it can't be inlined and won't be replicated + void CheckServerAuthedMoveAction(); + + // Set tracking paused for our root capsule and replicate the location to all connections + UFUNCTION(BlueprintCallable, Category = "VRMovement") + void PerformMoveAction_SetTrackingPaused(bool bNewTrackingPaused); + virtual void StoreSetTrackingPaused(bool bNewTrackingPaused); + + // Perform a snap turn in line with the move action system + // If bRotateAroundCapsule is true then the rotation is around the offset capsule (neck) rather than the actual camera location + UFUNCTION(BlueprintCallable, Category = "VRMovement") + void PerformMoveAction_SnapTurn(float SnapTurnDeltaYaw, EVRMoveActionVelocityRetention VelocityRetention = EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_None, bool bFlagGripTeleport = false, bool bFlagCharacterTeleport = false, bool bRotateAroundCapsule = true); + + // Perform a rotation set in line with the move actions system + // This node specifically sets the FACING direction to a value, where your HMD is pointed + // If bRotateAroundCapsule is true then the rotation is around the offset capsule (neck) rather than the actual camera location + UFUNCTION(BlueprintCallable, Category = "VRMovement") + void PerformMoveAction_SetRotation(float NewYaw, EVRMoveActionVelocityRetention VelocityRetention = EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_None, bool bFlagGripTeleport = false, bool bFlagCharacterTeleport = false, bool bRotateAroundCapsule = true); + + // Perform a teleport in line with the move action system + UFUNCTION(BlueprintCallable, Category = "VRMovement") + void PerformMoveAction_Teleport(FVector TeleportLocation, FRotator TeleportRotation, EVRMoveActionVelocityRetention VelocityRetention = EVRMoveActionVelocityRetention::VRMOVEACTION_Velocity_None, bool bSkipEncroachmentCheck = false); + + // Perform StopAllMovementImmediately in line with the move action system + UFUNCTION(BlueprintCallable, Category = "VRMovement") + void PerformMoveAction_StopAllMovement(); + + // Set the gravity direction for the character manually (optionall auto align to the new gravity) + UFUNCTION(BlueprintCallable, Category = "VRMovement") + void PerformMoveAction_SetGravityDirection(FVector NewGravityDirection, bool bOrientToNewGravity); + + // Perform a custom moveaction that you define, will call the OnCustomMoveActionPerformed event in the character when processed so you can run your own logic + // Be sure to set the minimum data replication requirements for your move action in order to save on replication. + // Flags will always replicate if it is non zero + UFUNCTION(BlueprintCallable, Category = "VRMovement") + void PerformMoveAction_Custom(EVRMoveAction MoveActionToPerform, EVRMoveActionDataReq DataRequirementsForMoveAction, FVector MoveActionVector, FRotator MoveActionRotator, uint8 MoveActionFlags = 0); + + FVRMoveActionArray MoveActionArray; + + virtual void RegenerateOffset() {}; + + bool CheckForMoveAction(); + virtual bool DoMASnapTurn(FVRMoveActionContainer& MoveAction); + virtual bool DoMASetRotation(FVRMoveActionContainer& MoveAction); + virtual bool DoMATeleport(FVRMoveActionContainer& MoveAction); + virtual bool DoMAStopAllMovement(FVRMoveActionContainer& MoveAction); + virtual bool DoMASetGravityDirection(FVRMoveActionContainer& MoveAction); + virtual bool DoMAPauseTracking(FVRMoveActionContainer& MoveAction); + + FVector CustomVRInputVector; + FVector AdditionalVRInputVector; + FVector LastPreAdditiveVRVelocity; + bool bHadExtremeInput; + bool bApplyAdditionalVRInputVectorAsNegative; + + // Rewind the relative movement that we had with the HMD + void RewindVRRelativeMovement(); + + // Any movement above this value we will consider as have been a tracking jump and null out the movement in the character + // Raise this value higher if players are noticing freezing when moving quickly. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement", meta = (ClampMin = "0.0", UIMin = "0")) + float TrackingLossThreshold; + + // If we hit the tracking loss threshold then rewind position instead of running to the new location + // Will force the HMD to stay in its original spot prior to the tracking jump + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement") + bool bHoldPositionOnTrackingLossThresholdHit; + + // Rewind the relative movement that we had with the HMD, this is exposed to Blueprint so that custom movement modes can use it to rewind prior to movement actions. + // Returns the Vector required to get back to the original position (for custom movement modes) + UFUNCTION(BlueprintCallable, Category = "VRMovement") + FVector RewindVRMovement(); + + // Gets the current CustomInputVector for use in custom movement modes + UFUNCTION(BlueprintCallable, Category = "VRMovement") + FVector GetCustomInputVector(); + + bool bWasInPushBack; + bool bIsInPushBack; + void StartPushBackNotification(FHitResult HitResult); + void EndPushBackNotification(); + + bool bJustUnseated; + + //virtual void SendClientAdjustment() override; + + virtual bool VerifyClientTimeStamp(float TimeStamp, FNetworkPredictionData_Server_Character & ServerData) override; + + inline void ApplyVRMotionToVelocity(float deltaTime) + { + bHadExtremeInput = false; + + if (AdditionalVRInputVector.IsNearlyZero() && CustomVRInputVector.IsNearlyZero()) + { + LastPreAdditiveVRVelocity = FVector::ZeroVector; + return; + } + + LastPreAdditiveVRVelocity = (AdditionalVRInputVector / deltaTime); // Save off pre-additive Velocity for restoration next tick + + if (LastPreAdditiveVRVelocity.SizeSquared() > FMath::Square(TrackingLossThreshold)) + { + bHadExtremeInput = true; + if (bHoldPositionOnTrackingLossThresholdHit) + { + LastPreAdditiveVRVelocity = FVector::ZeroVector; + } + } + + // Post the HMD velocity checks, add in our direct movement now + LastPreAdditiveVRVelocity += (CustomVRInputVector / deltaTime); + + Velocity += LastPreAdditiveVRVelocity; + + if (bCapHMDMovementToMaxMovementSpeed && GetReplicatedMovementMode() != EVRConjoinedMovementModes::C_MOVE_Falling) + { + if (IsExceedingMaxSpeed(GetMaxSpeed())) + { + // Force us to the max possible speed for the movement mode + Velocity = Velocity.GetSafeNormal() * GetMaxSpeed(); + } + } + } + + inline void RestorePreAdditiveVRMotionVelocity() + { + if (!LastPreAdditiveVRVelocity.IsNearlyZero()) + { + if (bHadExtremeInput) + { + // Just zero out the velocity here + Velocity = FVector::ZeroVector; + } + else + { + // This doesn't work with input in the opposing direction + /*FVector ProjectedVelocity = Velocity.ProjectOnToNormal(LastPreAdditiveVRVelocity.GetSafeNormal()); + float VelSq = ProjectedVelocity.SizeSquared(); + float AddSq = LastPreAdditiveVRVelocity.SizeSquared(); + + if (VelSq > AddSq || ProjectedVelocity.Equals(LastPreAdditiveVRVelocity, 0.1f)) + { + // Subtract velocity if we still relatively retain it in the normalized direction + Velocity -= LastPreAdditiveVRVelocity; + }*/ + + Velocity -= LastPreAdditiveVRVelocity; + } + } + + LastPreAdditiveVRVelocity = FVector::ZeroVector; + } + + virtual void PhysCustom(float deltaTime, int32 Iterations) override; + virtual void PhysCustom_Climbing(float deltaTime, int32 Iterations); + virtual void PhysCustom_LowGrav(float deltaTime, int32 Iterations); + + // Teleport grips on correction to fixup issues + virtual void OnClientCorrectionReceived(class FNetworkPredictionData_Client_Character& ClientData, float TimeStamp, FVector NewLocation, FVector NewVelocity, UPrimitiveComponent* NewBase, FName NewBaseBoneName, bool bHasBase, bool bBaseRelativePosition, uint8 ServerMovementMode, FVector ServerGravityDirection) override; + + // Fix network smoothing with our default mesh back in + virtual void SimulatedTick(float DeltaSeconds) override; + + // Skip updates with rotational differences + virtual void SmoothCorrection(const FVector& OldLocation, const FQuat& OldRotation, const FVector& NewLocation, const FQuat& NewRotation) override; + + /** + * Smooth mesh location for network interpolation, based on values set up by SmoothCorrection. + * Internally this simply calls SmoothClientPosition_Interpolate() then SmoothClientPosition_UpdateVisuals(). + * This function is not called when bNetworkSmoothingComplete is true. + * @param DeltaSeconds Time since last update. + */ + virtual void SmoothClientPosition(float DeltaSeconds) override; + + /** Update mesh location based on interpolated values. */ + void SmoothClientPosition_UpdateVRVisuals(); + + // Added in 4.16 + ///* Allow custom handling when character hits a wall while swimming. */ + //virtual void HandleSwimmingWallHit(const FHitResult& Hit, float DeltaTime); + + // If true will never count a physicsbody channel component as the floor, to prevent jitter / physics problems. + // Make sure that you set simulating objects to the physics body channel if you want this to work correctly + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement") + bool bIgnoreSimulatingComponentsInFloorCheck; + + // If true will run the control rotation in the CMC instead of in the player controller + // This puts the player rotation into the scoped movement (perf savings) and also ensures it is properly rotated prior to movement + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement") + bool bRunControlRotationInMovementComponent; + + // They have gravity checks incorrect in here so having to override it again + virtual bool FloorSweepTest( + struct FHitResult& OutHit, + const FVector& Start, + const FVector& End, + ECollisionChannel TraceChannel, + const struct FCollisionShape& CollisionShape, + const struct FCollisionQueryParams& Params, + const struct FCollisionResponseParams& ResponseParam + ) const override; + + virtual void ComputeFloorDist(const FVector& CapsuleLocation, float LineDistance, float SweepDistance, FFindFloorResult& OutFloorResult, float SweepRadius, const FHitResult* DownwardSweepResult = NULL) const override; + + // Need to use actual capsule location for step up + virtual bool VRClimbStepUp(const FVector& GravDir, const FVector& Delta, const FHitResult &InHit, FStepDownResult* OutStepDownResult = nullptr); + + // Height to auto step up + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Climbing") + float VRClimbingStepHeight; + + /* Custom distance that is required before accepting a climbing stepup + * This is to help with cases where head wobble causes falling backwards + * Do NOT set to larger than capsule radius! + * #TODO: Port to SimpleCharacter as well + */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Climbing") + float VRClimbingEdgeRejectDistance; + + // Higher values make it easier to trigger a step up onto a platform and moves you farther in to the base *DEFUNCT* + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Climbing") + float VRClimbingStepUpMultiplier; + + // If true will clamp the maximum movement on climbing step up to: VRClimbingStepUpMaxSize + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Climbing") + bool bClampClimbingStepUp; + + // Maximum X/Y vector size to use when climbing stepping up (prevents very deep step ups from large movements). + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Climbing") + float VRClimbingStepUpMaxSize; + + // If true will automatically set falling when a stepup occurs during climbing + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Climbing") + bool SetDefaultPostClimbMovementOnStepUp; + + // Max velocity on releasing a climbing grip + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Climbing") + float VRClimbingMaxReleaseVelocitySize; + + /* Custom distance that is required before accepting a walking stepup + * This is to help promote stepping up, engine default is 0.15f, generally you want it lower than that + * Do NOT set to larger than capsule radius! + * #TODO: Port to SimpleCharacter as well + */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement") + float VREdgeRejectDistance; + + UFUNCTION(BlueprintCallable, Category = "VRMovement|Climbing") + void SetClimbingMode(bool bIsClimbing); + + // Default movement mode to switch to post climb ended, only used if SetDefaultPostClimbMovementOnStepUp is true + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|Climbing") + EVRConjoinedMovementModes DefaultPostClimbMovement; + + // Overloading this to handle an edge case + virtual void ApplyNetworkMovementMode(const uint8 ReceivedMode) override; + + /* + * This is called client side to make a replicated movement mode change that hits the server in the saved move. + * + * Custom Movement Mode is currently limited to 0 - 8, the index's 0 and 1 are currently used up for the plugin movement modes. + * So setting it to 0 or 1 would be Climbing, and LowGrav respectivly, this leaves 2-8 as open index's for use. + * For a total of 6 Custom movement modes past the currently implemented plugin ones. + */ + UFUNCTION(BlueprintCallable, Category = "VRMovement") + void SetReplicatedMovementMode(EVRConjoinedMovementModes NewMovementMode); + + /* + * Call this to convert the current movement mode to a Conjoined one for reference + * + * Custom Movement Mode is currently limited to 0 - 8, the index's 0 and 1 are currently used up for the plugin movement modes. + * So setting it to 0 or 1 would be Climbing, and LowGrav respectivly, this leaves 2-8 as open index's for use. + * For a total of 6 Custom movement modes past the currently implemented plugin ones. + */ + UFUNCTION(BlueprintPure, Category = "VRMovement") + EVRConjoinedMovementModes GetReplicatedMovementMode(); + + // We use 4 bits for this so a maximum of 16 elements + EVRConjoinedMovementModes VRReplicatedMovementMode; + + FORCEINLINE void ApplyReplicatedMovementMode(EVRConjoinedMovementModes &NewMovementMode, bool bClearMovementMode = false) + { + if (NewMovementMode != EVRConjoinedMovementModes::C_MOVE_MAX)//None) + { + if (NewMovementMode <= EVRConjoinedMovementModes::C_MOVE_MAX) + { + // Is a default movement mode, just directly set it + SetMovementMode((EMovementMode)NewMovementMode); + } + else // Is Custom + { + // Auto calculates the difference for our VR movements, index is from 0 so using climbing should get me correct index's as it is the first custom mode + SetMovementMode(EMovementMode::MOVE_Custom, (((int8)NewMovementMode - (uint8)EVRConjoinedMovementModes::C_VRMOVE_Climbing))); + } + + // Clearing it here instead now, as this way the code can inject it during PerformMovement + // Specifically used by the Climbing Step up, so that server rollbacks are supported + if(bClearMovementMode) + NewMovementMode = EVRConjoinedMovementModes::C_MOVE_MAX;//None; + } + } + + void UpdateFromCompressedFlags(uint8 Flags) override; + + FVector RoundDirectMovement(FVector InMovement) const; + + // Setting this below 1.0 will change how fast you de-accelerate when touching a wall + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|LowGrav", meta = (ClampMin = "0.0", UIMin = "0", ClampMax = "5.0", UIMax = "5")) + float VRLowGravWallFrictionScaler; + + // If true then low grav will ignore the default physics volume fluid friction, useful if you have a mix of low grav and normal movement + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRMovement|LowGrav") + bool VRLowGravIgnoresDefaultFluidFriction; +}; + diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRCharacter.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRCharacter.h new file mode 100644 index 0000000..80e1217 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRCharacter.h @@ -0,0 +1,55 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "VRBaseCharacter.h" +#include "VRCharacter.generated.h" + +class UVRRootComponent; + +DECLARE_LOG_CATEGORY_EXTERN(LogVRCharacter, Log, All); + +UCLASS() +class VREXPANSIONPLUGIN_API AVRCharacter : public AVRBaseCharacter +{ + GENERATED_BODY() + +public: + AVRCharacter(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); + + // Overriding teleport so that it auto calls my controllers re-positioning + virtual bool TeleportTo(const FVector& DestLocation, const FRotator& DestRotation, bool bIsATest = false, bool bNoCheck = false) override; + + UPROPERTY(Category = VRCharacter, VisibleAnywhere, Transient, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) + TObjectPtr VRRootReference; + + virtual FVector GetTargetHeightOffset() override; + + virtual void OnStartCrouch(float HalfHeightAdjust, float ScaledHalfHeightAdjust) override; + virtual void OnEndCrouch(float HalfHeightAdjust, float ScaledHalfHeightAdjust) override; + + + // Regenerates the base offsetcomponenttoworld that VR uses + virtual void RegenerateOffsetComponentToWorld(bool bUpdateBounds, bool bCalculatePureYaw) override; + virtual void SetCharacterSizeVR(float NewRadius, float NewHalfHeight, bool bUpdateOverlaps = true) override; + virtual void SetCharacterHalfHeightVR(float HalfHeight, bool bUpdateOverlaps = true) override; + + /* + A helper function that offsets a given vector by the roots collision location + pass in a teleport location and it provides the correct spot for it to be at your feet + */ + virtual FVector GetTeleportLocation(FVector OriginalLocation) override; + + // Returns the head location projected from the world offset (if applicable) + virtual FVector GetProjectedVRLocation() const override; + + + // Overriding to correct some nav stuff + FVector GetNavAgentLocation() const override; + + // An extended simple move to location with additional parameters + virtual void ExtendedSimpleMoveToLocation(const FVector& GoalLocation, float AcceptanceRadius = -1, bool bStopOnOverlap = false, + bool bUsePathfinding = true, bool bProjectDestinationToNavigation = true, bool bCanStrafe = false, + TSubclassOf FilterClass = NULL, bool bAllowPartialPath = true) override; + +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRCharacterMovementComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRCharacterMovementComponent.h new file mode 100644 index 0000000..14e4765 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRCharacterMovementComponent.h @@ -0,0 +1,335 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#pragma once +#include "CoreMinimal.h" +//#include "Engine/EngineBaseTypes.h" +//#include "Engine/EngineTypes.h" +#include "CharacterMovementCompTypes.h" +#include "VRBaseCharacterMovementComponent.h" +#include "VRCharacterMovementComponent.generated.h" + +class FDebugDisplayInfo; +class ACharacter; +class AVRCharacter; +class UVRRootComponent; + +DECLARE_LOG_CATEGORY_EXTERN(LogVRCharacterMovement, Log, All); + +/** Shared pointer for easy memory management of FSavedMove_Character, for accumulating and replaying network moves. */ +//typedef TSharedPtr FSavedMovePtr; + + + +//FCharacterMoveResponseDataContainer VRMoveResponseDataContainer; + + +//============================================================================= +/** + * VRCharacterMovementComponent handles movement logic for the associated Character owner. + * It supports various movement modes including: walking, falling, swimming, flying, custom. + * + * Movement is affected primarily by current Velocity and Acceleration. Acceleration is updated each frame + * based on the input vector accumulated thus far (see UPawnMovementComponent::GetPendingInputVector()). + * + * Networking is fully implemented, with server-client correction and prediction included. + * + * @see ACharacter, UPawnMovementComponent + * @see https://docs.unrealengine.com/latest/INT/Gameplay/Framework/Pawn/Character/ + */ + +//DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FAIMoveCompletedSignature, FAIRequestID, RequestID, EPathFollowingResult::Type, Result); + +UCLASS() +class VREXPANSIONPLUGIN_API UVRCharacterMovementComponent : public UVRBaseCharacterMovementComponent +{ + GENERATED_BODY() +public: + + UPROPERTY(BlueprintReadOnly, Transient, Category = VRMovement) + TObjectPtr VRRootCapsule; + + virtual void RegenerateOffset() override; + + /** Reject sweep impacts that are this close to the edge of the vertical portion of the capsule when performing vertical sweeps, and try again with a smaller capsule. */ + static const float CLIMB_SWEEP_EDGE_REJECT_DISTANCE; + virtual bool IsWithinClimbingEdgeTolerance(const FVector& CapsuleLocation, const FVector& TestImpactPoint, const float CapsuleRadius) const; + virtual bool VRClimbStepUp(const FVector& GravDir, const FVector& Delta, const FHitResult &InHit, FStepDownResult* OutStepDownResult = nullptr) override; + + virtual bool IsWithinEdgeTolerance(const FVector& CapsuleLocation, const FVector& TestImpactPoint, const float CapsuleRadius) const override; + + // Allow merging movement replication (may cause issues when >10 players due to capsule location + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "VRCharacterMovementComponent") + bool bAllowMovementMerging; + + // If true we will run client corrections off of the HMD location instead of actor, this is a settable value to allow backwards compatibility + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "VRCharacterMovementComponent") + bool bRunClientCorrectionToHMD; + + // Higher values will cause more slide but better step up + //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRCharacterMovementComponent", meta = (ClampMin = "0.01", UIMin = "0", ClampMax = "1.0", UIMax = "1")) + //float WallRepulsionMultiplier; + + /** + * Checks if new capsule size fits (no encroachment), and call CharacterOwner->OnStartCrouch() if successful. + * In general you should set bWantsToCrouch instead to have the crouch persist during movement, or just use the crouch functions on the owning Character. + * @param bClientSimulation true when called when bIsCrouched is replicated to non owned clients, to update collision cylinder and offset. + */ + virtual void Crouch(bool bClientSimulation = false) override; + + /** + * Checks if default capsule size fits (no encroachment), and trigger OnEndCrouch() on the owner if successful. + * @param bClientSimulation true when called when bIsCrouched is replicated to non owned clients, to update collision cylinder and offset. + */ + virtual void UnCrouch(bool bClientSimulation = false) override; + + /** @return true if the character is allowed to crouch in the current state. By default it is allowed when walking or falling, if CanEverCrouch() is true. */ + //virtual bool CanCrouchInCurrentState() const; + + /////////////////////////// + // Navigation Functions + /////////////////////////// + + /** Blueprint notification that we've completed the current movement request */ + //UPROPERTY(BlueprintAssignable, meta = (DisplayName = "MoveCompleted")) + //FAIMoveCompletedSignature ReceiveMoveCompleted; + + virtual FBasedPosition GetActorFeetLocationBased() const override; + + /** + * Checks to see if the current location is not encroaching blocking geometry so the character can leave NavWalking. + * Restores collision settings and adjusts character location to avoid getting stuck in geometry. + * If it's not possible, MovementMode change will be delayed until character reach collision free spot. + * @return True if movement mode was successfully changed + */ + virtual bool TryToLeaveNavWalking() override; + + + virtual void PhysNavWalking(float deltaTime, int32 Iterations) override; + virtual void ProcessLanded(const FHitResult& Hit, float remainingTime, int32 Iterations) override; + + void PostPhysicsTickComponent(float DeltaTime, FCharacterMovementComponentPostPhysicsTickFunction& ThisTickFunction) override; + void SimulateMovement(float DeltaSeconds) override; + void MoveSmooth(const FVector& InVelocity, const float DeltaSeconds, FStepDownResult* OutStepDownResult) override; + //void PerformMovement(float DeltaSeconds) override; + + /////////////////////////// + // End Navigation Functions + /////////////////////////// + + + /////////////////////////// + // Client adjustment overrides to allow for rotation + /////////////////////////// + + // Engines version of this is private for some reason, making it impossible to override the function that uses it. + TWeakObjectPtr LastServerMovementBaseVR = nullptr; + + virtual bool ShouldCorrectRotation() const override { return !bUseClientControlRotation; } + virtual void ClientHandleMoveResponse(const FCharacterMoveResponseDataContainer& MoveResponse) override; + + //virtual void SendClientAdjustment() override; + /** + * Have the server check if the client is outside an error tolerance, and queue a client adjustment if so. + * If either GetPredictionData_Server_Character()->bForceClientUpdate or ServerCheckClientError() are true, the client adjustment will be sent. + * RelativeClientLocation will be a relative location if MovementBaseUtility::UseRelativePosition(ClientMovementBase) is true, or a world location if false. + * @see ServerCheckClientError() + */ + virtual void ServerMoveHandleClientErrorVR(float ClientTimeStamp, float DeltaTime, const FVector& Accel, const FVector& RelativeClientLocation, FRotator ClientRot, UPrimitiveComponent* ClientMovementBase, FName ClientBaseBoneName, uint8 ClientMovementMode); + + /** + * Check for Server-Client disagreement in position or other movement state important enough to trigger a client correction. + * @see ServerMoveHandleClientError() + */ + virtual bool ServerCheckClientErrorVR(float ClientTimeStamp, float DeltaTime, const FVector& Accel, const FVector& ClientWorldLocation, FRotator ClientRot, const FVector& RelativeClientLocation, UPrimitiveComponent* ClientMovementBase, FName ClientBaseBoneName, uint8 ClientMovementMode); + + /** Replicate position correction to client, associated with a timestamped servermove. Client will replay subsequent moves after applying adjustment. */ + virtual void ClientAdjustPositionVR_Implementation(float TimeStamp, FVector NewLoc, /*uint16 NewYaw,*/ FVector NewVel, UPrimitiveComponent* NewBase, FName NewBaseBoneName, bool bHasBase, bool bBaseRelativePosition, uint8 ServerMovementMode, TOptional OptionalRotation = TOptional(), TOptional OptionalGravityDirection = TOptional()); + + virtual bool ClientUpdatePositionAfterServerUpdate() override; + /////////////////////////// + // Replication Functions + /////////////////////////// + + //////////////////////////////////// + // Network RPCs for movement + //////////////////////////////////// + /** + * The actual RPCs are passed to ACharacter, which wrap to the _Implementation and _Validate call here, to avoid Component RPC overhead. + * For example: + * Client: UCharacterMovementComponent::ServerMove(...) => Calls CharacterOwner->ServerMove(...) triggering RPC on server + * Server: ACharacter::ServerMove_Implementation(...) => Calls CharacterMovement->ServerMove_Implementation + * To override the client call to the server RPC (on CharacterOwner), override ServerMove(). + * To override the server implementation, override ServerMove_Implementation(). + */ + + + // Using my own as I don't want to cast the standard fsavedmove + //virtual void CallServerMove(const class FSavedMove_Character* NewMove, const class FSavedMove_Character* OldMove) override; + + virtual void ServerMove_PerformMovement(const FCharacterNetworkMoveData& MoveData) override; + + FNetworkPredictionData_Client* GetPredictionData_Client() const override; + FNetworkPredictionData_Server* GetPredictionData_Server() const override; + + /////////////////////////// + // End Replication Functions + /////////////////////////// + + /** + * Default UObject constructor. + */ + UVRCharacterMovementComponent(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); + + virtual void OnRegister() override; + + float ImmersionDepth() const override; + bool CanCrouch(); + + // Don't really need to override this at all, it doesn't work that well even when fixed in VR + //void VisualizeMovement() const override; + + + /* + bool HasRootMotion() const + { + return RootMotionParams.bHasRootMotion; + }*/ + + // Had to modify this, since every frame can start in penetration (capsule component moves into wall before movement tick) + // It was throwing out the initial hit and not calling "step up", now I am only checking for penetration after adjustment but keeping the initial hit for step up. + // this makes for FAR more responsive step ups. + // I WILL need to override these for flying / swimming as well + bool SafeMoveUpdatedComponent(const FVector& Delta, const FQuat& NewRotation, bool bSweep, FHitResult& OutHit, ETeleportType Teleport = ETeleportType::None); + bool SafeMoveUpdatedComponent(const FVector& Delta, const FRotator& NewRotation, bool bSweep, FHitResult& OutHit, ETeleportType Teleport = ETeleportType::None); + + // This is here to force it to call the correct SafeMoveUpdatedComponent functions for floor movement + virtual void MoveAlongFloor(const FVector& InVelocity, float DeltaSeconds, FStepDownResult* OutStepDownResult) override; + + // Modify for correct location + virtual void ApplyRepulsionForce(float DeltaSeconds) override; + + // Update BaseOffset to be zero + virtual void UpdateBasedMovement(float DeltaSeconds) override; + + // Stop subtracting the capsules half height + virtual FVector GetImpartedMovementBaseVelocity() const override; + + // Cheating at the relative collision detection + void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction); + + // Need to fill our capsule component variable here and override the default tick ordering + virtual void SetUpdatedComponent(USceneComponent* NewUpdatedComponent) override; + + // Correct an offset sweep test + virtual void ReplicateMoveToServer(float DeltaTime, const FVector& NewAcceleration) override; + + // Always called with the capsulecomponent location, no idea why it doesn't just get it inside it already + // Had to force it within the function to use VRLocation instead. + virtual void FindFloor(const FVector& CapsuleLocation, FFindFloorResult& OutFloorResult, bool bCanUseCachedLocation, const FHitResult* DownwardSweepResult = NULL) const; + + // Need to use actual capsule location for step up + bool StepUp(const FVector& GravDir, const FVector& Delta, const FHitResult &InHit, FStepDownResult* OutStepDownResult = NULL) override; + + virtual FVector GetPenetrationAdjustment(const FHitResult& Hit) const override; + + // MOVED THIS TO THE BASE VR CHARACTER MOVEMENT COMPONENT + // Also added a control variable for it there + // Skip physics channels when looking for floor + /*virtual bool FloorSweepTest( + FHitResult& OutHit, + const FVector& Start, + const FVector& End, + ECollisionChannel TraceChannel, + const struct FCollisionShape& CollisionShape, + const struct FCollisionQueryParams& Params, + const struct FCollisionResponseParams& ResponseParam + ) const override;*/ + + // Multiple changes to support relative motion and ledge sweeps + virtual void PhysWalking(float deltaTime, int32 Iterations) override; + + // Supporting the direct move injection + virtual void PhysFlying(float deltaTime, int32 Iterations) override; + + // Need to use VR location, was defaulting to actor + virtual bool ShouldCheckForValidLandingSpot(float DeltaTime, const FVector& Delta, const FHitResult& Hit) const override; + + // Overriding the physfalling because valid landing spots were computed incorrectly. + virtual void PhysFalling(float deltaTime, int32 Iterations) override; + + virtual void PhysSwimming(float deltaTime, int32 Iterations) override; + /** + * Handle start swimming functionality + * @param OldLocation - Location on last tick + * @param OldVelocity - velocity at last tick + * @param timeTick - time since at OldLocation + * @param remainingTime - DeltaTime to complete transition to swimming + * @param Iterations - physics iteration count + */ + void StartSwimmingVR(FVector OldLocation, FVector OldVelocity, float timeTick, float remainingTime, int32 Iterations); + + /* Swimming uses gravity - but scaled by (1.f - buoyancy) */ + float SwimVR(FVector Delta, FHitResult& Hit); + + /** Check if swimming pawn just ran into edge of the pool and should jump out. */ + virtual bool CheckWaterJump(FVector CheckPoint, FVector& WallNormal) override; + + // Shouldn't need to override this + /** Get as close to waterline as possible, staying on same side as currently. */ + //FVector FindWaterLine(FVector Start, FVector End) override; + + // Just calls find floor + /** Verify that the supplied hit result is a valid landing spot when falling. */ + //virtual bool IsValidLandingSpot(const FVector& CapsuleLocation, const FHitResult& Hit) const override; + + // Making sure that impulses are correct + virtual void CapsuleTouched(UPrimitiveComponent* OverlappedComp, AActor* Other, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) override; + virtual void StoreSetTrackingPaused(bool bNewTrackingPaused) override; +}; + + +class VREXPANSIONPLUGIN_API FSavedMove_VRCharacter : public FSavedMove_VRBaseCharacter +{ + +public: + + virtual void SetInitialPosition(ACharacter* C); + virtual void PrepMoveFor(ACharacter* Character) override; + + FSavedMove_VRCharacter() : FSavedMove_VRBaseCharacter() + {} + +}; + +// Need this for capsule location replication +class VREXPANSIONPLUGIN_API FNetworkPredictionData_Client_VRCharacter : public FNetworkPredictionData_Client_Character +{ +public: + FNetworkPredictionData_Client_VRCharacter(const UCharacterMovementComponent& ClientMovement) + : FNetworkPredictionData_Client_Character(ClientMovement) + { + + } + + FSavedMovePtr AllocateNewMove() + { + return FSavedMovePtr(new FSavedMove_VRCharacter()); + } +}; + + +// Need this for capsule location replication????? +class VREXPANSIONPLUGIN_API FNetworkPredictionData_Server_VRCharacter : public FNetworkPredictionData_Server_Character +{ +public: + + FNetworkPredictionData_Server_VRCharacter(const UCharacterMovementComponent& ClientMovement) + : FNetworkPredictionData_Server_Character(ClientMovement) + { + } + + FSavedMovePtr AllocateNewMove() + { + return FSavedMovePtr(new FSavedMove_VRCharacter()); + } +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRExpansionFunctionLibrary.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRExpansionFunctionLibrary.h new file mode 100644 index 0000000..a7e12a4 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRExpansionFunctionLibrary.h @@ -0,0 +1,358 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "VRBPDatatypes.h" +#include "VRExpansionFunctionLibrary.generated.h" + +class USplineComponent; +class UPrimitiveComponent; +class UGripMotioncontroller; +struct FGameplayTag; +struct FGameplayTagContainer; + + +enum class EControllerHand : uint8; +enum class EBPHMDDeviceType : uint8; + +//General Advanced Sessions Log +DECLARE_LOG_CATEGORY_EXTERN(VRExpansionFunctionLibraryLog, Log, All); + +/** +* Redefining this for blueprint as it wasn't declared as BlueprintType +* Stores if the user is wearing the HMD or not. For HMDs without a sensor to detect the user wearing it, the state defaults to Unknown. +*/ +UENUM(BlueprintType) +enum class EBPHMDWornState : uint8 +{ + Unknown UMETA(DisplayName = "Unknown"), + Worn UMETA(DisplayName = "Worn"), + NotWorn UMETA(DisplayName = "Not Worn"), +}; + +UCLASS()//, meta = (BlueprintSpawnableComponent)) +class VREXPANSIONPLUGIN_API UVRExpansionFunctionLibrary : public UBlueprintFunctionLibrary +{ + //GENERATED_BODY() + GENERATED_BODY() + //~UVRExpansionFunctionLibrary(); +public: + + UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (WorldContext = "WorldContextObject", CallableWithoutWorldContext)) + static UGameViewportClient * GetGameViewportClient(UObject* WorldContextObject); + + + // Sets two primitive components to ignore collision between two specific bodies + // If bAddChildBones is true then it will also add all child bones of the given bone (or the entire skeleton if no name is given) + UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|Collision", meta = (bIgnoreSelf = "true", WorldContext = "WorldContextObject", CallableWithoutWorldContext)) + static void SetObjectsIgnoreCollision(UObject* WorldContextObject, UPrimitiveComponent* Prim1 = nullptr, FName OptionalBoneName1 = NAME_None, bool bAddChildBones1 = false, UPrimitiveComponent* Prim2 = nullptr, FName OptionalBoneName2 = NAME_None, bool bAddChildBones2 = false, bool bIgnoreCollision = true); + + // Sets two actors to entirely ignore collision between them + UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|Collision", meta = (bIgnoreSelf = "true", WorldContext = "WorldContextObject", CallableWithoutWorldContext)) + static void SetActorsIgnoreAllCollision(UObject* WorldContextObject, AActor* Actor1 = nullptr, AActor* Actor2 = nullptr, bool bIgnoreCollision = true); + + // Removes all collision ignore matches for the given primitive object + UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|Collision", meta = (bIgnoreSelf = "true", WorldContext = "WorldContextObject", CallableWithoutWorldContext)) + static void RemoveObjectCollisionIgnore(UObject* WorldContextObject, UPrimitiveComponent* Prim1); + + // Removes all collision ignore matches for the given actor + UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|Collision", meta = (bIgnoreSelf = "true", WorldContext = "WorldContextObject", CallableWithoutWorldContext)) + static void RemoveActorCollisionIgnore(UObject* WorldContextObject, AActor* Actor1); + + // Returns if the component is ignoring any collisions + UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|Collision", meta = (bIgnoreSelf = "true", WorldContext = "WorldContextObject", CallableWithoutWorldContext)) + static bool IsComponentIgnoringCollision(UObject* WorldContextObject, UPrimitiveComponent* Prim1); + + // Returns if the component is ignoring collisions with the specific component + // This does not check per bone, but rather at scale if any part of them are ignoring each other + UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|Collision", meta = (bIgnoreSelf = "true", WorldContext = "WorldContextObject", CallableWithoutWorldContext)) + static bool AreComponentsIgnoringCollisions(UObject* WorldContextObject, UPrimitiveComponent* Prim1, UPrimitiveComponent* Prim2); + + UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true", DisplayName = "GetHandFromMotionSourceName")) + static bool GetHandFromMotionSourceName(FName MotionSource, EControllerHand& Hand); + + // Gets the unwound yaw of the HMD + UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true", DisplayName = "GetHMDPureYaw")) + static FRotator GetHMDPureYaw(FRotator HMDRotation); + + inline static FRotator GetHMDPureYaw_I(FRotator HMDRotation) + { + // Took this from UnityVRToolkit, no shame, I liked it + FRotationMatrix HeadMat(HMDRotation); + FVector forward = HeadMat.GetScaledAxis(EAxis::X); + FVector forwardLeveled = forward; + forwardLeveled.Z = 0; + forwardLeveled.Normalize(); + FVector mixedInLocalForward = HeadMat.GetScaledAxis(EAxis::Z); + + if (forward.Z > 0) + { + mixedInLocalForward = -mixedInLocalForward; + } + + mixedInLocalForward.Z = 0; + mixedInLocalForward.Normalize(); + float dot = FMath::Clamp(FVector::DotProduct(forwardLeveled, forward), 0.0f, 1.0f); + FVector finalForward = FMath::Lerp(mixedInLocalForward, forwardLeveled, dot * dot); + + return FRotationMatrix::MakeFromXZ(finalForward, FVector::UpVector).Rotator(); + } + + // Applies a delta rotation around a pivot point, if bUseOriginalYawOnly is true then it only takes the original Yaw into account (characters) + UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true", DisplayName = "RotateAroundPivot")) + static void RotateAroundPivot(FRotator RotationDelta, FVector OriginalLocation, FRotator OriginalRotation, FVector PivotPoint, FVector & NewLocation, FRotator & NewRotation,bool bUseOriginalYawOnly = true) + { + if (bUseOriginalYawOnly) + { + // Keep original pitch/roll + NewRotation.Pitch = OriginalRotation.Pitch; + NewRotation.Roll = OriginalRotation.Roll; + + // Throw out pitch/roll before calculating offset + OriginalRotation.Roll = 0; + OriginalRotation.Pitch = 0; + + // Offset to pivot point + NewLocation = OriginalLocation + OriginalRotation.RotateVector(PivotPoint); + + // Combine rotations + OriginalRotation.Yaw = (OriginalRotation.Quaternion() * RotationDelta.Quaternion()).Rotator().Yaw; + NewRotation.Yaw = OriginalRotation.Yaw; + + // Remove pivot point offset + NewLocation -= OriginalRotation.RotateVector(PivotPoint); + + } + else + { + NewLocation = OriginalLocation + OriginalRotation.RotateVector(PivotPoint); + NewRotation = (OriginalRotation.Quaternion() * RotationDelta.Quaternion()).Rotator(); + NewLocation -= NewRotation.RotateVector(PivotPoint); + } + } + + // Returns a delta rotation to have Vec1 point towards Vec2, assumes that the v + UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true", DisplayName = "FindBetween")) + static FRotator BPQuat_FindBetween(FVector Vec1, FVector Vec2) + { + return FQuat::FindBetween(Vec1, Vec2).Rotator(); + } + + // Gets whether an HMD device is connected + UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true", DisplayName = "GetIsHMDConnected")) + static bool GetIsHMDConnected(); + + // Gets whether an HMD device is connected + UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true", DisplayName = "GetIsHMDWorn")) + static EBPHMDWornState GetIsHMDWorn(); + + // Gets whether an HMD device is connected + UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true", DisplayName = "GetHMDType")) + static EBPHMDDeviceType GetHMDType(); + + // Gets whether the game is running in VRPreview or is a non editor build game (returns true for either). + UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true", DisplayName = "IsInVREditorPreviewOrGame")) + static bool IsInVREditorPreviewOrGame(); + + // Gets whether the game is running in VRPreview + UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true", DisplayName = "IsInVREditorPreview")) + static bool IsInVREditorPreview(); + + /** + * Finds the minimum area rectangle that encloses all of the points in InVerts + * Engine default version is server only for some reason + * Uses algorithm found in http://www.geometrictools.com/Documentation/MinimumAreaRectangle.pdf + * + * @param InVerts - Points to enclose in the rectangle + * @outparam OutRectCenter - Center of the enclosing rectangle + * @outparam OutRectSideA - Vector oriented and sized to represent one edge of the enclosing rectangle, orthogonal to OutRectSideB + * @outparam OutRectSideB - Vector oriented and sized to represent one edge of the enclosing rectangle, orthogonal to OutRectSideA + */ + UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions", meta = (WorldContext = "WorldContextObject", CallableWithoutWorldContext)) + static void NonAuthorityMinimumAreaRectangle(UObject* WorldContextObject, const TArray& InVerts, const FVector& SampleSurfaceNormal, FVector& OutRectCenter, FRotator& OutRectRotation, float& OutSideLengthX, float& OutSideLengthY, bool bDebugDraw = false); + + // A Rolling average low pass filter + UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true", DisplayName = "LowPassFilter_RollingAverage")) + static void LowPassFilter_RollingAverage(FVector lastAverage, FVector newSample, FVector & newAverage, int32 numSamples = 10); + + // A exponential low pass filter + UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true", DisplayName = "LowPassFilter_Exponential")) + static void LowPassFilter_Exponential(FVector lastAverage, FVector newSample, FVector & newAverage, float sampleFactor = 0.25f); + + // Gets whether an HMD device is connected + UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions", meta = (bIgnoreSelf = "true", DisplayName = "GetIsActorMovable")) + static bool GetIsActorMovable(AActor * ActorToCheck); + + // Gets if an actors root component contains a grip slot within range + UFUNCTION(BlueprintPure, Category = "VRGrip", meta = (bIgnoreSelf = "true", DisplayName = "GetGripSlotInRangeByTypeName")) + static void GetGripSlotInRangeByTypeName(FName SlotType, AActor * Actor, FVector WorldLocation, float MaxRange, bool & bHadSlotInRange, FTransform & SlotWorldTransform, FName & SlotName, UGripMotionControllerComponent* QueryController = nullptr); + + // Gets if an actors root component contains a grip slot within range + UFUNCTION(BlueprintPure, Category = "VRGrip", meta = (bIgnoreSelf = "true", DisplayName = "GetGripSlotInRangeByTypeName_Component")) + static void GetGripSlotInRangeByTypeName_Component(FName SlotType, USceneComponent * Component, FVector WorldLocation, float MaxRange, bool & bHadSlotInRange, FTransform & SlotWorldTransform, FName & SlotName, UGripMotionControllerComponent* QueryController = nullptr); + + /* Returns true if the values are equal (A == B) */ + UFUNCTION(BlueprintPure, meta = (DisplayName = "Equal VR Grip", CompactNodeTitle = "==", Keywords = "== equal"), Category = "VRExpansionFunctions") + static bool EqualEqual_FBPActorGripInformation(const FBPActorGripInformation &A, const FBPActorGripInformation &B); + + /* Returns true if the grip is active (both valid and not paused) */ + UFUNCTION(BlueprintPure, Category = "VRExpansionFunctions") + static bool IsActiveGrip(const FBPActorGripInformation& Grip); + + /** Make a transform net quantize from location, rotation and scale */ + UFUNCTION(BlueprintPure, meta = (Scale = "1,1,1", Keywords = "construct build", NativeMakeFunc), Category = "VRExpansionLibrary|TransformNetQuantize") + static FTransform_NetQuantize MakeTransform_NetQuantize(FVector Location, FRotator Rotation, FVector Scale); + + /** Breaks apart a transform net quantize into location, rotation and scale */ + UFUNCTION(BlueprintPure, Category = "VRExpansionLibrary|TransformNetQuantize", meta = (NativeBreakFunc)) + static void BreakTransform_NetQuantize(const FTransform_NetQuantize& InTransform, FVector& Location, FRotator& Rotation, FVector& Scale); + + /** Converts a FTransform into a FTransform_NetQuantize */ + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToTransform_NetQuantize (Transform)", CompactNodeTitle = "->", BlueprintAutocast), Category = "VRExpansionLibrary|TransformNetQuantize") + static FTransform_NetQuantize Conv_TransformToTransformNetQuantize(const FTransform &InTransform); + + /** Converts a vector into a FVector_NetQuantize */ + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToVector_NetQuantize (Vector)", CompactNodeTitle = "->", BlueprintAutocast), Category = "VRExpansionLibrary|FVectorNetQuantize") + static FVector_NetQuantize Conv_FVectorToFVectorNetQuantize(const FVector &InVector); + + /** Make a transform net quantize from location, rotation and scale */ + UFUNCTION(BlueprintPure, meta = (Scale = "1,1,1", Keywords = "construct build", NativeMakeFunc), Category = "VRExpansionLibrary|FVectorNetQuantize") + static FVector_NetQuantize MakeVector_NetQuantize(FVector InVector); + + /** Converts a vector into a FVector_NetQuantize10 */ + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToVector_NetQuantize10 (Vector)", CompactNodeTitle = "->", BlueprintAutocast), Category = "VRExpansionLibrary|FVectorNetQuantize") + static FVector_NetQuantize10 Conv_FVectorToFVectorNetQuantize10(const FVector &InVector); + + /** Make a transform net quantize10 from location, rotation and scale */ + UFUNCTION(BlueprintPure, meta = (Scale = "1,1,1", Keywords = "construct build", NativeMakeFunc), Category = "VRExpansionLibrary|FVectorNetQuantize") + static FVector_NetQuantize10 MakeVector_NetQuantize10(FVector InVector); + + /** Converts a vector into a FVector_NetQuantize100 */ + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToVector_NetQuantize100 (Vector)", CompactNodeTitle = "->", BlueprintAutocast), Category = "VRExpansionLibrary|FVectorNetQuantize") + static FVector_NetQuantize100 Conv_FVectorToFVectorNetQuantize100(const FVector &InVector); + + /** Make a transform net quantize100 from location, rotation and scale */ + UFUNCTION(BlueprintPure, meta = (Scale = "1,1,1", Keywords = "construct build", NativeMakeFunc), Category = "VRExpansionLibrary|FVectorNetQuantize") + static FVector_NetQuantize100 MakeVector_NetQuantize100(FVector InVector); + + /** Converts a FBPGripPair into a MotionController */ + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToController (FBPGripPair)", CompactNodeTitle = "->", BlueprintAutocast), Category = "VRExpansionLibrary") + static UGripMotionControllerComponent * Conv_GripPairToMotionController(const FBPGripPair &GripPair); + + /** Converts a FBPGripPair into a GripID */ + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToGripID (FBPGripPair)", CompactNodeTitle = "->", BlueprintAutocast), Category = "VRExpansionLibrary") + static uint8 Conv_GripPairToGripID(const FBPGripPair &GripPair); + + // Adds a USceneComponent Subclass, that is based on the passed in Class, and added to the Outer(Actor) object + UFUNCTION(BlueprintCallable, meta = (DisplayName = "Add Scene Component By Class"), Category = "VRExpansionLibrary") + static USceneComponent* AddSceneComponentByClass(UObject* Outer, TSubclassOf Class, const FTransform & ComponentRelativeTransform); + + + /** Resets a Filter so that the first time it is used again it is clean */ + UFUNCTION(BlueprintCallable, Category = "LowPassFilter_Peak") + static void ResetPeakLowPassFilter(UPARAM(ref) FBPLowPassPeakFilter& TargetPeakFilter); + + /** Adds an entry to the Peak low pass filter */ + UFUNCTION(BlueprintCallable, Category = "LowPassFilter_Peak") + static void UpdatePeakLowPassFilter(UPARAM(ref) FBPLowPassPeakFilter& TargetPeakFilter, FVector NewSample); + + /** Gets the peak value of the Peak Low Pass Filter */ + UFUNCTION(BlueprintCallable, Category = "LowPassFilter_Peak") + static FVector GetPeak_PeakLowPassFilter(UPARAM(ref) FBPLowPassPeakFilter& TargetPeakFilter); + + + /** Resets a Euro Low Pass Filter so that the first time it is used again it is clean */ + UFUNCTION(BlueprintCallable, Category = "EuroLowPassFilter") + static void ResetEuroSmoothingFilter(UPARAM(ref) FBPEuroLowPassFilter& TargetEuroFilter); + + /** Runs the smoothing function of a Euro Low Pass Filter */ + UFUNCTION(BlueprintCallable, Category = "EuroLowPassFilter") + static void RunEuroSmoothingFilter(UPARAM(ref) FBPEuroLowPassFilter& TargetEuroFilter, FVector InRawValue, const float DeltaTime, FVector & SmoothedValue); + + // Applies the same laser smoothing that the vr editor uses to an array of points + UFUNCTION(BlueprintCallable, meta = (DisplayName = "Smooth Update Laser Spline"), Category = "VRExpansionLibrary") + static void SmoothUpdateLaserSpline(USplineComponent * LaserSplineComponent, TArray LaserSplineMeshComponents, FVector InStartLocation, FVector InEndLocation, FVector InForward, float LaserRadius); + + /** + * Determine if any tag in the BaseContainer matches against any tag in OtherContainer with a required direct parent for both + * + * @param TagParent Required direct parent tag + * @param BaseContainer Container containing values to check + * @param OtherContainer Container to check against. + * + * @return True if any tag was found that matches any tags explicitly present in OtherContainer with the same DirectParent + */ + UFUNCTION(BlueprintPure, Category = "GameplayTags") + static bool MatchesAnyTagsWithDirectParentTag(FGameplayTag DirectParentTag,const FGameplayTagContainer& BaseContainer, const FGameplayTagContainer& OtherContainer); + + /** + * Determine if any tag in the BaseContainer has the exact same direct parent tag and returns the first one + * @param TagParent Required direct parent tag + * @param BaseContainer Container containing values to check + + * @return True if any tag was found and also returns the tag + */ + UFUNCTION(BlueprintPure, Category = "GameplayTags") + static bool GetFirstGameplayTagWithExactParent(FGameplayTag DirectParentTag, const FGameplayTagContainer& BaseContainer, FGameplayTag& FoundTag); + + // #TODO: probably need to implement this some day + // This doesn't work for the web browser widget but it does for the normal widgets like text boxes + // Just have to SetKeyboardFocus or SetUserFocus for the input widget first + // Main problem is it takes focus from the player then.... + /*UFUNCTION(BlueprintCallable, Category = "KeyboardSimulation") + static void SimulateCharacterEntry(UPARAM(ref) const FString& InChar) + { + + for (int32 CharIndex = 0; CharIndex < InChar.Len(); CharIndex++) + { + TCHAR CharKey = InChar[CharIndex]; + const bool bRepeat = false; + FCharacterEvent CharacterEvent(CharKey, FModifierKeysState(), 0, bRepeat); + FSlateApplication::Get().ProcessKeyCharEvent(CharacterEvent); + } + + }*/ + /* + void FVREditorActionCallbacks::SimulateBackspace() + { + // Slate editable text fields handle backspace as a character entry + FString BackspaceString = FString(TEXT("\b")); + bool bRepeat = false; + SimulateCharacterEntry(BackspaceString); + } + + void FVREditorActionCallbacks::SimulateKeyDown(const FKey Key, const bool bRepeat) + { + const uint32* KeyCodePtr; + const uint32* CharCodePtr; + FInputKeyManager::Get().GetCodesFromKey(Key, KeyCodePtr, CharCodePtr); + + uint32 KeyCode = KeyCodePtr ? *KeyCodePtr : 0; + uint32 CharCode = CharCodePtr ? *CharCodePtr : 0; + + FKeyEvent KeyEvent(Key, FModifierKeysState(), 0, bRepeat, KeyCode, CharCode); + bool DownResult = FSlateApplication::Get().ProcessKeyDownEvent(KeyEvent); + + if (CharCodePtr) + { + FCharacterEvent CharacterEvent(CharCode, FModifierKeysState(), 0, bRepeat); + FSlateApplication::Get().ProcessKeyCharEvent(CharacterEvent); + } + } + + void FVREditorActionCallbacks::SimulateKeyUp(const FKey Key) + { + const uint32* KeyCodePtr; + const uint32* CharCodePtr; + FInputKeyManager::Get().GetCodesFromKey(Key, KeyCodePtr, CharCodePtr); + + uint32 KeyCode = KeyCodePtr ? *KeyCodePtr : 0; + uint32 CharCode = CharCodePtr ? *CharCodePtr : 0; + + FKeyEvent KeyEvent(Key, FModifierKeysState(), 0, false, KeyCode, CharCode); + FSlateApplication::Get().ProcessKeyUpEvent(KeyEvent); + }*/ +}; + + diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRExpansionPlugin.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRExpansionPlugin.h new file mode 100644 index 0000000..57fca23 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRExpansionPlugin.h @@ -0,0 +1,19 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "Modules/ModuleManager.h" + + +class FVRExpansionPluginModule : public IModuleInterface +{ +public: + + /** IModuleInterface implementation */ + virtual void StartupModule() override; + virtual void ShutdownModule() override; + + void RegisterSettings(); + + void UnregisterSettings(); +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRGestureComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRGestureComponent.h new file mode 100644 index 0000000..f594471 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRGestureComponent.h @@ -0,0 +1,378 @@ + + +#pragma once + +#include "CoreMinimal.h" +//#include "Engine/Engine.h" +#include "VRBPDatatypes.h" +#include "Engine/DataAsset.h" +#include "Components/SceneComponent.h" + +//#include "Engine/EngineTypes.h" +//#include "Engine/EngineBaseTypes.h" +#include "TimerManager.h" +#include "VRGestureComponent.generated.h" + +DECLARE_STATS_GROUP(TEXT("TICKGesture"), STATGROUP_TickGesture, STATCAT_Advanced); + +class USplineMeshComponent; +class USplineComponent; +class AVRBaseCharacter; + + +UENUM(Blueprintable) +enum class EVRGestureState : uint8 +{ + GES_None, + GES_Recording, + GES_Detecting +}; + + +UENUM(Blueprintable) +enum class EVRGestureMirrorMode : uint8 +{ + GES_NoMirror, + GES_MirrorLeft, + GES_MirrorRight, + GES_MirrorBoth +}; + +UENUM(Blueprintable) +enum class EVRGestureFlattenAxis : uint8 +{ + GES_FlattenX, + GES_FlattenY, + GES_FlattenZ, + GES_DontFlatten +}; + +USTRUCT(BlueprintType, Category = "VRGestures") +struct VREXPANSIONPLUGIN_API FVRGestureSettings +{ + GENERATED_BODY() +public: + + // Minimum length to start recognizing this gesture at + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGesture|Advanced") + int Minimum_Gesture_Length; + + // Maximum distance between the last observations before throwing out this gesture, raise this to make it easier to start checking this gesture + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGesture|Advanced") + float firstThreshold; + + // Full threshold before detecting the gesture, raise this to lower accuracy but make it easier to detect this gesture + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGesture|Advanced") + float FullThreshold; + + // If set to left/right, will mirror the detected gesture if the gesture component is set to match that value + // If set to Both mode, the gesture will be checked both normal and mirrored and the best match will be chosen + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGesture|Advanced") + EVRGestureMirrorMode MirrorMode; + + // If enabled this gesture will be checked when inside a DB + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGesture|Advanced") + bool bEnabled; + + // If enabled this gesture will have sample data scaled to it when recognizing (if false you will want to record the gesture without scaling) + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGesture|Advanced") + bool bEnableScaling; + + FVRGestureSettings() + { + Minimum_Gesture_Length = 1; + firstThreshold = 20.0f; + FullThreshold = 20.0f; + MirrorMode = EVRGestureMirrorMode::GES_NoMirror; + bEnabled = true; + bEnableScaling = true; + } +}; + +USTRUCT(BlueprintType, Category = "VRGestures") +struct VREXPANSIONPLUGIN_API FVRGesture +{ + GENERATED_BODY() +public: + + // Name of the recorded gesture + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGesture") + FString Name; + + // Enum uint8 for end user use + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGesture") + uint8 GestureType; + + // Samples in the recorded gesture + UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "VRGesture") + TArray Samples; + + UPROPERTY(BlueprintReadWrite, VisibleAnywhere, Category = "VRGesture") + FBox GestureSize; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGesture") + FVRGestureSettings GestureSettings; + + FVRGesture() + { + GestureType = 0; + GestureSize = FBox(); + } + + void CalculateSizeOfGesture(bool bAllowResizing = false, float TargetExtentSize = 1.f) + { + FVector NewSample; + for (int i = 0; i < Samples.Num(); ++i) + { + NewSample = Samples[i]; + GestureSize.Max.X = FMath::Max(NewSample.X, GestureSize.Max.X); + GestureSize.Max.Y = FMath::Max(NewSample.Y, GestureSize.Max.Y); + GestureSize.Max.Z = FMath::Max(NewSample.Z, GestureSize.Max.Z); + + GestureSize.Min.X = FMath::Min(NewSample.X, GestureSize.Min.X); + GestureSize.Min.Y = FMath::Min(NewSample.Y, GestureSize.Min.Y); + GestureSize.Min.Z = FMath::Min(NewSample.Z, GestureSize.Min.Z); + } + + if (bAllowResizing) + { + FVector BoxSize = GestureSize.GetSize(); + float Scaler = TargetExtentSize / BoxSize.GetMax(); + + for (int i = 0; i < Samples.Num(); ++i) + { + Samples[i] *= Scaler; + } + + GestureSize.Min *= Scaler; + GestureSize.Max *= Scaler; + } + } +}; + +/** +* Items Database DataAsset, here we can save all of our game items +*/ +UCLASS(BlueprintType, Category = "VRGestures") +class VREXPANSIONPLUGIN_API UGesturesDatabase : public UDataAsset +{ + GENERATED_BODY() +public: + + // Gestures in this database + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures") + TArray Gestures; + + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures") + float TargetGestureScale; + + UGesturesDatabase() + { + TargetGestureScale = 100.0f; + } + + // Recalculate size of gestures and re-scale them to the TargetGestureScale (if bScaleToDatabase is true) + UFUNCTION(BlueprintCallable, Category = "VRGestures") + void RecalculateGestures(bool bScaleToDatabase = true); + + // Fills a spline component with a gesture, optionally also generates spline mesh components for it (uses ones already attached if possible) + UFUNCTION(BlueprintCallable, Category = "VRGestures") + void FillSplineWithGesture(UPARAM(ref)FVRGesture &Gesture, USplineComponent * SplineComponent, bool bCenterPointsOnSpline = true, bool bScaleToBounds = false, float OptionalBounds = 0.0f, bool bUseCurvedPoints = true, bool bFillInSplineMeshComponents = true, UStaticMesh * Mesh = nullptr, UMaterial * MeshMat = nullptr); + + // Imports a spline as a gesture, Segment len is the max segment length (will break lines up into lengths of this size) + UFUNCTION(BlueprintCallable, Category = "VRGestures") + bool ImportSplineAsGesture(USplineComponent * HostSplineComponent, FString GestureName, bool bKeepSplineCurves = true, float SegmentLen = 10.0f, bool bScaleToDatabase = true); + +}; + + +USTRUCT(BlueprintType, Category = "VRGestures") +struct VREXPANSIONPLUGIN_API FVRGestureSplineDraw +{ + GENERATED_BODY() +public: + + UPROPERTY() + TObjectPtr SplineComponent; + + UPROPERTY() + TArray> SplineMeshes; + + int LastIndexSet; + int NextIndexCleared; + + // Marches through the array and clears the last point + void ClearLastPoint(); + + // Hides all spline meshes and re-inits the spline component + void Reset(); + + void Clear(); + + FVRGestureSplineDraw(); + + ~FVRGestureSplineDraw(); +}; + +/** Delegate for notification when the lever state changes. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams(FVRGestureDetectedSignature, uint8, GestureType, FString, DetectedGestureName, int, DetectedGestureIndex, UGesturesDatabase *, GestureDataBase, FVector, OriginalUnscaledGestureSize); + +/** +* A scene component that can sample its positions to record / track VR gestures +* Core code is from https://social.msdn.microsoft.com/Forums/en-US/4a428391-82df-445a-a867-557f284bd4b1/dynamic-time-warping-to-recognize-gestures?forum=kinectsdk +* I would also like to acknowledge RuneBerg as he appears to have used the same core codebase and I discovered that halfway through implementing this +* If this algorithm should not prove stable enough I will likely look into using a more complex and faster one in the future, I have several modifications +* to the base DTW algorithm noted from a few research papers. I only implemented this one first as it was a single header file and the quickest to implement. +*/ +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UVRGestureComponent : public USceneComponent +{ + GENERATED_BODY() + +public: + UVRGestureComponent(const FObjectInitializer& ObjectInitializer); + + + // Size of obeservations vectors. + //int dim; // Not needed, this is just dimensionality + // Can be used for arrays of samples (IE: multiple points), could add back in eventually + // if I decide to support three point tracked gestures or something at some point, but its a waste for single point. + + UFUNCTION(BlueprintImplementableEvent, Category = "BaseVRCharacter") + void OnGestureDetected(uint8 GestureType, FString &DetectedGestureName, int & DetectedGestureIndex, UGesturesDatabase * GestureDatabase, FVector OriginalUnscaledGestureSize); + + // Call to use an object + UPROPERTY(BlueprintAssignable, Category = "VRGestures") + FVRGestureDetectedSignature OnGestureDetected_Bind; + + // Known sequences + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures") + TObjectPtr GesturesDB; + + // Tolerance within we throw out duplicate samples + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures") + float SameSampleTolerance; + + // If a gesture is set to match this value then detection will mirror the gesture + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures") + EVRGestureMirrorMode MirroringHand; + + // Tolerance within we throw out duplicate samples + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures") + TObjectPtr TargetCharacter; + + FVRGestureSplineDraw RecordingGestureDraw; + + // Should we draw splines curved or straight + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures") + bool bDrawSplinesCurved; + + // If false will get the gesture in relative space instead + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures") + bool bGetGestureInWorldSpace; + + // Mesh to use when drawing splines + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures") + TObjectPtr SplineMesh; + + // Scaler to apply to the spline mesh components + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures") + FVector2D SplineMeshScaler; + + // Material to use when drawing splines + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures") + TObjectPtr SplineMaterial; + + // HTZ to run recording at for detection and saving - now being used as a frame time instead of a HTZ + float RecordingDelta; + + // Number of samples to keep in memory during detection + int RecordingBufferSize; + + float RecordingClampingTolerance = 0.0f; + EVRGestureFlattenAxis RecordingFlattenAxis = EVRGestureFlattenAxis::GES_DontFlatten; + bool bDrawRecordingGesture = false; + bool bDrawRecordingGestureAsSpline = false; + bool bGestureChanged = false; + + // Handle to our update timer + FTimerHandle TickGestureTimer_Handle; + + // Maximum vertical or horizontal steps in a row in the lookup table before throwing out a gesture + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures") + int maxSlope; + + UPROPERTY(BlueprintReadOnly, Category = "VRGestures") + EVRGestureState CurrentState; + + // Currently recording gesture + UPROPERTY(BlueprintReadOnly, Category = "VRGestures") + FVRGesture GestureLog; + + inline float GetGestureDistance(FVector Seq1, FVector Seq2, bool bMirrorGesture = false) + { + if (bMirrorGesture) + { + return FVector::DistSquared(Seq1, FVector(Seq2.X, -Seq2.Y, Seq2.Z)); + } + + return FVector::DistSquared(Seq1, Seq2); + } + + virtual void BeginDestroy() override; + + // Recalculates a gestures size and re-scales it to the given database + UFUNCTION(BlueprintCallable, Category = "VRGestures") + void RecalculateGestureSize(UPARAM(ref) FVRGesture & InputGesture, UGesturesDatabase * GestureDB); + + // Draw a gesture with a debug line batch + UFUNCTION(BlueprintCallable, Category = "VRGestures", meta = (WorldContext = "WorldContextObject")) + void DrawDebugGesture(UObject* WorldContextObject, UPARAM(ref)FTransform& StartTransform, FVRGesture GestureToDraw, FColor const& Color, bool bPersistentLines = false, uint8 DepthPriority = 0, float LifeTime = -1.f, float Thickness = 0.f); + + FVector StartVector; + FTransform OriginatingTransform; + FTransform ParentRelativeTransform; + + /* Function to begin recording a gesture for detection or saving + * + * bRunDetection: Should we detect gestures or only record them + * bFlattenGestue: Should we flatten the gesture into 2 dimensions (more stable detection and recording, less pretty visually) + * bDrawGesture: Should we draw the gesture during recording of it + * bDrawAsSpline: If true we will use spline meshes, if false we will draw as debug lines + * SamplingHTZ: How many times a second we will record a gesture point, recording is done with a timer now, i would steer away + * from htz > possible frames as that could cause double timer updates with how timers are implemented. + * SampleBufferSize: How many points we will store in history at a time + * ClampingTolerance: If larger than 0.0, we will clamp points to a grid of this size + */ + UFUNCTION(BlueprintCallable, Category = "VRGestures") + void BeginRecording(bool bRunDetection, EVRGestureFlattenAxis FlattenAxis = EVRGestureFlattenAxis::GES_FlattenX, bool bDrawGesture = true, bool bDrawAsSpline = false, int SamplingHTZ = 30, int SampleBufferSize = 60, float ClampingTolerance = 0.01f); + + // Ends recording and returns the recorded gesture + UFUNCTION(BlueprintCallable, Category = "VRGestures") + FVRGesture EndRecording(); + + // Clears the current recording + UFUNCTION(BlueprintCallable, Category = "VRGestures") + void ClearRecording(); + + // Saves a VRGesture to the database, if Scale To Database is true then it will scale the data + UFUNCTION(BlueprintCallable, Category = "VRGestures") + void SaveRecording(UPARAM(ref) FVRGesture &Recording, FString RecordingName, bool bScaleRecordingToDatabase = true); + + void CaptureGestureFrame(); + + // Ticks the logic from the gameplay timer. + void TickGesture(); + + + // Recognize gesture in the given sequence. + // It will always assume that the gesture ends on the last observation of that sequence. + // If the distance between the last observations of each sequence is too great, or if the overall DTW distance between the two sequences is too great, no gesture will be recognized. + void RecognizeGesture(FVRGesture inputGesture); + + + // Compute the min DTW distance between seq2 and all possible endings of seq1. + float dtw(FVRGesture seq1, FVRGesture seq2, bool bMirrorGesture = false, float Scaler = 1.f); + +}; + diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRGlobalSettings.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRGlobalSettings.h new file mode 100644 index 0000000..dd6d171 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRGlobalSettings.h @@ -0,0 +1,326 @@ +#pragma once +#include "CoreMinimal.h" +#include "GameFramework/PlayerInput.h" +#include "GameFramework/InputSettings.h" +#include "VRBPDatatypes.h" +#include "Curves/CurveFloat.h" +#include "GripScripts/GS_Melee.h" +#include "GripScripts/GS_GunTools.h" +#include "VRGlobalSettings.generated.h" + +class UGrippableSkeletalMeshComponent; + +USTRUCT(BlueprintType, Category = "ControllerProfiles") +struct VREXPANSIONPLUGIN_API FBPVRControllerProfile +{ + GENERATED_BODY() +public: + + // Name of controller profile + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ControllerProfiles") + FName ControllerName; + + // Offset to use with this controller + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ControllerProfiles") + FTransform_NetQuantize SocketOffsetTransform; + + // Offset to use with this controller + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ControllerProfiles") + bool bUseSeperateHandOffsetTransforms; + + // Offset to use with this controller + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ControllerProfiles", meta = (editcondition = "bUseSeperateHandOffsetTransforms")) + FTransform_NetQuantize SocketOffsetTransformRightHand; + + + FBPVRControllerProfile() : + ControllerName(NAME_None), + SocketOffsetTransform(FTransform::Identity), + bUseSeperateHandOffsetTransforms(false), + SocketOffsetTransformRightHand(FTransform::Identity) + {} + + FBPVRControllerProfile(FName ControllerName) : + ControllerName(ControllerName), + SocketOffsetTransform(FTransform::Identity), + bUseSeperateHandOffsetTransforms(false), + SocketOffsetTransformRightHand(FTransform::Identity) + {} + + FBPVRControllerProfile(FName ControllerNameIn, const FTransform & Offset) : + ControllerName(ControllerNameIn), + SocketOffsetTransform(Offset), + bUseSeperateHandOffsetTransforms(false), + SocketOffsetTransformRightHand(FTransform::Identity) + {} + + FBPVRControllerProfile(FName ControllerNameIn, const FTransform & Offset, const FTransform & OffsetRight) : + ControllerName(ControllerNameIn), + SocketOffsetTransform(Offset), + bUseSeperateHandOffsetTransforms(true), + SocketOffsetTransformRightHand(OffsetRight) + {} + + FORCEINLINE bool operator==(const FBPVRControllerProfile &Other) const + { + return this->ControllerName == Other.ControllerName; + } +}; + +UCLASS(config = Engine, defaultconfig) +class VREXPANSIONPLUGIN_API UVRGlobalSettings : public UObject +{ + GENERATED_BODY() + +public: + UVRGlobalSettings(const FObjectInitializer& ObjectInitializer); + + // Set scaler values + void SetScalers(); + +#if WITH_EDITOR + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; +#endif + + // The skeletal mesh component class to use for grippable characters + // If you set this to none it will fall back to the default grippable class so that it doesn't brick your project + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "Misc") + TSubclassOf DefaultGrippableCharacterMeshComponentClass; + + // Using a getter to stay safe from bricking peoples projects if they set it to none somehow + static TSubclassOf GetDefaultGrippableCharacterMeshComponentClass(); + + // If true we will use contact modification for the collision ignore subsystem + // Its more expensive but works with non simulating pairs + // #WARNING: Don't use yet EXPERIMENTAL + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "ChaosPhysics|CollisionIgnore") + bool bUseCollisionModificationForCollisionIgnore; + + // Number of updates a second to use for the collision cleanup checks + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "ChaosPhysics|CollisionIgnore") + float CollisionIgnoreSubsystemUpdateRate; + + // Whether we should use the physx to chaos translation scalers or not + // This should be off on native chaos projects that have been set with the correct stiffness and damping settings already + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "ChaosPhysics") + bool bUseChaosTranslationScalers; + + // If true we will also set the engines chaos scalers as well to equal our overrides + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "ChaosPhysics") + bool bSetEngineChaosScalers; + + // A scaler to apply to constraint drives when chaos is active + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "ChaosPhysics") + float LinearDriveStiffnessScale; + + // A scaler to apply to constraint drives when chaos is active + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "ChaosPhysics") + float LinearDriveDampingScale; + + // A scaler to apply to constraint drives when chaos is active + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "ChaosPhysics") + float AngularDriveStiffnessScale; + + // A scaler to apply to constraint drives when chaos is active + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "ChaosPhysics") + float AngularDriveDampingScale; + + // Hard joint stiffness + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "ChaosPhysics|Constraints") + float JointStiffness; + + // A scaler to apply to constraints when chaos is active + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "ChaosPhysics|Constraints") + float SoftLinearStiffnessScale; + + // A scaler to apply to constraints when chaos is active + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "ChaosPhysics|Constraints") + float SoftLinearDampingScale; + + // A scaler to apply to constraints when chaos is active + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "ChaosPhysics|Constraints") + float SoftAngularStiffnessScale; + + // A scaler to apply to constraints when chaos is active + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "ChaosPhysics|Constraints") + float SoftAngularDampingScale; + + // A scaler to apply to constraints when chaos is active + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "ChaosPhysics|Constraints") + float JointLinearBreakScale; + + // A scaler to apply to constraints when chaos is active + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "ChaosPhysics|Constraints") + float JointAngularBreakScale; + + // If we should lerp hybrid with sweep grips out of collision + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "HybridWithSweepLerp") + bool bLerpHybridWithSweepGrips; + + // If true we only lerp the rotation of hybrid grips + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "HybridWithSweepLerp") + bool bOnlyLerpHybridRotation; + + // If true we calculate a speed off of the lerp duration and TInterp using it + // The Hybrid with sweep lerp duration then is used to divide 1.0f (x10) to get the speed (lower duration = faster movement) + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "HybridWithSweepLerp") + bool bHybridWithSweepUseDistanceBasedLerp; + + // Duration that the typical lerp takes, for the distance based lerp this is turned into a speed value based off of 1.0f / it + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "HybridWithSweepLerp") + float HybridWithSweepLerpDuration; + + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "GlobalLerpToHand") + bool bUseGlobalLerpToHand; + + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "GlobalLerpToHand") + bool bSkipLerpToHandIfHeld; + + // If the initial grip distance is closer than this value then the lerping will not be performed. + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "GlobalLerpToHand") + float MinDistanceForLerp; + + // How many seconds the lerp should take + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "GlobalLerpToHand") + float LerpDuration; + + // The minimum speed (in UU per second) that that the lerp should have across the initial grip distance + // Will speed the LerpSpeed up to try and maintain this initial speed if required + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "GlobalLerpToHand") + float MinSpeedForLerp; + + // The maximum speed (in UU per second) that the lerp should have across the initial grip distance + // Will slow the LerpSpeed down to try and maintain this initial speed if required + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "GlobalLerpToHand") + float MaxSpeedForLerp; + + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "GlobalLerpToHand") + EVRLerpInterpolationMode LerpInterpolationMode; + + // Whether to use a curve map to map the lerp to + UPROPERTY(config, BlueprintReadWrite, EditAnywhere, Category = "GlobalLerpToHand|Curve") + bool bUseCurve; + + // The curve to follow when using a curve map, only uses from 0.0 - 1.0 of the curve timeline and maps it across the entire duration + UPROPERTY(config, Category = "GlobalLerpToHand|Curve", EditAnywhere, meta = (editcondition = "bUseCurve")) + FRuntimeFloatCurve OptionalCurveToFollow; + + // Alter the values of the virtual stock settings and save them out + UFUNCTION(BlueprintPure, Category = "GlobalLerpToHand") + static bool IsGlobalLerpEnabled(); + + // List of surfaces and their properties for the melee script + UPROPERTY(config, EditAnywhere, Category = "MeleeSettings") + TArray MeleeSurfaceSettings; + + // Default global virtual stock settings for the gun script + UPROPERTY(config, EditAnywhere, Category = "GunSettings") + FBPVirtualStockSettings VirtualStockSettings; + + // Setting to use for the OneEuro smoothing low pass filter when double gripping something held with a hand + UPROPERTY(config, EditAnywhere, Category = "GunSettings|Secondary Grip 1Euro Settings") + float OneEuroMinCutoff; + + // Setting to use for the OneEuro smoothing low pass filter when double gripping something held with a hand + UPROPERTY(config, EditAnywhere, Category = "GunSettings|Secondary Grip 1Euro Settings") + float OneEuroCutoffSlope; + + // Setting to use for the OneEuro smoothing low pass filter when double gripping something held with a hand + UPROPERTY(config, EditAnywhere, Category = "GunSettings|Secondary Grip 1Euro Settings") + float OneEuroDeltaCutoff; + + // Get the values of the virtual stock settings + UFUNCTION(BlueprintCallable, Category = "MeleeSettings") + static void GetMeleeSurfaceGlobalSettings(TArray& OutMeleeSurfaceSettings); + + // Get the values of the virtual stock settings + UFUNCTION(BlueprintCallable, Category = "GunSettings|VirtualStock") + static void GetVirtualStockGlobalSettings(FBPVirtualStockSettings& OutVirtualStockSettings); + + // Alter the values of the virtual stock settings and save them out + UFUNCTION(BlueprintCallable, Category = "GunSettings|VirtualStock") + static void SaveVirtualStockGlobalSettings(FBPVirtualStockSettings NewVirtualStockSettings); + + + DECLARE_MULTICAST_DELEGATE(FVRControllerProfileChangedEvent); + /** Delegate for notification when the controller profile changes. */ + FVRControllerProfileChangedEvent OnControllerProfileChangedEvent; + + // Controller profiles to store related information on a per profile basis + UPROPERTY(config, EditAnywhere, Category = "ControllerProfiles") + TArray ControllerProfiles; + + // Store these to save some processing when getting the transform after a profile is loaded + FName CurrentControllerProfileInUse; + FTransform CurrentControllerProfileTransform; + bool bUseSeperateHandTransforms; + FTransform CurrentControllerProfileTransformRight; + + // Adjust the transform of a socket for a particular controller model, if a name is not sent in, it will use the currently loaded one + // If there is no currently loaded one, it will return the input transform as is. + // If bIsRightHand and the target profile uses seperate hand transforms it will use the right hand transform + UFUNCTION(BlueprintPure, Category = "VRControllerProfiles") + static FTransform AdjustTransformByControllerProfile(FName OptionalControllerProfileName, const FTransform& SocketTransform, bool bIsRightHand = false); + + // Adjust the transform of a socket for a particular controller model + // If there is no currently loaded one, it will return the input transform as is. + // If bIsRightHand and the target profile uses seperate hand transforms it will use the right hand transform + UFUNCTION(BlueprintPure, Category = "VRControllerProfiles") + static FTransform AdjustTransformByGivenControllerProfile(UPARAM(ref) FBPVRControllerProfile& ControllerProfile, const FTransform& SocketTransform, bool bIsRightHand = false); + + // Get array of controller profiles + UFUNCTION(BlueprintCallable, Category = "VRControllerProfiles") + static TArray GetControllerProfiles(); + + // Overwrite a controller profile + UFUNCTION(BlueprintCallable, Category = "VRControllerProfiles|Operations") + static void OverwriteControllerProfile(UPARAM(ref)FBPVRControllerProfile& OverwritingProfile, bool bSaveOutToConfig = true); + + // Add a controller profile + UFUNCTION(BlueprintCallable, Category = "VRControllerProfiles|Operations") + static void AddControllerProfile(UPARAM(ref)FBPVRControllerProfile& NewProfile, bool bSaveOutToConfig = true); + + // Overwrite a controller profile + UFUNCTION(BlueprintCallable, Category = "VRControllerProfiles|Operations") + static void DeleteControllerProfile(FName ControllerProfileName, bool bSaveOutToConfig = true); + + // Saved the VRGlobalSettings out to its config file, will include any alterations that you made to the profile + UFUNCTION(BlueprintCallable, Category = "VRControllerProfiles|Operations") + static void SaveControllerProfiles(); + + + // Get name of currently loaded profile (if one is loaded) + UFUNCTION(BlueprintCallable, Category = "VRControllerProfiles") + static FName GetCurrentProfileName(bool& bHadLoadedProfile); + + // Get name of currently loaded profile (if one is loaded) + UFUNCTION(BlueprintCallable, Category = "VRControllerProfiles") + static FBPVRControllerProfile GetCurrentProfile(bool& bHadLoadedProfile); + + // Get a controller profile by name + UFUNCTION(BlueprintCallable, Category = "VRControllerProfiles") + static bool GetControllerProfile(FName ControllerProfileName, FBPVRControllerProfile& OutProfile); + + // Load a controller profile by name + // Action / Axis mappings overwrite ones with the same action/axis name in the input settings. + // If you have an action/axis override but don't assign buttons to it then it will just delete it. + // This can be useful for removing actions and using multiple actions (IE: Grip Touch, Grip Vive actions) + // For when just changing the buttons isn't good enough + // If bSetDefaults is true, will set this as the currently loaded profile + // Otherwise will just load it (useful for Left/Right handed profile additions and the like to have it false) + UFUNCTION(BlueprintCallable, Category = "VRControllerProfiles") + static bool LoadControllerProfileByName(FName ControllerProfileName, bool bSetAsCurrentProfile = true); + + // Load a controller profile + // Action / Axis mappings overwrite ones with the same action/axis name in the input settings. + // If you have an action/axis override but don't assign buttons to it then it will just delete it. + // This can be useful for removing actions and using multiple actions (IE: Grip Touch, Grip Vive actions) + // For when just changing the buttons isn't good enough + // If bSetDefaults is true, will set this as the currently loaded profile + // Otherwise will just load it (useful for Left/Right handed profile additions and the like to have it false) + // AS OF 4.25 AXIS and ACTION mappings do nothing, will be deleting around 4.26 #TODO: Delete around 4.26 + UFUNCTION(BlueprintCallable, Category = "VRControllerProfiles") + static bool LoadControllerProfile(const FBPVRControllerProfile& ControllerProfile, bool bSetAsCurrentProfile = true); + + virtual void PostInitProperties() override; +}; diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRGripInterface.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRGripInterface.h new file mode 100644 index 0000000..67a5db1 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRGripInterface.h @@ -0,0 +1,160 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +//#include "UObject/ObjectMacros.h" +//#include "UObject/ScriptMacros.h" +#include "VRBPDatatypes.h" +#include "InputCoreTypes.h" +#include "Engine/EngineBaseTypes.h" +#include "UObject/Interface.h" + +#include "VRGripInterface.generated.h" + +// Forward declare +class UGripMotionControllerComponent; +class UVRGripScriptBase; + +UINTERFACE(Blueprintable) +class VREXPANSIONPLUGIN_API UVRGripInterface: public UInterface +{ + GENERATED_UINTERFACE_BODY() +}; + + +/** Delegate for notification when the controller grips a new object. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FVROnGripSignature, UGripMotionControllerComponent *, GrippingController, const FBPActorGripInformation&, GripInformation); + +/** Delegate for notification when the controller drops a gripped object. */ +DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FVROnDropSignature, UGripMotionControllerComponent*, GrippingController, const FBPActorGripInformation&, GripInformation, bool, bWasSocketed); + +class VREXPANSIONPLUGIN_API IVRGripInterface +{ + GENERATED_IINTERFACE_BODY() + +public: + + // Set up as deny instead of allow so that default allows for gripping + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface", meta = (DisplayName = "IsDenyingGrips")) + bool DenyGripping(UGripMotionControllerComponent * GripInitiator = nullptr); + + // How an interfaced object behaves when teleporting + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + EGripInterfaceTeleportBehavior TeleportBehavior(); + + // Should this object simulate on drop + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + bool SimulateOnDrop(); + + // Grip type to use + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + EGripCollisionType GetPrimaryGripType(bool bIsSlot); + + // Double Grip Type + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + ESecondaryGripType SecondaryGripType(); + + // Define the late update setting + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + EGripLateUpdateSettings GripLateUpdateSetting(); + + // Define which movement repliation setting to use + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + EGripMovementReplicationSettings GripMovementReplicationType(); + + // What grip stiffness and damping to use if using a physics constraint + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + void GetGripStiffnessAndDamping(float &GripStiffnessOut, float &GripDampingOut); + + // Get the advanced physics settings for this grip + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + FBPAdvGripSettings AdvancedGripSettings(); + + // What distance to break a grip at (only relevent with physics enabled grips + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + float GripBreakDistance(); + + /** + * Called to get the closest grip socket in range + * @param WorldLocation - World Location to check near + * @param bSecondarySlot - True if this is a check for a secondary slot or not + * @param CallingController - Controller checking for the slot (can be used in overrides for per hand checks) + * @param OverridePrefix - A different substring to check against in the socket names to find relevant ones + */ + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + void ClosestGripSlotInRange(FVector WorldLocation, bool bSecondarySlot, bool & bHadSlotInRange, FTransform & SlotWorldTransform, FName & SlotName, UGripMotionControllerComponent * CallingController = nullptr, FName OverridePrefix = NAME_None); + + // Events that can be called for interface inheriting actors + + // Event triggered each tick on the interfaced object when gripped, can be used for custom movement or grip based logic + UFUNCTION(BlueprintNativeEvent, Category = "VRGripInterface") + void TickGrip(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation, float DeltaTime); + + // Event triggered on the interfaced object when gripped + UFUNCTION(BlueprintNativeEvent, Category = "VRGripInterface") + void OnGrip(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation); + + // Event triggered on the interfaced object when grip is released + UFUNCTION(BlueprintNativeEvent, Category = "VRGripInterface") + void OnGripRelease(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed = false); + + virtual void Native_NotifyThrowGripDelegates(UGripMotionControllerComponent* Controller, bool bGripped, const FBPActorGripInformation& GripInformation, bool bWasSocketed = false); + + // Event triggered on the interfaced object when child component is gripped + UFUNCTION(BlueprintNativeEvent, Category = "VRGripInterface") + void OnChildGrip(UGripMotionControllerComponent * GrippingController, const FBPActorGripInformation & GripInformation); + + // Event triggered on the interfaced object when child component is released + UFUNCTION(BlueprintNativeEvent, Category = "VRGripInterface") + void OnChildGripRelease(UGripMotionControllerComponent * ReleasingController, const FBPActorGripInformation & GripInformation, bool bWasSocketed = false); + + // Event triggered on the interfaced object when secondary gripped + UFUNCTION(BlueprintNativeEvent, Category = "VRGripInterface") + void OnSecondaryGrip(UGripMotionControllerComponent * GripOwningController, USceneComponent * SecondaryGripComponent, const FBPActorGripInformation & GripInformation); + + // Event triggered on the interfaced object when secondary grip is released + UFUNCTION(BlueprintNativeEvent, Category = "VRGripInterface") + void OnSecondaryGripRelease(UGripMotionControllerComponent * GripOwningController, USceneComponent * ReleasingSecondaryGripComponent, const FBPActorGripInformation & GripInformation); + + // Interaction Functions + + // Call to use an object + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + void OnUsed(); + + // Call to stop using an object + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + void OnEndUsed(); + + // Call to use an object + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + void OnSecondaryUsed(); + + // Call to stop using an object + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + void OnEndSecondaryUsed(); + + // Call to send an action event to the object + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + void OnInput(FKey Key, EInputEvent KeyEvent); + + // Check if an object allows multiple grips at one time + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + bool AllowsMultipleGrips(); + + // Returns if the object is held and if so, which controllers are holding it + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + void IsHeld(TArray & HoldingControllers, bool & bIsHeld); + + // Sets is held, used by the plugin + UFUNCTION(BlueprintNativeEvent, /*BlueprintCallable,*/ Category = "VRGripInterface") + void SetHeld(UGripMotionControllerComponent * HoldingController, uint8 GripID, bool bIsHeld); + + // Returns if the object requests to be socketed to something + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + bool RequestsSocketing(USceneComponent *& ParentToSocketTo, FName & OptionalSocketName, FTransform_NetQuantize & RelativeTransform); + + // Get grip scripts + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "VRGripInterface") + bool GetGripScripts(TArray& ArrayReference); +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRPathFollowingComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRPathFollowingComponent.h new file mode 100644 index 0000000..eb8a7ab --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRPathFollowingComponent.h @@ -0,0 +1,56 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "VRBPDatatypes.h" +#include "VRRootComponent.h" +#include "VRBaseCharacterMovementComponent.h" +#include "Navigation/PathFollowingComponent.h" +#include "AbstractNavData.h" +#include "Runtime/Launch/Resources/Version.h" +#include "VRPathFollowingComponent.generated.h" + +DECLARE_LOG_CATEGORY_EXTERN(LogPathFollowingVR, Warning, All); + +UCLASS() +class VREXPANSIONPLUGIN_API UVRPathFollowingComponent : public UPathFollowingComponent +{ + GENERATED_BODY() + +public: + UPROPERTY(transient) + UVRBaseCharacterMovementComponent* VRMovementComp; + + // Add link to VRMovementComp + void SetMovementComponent(UNavMovementComponent* MoveComp) override; + + ///////UPDATE WITH 4.13//////// + // Have to override this to call the correct HasReachCurrentTarget + void UpdatePathSegment() override; + bool HasReachedCurrentTarget(const FVector& CurrentLocation) const; + + // Had to override this to get the correct DebugReachTest + virtual void GetDebugStringTokens(TArray& Tokens, TArray& Flags) const override; + void DebugReachTest(float& CurrentDot, float& CurrentDistance, float& CurrentHeight, uint8& bDotFailed, uint8& bDistanceFailed, uint8& bHeightFailed) const; + + void FollowPathSegment(float DeltaTime) override; + int32 DetermineStartingPathPoint(const FNavigationPath* ConsideredPath) const override; + + + // This has a foot location when using meta paths, i'm not overriding it yet but this means that meta paths might have slightly bugged implementation. + /** notify about finished movement */ + //virtual void OnPathFinished(const FPathFollowingResult& Result) override; + + /** pause path following + * @param RequestID - request to pause, FAIRequestID::CurrentRequest means pause current request, regardless of its ID */ + void PauseMove(FAIRequestID RequestID = FAIRequestID::CurrentRequest, EPathFollowingVelocityMode VelocityMode = EPathFollowingVelocityMode::Reset) override; + // Now has an actor feet call .......Just a debug reference + //virtual FAIRequestID RequestMove(FNavPathSharedPtr Path, FRequestCompletedSignature OnComplete, const AActor* DestinationActor = NULL, float AcceptanceRadius = UPathFollowingComponent::DefaultAcceptanceRadius, bool bStopOnOverlap = true, FCustomMoveSharedPtr GameData = NULL) override; + // + // Fine in 4.13 + bool ShouldCheckPathOnResume() const override; + + // Fine in 4.13, had to change feet based for both + bool UpdateBlockDetection() override; + +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRPlayerController.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRPlayerController.h new file mode 100644 index 0000000..aa70f8a --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRPlayerController.h @@ -0,0 +1,86 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "GameFramework/PlayerController.h" +#include "Engine/LocalPlayer.h" +#include "VRPlayerController.generated.h" + +// A base player controller specifically for handling OnCameraManagerCreated. +// Used in case you don't want the VRPlayerCharacter changes in a PendingPlayerController +UCLASS() +class VREXPANSIONPLUGIN_API AVRBasePlayerController : public APlayerController +{ + GENERATED_BODY() + +public: + + // Event called in BPs when the camera manager is created (only fired on locally controlled player controllers) + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "OnCameraManagerCreated"), Category = Actor) + void OnCameraManagerCreated(APlayerCameraManager* CameraManager); + + virtual void SpawnPlayerCameraManager() override + { + Super::SpawnPlayerCameraManager(); + + if (PlayerCameraManager != NULL && IsLocalController()) + { + OnCameraManagerCreated(PlayerCameraManager); + } + } + +}; + + +UCLASS() +class VREXPANSIONPLUGIN_API AVRPlayerController : public AVRBasePlayerController +{ + GENERATED_BODY() + +public: + AVRPlayerController(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); + + // New path finding return, not actually sending anything currently unless the character created one for us + // or the user added one to us. The default implementation is fine for us. + //virtual IPathFollowingAgentInterface* GetPathFollowingAgent() const override; + + // Disable the ServerUpdateCamera function defaulted on in PlayerCameraManager + // We are manually replicating the camera position and rotation ourselves anyway + // Generally that function will just be additional replication overhead + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRPlayerController") + bool bDisableServerUpdateCamera; + + /** spawn cameras for servers and owning players */ + virtual void SpawnPlayerCameraManager() override; + + FRotator LastRotationInput; + + /** + * Processes player input (immediately after PlayerInput gets ticked) and calls UpdateRotation(). + * PlayerTick is only called if the PlayerController has a PlayerInput object. Therefore, it will only be called for locally controlled PlayerControllers. + * I am overriding this so that for VRCharacters it doesn't apply the view rotation and instead lets CMC handle it + */ + virtual void PlayerTick(float DeltaTime) override; +}; + +/** +* Utility class, when set as the default local player it will spawn the target PlayerController class instead as the pending player controller +*/ +UCLASS(Blueprintable, meta = (ShortTooltip = "Utility class, when set as the default local player it will spawn the target PlayerController class instead as the pending one")) +class VREXPANSIONPLUGIN_API UVRLocalPlayer : public ULocalPlayer +{ + GENERATED_UCLASS_BODY() + + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "LocalPlayer") + TSubclassOf OverridePendingLevelPlayerControllerClass; + + virtual bool SpawnPlayActor(const FString& URL, FString& OutError, UWorld* InWorld) + { + if (OverridePendingLevelPlayerControllerClass) + { + PendingLevelPlayerControllerClass = OverridePendingLevelPlayerControllerClass; + } + + return Super::SpawnPlayActor(URL, OutError, InWorld); + } +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRRootComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRRootComponent.h new file mode 100644 index 0000000..08ac90f --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRRootComponent.h @@ -0,0 +1,299 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +//#include "Engine/Engine.h" +//#include "Components/ShapeComponent.h" +#include "VRTrackedParentInterface.h" +#include "VRBaseCharacter.h" +#include "VRExpansionFunctionLibrary.h" +#include "GameFramework/PhysicsVolume.h" +#include "Components/CapsuleComponent.h" +#include "VRRootComponent.generated.h" + +//For UE4 Profiler ~ Stat Group +//DECLARE_STATS_GROUP(TEXT("VRPhysicsUpdate"), STATGROUP_VRPhysics, STATCAT_Advanced); + +//class AVRBaseCharacter; + +DECLARE_LOG_CATEGORY_EXTERN(LogVRRootComponent, Log, All); + +DECLARE_STATS_GROUP(TEXT("VRRootComponent"), STATGROUP_VRRootComponent, STATCAT_Advanced); +DECLARE_CYCLE_STAT(TEXT("VR Root Set Half Height"), STAT_VRRootSetHalfHeight, STATGROUP_VRRootComponent); +DECLARE_CYCLE_STAT(TEXT("VR Root Set Capsule Size"), STAT_VRRootSetCapsuleSize, STATGROUP_VRRootComponent); + +/** +* A capsule component that repositions its physics scene and rendering location to the camera/HMD's relative position. +* Generally not to be used by itself unless on a base Pawn and not a character, the VRCharacter has been highly customized to correctly support it. +*/ +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = VRExpansionLibrary) +class VREXPANSIONPLUGIN_API UVRRootComponent : public UCapsuleComponent, public IVRTrackedParentInterface +{ + GENERATED_BODY() + +public: + UVRRootComponent(const FObjectInitializer& ObjectInitializer); + + friend class FDrawCylinderSceneProxy; + + bool bCalledUpdateTransform; + + // Overriding this and applying the offset to world position for the elements + virtual void GetNavigationData(FNavigationRelevantData& Data) const override; + + FORCEINLINE void GenerateOffsetToWorld(bool bUpdateBounds = true, bool bGetPureYaw = true); + + // If valid will use this as the tracked parent instead of the HMD / Parent + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRTrackedParentInterface") + FBPVRWaistTracking_Info OptionalWaistTrackingParent; + + virtual void SetTrackedParent(UPrimitiveComponent * NewParentComponent, float WaistRadius, EBPVRWaistTrackingMode WaistTrackingMode) override + { + IVRTrackedParentInterface::Default_SetTrackedParent_Impl(NewParentComponent, WaistRadius, WaistTrackingMode, OptionalWaistTrackingParent, this); + } + + // Get the target height offset for the current capsule settings + // Generally for when using bRetainRoomscale + inline FVector GetTargetHeightOffset() + { + //return FVector::ZeroVector; + return FVector(0.f, 0.f, (-this->GetUnscaledCapsuleHalfHeight()) - VRCapsuleOffset.Z); + } + + /** + * This is overidden for the VR Character to re-set physics location + * If updating the capsule height in VR you should be using this function or SetCapsuleHalfHeightVR + * Change the capsule size. This is the unscaled size, before component scale is applied. + * @param InRadius : radius of end-cap hemispheres and center cylinder. + * @param InHalfHeight : half-height, from capsule center to end of top or bottom hemisphere. + * @param bUpdateOverlaps: if true and this shape is registered and collides, updates touching array for owner actor. + */ + UFUNCTION(BlueprintCallable, Category = "Components|Capsule") + virtual void SetCapsuleSizeVR(float NewRadius, float NewHalfHeight, bool bUpdateOverlaps = true); + + // Used to update the capsule half height and calculate the new offset value for VR + // If updating the capsule height in VR you should be using this function or SetCapsuleSizeVR + UFUNCTION(BlueprintCallable, Category = "Components|Capsule") + void SetCapsuleHalfHeightVR(float HalfHeight, bool bUpdateOverlaps = true); + + inline void OnUpdateTransform_Public(EUpdateTransformFlags UpdateTransformFlags, ETeleportType Teleport = ETeleportType::None) + { + OnUpdateTransform(UpdateTransformFlags, Teleport); + if (bNavigationRelevant && bRegistered) + { + UpdateNavigationData(); + PostUpdateNavigationData(); + } + } + + virtual void SetSimulatePhysics(bool bSimulate) override; + +protected: + virtual bool MoveComponentImpl(const FVector& Delta, const FQuat& NewRotation, bool bSweep, FHitResult* OutHit = NULL, EMoveComponentFlags MoveFlags = MOVECOMP_NoFlags, ETeleportType Teleport = ETeleportType::None) override; + virtual void OnUpdateTransform(EUpdateTransformFlags UpdateTransformFlags, ETeleportType Teleport = ETeleportType::None) override; + + void SendPhysicsTransform(ETeleportType Teleport); + virtual bool UpdateOverlapsImpl(const TOverlapArrayView* NewPendingOverlaps = nullptr, bool bDoNotifies = true, const TOverlapArrayView* OverlapsAtEndLocation = nullptr) override; + + ///** Convert a set of overlaps from a symmetric change in rotation to a subset that includes only those at the end location (filling in OverlapsAtEndLocation). */ + template + bool ConvertRotationOverlapsToCurrentOverlapsVR(TArray& OutOverlapsAtEndLocation, const TOverlapArrayView& CurrentOverlaps); + + template + bool GetOverlapsWithActor_TemplateVR(const AActor* Actor, TArray& OutOverlaps) const; + + /** Convert a set of overlaps from a sweep to a subset that includes only those at the end location (filling in OverlapsAtEndLocation). */ + template + bool ConvertSweptOverlapsToCurrentOverlapsVR(TArray& OutOverlapsAtEndLocation, const TOverlapArrayView& SweptOverlaps, int32 SweptOverlapsIndex, const FVector& EndLocation, const FQuat& EndRotationQuat); + + +public: + virtual void BeginPlay() override; + virtual void InitializeComponent() override; + + bool IsLocallyControlled() const; + + UPROPERTY(BlueprintReadWrite, Transient, Category = "VRExpansionLibrary") + TObjectPtr TargetPrimitiveComponent; + + //UPROPERTY(BlueprintReadWrite, Transient, Category = "VRExpansionLibrary") + TObjectPtr owningVRChar; + + //UPROPERTY(BlueprintReadWrite, Transient, Category = "VRExpansionLibrary") + //UCapsuleComponent * VRCameraCollider; + + FVector DifferenceFromLastFrame; + //UPROPERTY(BlueprintReadOnly, Transient, Category = "VRExpansionLibrary") + FTransform OffsetComponentToWorld; + + // Used to offset the collision (IE backwards from the player slightly. + // The default 2.15 Z offset is to account for floor hover from the character movement component. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary") + FVector VRCapsuleOffset; + + // Store last half height so that we can offset the net smoother based on changes to it + float LastCapsuleHalfHeight = 0.0f; + + // Sample current and last capsule half heights and apply an offset based on the difference + void UpdateCharacterCapsuleOffset(); + + + + // If true we will stop tracking the camera / hmd until enabled again + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary") + bool bPauseTracking; + + UFUNCTION(BlueprintCallable, Category = "VRExpansionLibrary") + void SetTrackingPaused(bool bPaused); + + // #TODO: Test with 100.f rounding to make sure it isn't noticable, currently that is what it is + // If true will subtract the HMD's location from the position, useful for if the actors base is set to the HMD location always (simple character). + /*UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ReplicatedCamera") + bool bOffsetByHMD; + */ + + + + // #TODO: See if making this multiplayer compatible is viable + // Offsets capsule to be centered on HMD - currently NOT multiplayer compatible + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary") + bool bCenterCapsuleOnHMD; + + // Allows the root component to be blocked by simulating objects (default off due to sickness inducing stuttering). + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary") + bool bAllowSimulatingCollision; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary") + bool bUseWalkingCollisionOverride; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRExpansionLibrary") + TEnumAsByte WalkingCollisionOverride; + + bool bIsOverridingCollision = false; + TEnumAsByte OriginalCollision = ECollisionChannel::ECC_Pawn; + + void SetCollisionOverride(bool bOverrideCollision) + { + if (bOverrideCollision && !bIsOverridingCollision) + { + OriginalCollision = this->GetCollisionObjectType(); + SetCollisionObjectType(WalkingCollisionOverride); + bIsOverridingCollision = true; + } + else if (!bOverrideCollision && bIsOverridingCollision) + { + SetCollisionObjectType(OriginalCollision); + bIsOverridingCollision = false; + } + } + + FVector curCameraLoc; + FRotator curCameraRot; + FRotator StoredCameraRotOffset; + + FVector lastCameraLoc = FVector::ZeroVector; + FRotator lastCameraRot = FRotator::ZeroRotator; + bool bTickedOnce = false; + + // While misnamed, is true if we collided with a wall/obstacle due to the HMDs movement in this frame (not movement components) + UPROPERTY(BlueprintReadOnly, Category = "VRExpansionLibrary") + bool bHadRelativeMovement; + + FPrimitiveSceneProxy* CreateSceneProxy() override; + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; + + virtual void UpdatePhysicsVolume(bool bTriggerNotifiers) override; + + inline bool AreWeOverlappingVolume(APhysicsVolume* V) + { + bool bInsideVolume = true; + if (!V->bPhysicsOnContact) + { + FVector ClosestPoint(0.f); + // If there is no primitive component as root we consider you inside the volume. This is odd, but the behavior + // has existed for a long time, so keeping it this way + UPrimitiveComponent* RootPrimitive = Cast(V->GetRootComponent()); + if (RootPrimitive) + { + float DistToCollisionSqr = -1.f; + if (RootPrimitive->GetSquaredDistanceToCollision(OffsetComponentToWorld.GetTranslation(), DistToCollisionSqr, ClosestPoint)) + { + bInsideVolume = (DistToCollisionSqr == 0.f); + } + else + { + bInsideVolume = false; + } + } + } + + return bInsideVolume; + } + + // Expose this + inline float GetLineThickness() const {return LineThickness;} + +public: + // Begin UObject interface +#if WITH_EDITOR + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; + void PreEditChange(FProperty* PropertyThatWillChange); +#endif // WITH_EDITOR + // End UObject interface + + virtual FBoxSphereBounds CalcBounds(const FTransform& LocalToWorld) const override; + + private: + friend class FVRCharacterScopedMovementUpdate; +}; + + +// Have to declare inlines here for blueprint +void inline UVRRootComponent::GenerateOffsetToWorld(bool bUpdateBounds, bool bGetPureYaw) +{ + FRotator CamRotOffset; + + if (bGetPureYaw) + CamRotOffset = StoredCameraRotOffset;//UVRExpansionFunctionLibrary::GetHMDPureYaw_I(curCameraRot); + else + CamRotOffset = curCameraRot; + + /*if(bOffsetByHMD) + { + OffsetComponentToWorld = FTransform(CamRotOffset.Quaternion(), FVector(0, 0, bCenterCapsuleOnHMD ? curCameraLoc.Z : CapsuleHalfHeight) + CamRotOffset.RotateVector(VRCapsuleOffset), FVector(1.0f)) * GetComponentTransform(); + } + else*/ + + if(owningVRChar && !owningVRChar->bRetainRoomscale) + { + OffsetComponentToWorld = FTransform(CamRotOffset.Quaternion(), FVector(0.0f, 0.0f, bCenterCapsuleOnHMD ? curCameraLoc.Z : 0.0f), FVector(1.0f)) * GetComponentTransform(); + } + else + { + OffsetComponentToWorld = FTransform(CamRotOffset.Quaternion(), FVector(curCameraLoc.X, curCameraLoc.Y, bCenterCapsuleOnHMD ? curCameraLoc.Z : CapsuleHalfHeight) + CamRotOffset.RotateVector(VRCapsuleOffset), FVector(1.0f)) * GetComponentTransform(); + } + + if (owningVRChar) + { + owningVRChar->OffsetComponentToWorld = OffsetComponentToWorld; + + // Check if we need to move our parents NetSmoother into place + UpdateCharacterCapsuleOffset(); + } + + if (bUpdateBounds) + UpdateBounds(); +} + + +FORCEINLINE void UVRRootComponent::SetCapsuleHalfHeightVR(float HalfHeight, bool bUpdateOverlaps) +{ + SCOPE_CYCLE_COUNTER(STAT_VRRootSetHalfHeight); + + if (FMath::IsNearlyEqual(HalfHeight, CapsuleHalfHeight)) + { + return; + } + + SetCapsuleSizeVR(GetUnscaledCapsuleRadius(), HalfHeight, bUpdateOverlaps); +} \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRStereoWidgetComponent.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRStereoWidgetComponent.h new file mode 100644 index 0000000..9fddf36 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRStereoWidgetComponent.h @@ -0,0 +1,247 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +//#include "Engine/Engine.h" +//#include "VRBPDatatypes.h" +#include "Components/StereoLayerComponent.h" +#include "Components/WidgetComponent.h" +//#include "Animation/UMGSequencePlayer.h" + +#include "VRStereoWidgetComponent.generated.h" + +class FWidgetRenderer; +class UUserWidget; +class UTextureRenderTarget2D; +class UStereoLayerShape; + + +/** +* A stereo component that displays a widget instead of a texture. +*/ +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = (VRExpansionPlugin), HideCategories = ("Stereoscopic Properties", Collision)) +class VREXPANSIONPLUGIN_API UVRStereoWidgetRenderComponent : public UStereoLayerComponent +{ + GENERATED_BODY() + +public: + UVRStereoWidgetRenderComponent(const FObjectInitializer& ObjectInitializer); + + /** The class of User Widget to create and display an instance of */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "WidgetSettings", meta = (ExposeOnSpawn = true)) + TSubclassOf WidgetClass; + + /** The User Widget object displayed and managed by this component */ + UPROPERTY(BlueprintReadWrite, Transient, DuplicateTransient, Category = "WidgetSettings") + TObjectPtr Widget; + + /** If true then we sample the requested size of the widget and reset the texture to be that size */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "WidgetSettings", meta = (ExposeOnSpawn = true)) + bool bDrawAtDesiredSize; + + /** The desired render scale of the widget */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "WidgetSettings", meta = (ExposeOnSpawn = true)) + float WidgetRenderScale; + + /** The desired render gamma of the widget */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "WidgetSettings", meta = (ExposeOnSpawn = true)) + float WidgetRenderGamma; + + /** Automatically correct for gamma */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "WidgetSettings", meta = (ExposeOnSpawn = true)) + bool bUseGammaCorrection; + + /** The desired clear color of the render target */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "WidgetSettings", meta = (ExposeOnSpawn = true)) + FLinearColor RenderTargetClearColor; + + /** If true we will draw to the render target even without active stereo layers and skip the stereo tick*/ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "WidgetSettings", meta = (ExposeOnSpawn = true)) + bool bDrawWithoutStereo; + + /** Rate (HTZ) we should draw the texture at */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "WidgetSettings", meta = (ExposeOnSpawn = true)) + float DrawRate; + + // Counts how long until next draw + float DrawCounter; + + /** The Slate widget to be displayed by this component. Only one of either Widget or SlateWidget can be used */ + TSharedPtr SlateWidget; + + class FWidgetRenderer* WidgetRenderer; + + /** The render target being display */ + UPROPERTY(BlueprintReadOnly, Transient, DuplicateTransient, Category = "WidgetSettings") + TObjectPtr RenderTarget; + + /** The slate window that contains the user widget content */ + TSharedPtr SlateWindow; + + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; + virtual void BeginPlay() override; + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + virtual void DestroyComponent(bool bPromoteChildren/*= false*/) override; + + UFUNCTION(BlueprintCallable, Category = "WidgetSettings") + void SetWidgetAndInit(TSubclassOf NewWidgetClass); + + void OnLevelRemovedFromWorld(ULevel* InLevel, UWorld* InWorld); + void InitWidget(); + void RenderWidget(float DeltaTime); + void ReleaseResources(); +}; + + +/** +* A widget component that displays the widget in a stereo layer instead of in worldspace. +* Currently this class uses a custom postion instead of the engines WorldLocked for stereo layers +* This is because world locked stereo layers don't account for player movement currently. +*/ +UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = (VRExpansionPlugin)) +class VREXPANSIONPLUGIN_API UVRStereoWidgetComponent : public UWidgetComponent +{ + GENERATED_BODY() + +public: + UVRStereoWidgetComponent(const FObjectInitializer& ObjectInitializer); + + friend class FStereoLayerComponentVisualizer; + + ~UVRStereoWidgetComponent(); + + + /** Specifies which shape of layer it is. Note that some shapes will be supported only on certain platforms! **/ + UPROPERTY(EditAnywhere, BlueprintReadOnly, NoClear, Instanced, Category = "StereoLayer", DisplayName = "Stereo Layer Shape") + TObjectPtr Shape; + + void BeginDestroy() override; + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + void OnUnregister() override; + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; + virtual void DrawWidgetToRenderTarget(float DeltaTime) override; + virtual TStructOnScope GetComponentInstanceData() const override; + void ApplyVRComponentInstanceData(class FVRStereoWidgetComponentInstanceData* WidgetInstanceData); + + virtual void UpdateRenderTarget(FIntPoint DesiredRenderTargetSize) override; + virtual FPrimitiveSceneProxy* CreateSceneProxy() override; + + + /** If true then this stereo widget will skip visibility checks when in stereo mode */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "StereoLayer") + bool bAlwaysVisible = false; + + // If true forces the widget to render both stereo and world widgets + // Overriden by the console command vr.ForceNoStereoWithVRWidgets if it is set to 1 + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "StereoLayer") + bool bRenderBothStereoAndWorld; + + /** Forces the widget to skip stereo regardless of all other settings (localized version of vr.ForceNoStereoWithVRWidgets)*/ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "StereoLayer") + bool bDrawWithoutStereo; + + // If true, use Epics world locked stereo implementation instead of my own temp solution + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "StereoLayer") + bool bUseEpicsWorldLockedStereo; + + // If true, will cache and delay the transform adjustment for one frame in order to sync with the game thread better + // Not for use with late updated parents. + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "StereoLayer") + bool bDelayForRenderThread; + + // If true will not render or update until false + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "StereoLayer") + bool bIsSleeping; + + /** + * Change the layer's render priority, higher priorities render on top of lower priorities + * @param InPriority: Priority value + */ + UFUNCTION(BlueprintCallable, Category = "Components|Stereo Layer") + void SetPriority(int32 InPriority); + + // @return the render priority + UFUNCTION(BlueprintCallable, Category = "Components|Stereo Layer") + int32 GetPriority() const { return Priority; } + + /** True if the stereo layer needs to support depth intersections with the scene geometry, if available on the platform */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "StereoLayer") + uint32 bSupportsDepth : 1; + + /** True if the texture should not use its own alpha channel (1.0 will be substituted) */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "StereoLayer") + uint32 bNoAlphaChannel : 1; + + /** True if the quad should internally set it's Y value based on the set texture's dimensions */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "StereoLayer") + uint32 bQuadPreserveTextureRatio : 1; + + /** Additional flags not included in IStereoLayers::ELayerFlags */ + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "StereoLayer", Meta = (GetOptions = "EditorFlagCollector.GetFlagNames")) + TArray AdditionalFlags; + +protected: + /** Texture displayed on the stereo layer (is stereocopic textures are supported on the platfrom and more than one texture is provided, this will be the right eye) **/ + //UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "StereoLayer") + // class UTexture* Texture; + + // Forget left texture implementation + /** Texture displayed on the stereo layer for left eye, if stereoscopic textures are supported on the platform **/ + //UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "StereoLayer | Cubemap Overlay Properties") + // class UTexture* LeftTexture; + +public: + /** Size of the rendered stereo layer quad **/ + //UPROPERTY(EditAnywhere, BlueprintReadOnly, export, Category = "StereoLayer | Quad Overlay Properties") + // FVector2D StereoLayerQuadSize; + + /** UV coordinates mapped to the quad face **/ + //UPROPERTY(EditAnywhere, BlueprintReadOnly, export, Category = "StereoLayer | Quad Overlay Properties") + FBox2D UVRect; + + /** Radial size of the rendered stereo layer cylinder **/ + //UPROPERTY(EditAnywhere, BlueprintReadOnly, export, Category = "StereoLayer | Cylinder Overlay Properties") + // float CylinderRadius; + + /** Arc angle for the stereo layer cylinder **/ + //UPROPERTY(EditAnywhere, BlueprintReadOnly, export, Category = "StereoLayer | Cylinder Overlay Properties") + //float CylinderOverlayArc; + + /** Height of the stereo layer cylinder **/ + ///UPROPERTY(EditAnywhere, BlueprintReadOnly, export, Category = "StereoLayer | Cylinder Overlay Properties") + // int CylinderHeight; + + /** Specifies how and where the quad is rendered to the screen **/ + //UPROPERTY(EditAnywhere, BlueprintReadOnly, export, Category = "StereoLayer") + //TEnumAsByte StereoLayerType; + + // Forcing quad layer so that it works with the widget better + /** Specifies which type of layer it is. Note that some shapes will be supported only on certain platforms! **/ + //UPROPERTY(EditAnywhere, BlueprintReadOnly, export, Category = "StereoLayer") + // TEnumAsByte StereoLayerShape; + + /** Render priority among all stereo layers, higher priority render on top of lower priority **/ + UPROPERTY(EditAnywhere, BlueprintReadOnly, export, Category = "StereoLayer") + int32 Priority; + + /** IStereoLayer id, 0 is unassigned **/ + uint32 LayerId; + + bool bShouldCreateProxy; + +private: + /** Dirty state determines whether the stereo layer needs updating **/ + bool bIsDirty; + bool bDirtyRenderTarget; + + /** Texture needs to be marked for update **/ + bool bTextureNeedsUpdate; + + /** Last transform is cached to determine if the new frames transform has changed **/ + FTransform LastTransform; + + /** Last frames visiblity state **/ + bool bLastVisible; + +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRTrackedParentInterface.h b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRTrackedParentInterface.h new file mode 100644 index 0000000..ae9dbd2 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/Public/VRTrackedParentInterface.h @@ -0,0 +1,32 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "VRBPDatatypes.h" +#include "UObject/Interface.h" + +#include "VRTrackedParentInterface.generated.h" + +UINTERFACE(MinimalAPI, meta = (CannotImplementInterfaceInBlueprint)) +class UVRTrackedParentInterface: public UInterface +{ + GENERATED_UINTERFACE_BODY() +}; + + +class VREXPANSIONPLUGIN_API IVRTrackedParentInterface +{ + GENERATED_IINTERFACE_BODY() + +public: + + // Set a tracked parent + UFUNCTION(BlueprintCallable, Category = "VRTrackedParentInterface") + virtual void SetTrackedParent(UPrimitiveComponent * NewParentComponent, float WaistRadius, EBPVRWaistTrackingMode WaistTrackingMode) + {} + + static void Default_SetTrackedParent_Impl(UPrimitiveComponent * NewParentComponent, float WaistRadius, EBPVRWaistTrackingMode WaistTrackingMode, FBPVRWaistTracking_Info & OptionalWaistTrackingParent, USceneComponent * Self); + + // Returns local transform of the parent relative attachment + static FTransform Default_GetWaistOrientationAndPosition(FBPVRWaistTracking_Info & WaistTrackingInfo); +}; \ No newline at end of file diff --git a/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/VRExpansionPlugin.Build.cs b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/VRExpansionPlugin.Build.cs new file mode 100644 index 0000000..f065a80 --- /dev/null +++ b/Plugins/VRExpansionPlugin/Source/VRExpansionPlugin/VRExpansionPlugin.Build.cs @@ -0,0 +1,120 @@ +// Some copyright should be here... +using System.IO; +using UnrealBuildTool; + +public class VRExpansionPlugin : ModuleRules +{ + private string PluginsPath + { + get { return Path.GetFullPath(Target.RelativeEnginePath) + "Plugins/Runtime/"; } + } + + public VRExpansionPlugin(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; + //bEnforceIWYU = true; + + PublicDefinitions.Add("WITH_VR_EXPANSION=1"); + SetupIrisSupport(Target); + + // To detect VR Preview, not built out in packaged builds + if (Target.bBuildEditor == true) + { + PrivateDependencyModuleNames.AddRange( + new string[] { + "UnrealEd" + } + ); + } + + PrivateIncludePathModuleNames.AddRange( + new string[] { + "Settings" + } + ); + + PublicIncludePaths.AddRange( + new string[] { + //"VRExpansionPlugin/Public", + //"VRExpansionPlugin/Public/SimpleChar", + //"HeadMountedDisplay/Public", + //"Runtime/Engine/Private/PhysicsEngine" + + // ... add public include paths required here ... + } + ); + + PrivateIncludePaths.AddRange( + new string[] { + //"VRExpansionPlugin/Private", + //"VRExpansionPlugin/Private/SimpleChar", + // ... add other private include paths required here ... + } + ); + + PublicDependencyModuleNames.AddRange( + new string[] + { + "Core", + "NetCore", + "CoreUObject", + "Engine", + "PhysicsCore", + "HeadMountedDisplay", + "UMG", + "NavigationSystem", + "AIModule", + "AnimGraphRuntime", + "XRBase", + "GameplayTags", + "Mover" + }); + + //if(Target.bUseChaos) + // { + PublicDependencyModuleNames.Add("Chaos"); + PublicDependencyModuleNames.Add("ChaosVehicles"); + //} + + PrivateDependencyModuleNames.AddRange( + new string[] + { + // "Core", + // "CoreUObject", + //"Engine", + "InputCore", + //"FLEX", remove comment if building in the NVIDIA flex branch - NOTE when put in place FLEX only listed win32 and win64 at compatible platforms + //"HeadMountedDisplay", + "RHI", + "ApplicationCore", + "RenderCore", + // "ShaderCore", + "NetworkReplayStreaming" + //"Renderer", + // "UtilityShaders" + }); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + //"CoreUObject", + //"Engine", + "Slate", + "SlateCore" + + // ... add private dependencies that you statically link with here ... + } + ); + + // Allow gameplay debugger on editor builds + if (Target.bBuildDeveloperTools || (Target.Configuration != UnrealTargetConfiguration.Shipping && Target.Configuration != UnrealTargetConfiguration.Test)) + { + PrivateDependencyModuleNames.Add("GameplayDebugger"); + PublicDefinitions.Add("WITH_GAMEPLAY_DEBUGGER=1"); // Already in AI Module, but gameplay abilities and other modules also duplicate the definition + } + else + { + PublicDefinitions.Add("WITH_GAMEPLAY_DEBUGGER=0"); + } + } +} diff --git a/Plugins/VRExpansionPlugin/VRExpansionPlugin.uplugin b/Plugins/VRExpansionPlugin/VRExpansionPlugin.uplugin new file mode 100644 index 0000000..cb68065 --- /dev/null +++ b/Plugins/VRExpansionPlugin/VRExpansionPlugin.uplugin @@ -0,0 +1,50 @@ +{ + "FileVersion": 3, + "Version": 5.4, + "VersionName": "5.4", + "FriendlyName": "VRExpansionPlugin", + "Description": "Adds several new VR features & components to UE4", + "Category": "VRExpansion", + "CreatedBy": "Joshua (MordenTral) Statzer", + "CreatedByURL": "http://www.vreue4.com", + "DocsURL": "http://www.vreue4.com", + "MarketplaceURL": "", + "SupportURL": "", + "EnabledByDefault": true, + "CanContainContent": false, + "IsBetaVersion": false, + "Installed": true, + "SupportedTargetPlatforms": [ + "Win64", + "Linux", + "Android", + "Mac", + "IOS" + ], + "Modules": [ + { + "Name": "VRExpansionPlugin", + "Type": "RunTime", + "LoadingPhase": "Default" + }, + { + "Name": "VRExpansionEditor", + "Type": "UnCookedOnly", + "LoadingPhase": "PostEngineInit" + } + ], + "Plugins": [ + { + "Name": "ChaosVehiclesPlugin", + "Enabled": true + }, + { + "Name": "XRBase", + "Enabled": true + }, + { + "Name": "Mover", + "Enabled": true + } + ] +} \ No newline at end of file diff --git a/SGVRETemplate.uproject b/SGVRETemplate.uproject new file mode 100644 index 0000000..deec442 --- /dev/null +++ b/SGVRETemplate.uproject @@ -0,0 +1,149 @@ +{ + "FileVersion": 3, + "EngineAssociation": "5.4", + "Category": "", + "Description": "", + "Modules": [ + { + "Name": "SGVRETemplate", + "Type": "Runtime", + "LoadingPhase": "Default" + } + ], + "Plugins": [ + { + "Name": "SenseGlove", + "Enabled": true, + "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/5e1d408f517b4966a269ec1035de0b9e", + "SupportedTargetPlatforms": [ + "Android", + "Linux", + "Win64" + ] + }, + { + "Name": "AdvancedSessions", + "Enabled": true + }, + { + "Name": "AdvancedSteamSessions", + "Enabled": true + }, + { + "Name": "ChaosVehiclesPlugin", + "Enabled": true + }, + { + "Name": "Mover", + "Enabled": true + }, + { + "Name": "MoverExamples", + "Enabled": true + }, + { + "Name": "OculusXR", + "Enabled": false, + "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/8313d8d7e7cf4e03a33e79eb757bccba", + "SupportedTargetPlatforms": [ + "Win64", + "Android" + ] + }, + { + "Name": "OnlineSubsystem", + "Enabled": true + }, + { + "Name": "OnlineSubsystemSteam", + "Enabled": true + }, + { + "Name": "OnlineSubsystemUtils", + "Enabled": true + }, + { + "Name": "OpenXR", + "Enabled": true, + "SupportedTargetPlatforms": [ + "Win64", + "Linux", + "Android", + "VisionOS" + ] + }, + { + "Name": "OpenXRExpansionPlugin", + "Enabled": true, + "SupportedTargetPlatforms": [ + "Win64", + "Linux", + "Android", + "Mac", + "IOS" + ] + }, + { + "Name": "OpenXRHandTracking", + "Enabled": false, + "SupportedTargetPlatforms": [ + "Win64", + "Linux", + "Android", + "HoloLens" + ] + }, + { + "Name": "OpenXRViveTracker", + "Enabled": false, + "SupportedTargetPlatforms": [ + "Win64", + "Linux", + "Android" + ] + }, + { + "Name": "SteamShared", + "Enabled": true + }, + { + "Name": "SteamVR", + "Enabled": false, + "SupportedTargetPlatforms": [ + "Win32", + "Win64", + "Linux" + ] + }, + { + "Name": "ViveOpenXR", + "Enabled": false, + "SupportedTargetPlatforms": [ + "Win64", + "Android" + ] + }, + { + "Name": "VRExpansionPlugin", + "Enabled": true, + "SupportedTargetPlatforms": [ + "Win64", + "Linux", + "Android", + "Mac", + "IOS" + ] + }, + { + "Name": "XRBase", + "Enabled": true + } + ], + "TargetPlatforms": [ + "PS4", + "WindowsNoEditor", + "Android", + "Windows", + "Linux" + ] +} \ No newline at end of file diff --git a/Source/SGVRETemplate.Target.cs b/Source/SGVRETemplate.Target.cs new file mode 100644 index 0000000..0be0f0f --- /dev/null +++ b/Source/SGVRETemplate.Target.cs @@ -0,0 +1,64 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +using UnrealBuildTool; +using System.Collections.Generic; + +public class SGVRETemplateTarget : TargetRules +{ + public SGVRETemplateTarget(TargetInfo Target) : base(Target) + { + + DefaultBuildSettings = BuildSettingsVersion.Latest; + IncludeOrderVersion = EngineIncludeOrderVersion.Latest; + + // For debugging with push disabled + //bWithPushModel = false; + + //bUseLoggingInShipping = true; + Type = TargetType.Game; + ExtraModuleNames.AddRange(new string[] { "SGVRETemplate" }); + //bUsePCHFiles = false; + //bUseUnityBuild = false; + + /* + * This is our Steam App ID. + * # Define in both server and client targets + */ + ProjectDefinitions.Add("UE_PROJECT_STEAMSHIPPINGID=480"); + + + + /* + * This is used on SetProduct(), and should be the same as your Product Name + * under Dedicated Game Server Information in Steamworks + * # Define in the Server target + */ + //ProjectDefinitions.Add("UE_PROJECT_STEAMPRODUCTNAME=\"MyGame\""); + + /* + * This is used on SetModDir(), and should be the same as your Product Name + * under Dedicated Game Server Information in Steamworks + * # Define in the client target + */ + //ProjectDefinitions.Add("UE_PROJECT_STEAMGAMEDIR=\"MyGame\""); + + /* + * This is what shows up under the game filter in Steam server browsers. + * # Define in both server and client targets + */ + //ProjectDefinitions.Add("UE_PROJECT_STEAMGAMEDESC=\"My Game\""); + } + + // + // TargetRules interface. + // + + /*public override void SetupBinaries( + TargetInfo Target, + ref List OutBuildBinaryConfigurations, + ref List OutExtraModuleNames + ) + { + OutExtraModuleNames.AddRange( new string[] { "SGVRETemplate" } ); + }*/ +} diff --git a/Source/SGVRETemplate/EmptyClassForProject.cpp b/Source/SGVRETemplate/EmptyClassForProject.cpp new file mode 100644 index 0000000..3595ab7 --- /dev/null +++ b/Source/SGVRETemplate/EmptyClassForProject.cpp @@ -0,0 +1,12 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +//#include "SGVRETemplate.h" +#include "EmptyClassForProject.h" + +EmptyClassForProject::EmptyClassForProject() +{ +} + +EmptyClassForProject::~EmptyClassForProject() +{ +} diff --git a/Source/SGVRETemplate/EmptyClassForProject.h b/Source/SGVRETemplate/EmptyClassForProject.h new file mode 100644 index 0000000..17aa02d --- /dev/null +++ b/Source/SGVRETemplate/EmptyClassForProject.h @@ -0,0 +1,27 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "VRCharacter.h" +#include "GripMotionControllerComponent.h" +#include "VRBPDatatypes.h" +#include "VRGripInterface.h" +#include "VRPlayerController.h" +#include "VRExpansionFunctionLibrary.h" +#include "Grippables/GrippableBoxComponent.h" +#include "VRStereoWidgetComponent.h" +#include "VRCharacterMovementComponent.h" +#include "Misc/VRLogComponent.h" +#include "VRAIController.h" +#include "VRPathFollowingComponent.h" +#include "VRRootComponent.h" + +/** + * + */ +class SGVRETEMPLATE_API EmptyClassForProject +{ +public: + EmptyClassForProject(); + ~EmptyClassForProject(); + +}; diff --git a/Source/SGVRETemplate/SGVRETemplate.Build.cs b/Source/SGVRETemplate/SGVRETemplate.Build.cs new file mode 100644 index 0000000..3eca6c4 --- /dev/null +++ b/Source/SGVRETemplate/SGVRETemplate.Build.cs @@ -0,0 +1,27 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +using UnrealBuildTool; + +public class SGVRETemplate : ModuleRules +{ + public SGVRETemplate(ReadOnlyTargetRules Target) : base(Target) + { + + //SetupIrisSupport(Target); + + PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; + // PrivatePCHHeaderFile = "Private/WindowsMixedRealityPrecompiled.h"; + + PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "AdvancedSessions", "VRExpansionPlugin" }); + + PrivateDependencyModuleNames.AddRange(new string[] { }); + + // Uncomment if you are using Slate UI + // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); + + // Uncomment if you are using online features + // PrivateDependencyModuleNames.Add("OnlineSubsystem"); + + // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true + } +} diff --git a/Source/SGVRETemplate/SGVRETemplate.cpp b/Source/SGVRETemplate/SGVRETemplate.cpp new file mode 100644 index 0000000..0d679fd --- /dev/null +++ b/Source/SGVRETemplate/SGVRETemplate.cpp @@ -0,0 +1,5 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#include "SGVRETemplate.h" + +IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, SGVRETemplate, "SGVRETemplate" ); diff --git a/Source/SGVRETemplate/SGVRETemplate.h b/Source/SGVRETemplate/SGVRETemplate.h new file mode 100644 index 0000000..3d85d22 --- /dev/null +++ b/Source/SGVRETemplate/SGVRETemplate.h @@ -0,0 +1,6 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "Engine.h" + diff --git a/Source/SGVRETemplateEditor.Target.cs b/Source/SGVRETemplateEditor.Target.cs new file mode 100644 index 0000000..764cb45 --- /dev/null +++ b/Source/SGVRETemplateEditor.Target.cs @@ -0,0 +1,31 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +using UnrealBuildTool; +using System.Collections.Generic; + +public class SGVRETemplateEditorTarget : TargetRules +{ + public SGVRETemplateEditorTarget(TargetInfo Target) : base(Target) + { + DefaultBuildSettings = BuildSettingsVersion.Latest; // V5 + IncludeOrderVersion = EngineIncludeOrderVersion.Latest; + + Type = TargetType.Editor; + ExtraModuleNames.AddRange(new string[] { "SGVRETemplate" }); + //bUseUnityBuild = false; + //bUsePCHFiles = false; + } + + // + // TargetRules interface. + // + +/* public override void SetupBinaries( + TargetInfo Target, + ref List OutBuildBinaryConfigurations, + ref List OutExtraModuleNames + ) + { + OutExtraModuleNames.AddRange( new string[] { "SGVRETemplate" } ); + }*/ +}