拆分模型加载+UI优化
This commit is contained in:
parent
d9e96b0d69
commit
c5186f75b5
|
@ -950,7 +950,7 @@ MonoBehaviour:
|
||||||
m_Arguments:
|
m_Arguments:
|
||||||
m_ObjectArgument: {fileID: 0}
|
m_ObjectArgument: {fileID: 0}
|
||||||
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||||
m_IntArgument: 5
|
m_IntArgument: 4
|
||||||
m_FloatArgument: 0
|
m_FloatArgument: 0
|
||||||
m_StringArgument:
|
m_StringArgument:
|
||||||
m_BoolArgument: 0
|
m_BoolArgument: 0
|
||||||
|
@ -3499,7 +3499,7 @@ MonoBehaviour:
|
||||||
m_Arguments:
|
m_Arguments:
|
||||||
m_ObjectArgument: {fileID: 0}
|
m_ObjectArgument: {fileID: 0}
|
||||||
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||||
m_IntArgument: 3
|
m_IntArgument: 2
|
||||||
m_FloatArgument: 0
|
m_FloatArgument: 0
|
||||||
m_StringArgument:
|
m_StringArgument:
|
||||||
m_BoolArgument: 0
|
m_BoolArgument: 0
|
||||||
|
@ -5707,6 +5707,140 @@ MonoBehaviour:
|
||||||
keepAlphaValue: 1
|
keepAlphaValue: 1
|
||||||
useCustomColor: 0
|
useCustomColor: 0
|
||||||
colorType: 2
|
colorType: 2
|
||||||
|
--- !u!1 &3587488935766229191
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 8025476141745189055}
|
||||||
|
- component: {fileID: 5565143401225979560}
|
||||||
|
- component: {fileID: 5503859348676013585}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: Text (TMP)
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &8025476141745189055
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3587488935766229191}
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 1975068002469358035}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
m_AnchorMax: {x: 1, y: 1}
|
||||||
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
|
m_SizeDelta: {x: 0, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &5565143401225979560
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3587488935766229191}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &5503859348676013585
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3587488935766229191}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
m_RaycastTarget: 1
|
||||||
|
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_Maskable: 1
|
||||||
|
m_OnCullStateChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_text:
|
||||||
|
m_isRightToLeft: 0
|
||||||
|
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||||
|
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||||
|
m_fontSharedMaterials: []
|
||||||
|
m_fontMaterial: {fileID: 0}
|
||||||
|
m_fontMaterials: []
|
||||||
|
m_fontColor32:
|
||||||
|
serializedVersion: 2
|
||||||
|
rgba: 4281479730
|
||||||
|
m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||||
|
m_enableVertexGradient: 0
|
||||||
|
m_colorMode: 3
|
||||||
|
m_fontColorGradient:
|
||||||
|
topLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
topRight: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
bottomRight: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
m_fontColorGradientPreset: {fileID: 0}
|
||||||
|
m_spriteAsset: {fileID: 0}
|
||||||
|
m_tintAllSprites: 0
|
||||||
|
m_StyleSheet: {fileID: 0}
|
||||||
|
m_TextStyleHashCode: -1183493901
|
||||||
|
m_overrideHtmlColors: 0
|
||||||
|
m_faceColor:
|
||||||
|
serializedVersion: 2
|
||||||
|
rgba: 4294967295
|
||||||
|
m_fontSize: 24
|
||||||
|
m_fontSizeBase: 24
|
||||||
|
m_fontWeight: 400
|
||||||
|
m_enableAutoSizing: 0
|
||||||
|
m_fontSizeMin: 18
|
||||||
|
m_fontSizeMax: 72
|
||||||
|
m_fontStyle: 0
|
||||||
|
m_HorizontalAlignment: 2
|
||||||
|
m_VerticalAlignment: 512
|
||||||
|
m_textAlignment: 65535
|
||||||
|
m_characterSpacing: 0
|
||||||
|
m_wordSpacing: 0
|
||||||
|
m_lineSpacing: 0
|
||||||
|
m_lineSpacingMax: 0
|
||||||
|
m_paragraphSpacing: 0
|
||||||
|
m_charWidthMaxAdj: 0
|
||||||
|
m_enableWordWrapping: 1
|
||||||
|
m_wordWrappingRatios: 0.4
|
||||||
|
m_overflowMode: 0
|
||||||
|
m_linkedTextComponent: {fileID: 0}
|
||||||
|
parentLinkedComponent: {fileID: 0}
|
||||||
|
m_enableKerning: 1
|
||||||
|
m_enableExtraPadding: 0
|
||||||
|
checkPaddingRequired: 0
|
||||||
|
m_isRichText: 1
|
||||||
|
m_parseCtrlCharacters: 1
|
||||||
|
m_isOrthographic: 1
|
||||||
|
m_isCullingEnabled: 0
|
||||||
|
m_horizontalMapping: 0
|
||||||
|
m_verticalMapping: 0
|
||||||
|
m_uvLineOffset: 0
|
||||||
|
m_geometrySortingOrder: 0
|
||||||
|
m_IsTextObjectScaleStatic: 0
|
||||||
|
m_VertexBufferAutoSizeReduction: 0
|
||||||
|
m_useMaxVisibleDescender: 1
|
||||||
|
m_pageToDisplay: 1
|
||||||
|
m_margin: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_isUsingLegacyAnimationComponent: 0
|
||||||
|
m_isVolumetricText: 0
|
||||||
|
m_hasFontAssetChanged: 0
|
||||||
|
m_baseMaterial: {fileID: 0}
|
||||||
|
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
--- !u!1 &3635298159763109128
|
--- !u!1 &3635298159763109128
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -6324,6 +6458,7 @@ RectTransform:
|
||||||
m_Children:
|
m_Children:
|
||||||
- {fileID: 2445187332351384993}
|
- {fileID: 2445187332351384993}
|
||||||
- {fileID: 458346039371182555}
|
- {fileID: 458346039371182555}
|
||||||
|
- {fileID: 1975068002469358035}
|
||||||
m_Father: {fileID: 6472390402513143558}
|
m_Father: {fileID: 6472390402513143558}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
m_AnchorMin: {x: 0, y: 0}
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
@ -7580,7 +7715,7 @@ MonoBehaviour:
|
||||||
m_Arguments:
|
m_Arguments:
|
||||||
m_ObjectArgument: {fileID: 0}
|
m_ObjectArgument: {fileID: 0}
|
||||||
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||||
m_IntArgument: 4
|
m_IntArgument: 3
|
||||||
m_FloatArgument: 0
|
m_FloatArgument: 0
|
||||||
m_StringArgument:
|
m_StringArgument:
|
||||||
m_BoolArgument: 0
|
m_BoolArgument: 0
|
||||||
|
@ -10844,6 +10979,139 @@ CanvasRenderer:
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 8229600306201579037}
|
m_GameObject: {fileID: 8229600306201579037}
|
||||||
m_CullTransparentMesh: 0
|
m_CullTransparentMesh: 0
|
||||||
|
--- !u!1 &8265266211400670364
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1975068002469358035}
|
||||||
|
- component: {fileID: 1474344257591453156}
|
||||||
|
- component: {fileID: 3105870774428680706}
|
||||||
|
- component: {fileID: 4592116318987236448}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: back
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &1975068002469358035
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 8265266211400670364}
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
|
m_LocalScale: {x: 0.5, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children:
|
||||||
|
- {fileID: 8025476141745189055}
|
||||||
|
m_Father: {fileID: 3228235001121865301}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||||
|
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||||
|
m_AnchoredPosition: {x: -832, y: 0}
|
||||||
|
m_SizeDelta: {x: 256, y: 256}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &1474344257591453156
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 8265266211400670364}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &3105870774428680706
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 8265266211400670364}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Color: {r: 0.34509805, g: 0.34509805, b: 0.34509805, a: 1}
|
||||||
|
m_RaycastTarget: 1
|
||||||
|
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_Maskable: 1
|
||||||
|
m_OnCullStateChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_Sprite: {fileID: 21300000, guid: 96b53986fbf913d47864b19cbe98e372, type: 3}
|
||||||
|
m_Type: 0
|
||||||
|
m_PreserveAspect: 0
|
||||||
|
m_FillCenter: 1
|
||||||
|
m_FillMethod: 4
|
||||||
|
m_FillAmount: 1
|
||||||
|
m_FillClockwise: 1
|
||||||
|
m_FillOrigin: 0
|
||||||
|
m_UseSpriteMesh: 0
|
||||||
|
m_PixelsPerUnitMultiplier: 1
|
||||||
|
--- !u!114 &4592116318987236448
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 8265266211400670364}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Navigation:
|
||||||
|
m_Mode: 3
|
||||||
|
m_WrapAround: 0
|
||||||
|
m_SelectOnUp: {fileID: 0}
|
||||||
|
m_SelectOnDown: {fileID: 0}
|
||||||
|
m_SelectOnLeft: {fileID: 0}
|
||||||
|
m_SelectOnRight: {fileID: 0}
|
||||||
|
m_Transition: 1
|
||||||
|
m_Colors:
|
||||||
|
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||||
|
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||||
|
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||||
|
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||||
|
m_ColorMultiplier: 1
|
||||||
|
m_FadeDuration: 0.1
|
||||||
|
m_SpriteState:
|
||||||
|
m_HighlightedSprite: {fileID: 0}
|
||||||
|
m_PressedSprite: {fileID: 0}
|
||||||
|
m_SelectedSprite: {fileID: 0}
|
||||||
|
m_DisabledSprite: {fileID: 0}
|
||||||
|
m_AnimationTriggers:
|
||||||
|
m_NormalTrigger: Normal
|
||||||
|
m_HighlightedTrigger: Highlighted
|
||||||
|
m_PressedTrigger: Pressed
|
||||||
|
m_SelectedTrigger: Selected
|
||||||
|
m_DisabledTrigger: Disabled
|
||||||
|
m_Interactable: 1
|
||||||
|
m_TargetGraphic: {fileID: 3105870774428680706}
|
||||||
|
m_OnClick:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls:
|
||||||
|
- m_Target: {fileID: -5447994580174514295}
|
||||||
|
m_TargetAssemblyTypeName: ActionListUIPanel, Assembly-CSharp
|
||||||
|
m_MethodName: OnBackBtnClicked
|
||||||
|
m_Mode: 1
|
||||||
|
m_Arguments:
|
||||||
|
m_ObjectArgument: {fileID: 0}
|
||||||
|
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||||
|
m_IntArgument: 0
|
||||||
|
m_FloatArgument: 0
|
||||||
|
m_StringArgument:
|
||||||
|
m_BoolArgument: 0
|
||||||
|
m_CallState: 2
|
||||||
--- !u!1 &8275927407155805902
|
--- !u!1 &8275927407155805902
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|
|
@ -88,81 +88,6 @@ CanvasGroup:
|
||||||
m_Interactable: 1
|
m_Interactable: 1
|
||||||
m_BlocksRaycasts: 1
|
m_BlocksRaycasts: 1
|
||||||
m_IgnoreParentGroups: 0
|
m_IgnoreParentGroups: 0
|
||||||
--- !u!1 &1381910008050731583
|
|
||||||
GameObject:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
serializedVersion: 6
|
|
||||||
m_Component:
|
|
||||||
- component: {fileID: 2790109640146298654}
|
|
||||||
- component: {fileID: 2214680058021086237}
|
|
||||||
- component: {fileID: 40271058087427464}
|
|
||||||
m_Layer: 5
|
|
||||||
m_Name: Logo
|
|
||||||
m_TagString: Untagged
|
|
||||||
m_Icon: {fileID: 0}
|
|
||||||
m_NavMeshLayer: 0
|
|
||||||
m_StaticEditorFlags: 0
|
|
||||||
m_IsActive: 1
|
|
||||||
--- !u!224 &2790109640146298654
|
|
||||||
RectTransform:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 1381910008050731583}
|
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
|
||||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
|
||||||
m_ConstrainProportionsScale: 0
|
|
||||||
m_Children: []
|
|
||||||
m_Father: {fileID: 8805156796672989800}
|
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
|
||||||
m_AnchorMin: {x: 0, y: 1}
|
|
||||||
m_AnchorMax: {x: 0, y: 1}
|
|
||||||
m_AnchoredPosition: {x: 20, y: -20}
|
|
||||||
m_SizeDelta: {x: 200, y: 100}
|
|
||||||
m_Pivot: {x: 0, y: 1}
|
|
||||||
--- !u!222 &2214680058021086237
|
|
||||||
CanvasRenderer:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 1381910008050731583}
|
|
||||||
m_CullTransparentMesh: 1
|
|
||||||
--- !u!114 &40271058087427464
|
|
||||||
MonoBehaviour:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 1381910008050731583}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
m_Material: {fileID: 0}
|
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
|
||||||
m_RaycastTarget: 1
|
|
||||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
|
||||||
m_Maskable: 1
|
|
||||||
m_OnCullStateChanged:
|
|
||||||
m_PersistentCalls:
|
|
||||||
m_Calls: []
|
|
||||||
m_Sprite: {fileID: 21300000, guid: eb6f879a267ac444d86df8427a559c97, type: 3}
|
|
||||||
m_Type: 0
|
|
||||||
m_PreserveAspect: 0
|
|
||||||
m_FillCenter: 1
|
|
||||||
m_FillMethod: 4
|
|
||||||
m_FillAmount: 1
|
|
||||||
m_FillClockwise: 1
|
|
||||||
m_FillOrigin: 0
|
|
||||||
m_UseSpriteMesh: 0
|
|
||||||
m_PixelsPerUnitMultiplier: 1
|
|
||||||
--- !u!1 &4327728351019041244
|
--- !u!1 &4327728351019041244
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -194,7 +119,6 @@ RectTransform:
|
||||||
m_Children:
|
m_Children:
|
||||||
- {fileID: 5390399916831871626}
|
- {fileID: 5390399916831871626}
|
||||||
- {fileID: 5279216800401342767}
|
- {fileID: 5279216800401342767}
|
||||||
- {fileID: 2790109640146298654}
|
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
m_AnchorMin: {x: 0, y: 0}
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
|
|
@ -10,6 +10,8 @@ GameObject:
|
||||||
m_Component:
|
m_Component:
|
||||||
- component: {fileID: 7882980980823895129}
|
- component: {fileID: 7882980980823895129}
|
||||||
- component: {fileID: 44101575073041383}
|
- component: {fileID: 44101575073041383}
|
||||||
|
- component: {fileID: 4721913218893670612}
|
||||||
|
- component: {fileID: 262072879874942703}
|
||||||
m_Layer: 5
|
m_Layer: 5
|
||||||
m_Name: HUDRoot
|
m_Name: HUDRoot
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
|
@ -49,6 +51,40 @@ MonoBehaviour:
|
||||||
m_Script: {fileID: 11500000, guid: 685773266ab8a444e9ff5131cde3c8ae, type: 3}
|
m_Script: {fileID: 11500000, guid: 685773266ab8a444e9ff5131cde3c8ae, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
|
--- !u!95 &4721913218893670612
|
||||||
|
Animator:
|
||||||
|
serializedVersion: 7
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 591297386902869668}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_Avatar: {fileID: 0}
|
||||||
|
m_Controller: {fileID: 0}
|
||||||
|
m_CullingMode: 0
|
||||||
|
m_UpdateMode: 0
|
||||||
|
m_ApplyRootMotion: 0
|
||||||
|
m_LinearVelocityBlending: 0
|
||||||
|
m_StabilizeFeet: 0
|
||||||
|
m_AnimatePhysics: 0
|
||||||
|
m_WarningMessage:
|
||||||
|
m_HasTransformHierarchy: 1
|
||||||
|
m_AllowConstantClipSamplingOptimization: 1
|
||||||
|
m_KeepAnimatorStateOnDisable: 0
|
||||||
|
m_WriteDefaultValuesOnDisable: 0
|
||||||
|
--- !u!225 &262072879874942703
|
||||||
|
CanvasGroup:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 591297386902869668}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_Alpha: 1
|
||||||
|
m_Interactable: 1
|
||||||
|
m_BlocksRaycasts: 1
|
||||||
|
m_IgnoreParentGroups: 0
|
||||||
--- !u!1001 &1332753061905480905
|
--- !u!1001 &1332753061905480905
|
||||||
PrefabInstance:
|
PrefabInstance:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -91,7 +127,7 @@ PrefabInstance:
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 224602918499771590, guid: a5c1511e3af132c44b6f11542f709726, type: 3}
|
- target: {fileID: 224602918499771590, guid: a5c1511e3af132c44b6f11542f709726, type: 3}
|
||||||
propertyPath: m_AnchorMax.x
|
propertyPath: m_AnchorMax.x
|
||||||
value: 0
|
value: 0.5
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 224602918499771590, guid: a5c1511e3af132c44b6f11542f709726, type: 3}
|
- target: {fileID: 224602918499771590, guid: a5c1511e3af132c44b6f11542f709726, type: 3}
|
||||||
propertyPath: m_AnchorMax.y
|
propertyPath: m_AnchorMax.y
|
||||||
|
@ -99,7 +135,7 @@ PrefabInstance:
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 224602918499771590, guid: a5c1511e3af132c44b6f11542f709726, type: 3}
|
- target: {fileID: 224602918499771590, guid: a5c1511e3af132c44b6f11542f709726, type: 3}
|
||||||
propertyPath: m_AnchorMin.x
|
propertyPath: m_AnchorMin.x
|
||||||
value: 0
|
value: 0.5
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 224602918499771590, guid: a5c1511e3af132c44b6f11542f709726, type: 3}
|
- target: {fileID: 224602918499771590, guid: a5c1511e3af132c44b6f11542f709726, type: 3}
|
||||||
propertyPath: m_AnchorMin.y
|
propertyPath: m_AnchorMin.y
|
||||||
|
@ -143,7 +179,7 @@ PrefabInstance:
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 224602918499771590, guid: a5c1511e3af132c44b6f11542f709726, type: 3}
|
- target: {fileID: 224602918499771590, guid: a5c1511e3af132c44b6f11542f709726, type: 3}
|
||||||
propertyPath: m_AnchoredPosition.x
|
propertyPath: m_AnchoredPosition.x
|
||||||
value: 230
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 224602918499771590, guid: a5c1511e3af132c44b6f11542f709726, type: 3}
|
- target: {fileID: 224602918499771590, guid: a5c1511e3af132c44b6f11542f709726, type: 3}
|
||||||
propertyPath: m_AnchoredPosition.y
|
propertyPath: m_AnchoredPosition.y
|
||||||
|
|
|
@ -937,7 +937,7 @@ MonoBehaviour:
|
||||||
m_Script: {fileID: 11500000, guid: df35b0c19ca97734e87299a664cea35f, type: 3}
|
m_Script: {fileID: 11500000, guid: df35b0c19ca97734e87299a664cea35f, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
_requestedDeviceName: 1
|
_requestedDeviceName: 2
|
||||||
_requestedWidth: 1280
|
_requestedWidth: 1280
|
||||||
_requestedHeight: 960
|
_requestedHeight: 960
|
||||||
_requestedIsFrontFacing: 0
|
_requestedIsFrontFacing: 0
|
||||||
|
@ -1005,11 +1005,6 @@ MonoBehaviour:
|
||||||
m_Script: {fileID: 11500000, guid: c96807d839ba7554d92494fd6d25bb28, type: 3}
|
m_Script: {fileID: 11500000, guid: c96807d839ba7554d92494fd6d25bb28, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
inpWidth: 416
|
|
||||||
inpHeight: 416
|
|
||||||
confThreshold: 0.35
|
|
||||||
nmsThreshold: 0.6
|
|
||||||
topK: 1000
|
|
||||||
SamplingRate: 0.1
|
SamplingRate: 0.1
|
||||||
--- !u!1 &1680658391
|
--- !u!1 &1680658391
|
||||||
GameObject:
|
GameObject:
|
||||||
|
|
|
@ -3,6 +3,7 @@ using UnityEngine.Rendering;
|
||||||
|
|
||||||
public class Boot : MonoBehaviour
|
public class Boot : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
private bool _isInited = false;
|
||||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen)]
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen)]
|
||||||
public static void StopLogo()
|
public static void StopLogo()
|
||||||
{
|
{
|
||||||
|
@ -19,13 +20,20 @@ public class Boot : MonoBehaviour
|
||||||
Screen.sleepTimeout = SleepTimeout.NeverSleep;
|
Screen.sleepTimeout = SleepTimeout.NeverSleep;
|
||||||
//设置屏幕方向
|
//设置屏幕方向
|
||||||
Screen.orientation = ScreenOrientation.LandscapeLeft;
|
Screen.orientation = ScreenOrientation.LandscapeLeft;
|
||||||
|
_isInited = UIManager.IsInited;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
{
|
{
|
||||||
//加载
|
//加载
|
||||||
UIManager.Instance.Init();
|
//UIManager.Instance.Init();
|
||||||
UIManager.Instance.ShowPanel<SplashUI>();
|
if (!_isInited)
|
||||||
|
UIManager.Instance.ShowPanel<SplashUI>();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UIManager.Instance.LoadReset();
|
||||||
|
UIManager.Instance.ShowPanel<MainUIPanel>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update is called once per frame
|
// Update is called once per frame
|
||||||
|
|
|
@ -1,214 +0,0 @@
|
||||||
using OpenCVForUnity.CoreModule;
|
|
||||||
using OpenCVForUnity.DnnModule;
|
|
||||||
using OpenCVForUnity.ImgprocModule;
|
|
||||||
using OpenCVForUnity.UnityUtils;
|
|
||||||
using OpenCVForUnity.UnityUtils.Helper;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
using UnityEngine;
|
|
||||||
using Yoga;
|
|
||||||
|
|
||||||
public class CVEstimator : Singleton<CVEstimator>
|
|
||||||
{
|
|
||||||
private bool isInited = false;
|
|
||||||
|
|
||||||
public bool IsInited { get => isInited; private set => isInited = value; }
|
|
||||||
public bool IsRunning { get; private set; }
|
|
||||||
|
|
||||||
private Thread _mainThread;
|
|
||||||
private Thread _estimateThread;
|
|
||||||
|
|
||||||
private static readonly TimeSpan _refreshRate = TimeSpan.FromSeconds(1 / 30);
|
|
||||||
|
|
||||||
public void Init(params object[] args)
|
|
||||||
{
|
|
||||||
if (IsInited)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_mainThread != null)
|
|
||||||
{
|
|
||||||
_mainThread.Abort();
|
|
||||||
_mainThread = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//先用YOLOv7检测人体,再用OpenPose检测人体姿态
|
|
||||||
if (args.Length < 2)
|
|
||||||
throw new ArgumentException("CVEstimator.Init: args.Length < 2");
|
|
||||||
|
|
||||||
_objectDetector = args[0] as YOLOv7ObjectDetector;
|
|
||||||
if (_objectDetector == null)
|
|
||||||
throw new ArgumentException("CVEstimator.Init: args[0] is not YOLOv7ObjectDetector");
|
|
||||||
|
|
||||||
_openPoseModel = args[1] as KeypointsModel;
|
|
||||||
if (_openPoseModel == null)
|
|
||||||
throw new ArgumentException("CVEstimator.Init: args[1] is not KeypointsModel");
|
|
||||||
|
|
||||||
_mainThread = new Thread(new ThreadStart(MainThread));
|
|
||||||
_mainThread.Start();
|
|
||||||
|
|
||||||
IsInited = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StartEstimation()
|
|
||||||
{
|
|
||||||
if (!IsInited)
|
|
||||||
{
|
|
||||||
Debug.LogError("CVEstimator is not inited. ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_estimateThread.Start();
|
|
||||||
if (IsRunning)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
IsRunning = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if (!IsInited)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
IsRunning = false;
|
|
||||||
_estimateThread.Abort();
|
|
||||||
_mainThread.Abort();
|
|
||||||
IsInited = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private YOLOv7ObjectDetector _objectDetector;
|
|
||||||
public int inpWidth = 416;
|
|
||||||
public int inpHeight = 416;
|
|
||||||
public float confThreshold = 0.35f;
|
|
||||||
public float nmsThreshold = 0.6f;
|
|
||||||
public int topK = 1000;
|
|
||||||
private double threshold = 0.5;
|
|
||||||
|
|
||||||
private Net _net;
|
|
||||||
private KeypointsModel _openPoseModel;
|
|
||||||
|
|
||||||
private void MainThread()
|
|
||||||
{
|
|
||||||
//加载模型
|
|
||||||
Utils.setDebugMode(true); //打印日志
|
|
||||||
//解析数据
|
|
||||||
_estimateThread = new Thread(new ThreadStart(Estimation));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Estimation()
|
|
||||||
{
|
|
||||||
DateTime startTime = DateTime.Now;
|
|
||||||
Mat bgrMat = new Mat();
|
|
||||||
while (IsRunning)
|
|
||||||
{
|
|
||||||
if (_objectDetector == null)
|
|
||||||
{
|
|
||||||
Debug.LogWarning("ObjectDetector is not ready. ");
|
|
||||||
IsRunning = false; //停止检测
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取数据
|
|
||||||
Mat rgbaMat = MotionCaptureManager.Instance.RgbaMat;
|
|
||||||
if (rgbaMat == null)
|
|
||||||
{
|
|
||||||
Debug.Log("WebCamTexture is null. ");
|
|
||||||
Debug.Log("Re-Estimation.");
|
|
||||||
continue; //重新检测
|
|
||||||
}
|
|
||||||
|
|
||||||
Imgproc.cvtColor(rgbaMat, bgrMat, Imgproc.COLOR_RGBA2BGR);
|
|
||||||
Mat results = _objectDetector.infer(bgrMat);
|
|
||||||
var voloResultBox = new List<float[]>();
|
|
||||||
bool hasValidObject = false;
|
|
||||||
for (int i = results.rows() - 1; i >= 0; --i)
|
|
||||||
{
|
|
||||||
float[] box = new float[4];
|
|
||||||
results.get(i, 0, box); //方框
|
|
||||||
float[] conf = new float[1];
|
|
||||||
results.get(i, 4, conf); //检测数据
|
|
||||||
float[] cls = new float[1];
|
|
||||||
results.get(i, 5, cls); //类别
|
|
||||||
|
|
||||||
if (!IsObjectValid(box, conf, cls, rgbaMat))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
hasValidObject = true;
|
|
||||||
voloResultBox.Clear();
|
|
||||||
voloResultBox.Add(box);
|
|
||||||
voloResultBox.Add(conf);
|
|
||||||
voloResultBox.Add(cls);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasValidObject) //没有检测到人体
|
|
||||||
{
|
|
||||||
Debug.Log("No person block found. Re-Estimation.");
|
|
||||||
continue; //重新检测
|
|
||||||
}
|
|
||||||
//更新人物框检测结果
|
|
||||||
MotionCaptureManager.Instance.VoloResult = voloResultBox;
|
|
||||||
|
|
||||||
OpenCVForUnity.CoreModule.Rect roiRect = new OpenCVForUnity.CoreModule.Rect(
|
|
||||||
(int)voloResultBox[0][0],
|
|
||||||
(int)voloResultBox[0][1],
|
|
||||||
Math.Abs((int)(voloResultBox[0][2] - voloResultBox[0][0])),
|
|
||||||
Math.Abs((int)(voloResultBox[0][3] - voloResultBox[0][1])));
|
|
||||||
|
|
||||||
if (roiRect.y < 0 || //0 <= _rowRange.start
|
|
||||||
(roiRect.y + roiRect.height) < roiRect.y || // _rowRange.start <= _rowRange.end
|
|
||||||
bgrMat.rows() < (roiRect.y + roiRect.height)) //_rowRange.end <= m.rows
|
|
||||||
continue; //重新检测
|
|
||||||
|
|
||||||
Mat personRectImg = new Mat(bgrMat, roiRect);//获取人体区域
|
|
||||||
List<Point> points = _openPoseModel.estimate(personRectImg, (float)threshold).toList();
|
|
||||||
//将人体区域的坐标转换为原图坐标
|
|
||||||
for (int j = 0; j < points.Count; j++)
|
|
||||||
{
|
|
||||||
if (points[j] == null ||
|
|
||||||
(points[j].x == -1 && points[j].y == -1)) //没找到的点,跳过
|
|
||||||
continue;
|
|
||||||
|
|
||||||
points[j].x += roiRect.x;
|
|
||||||
points[j].y += roiRect.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!YogaManager.Instance.ActionCheckPoints(points))
|
|
||||||
{
|
|
||||||
Debug.Log("ActionCheckPoints failed. Re-Estimation.");
|
|
||||||
continue; //重新检测
|
|
||||||
}
|
|
||||||
|
|
||||||
//更新关键点位检测结果
|
|
||||||
MotionCaptureManager.Instance.CurrPersonPoints = points;
|
|
||||||
|
|
||||||
//等待到下一个更新周期
|
|
||||||
if (DateTime.Now - startTime > _refreshRate)
|
|
||||||
{
|
|
||||||
startTime = DateTime.Now;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Thread.Sleep(_refreshRate - (DateTime.Now - startTime));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bgrMat.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsObjectValid(float[] box, float[] confidence, float[] classID, Mat rgbaMat)
|
|
||||||
{
|
|
||||||
if ((int)classID[0] != 0 || confidence[0] < 0.8f) //只检测人体,且置信度大于80%
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//是否满足主驾/副驾的位置条件
|
|
||||||
float width = rgbaMat.width();
|
|
||||||
//获取矩形的中点
|
|
||||||
float centerX = (box[0] + box[2]) / 2;
|
|
||||||
//左边副驾驶,右边主驾驶
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5dfab41ece4615444a5c6384f28728eb
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,144 @@
|
||||||
|
using OpenCVForUnity.CoreModule;
|
||||||
|
using OpenCVForUnity.DnnModule;
|
||||||
|
using OpenCVForUnity.ImgprocModule;
|
||||||
|
using OpenCVForUnity.UnityUtils;
|
||||||
|
using OpenCVForUnity.UnityUtils.Helper;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using UnityEngine;
|
||||||
|
using Yoga;
|
||||||
|
|
||||||
|
public class CVEstimator : Singleton<CVEstimator>
|
||||||
|
{
|
||||||
|
private bool isInited = false;
|
||||||
|
|
||||||
|
public bool IsInited { get => isInited; private set => isInited = value; }
|
||||||
|
public bool IsRunning { get; private set; }
|
||||||
|
|
||||||
|
private Thread _mainThread;
|
||||||
|
private Thread _estimateThread;
|
||||||
|
|
||||||
|
private static readonly TimeSpan _refreshRate = TimeSpan.FromSeconds(1 / 30);
|
||||||
|
|
||||||
|
//public int inpWidth = 416;
|
||||||
|
//public int inpHeight = 416;
|
||||||
|
//public float confThreshold = 0.35f;
|
||||||
|
//public float nmsThreshold = 0.6f;
|
||||||
|
//public int topK = 1000;
|
||||||
|
//private double threshold = 0.5;
|
||||||
|
|
||||||
|
private Net _net;
|
||||||
|
private KeypointsModel _openPoseModel;
|
||||||
|
|
||||||
|
public void Init(params object[] args)
|
||||||
|
{
|
||||||
|
if (IsInited)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_mainThread != null)
|
||||||
|
{
|
||||||
|
_mainThread.Abort();
|
||||||
|
_mainThread = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//先用YOLOv7检测人体,再用OpenPose检测人体姿态
|
||||||
|
//if (args.Length < 1)
|
||||||
|
// throw new ArgumentException("CVEstimator.Init: args.Length < 2");
|
||||||
|
|
||||||
|
//_objectDetector = args[0] as YOLOv7ObjectDetector;
|
||||||
|
//if (_objectDetector == null)
|
||||||
|
// throw new ArgumentException("CVEstimator.Init: args[0] is not YOLOv7ObjectDetector");
|
||||||
|
|
||||||
|
//_openPoseModel = args[1] as KeypointsModel;
|
||||||
|
//if (_openPoseModel == null)
|
||||||
|
// throw new ArgumentException("CVEstimator.Init: args[1] is not KeypointsModel");
|
||||||
|
|
||||||
|
_mainThread = new Thread(new ThreadStart(MainThread));
|
||||||
|
_mainThread.Start();
|
||||||
|
|
||||||
|
IsInited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartEstimation()
|
||||||
|
{
|
||||||
|
if (!IsInited)
|
||||||
|
{
|
||||||
|
Debug.LogError("CVEstimator is not inited. ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_estimateThread.Start();
|
||||||
|
if (IsRunning)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
IsRunning = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (!IsInited)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
IsRunning = false;
|
||||||
|
_estimateThread.Abort();
|
||||||
|
_mainThread.Abort();
|
||||||
|
IsInited = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MainThread()
|
||||||
|
{
|
||||||
|
//加载模型
|
||||||
|
Utils.setDebugMode(true); //打印日志
|
||||||
|
//解析数据
|
||||||
|
_estimateThread = new Thread(new ThreadStart(Estimation));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Estimation()
|
||||||
|
{
|
||||||
|
DateTime startTime = DateTime.Now;
|
||||||
|
Mat bgrMat = new Mat();
|
||||||
|
|
||||||
|
while (IsRunning)
|
||||||
|
{
|
||||||
|
Mat rgbaMat = MotionCaptureManager.Instance.RgbaMat;
|
||||||
|
if (rgbaMat == null)
|
||||||
|
{
|
||||||
|
Debug.Log("WebCamTexture is null. ");
|
||||||
|
Debug.Log("Re-Estimation.");
|
||||||
|
continue; //重新检测
|
||||||
|
}
|
||||||
|
Imgproc.cvtColor(rgbaMat, bgrMat, Imgproc.COLOR_RGBA2BGR);
|
||||||
|
|
||||||
|
if (!YogaManager.Instance.CurrentEstimator.TryGetROIRegionMat(rgbaMat, bgrMat, out List<float[]> voloResultBox))
|
||||||
|
{
|
||||||
|
continue; //重新检测
|
||||||
|
}
|
||||||
|
|
||||||
|
//更新人物框检测结果
|
||||||
|
MotionCaptureManager.Instance.VoloResult = voloResultBox;
|
||||||
|
|
||||||
|
if (!YogaManager.Instance.CurrentEstimator.Esitmate(bgrMat, voloResultBox, out List<Point> points))
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Pose estimation failed. Re-Estimating.");
|
||||||
|
continue; //重新检测
|
||||||
|
}
|
||||||
|
|
||||||
|
//更新关键点位检测结果
|
||||||
|
MotionCaptureManager.Instance.CurrPersonPoints = points;
|
||||||
|
|
||||||
|
//等待到下一个更新周期
|
||||||
|
if (DateTime.Now - startTime > _refreshRate)
|
||||||
|
{
|
||||||
|
startTime = DateTime.Now;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Thread.Sleep(_refreshRate - (DateTime.Now - startTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bgrMat.Dispose();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
using OpenCVForUnity.CoreModule;
|
||||||
|
using OpenCVForUnity.ImgprocModule;
|
||||||
|
using OpenCVForUnity.UnityUtils;
|
||||||
|
using OpenCVForUnity.UnityUtils.Helper;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using Yoga;
|
||||||
|
|
||||||
|
public abstract class Estimator
|
||||||
|
{
|
||||||
|
private YOLOv7ObjectDetector _objectDetector;
|
||||||
|
public int inpWidth = 416;
|
||||||
|
public int inpHeight = 416;
|
||||||
|
public float confThreshold = 0.35f;
|
||||||
|
public float nmsThreshold = 0.6f;
|
||||||
|
public int topK = 1000;
|
||||||
|
|
||||||
|
//初始化
|
||||||
|
public void Init()
|
||||||
|
{
|
||||||
|
_objectDetector = new YOLOv7ObjectDetector(
|
||||||
|
Utils.getFilePath("OpenCVForUnity/dnn/yolov7-tiny.weights"),
|
||||||
|
Utils.getFilePath("OpenCVForUnity/dnn/yolov7-tiny.cfg"),
|
||||||
|
Utils.getFilePath("OpenCVForUnity/dnn/coco.names"),
|
||||||
|
new Size(inpWidth, inpHeight), confThreshold, nmsThreshold/*, topK*/);
|
||||||
|
|
||||||
|
InitModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void InitModel();
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
DisposeModel();
|
||||||
|
}
|
||||||
|
public abstract void DisposeModel();
|
||||||
|
|
||||||
|
//检测到的人体框 默认使用VOLO7
|
||||||
|
public virtual bool TryGetROIRegionMat(Mat rgbaMat, Mat bgrMat, out List<float[]> voloResult)
|
||||||
|
{
|
||||||
|
voloResult = null;
|
||||||
|
if (_objectDetector == null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("ObjectDetector is not ready. ");
|
||||||
|
return false; //重新检测
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取数据
|
||||||
|
Mat results = _objectDetector.infer(bgrMat);
|
||||||
|
var voloResultBox = new List<float[]>();
|
||||||
|
bool hasValidObject = false;
|
||||||
|
for (int i = results.rows() - 1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
float[] box = new float[4];
|
||||||
|
results.get(i, 0, box); //方框
|
||||||
|
float[] conf = new float[1];
|
||||||
|
results.get(i, 4, conf); //检测数据
|
||||||
|
float[] cls = new float[1];
|
||||||
|
results.get(i, 5, cls); //类别
|
||||||
|
|
||||||
|
if (!IsObjectValid(box, conf, cls, rgbaMat))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
hasValidObject = true;
|
||||||
|
voloResultBox.Clear();
|
||||||
|
voloResultBox.Add(box);
|
||||||
|
voloResultBox.Add(conf);
|
||||||
|
voloResultBox.Add(cls);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValidObject) //没有检测到人体
|
||||||
|
{
|
||||||
|
Debug.Log("No person block found. Re-Estimation.");
|
||||||
|
return false; //重新检测
|
||||||
|
}
|
||||||
|
|
||||||
|
voloResult = voloResultBox;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected bool IsObjectValid(float[] box, float[] confidence, float[] classID, Mat rgbaMat)
|
||||||
|
{
|
||||||
|
if ((int)classID[0] != 0 || confidence[0] < 0.8f) //只检测人体,且置信度大于80%
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//是否满足主驾/副驾的位置条件
|
||||||
|
float width = rgbaMat.width();
|
||||||
|
//获取矩形的中点
|
||||||
|
float centerX = (box[0] + box[2]) / 2;
|
||||||
|
//左边副驾驶,右边主驾驶
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DebugPrintObjectLayout(Mat image, float[] box, float[] conf, float[] cls, bool isRGB = false)
|
||||||
|
{
|
||||||
|
|
||||||
|
float left = box[0];
|
||||||
|
float top = box[1];
|
||||||
|
float right = box[2];
|
||||||
|
float bottom = box[3];
|
||||||
|
int classId = (int)cls[0];
|
||||||
|
|
||||||
|
Scalar c = _objectDetector.palette[classId % _objectDetector.palette.Count];
|
||||||
|
Scalar color = isRGB ? c : new Scalar(c.val[2], c.val[1], c.val[0], c.val[3]);
|
||||||
|
|
||||||
|
Imgproc.rectangle(image, new Point(left, top), new Point(right, bottom), color, 2);
|
||||||
|
|
||||||
|
string label = String.Format("{0:0.00}", conf[0]);
|
||||||
|
if (_objectDetector.classNames != null && _objectDetector.classNames.Count != 0)
|
||||||
|
{
|
||||||
|
if (classId < (int)_objectDetector.classNames.Count)
|
||||||
|
{
|
||||||
|
label = _objectDetector.classNames[classId] + " " + label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] baseLine = new int[1];
|
||||||
|
Size labelSize = Imgproc.getTextSize(label, Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, 1, baseLine);
|
||||||
|
|
||||||
|
top = Mathf.Max((float)top, (float)labelSize.height);
|
||||||
|
Imgproc.rectangle(image, new Point(left, top - labelSize.height),
|
||||||
|
new Point(left + labelSize.width, top + baseLine[0]), color, Core.FILLED);
|
||||||
|
Imgproc.putText(image, label, new Point(left, top), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, Scalar.all(255), 1, Imgproc.LINE_AA);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract bool Esitmate(Mat bgrMat, List<float[]> voloResultBox, out List<Point> points);
|
||||||
|
|
||||||
|
public virtual void Check(ref Mat img) { }
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9b182376ae5163a4e8f57f947c81ddc1
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,21 @@
|
||||||
|
using OpenCVForUnity.CoreModule;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public class MediaPipeEstimator : Estimator
|
||||||
|
{
|
||||||
|
public override void InitModel()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Esitmate(Mat bgrMat, List<float[]> voloResultBox, out List<Point> points)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DisposeModel()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5218b8c2234cf5145a26a3eb202cafd2
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,89 @@
|
||||||
|
using OpenCVForUnity.CoreModule;
|
||||||
|
using OpenCVForUnity.DnnModule;
|
||||||
|
using OpenCVForUnity.ImgprocModule;
|
||||||
|
using OpenCVForUnity.UnityUtils;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using Yoga;
|
||||||
|
|
||||||
|
public class OpenPoseEsimater : Estimator
|
||||||
|
{
|
||||||
|
KeypointsModel _openPoseModel;
|
||||||
|
private Net _net;
|
||||||
|
|
||||||
|
private double threshold = 0.5;
|
||||||
|
public override void InitModel()
|
||||||
|
{
|
||||||
|
_net = null;
|
||||||
|
var modelFilePath = Utils.getFilePath(YogaConfig.MODEL_PATHS[ModelType.OpenPose]);
|
||||||
|
if (string.IsNullOrEmpty(modelFilePath))
|
||||||
|
{
|
||||||
|
Debug.LogError("modelFilePath is empty. Please copy from “OpenCVForUnity/StreamingAssets/” to “Assets/StreamingAssets/” folder. ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_net = Dnn.readNet(modelFilePath);
|
||||||
|
|
||||||
|
_openPoseModel = new KeypointsModel(_net);
|
||||||
|
_openPoseModel.setInputScale(new Scalar(YogaConfig.InScale));
|
||||||
|
_openPoseModel.setInputSize(new Size(YogaConfig.InWidth, YogaConfig.InHeight));
|
||||||
|
_openPoseModel.setInputMean(new Scalar(YogaConfig.InMean));
|
||||||
|
_openPoseModel.setInputSwapRB(false);
|
||||||
|
_openPoseModel.setInputCrop(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DisposeModel()
|
||||||
|
{
|
||||||
|
if (_net != null)
|
||||||
|
_net.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Esitmate(Mat bgrMat, List<float[]> voloResultBox, out List<Point> points)
|
||||||
|
{
|
||||||
|
points = null;
|
||||||
|
|
||||||
|
if (_openPoseModel == null)
|
||||||
|
throw new ArgumentException("CVEstimator.Init: args[1] is not KeypointsModel")
|
||||||
|
;
|
||||||
|
OpenCVForUnity.CoreModule.Rect roiRect = new OpenCVForUnity.CoreModule.Rect(
|
||||||
|
(int)voloResultBox[0][0],
|
||||||
|
(int)voloResultBox[0][1],
|
||||||
|
Math.Abs((int)(voloResultBox[0][2] - voloResultBox[0][0])),
|
||||||
|
Math.Abs((int)(voloResultBox[0][3] - voloResultBox[0][1])));
|
||||||
|
|
||||||
|
if (roiRect.y < 0 || //0 <= _rowRange.start
|
||||||
|
(roiRect.y + roiRect.height) < roiRect.y || // _rowRange.start <= _rowRange.end
|
||||||
|
bgrMat.rows() < (roiRect.y + roiRect.height)) //_rowRange.end <= m.rows
|
||||||
|
return false; //重新检测
|
||||||
|
|
||||||
|
Mat personRectImg = new Mat(bgrMat, roiRect);//获取人体区域
|
||||||
|
points = _openPoseModel.estimate(personRectImg, (float)threshold).toList();
|
||||||
|
//将人体区域的坐标转换为原图坐标
|
||||||
|
for (int j = 0; j < points.Count; j++)
|
||||||
|
{
|
||||||
|
if (points[j] == null ||
|
||||||
|
(points[j].x == -1 && points[j].y == -1)) //没找到的点,跳过
|
||||||
|
continue;
|
||||||
|
|
||||||
|
points[j].x += roiRect.x;
|
||||||
|
points[j].y += roiRect.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!YogaManager.Instance.ActionCheckPoints(points))
|
||||||
|
{
|
||||||
|
Debug.Log("ActionCheckPoints failed. Re-Estimation.");
|
||||||
|
return false; //重新检测
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Check(ref Mat img)
|
||||||
|
{
|
||||||
|
if (_net == null)
|
||||||
|
{
|
||||||
|
Imgproc.putText(img, "model file is not loaded.", new Point(5, img.rows() - 30), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255), 2, Imgproc.LINE_AA, false);
|
||||||
|
Imgproc.putText(img, "Please read console message.", new Point(5, img.rows() - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255), 2, Imgproc.LINE_AA, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 74f91c9ecee115b44bc9368fe1e41afd
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -1,11 +1,6 @@
|
||||||
#undef DEBUG_MODE
|
using OpenCVForUnity.CoreModule;
|
||||||
#define DEBUG_MODE
|
|
||||||
|
|
||||||
|
|
||||||
using OpenCVForUnity.CoreModule;
|
|
||||||
using OpenCVForUnity.DnnModule;
|
using OpenCVForUnity.DnnModule;
|
||||||
using OpenCVForUnity.ImgprocModule;
|
using OpenCVForUnity.ImgprocModule;
|
||||||
using OpenCVForUnity.ObjdetectModule;
|
|
||||||
using OpenCVForUnity.UnityUtils;
|
using OpenCVForUnity.UnityUtils;
|
||||||
using OpenCVForUnity.UnityUtils.Helper;
|
using OpenCVForUnity.UnityUtils.Helper;
|
||||||
using OpenCVForUnityExample;
|
using OpenCVForUnityExample;
|
||||||
|
@ -26,27 +21,13 @@ namespace Yoga
|
||||||
private bool isInited = false;
|
private bool isInited = false;
|
||||||
private Texture2D texture;
|
private Texture2D texture;
|
||||||
|
|
||||||
private Net _net;
|
|
||||||
private Dictionary<ModelType, KeypointsModel> _models = new Dictionary<ModelType, KeypointsModel>();
|
|
||||||
|
|
||||||
private KeypointsModel _openPoseModel;
|
|
||||||
|
|
||||||
public int inpWidth = 416;
|
|
||||||
public int inpHeight = 416;
|
|
||||||
public float confThreshold = 0.35f;
|
|
||||||
public float nmsThreshold = 0.6f;
|
|
||||||
public int topK = 1000;
|
|
||||||
|
|
||||||
public float SamplingRate = 0.3f;
|
public float SamplingRate = 0.3f;
|
||||||
|
|
||||||
private List<float[]> _voloResult = new List<float[]>();
|
private List<float[]> _voloResult = new List<float[]>();
|
||||||
private List<Point> _currPersonPoints = new List<Point>();
|
private List<Point> _currPersonPoints = new List<Point>();
|
||||||
|
|
||||||
private YOLOv7ObjectDetector _objectDetector;
|
|
||||||
private Mat _bgrMat;
|
private Mat _bgrMat;
|
||||||
|
|
||||||
private double threshold = 0.5;
|
|
||||||
|
|
||||||
private bool _isOnCamCapture = false;
|
private bool _isOnCamCapture = false;
|
||||||
public bool IsOnCamCapture { get => _isOnCamCapture; internal set => _isOnCamCapture = value; }
|
public bool IsOnCamCapture { get => _isOnCamCapture; internal set => _isOnCamCapture = value; }
|
||||||
public WebCamTextureToMatHelper WebCamTextureToMatHelper => _webCamTextureToMatHelper;
|
public WebCamTextureToMatHelper WebCamTextureToMatHelper => _webCamTextureToMatHelper;
|
||||||
|
@ -82,45 +63,28 @@ namespace Yoga
|
||||||
_webCamTextureToMatHelper = gameObject.GetComponent<WebCamTextureToMatHelper>();
|
_webCamTextureToMatHelper = gameObject.GetComponent<WebCamTextureToMatHelper>();
|
||||||
_webCamTextureToMatHelper.Initialize();
|
_webCamTextureToMatHelper.Initialize();
|
||||||
|
|
||||||
YogaManager.Instance.InitData();
|
UIManager.Instance.LoadReset();
|
||||||
|
|
||||||
|
if (YogaManager.Instance.Action == null)
|
||||||
|
YogaManager.Instance.InitData();
|
||||||
|
|
||||||
|
|
||||||
UIManager.Instance.Init();
|
|
||||||
UIManager.Instance.ShowPanel<ActionGuideVideoPanel>(false, YogaManager.Instance.Action);
|
UIManager.Instance.ShowPanel<ActionGuideVideoPanel>(false, YogaManager.Instance.Action);
|
||||||
|
|
||||||
LoadModels();//加载模型
|
Utils.setDebugMode(true); //打印日志
|
||||||
|
//LoadModels();//加载模型
|
||||||
|
|
||||||
CVEstimator.Instance.Init(_objectDetector, _openPoseModel);//初始化姿态检测
|
switch (YogaManager.Instance.Action.ModelType)
|
||||||
}
|
|
||||||
|
|
||||||
private void LoadModels()
|
|
||||||
{
|
|
||||||
//Utils.setDebugMode(true); //打印日志
|
|
||||||
_net = null;
|
|
||||||
|
|
||||||
//先用YOLOv7检测人体,再用OpenPose检测人体姿态
|
|
||||||
_objectDetector = new YOLOv7ObjectDetector(
|
|
||||||
Utils.getFilePath("OpenCVForUnity/dnn/yolov7-tiny.weights"),
|
|
||||||
Utils.getFilePath("OpenCVForUnity/dnn/yolov7-tiny.cfg"),
|
|
||||||
Utils.getFilePath("OpenCVForUnity/dnn/coco.names"),
|
|
||||||
new Size(inpWidth, inpHeight), confThreshold, nmsThreshold/*, topK*/);
|
|
||||||
|
|
||||||
|
|
||||||
var modelFilePath = Utils.getFilePath(YogaConfig.MODEL_PATHS[ModelType.OpenPose]);
|
|
||||||
if (string.IsNullOrEmpty(modelFilePath))
|
|
||||||
{
|
{
|
||||||
Debug.LogError("modelFilePath is empty. Please copy from “OpenCVForUnity/StreamingAssets/” to “Assets/StreamingAssets/” folder. ");
|
case ModelType.OpenPose:
|
||||||
return;
|
YogaManager.Instance.CurrentEstimator = new OpenPoseEsimater();
|
||||||
|
break;
|
||||||
|
case ModelType.Mediapipe:
|
||||||
|
YogaManager.Instance.CurrentEstimator = new MediaPipeEstimator();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
YogaManager.Instance.CurrentEstimator.Init();
|
||||||
|
|
||||||
_net = Dnn.readNet(modelFilePath);
|
CVEstimator.Instance.Init();//初始化姿态检测
|
||||||
|
|
||||||
_openPoseModel = new KeypointsModel(_net);
|
|
||||||
_openPoseModel.setInputScale(new Scalar(YogaConfig.InScale));
|
|
||||||
_openPoseModel.setInputSize(new Size(YogaConfig.InWidth, YogaConfig.InHeight));
|
|
||||||
_openPoseModel.setInputMean(new Scalar(YogaConfig.InMean));
|
|
||||||
_openPoseModel.setInputSwapRB(false);
|
|
||||||
_openPoseModel.setInputCrop(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
|
@ -137,14 +101,12 @@ namespace Yoga
|
||||||
Mat img = _webCamTextureToMatHelper.GetMat();
|
Mat img = _webCamTextureToMatHelper.GetMat();
|
||||||
Imgproc.cvtColor(img, img, Imgproc.COLOR_BGR2RGB);
|
Imgproc.cvtColor(img, img, Imgproc.COLOR_BGR2RGB);
|
||||||
_rgbaMat = img.clone();
|
_rgbaMat = img.clone();
|
||||||
if (_net == null)
|
|
||||||
{
|
YogaManager.Instance.CurrentEstimator.Check(ref img);//检测模型,将错误信息打印在图片上
|
||||||
Imgproc.putText(img, "model file is not loaded.", new Point(5, img.rows() - 30), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255), 2, Imgproc.LINE_AA, false);
|
|
||||||
Imgproc.putText(img, "Please read console message.", new Point(5, img.rows() - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255), 2, Imgproc.LINE_AA, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_voloResult.Count >= 2)
|
if (_voloResult.Count >= 2)
|
||||||
DebugPrintObjectLayout(img, _voloResult[0], _voloResult[1], _voloResult[2]);
|
YogaManager.Instance.CurrentEstimator.DebugPrintObjectLayout(img, _voloResult[0], _voloResult[1], _voloResult[2]);
|
||||||
|
|
||||||
if (_currPersonPoints != null && _currPersonPoints.Count > 0)
|
if (_currPersonPoints != null && _currPersonPoints.Count > 0)
|
||||||
{
|
{
|
||||||
|
@ -218,7 +180,6 @@ namespace Yoga
|
||||||
}
|
}
|
||||||
AvatarAction actionType = (AvatarAction)args.FirstOrDefault();
|
AvatarAction actionType = (AvatarAction)args.FirstOrDefault();
|
||||||
|
|
||||||
UIManager.Instance.ShowHint(actionType.ToString(), "Follow the robot!");
|
|
||||||
|
|
||||||
//检测动作
|
//检测动作
|
||||||
var startTime = DateTime.Now;
|
var startTime = DateTime.Now;
|
||||||
|
@ -241,37 +202,7 @@ namespace Yoga
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void DebugPrintObjectLayout(Mat image, float[] box, float[] conf, float[] cls, bool isRGB = false)
|
|
||||||
{
|
|
||||||
|
|
||||||
float left = box[0];
|
|
||||||
float top = box[1];
|
|
||||||
float right = box[2];
|
|
||||||
float bottom = box[3];
|
|
||||||
int classId = (int)cls[0];
|
|
||||||
|
|
||||||
Scalar c = _objectDetector.palette[classId % _objectDetector.palette.Count];
|
|
||||||
Scalar color = isRGB ? c : new Scalar(c.val[2], c.val[1], c.val[0], c.val[3]);
|
|
||||||
|
|
||||||
Imgproc.rectangle(image, new Point(left, top), new Point(right, bottom), color, 2);
|
|
||||||
|
|
||||||
string label = String.Format("{0:0.00}", conf[0]);
|
|
||||||
if (_objectDetector.classNames != null && _objectDetector.classNames.Count != 0)
|
|
||||||
{
|
|
||||||
if (classId < (int)_objectDetector.classNames.Count)
|
|
||||||
{
|
|
||||||
label = _objectDetector.classNames[classId] + " " + label;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int[] baseLine = new int[1];
|
|
||||||
Size labelSize = Imgproc.getTextSize(label, Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, 1, baseLine);
|
|
||||||
|
|
||||||
top = Mathf.Max((float)top, (float)labelSize.height);
|
|
||||||
Imgproc.rectangle(image, new Point(left, top - labelSize.height),
|
|
||||||
new Point(left + labelSize.width, top + baseLine[0]), color, Core.FILLED);
|
|
||||||
Imgproc.putText(image, label, new Point(left, top), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, Scalar.all(255), 1, Imgproc.LINE_AA);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raises the destroy event.
|
/// Raises the destroy event.
|
||||||
|
@ -280,11 +211,9 @@ namespace Yoga
|
||||||
{
|
{
|
||||||
_webCamTextureToMatHelper.Dispose();
|
_webCamTextureToMatHelper.Dispose();
|
||||||
|
|
||||||
if (_net != null)
|
YogaManager.Instance.CurrentEstimator.Dispose();
|
||||||
_net.Dispose();
|
|
||||||
|
|
||||||
_bgrMat.Dispose();
|
_bgrMat.Dispose();
|
||||||
_models.Clear();
|
|
||||||
CVEstimator.Instance.Dispose();
|
CVEstimator.Instance.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,14 @@ public class ActionListUIPanel : UIPanelBase
|
||||||
public void OnLoadBtnClicked(int index)
|
public void OnLoadBtnClicked(int index)
|
||||||
{
|
{
|
||||||
YogaManager.Instance.ActionIndex = index;
|
YogaManager.Instance.ActionIndex = index;
|
||||||
|
YogaManager.Instance.InitData();
|
||||||
LoadingManager.Instance.Load("YogaMain");
|
LoadingManager.Instance.Load("YogaMain");
|
||||||
UIManager.Instance.ClearPanel();
|
UIManager.Instance.ClearPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnBackBtnClicked()
|
||||||
|
{
|
||||||
|
UIManager.Instance.CloseCurrent();
|
||||||
|
UIManager.Instance.ShowPanel<MainUIPanel>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,11 @@ public class LoadingManager:MonoSingleton<LoadingManager>
|
||||||
|
|
||||||
private IEnumerator LoadingScene(string targetScene)
|
private IEnumerator LoadingScene(string targetScene)
|
||||||
{
|
{
|
||||||
yield return new WaitForSeconds(3f);
|
//演示用,正式版需要根据场景大小调整
|
||||||
|
if (targetScene.Equals("YogaMain"))
|
||||||
|
{
|
||||||
|
yield return new WaitForSeconds(3f);
|
||||||
|
}
|
||||||
var loadNew = SceneManager.LoadSceneAsync(targetScene, LoadSceneMode.Single);
|
var loadNew = SceneManager.LoadSceneAsync(targetScene, LoadSceneMode.Single);
|
||||||
loadNew.completed += (AsyncOperation obj2) =>
|
loadNew.completed += (AsyncOperation obj2) =>
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,6 +15,9 @@ public class UIManager : MonoSingleton<UIManager>
|
||||||
|
|
||||||
public Camera UiCamera { get; set; }
|
public Camera UiCamera { get; set; }
|
||||||
|
|
||||||
|
private static bool _isInited = false;
|
||||||
|
public static bool IsInited { get => _isInited; private set => _isInited = value; }
|
||||||
|
|
||||||
private RectTransform _uiPanelRoot;
|
private RectTransform _uiPanelRoot;
|
||||||
private RectTransform _uiPopRoot;
|
private RectTransform _uiPopRoot;
|
||||||
|
|
||||||
|
@ -27,6 +30,8 @@ public class UIManager : MonoSingleton<UIManager>
|
||||||
|
|
||||||
public override void Init()
|
public override void Init()
|
||||||
{
|
{
|
||||||
|
if (_isInited)
|
||||||
|
return;
|
||||||
//查找当前scene的摄像机
|
//查找当前scene的摄像机
|
||||||
UiCamera = Camera.main;
|
UiCamera = Camera.main;
|
||||||
|
|
||||||
|
@ -99,8 +104,14 @@ public class UIManager : MonoSingleton<UIManager>
|
||||||
else
|
else
|
||||||
_hud = transform.Find("HUDRoot").GetComponent<HudUI>();
|
_hud = transform.Find("HUDRoot").GetComponent<HudUI>();
|
||||||
_hud.transform.SetSiblingIndex(3);
|
_hud.transform.SetSiblingIndex(3);
|
||||||
|
_isInited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void LoadReset()
|
||||||
|
{
|
||||||
|
_isInited = false;
|
||||||
|
Init();
|
||||||
|
}
|
||||||
private T GetPanel<T>() where T : UIBase
|
private T GetPanel<T>() where T : UIBase
|
||||||
{
|
{
|
||||||
Type type = typeof(T);
|
Type type = typeof(T);
|
||||||
|
|
|
@ -139,9 +139,4 @@ public static class YogaConfig
|
||||||
public static readonly double[] InMean = new double[] { 128.0, 128.0, 128.0 };
|
public static readonly double[] InMean = new double[] { 128.0, 128.0, 128.0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ModelType
|
|
||||||
{
|
|
||||||
OpenPose,
|
|
||||||
YoloV7,
|
|
||||||
//,
|
|
||||||
}
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ public class YogaDataLoader
|
||||||
{
|
{
|
||||||
VideoPath = "Video/Action2",
|
VideoPath = "Video/Action2",
|
||||||
Action = AvatarAction.Nod,
|
Action = AvatarAction.Nod,
|
||||||
|
ModelType = ModelType.OpenPose,
|
||||||
MaxActionCount = 1000,
|
MaxActionCount = 1000,
|
||||||
TotalSeconds = 20.0f,
|
TotalSeconds = 20.0f,
|
||||||
MustPoints = new List<string>() { "Nose", "REye", "LEye", "Neck" },
|
MustPoints = new List<string>() { "Nose", "REye", "LEye", "Neck" },
|
||||||
|
@ -25,6 +26,7 @@ public class YogaDataLoader
|
||||||
{
|
{
|
||||||
VideoPath = "Video/Action1",
|
VideoPath = "Video/Action1",
|
||||||
Action = AvatarAction.HeadShake,
|
Action = AvatarAction.HeadShake,
|
||||||
|
ModelType = ModelType.OpenPose,
|
||||||
MaxActionCount = 4,
|
MaxActionCount = 4,
|
||||||
TotalSeconds = 20.0f,
|
TotalSeconds = 20.0f,
|
||||||
MustPoints = new List<string>() { "Nose", "REye", "LEye", "Neck" }
|
MustPoints = new List<string>() { "Nose", "REye", "LEye", "Neck" }
|
||||||
|
@ -33,6 +35,7 @@ public class YogaDataLoader
|
||||||
{
|
{
|
||||||
VideoPath = "Video/Action2",
|
VideoPath = "Video/Action2",
|
||||||
Action = AvatarAction.Nod,
|
Action = AvatarAction.Nod,
|
||||||
|
ModelType = ModelType.OpenPose,
|
||||||
MaxActionCount = 4,
|
MaxActionCount = 4,
|
||||||
TotalSeconds = 20.0f,
|
TotalSeconds = 20.0f,
|
||||||
MustPoints = new List<string>() { "Nose", "REye", "LEye", "Neck" }
|
MustPoints = new List<string>() { "Nose", "REye", "LEye", "Neck" }
|
||||||
|
@ -41,6 +44,7 @@ public class YogaDataLoader
|
||||||
{
|
{
|
||||||
VideoPath = "Video/Action3",
|
VideoPath = "Video/Action3",
|
||||||
Action = AvatarAction.HandsUp,
|
Action = AvatarAction.HandsUp,
|
||||||
|
ModelType = ModelType.OpenPose,
|
||||||
MaxActionCount = 4,
|
MaxActionCount = 4,
|
||||||
TotalSeconds = 12.66f,
|
TotalSeconds = 12.66f,
|
||||||
MustPoints = new List<string>() { "Nose", "RShoulder", "LShoulder", "RightWrist" }
|
MustPoints = new List<string>() { "Nose", "RShoulder", "LShoulder", "RightWrist" }
|
||||||
|
@ -61,8 +65,17 @@ public class YogaData
|
||||||
{
|
{
|
||||||
public string VideoPath;
|
public string VideoPath;
|
||||||
public AvatarAction Action;
|
public AvatarAction Action;
|
||||||
|
public ModelType ModelType;
|
||||||
public int MaxActionCount;
|
public int MaxActionCount;
|
||||||
public float TotalSeconds;
|
public float TotalSeconds;
|
||||||
public List<string> MustPoints = new List<string>();
|
public List<string> MustPoints = new List<string>();
|
||||||
public List<string> AnyPoints = new List<string>();
|
public List<string> AnyPoints = new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ModelType
|
||||||
|
{
|
||||||
|
OpenPose,
|
||||||
|
YoloV7,
|
||||||
|
Mediapipe,
|
||||||
|
//,
|
||||||
}
|
}
|
|
@ -33,8 +33,15 @@ public class YogaManager : MonoSingleton<YogaManager>
|
||||||
private Dictionary<AvatarAction, PoseBase> _actions = new Dictionary<AvatarAction, PoseBase>();
|
private Dictionary<AvatarAction, PoseBase> _actions = new Dictionary<AvatarAction, PoseBase>();
|
||||||
|
|
||||||
|
|
||||||
public YogaData Action { get => _action; set => _action = value; }
|
public YogaData Action
|
||||||
|
{
|
||||||
|
get => _action;
|
||||||
|
set => _action = value;
|
||||||
|
}
|
||||||
|
public Estimator CurrentEstimator { get => currentEstimator; internal set => currentEstimator = value; }
|
||||||
|
|
||||||
private YogaData _action = null;
|
private YogaData _action = null;
|
||||||
|
private Estimator currentEstimator;
|
||||||
|
|
||||||
public void InitData()
|
public void InitData()
|
||||||
{
|
{
|
||||||
|
@ -126,7 +133,7 @@ public class YogaManager : MonoSingleton<YogaManager>
|
||||||
{
|
{
|
||||||
//Debug.LogError($"ActionCheckPoints failed, {p} is not valid");
|
//Debug.LogError($"ActionCheckPoints failed, {p} is not valid");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//不设的情况下,不检测
|
//不设的情况下,不检测
|
||||||
|
@ -144,4 +151,4 @@ public class YogaManager : MonoSingleton<YogaManager>
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
|
@ -0,0 +1,124 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 96b53986fbf913d47864b19cbe98e372
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 12
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 0
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
ignoreMipmapLimit: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 0
|
||||||
|
nPOTScale: 0
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 1
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 1
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 8
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
|
cookieLightType: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Android
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID: 5e97eb03825dee720800000000000000
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
nameFileIdTable: {}
|
||||||
|
mipmapLimitGroupName:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Loading…
Reference in New Issue