diff --git a/Assets/Resources/Prefabs/Facts/Circle.prefab b/Assets/Resources/Prefabs/Facts/Circle.prefab index e9b352131d9a177cba1d7de192ae16fa71dfa22a..f32e8f44c0ce01f542f76b77a8f713da96011b2a 100644 --- a/Assets/Resources/Prefabs/Facts/Circle.prefab +++ b/Assets/Resources/Prefabs/Facts/Circle.prefab @@ -436,7 +436,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 6839596689016440457} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalPosition: {x: -0.019, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: @@ -457,13 +457,14 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 405087c38b8537e43bcc99727c5325ec, type: 3} m_Name: m_EditorClassIdentifier: - radius: 1 - sideCount: 500 - circleMesh: + Meshs: - {fileID: 7167210412035754299} - {fileID: 3164742056485930267} - {fileID: 1312883106029576503} - {fileID: 6626359674163989219} + NormalOffset: [] + radius: 1 + sideCount: 500 --- !u!114 &6950663371922587874 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/Assets/Resources/Prefabs/Facts/Cone.prefab b/Assets/Resources/Prefabs/Facts/Cone.prefab new file mode 100644 index 0000000000000000000000000000000000000000..035e2830d680e4a450612ec39bc6dbaea5dc53f7 --- /dev/null +++ b/Assets/Resources/Prefabs/Facts/Cone.prefab @@ -0,0 +1,662 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &2317807655120713368 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5818562496562931847} + - component: {fileID: 2028494018615604281} + - component: {fileID: 77904359947812862} + m_Layer: 17 + m_Name: Cone + m_TagString: Selectable + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &5818562496562931847 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2317807655120713368} + 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: + - {fileID: 2267903722640728620} + - {fileID: 1517323377706769618} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &2028494018615604281 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2317807655120713368} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 626c435b76e0d334f959ede8b54b07ac, type: 3} + m_Name: + m_EditorClassIdentifier: + _URI: + FactText: + - {fileID: 1723009895384754658} + StringLabelFormats: + - '{0}' + Default: {fileID: 0} + Selected: {fileID: 0} + Hint: {fileID: 0} + Solution: {fileID: 0} + renderer: [] +--- !u!114 &77904359947812862 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2317807655120713368} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 171f36100fbf6384591cca35fc917317, type: 3} + m_Name: + m_EditorClassIdentifier: + Meshs: + - {fileID: 6398251481098695290} + - {fileID: 8620665629189134186} + - {fileID: 2701943617241909663} + NormalOffset: + - 0 + - 0 + - 0 + AlternateNormals: 0 + bottomRadius: 1 + topRadius: 0.5 + topPosition: {x: 0, y: 2, z: 0} + sideCount: 50 +--- !u!1 &4853696702160906218 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7972877566157790116} + - component: {fileID: 2096909858734684758} + - component: {fileID: 1723009895384754658} + - component: {fileID: 1586728893263614116} + m_Layer: 17 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7972877566157790116 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4853696702160906218} + m_LocalRotation: {x: -0, y: 0.7071068, z: -0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1517323377706769618} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 4, y: 0.5} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!23 &2096909858734684758 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4853696702160906218} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 1 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!114 &1723009895384754658 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4853696702160906218} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9541d86e2fd84c1d9990edf0852d74ab, 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: Test + 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: 4294967293 + m_fontColor: {r: 0.993, g: 1, b: 1, 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: 4 + m_fontSizeBase: 4 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 256 + 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: 0 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 1 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + _SortingLayer: 0 + _SortingLayerID: 0 + _SortingOrder: 0 + m_hasFontAssetChanged: 0 + m_renderer: {fileID: 2096909858734684758} + m_maskType: 0 +--- !u!114 &1586728893263614116 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4853696702160906218} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8cf5a358dacd3b54ab093ee289dd9ba2, type: 3} + m_Name: + m_EditorClassIdentifier: + Cam1: {fileID: 0} + Cam2: {fileID: 0} + BackUPCam: {fileID: 0} +--- !u!1 &6028669276398914237 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2267903722640728620} + m_Layer: 17 + m_Name: PolyMeshs + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2267903722640728620 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6028669276398914237} + 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: + - {fileID: 3517099398133763913} + - {fileID: 2374130608748553515} + m_Father: {fileID: 5818562496562931847} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &6247621022589904505 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4678806186037624479} + - component: {fileID: 2701943617241909663} + - component: {fileID: 4008433908760336842} + m_Layer: 17 + m_Name: PolyHighlight + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4678806186037624479 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6247621022589904505} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: -0.01, z: 0} + m_LocalScale: {x: 1.01, y: 1.01, z: 1.01} + m_ConstrainProportionsScale: 1 + m_Children: [] + m_Father: {fileID: 2374130608748553515} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &2701943617241909663 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6247621022589904505} + m_Mesh: {fileID: 0} +--- !u!23 &4008433908760336842 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6247621022589904505} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 8ae9adf4dc782964387385c1e8c0eb72, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!1 &6378548342073962023 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3517099398133763913} + - component: {fileID: 6398251481098695290} + - component: {fileID: 6015977261426572496} + - component: {fileID: 8352602335830303231} + - component: {fileID: 9072308735336053453} + - component: {fileID: 184519196497952346} + m_Layer: 17 + m_Name: PolyOuter + m_TagString: SnapZone + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &3517099398133763913 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6378548342073962023} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: -0.05, z: 0} + m_LocalScale: {x: 1.05, y: 1.05, z: 1.05} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2267903722640728620} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &6398251481098695290 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6378548342073962023} + m_Mesh: {fileID: 0} +--- !u!23 &6015977261426572496 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6378548342073962023} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 8ae9adf4dc782964387385c1e8c0eb72, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!64 &8352602335830303231 +MeshCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6378548342073962023} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 4 + m_Convex: 0 + m_CookingOptions: 30 + m_Mesh: {fileID: 0} +--- !u!95 &9072308735336053453 +Animator: + serializedVersion: 4 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6378548342073962023} + m_Enabled: 1 + m_Avatar: {fileID: 0} + m_Controller: {fileID: 9100000, guid: 7f5a2c4324ecb83488857feb7887b5a7, type: 2} + m_CullingMode: 0 + m_UpdateMode: 0 + m_ApplyRootMotion: 0 + m_LinearVelocityBlending: 0 + m_StabilizeFeet: 0 + m_WarningMessage: + m_HasTransformHierarchy: 1 + m_AllowConstantClipSamplingOptimization: 1 + m_KeepAnimatorControllerStateOnDisable: 0 +--- !u!114 &184519196497952346 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6378548342073962023} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 626c435b76e0d334f959ede8b54b07ac, type: 3} + m_Name: + m_EditorClassIdentifier: + _URI: + FactText: [] + StringLabelFormats: [] + Default: {fileID: 2100000, guid: 8ae9adf4dc782964387385c1e8c0eb72, type: 2} + Selected: {fileID: 2100000, guid: 34a95baef388bb8458c97a626b732f9f, type: 2} + Hint: {fileID: 2100000, guid: 8621b710d7d1d5041bc6bfd0cc37cdff, type: 2} + Solution: {fileID: 2100000, guid: 2a003f0807acc1142965bb21bdc824f6, type: 2} + renderer: + - {fileID: 6015977261426572496} +--- !u!1 &7289674876073244909 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1517323377706769618} + - component: {fileID: 4409226297024899106} + m_Layer: 17 + m_Name: TextAnker + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1517323377706769618 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7289674876073244909} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 7972877566157790116} + m_Father: {fileID: 5818562496562931847} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &4409226297024899106 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7289674876073244909} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0b53a9efe2eaabd4a9ae38ae148bed9e, type: 3} + m_Name: + m_EditorClassIdentifier: + x: 1 + y: 1 + z: 1 + mesh: {fileID: 8620665629189134186} +--- !u!1 &8536634090652517107 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2374130608748553515} + - component: {fileID: 8620665629189134186} + - component: {fileID: 2279887988868225897} + m_Layer: 17 + m_Name: PolyInner + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2374130608748553515 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8536634090652517107} + 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: + - {fileID: 4678806186037624479} + m_Father: {fileID: 2267903722640728620} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &8620665629189134186 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8536634090652517107} + m_Mesh: {fileID: 0} +--- !u!23 &2279887988868225897 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8536634090652517107} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a8a7bf60a30970f469a9c9d3ae2de6ef, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} diff --git a/Assets/Resources/Prefabs/Facts/Cone.prefab.meta b/Assets/Resources/Prefabs/Facts/Cone.prefab.meta new file mode 100644 index 0000000000000000000000000000000000000000..8a1d149b4355711df912ddfbebe19df3145f8487 --- /dev/null +++ b/Assets/Resources/Prefabs/Facts/Cone.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5ed47fa3432595f4398cb37a4f9bf30d +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Prefabs/Facts/Line.prefab b/Assets/Resources/Prefabs/Facts/Line.prefab index 9da29198ba8341ff37f9d4928ef83f2cdf871860..552ad2a748d8501aa9181886d4bb21d8b0569556 100644 --- a/Assets/Resources/Prefabs/Facts/Line.prefab +++ b/Assets/Resources/Prefabs/Facts/Line.prefab @@ -46,15 +46,16 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 626c435b76e0d334f959ede8b54b07ac, type: 3} m_Name: m_EditorClassIdentifier: + _URI: FactText: - {fileID: 1723009895384754658} StringLabelFormats: - '{0}' - renderer: [] Default: {fileID: 0} Selected: {fileID: 0} Hint: {fileID: 0} Solution: {fileID: 0} + renderer: [] --- !u!1 &4853696702160906218 GameObject: m_ObjectHideFlags: 0 @@ -490,14 +491,15 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 626c435b76e0d334f959ede8b54b07ac, type: 3} m_Name: m_EditorClassIdentifier: + _URI: FactText: [] StringLabelFormats: [] - renderer: - - {fileID: 6015977261426572496} Default: {fileID: 2100000, guid: 8ae9adf4dc782964387385c1e8c0eb72, type: 2} Selected: {fileID: 2100000, guid: 34a95baef388bb8458c97a626b732f9f, type: 2} Hint: {fileID: 2100000, guid: 8621b710d7d1d5041bc6bfd0cc37cdff, type: 2} Solution: {fileID: 2100000, guid: 2a003f0807acc1142965bb21bdc824f6, type: 2} + renderer: + - {fileID: 6015977261426572496} --- !u!1 &6754103560634016048 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Resources/Prefabs/Facts/Prism.prefab b/Assets/Resources/Prefabs/Facts/Prism.prefab new file mode 100644 index 0000000000000000000000000000000000000000..9b60a73fb40b72dd858578fa569e899db0a581e5 --- /dev/null +++ b/Assets/Resources/Prefabs/Facts/Prism.prefab @@ -0,0 +1,664 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &2317807655120713368 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5818562496562931847} + - component: {fileID: 2028494018615604281} + - component: {fileID: 8334482767163788216} + m_Layer: 16 + m_Name: Prism + m_TagString: Selectable + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &5818562496562931847 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2317807655120713368} + 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: + - {fileID: 2267903722640728620} + - {fileID: 1517323377706769618} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &2028494018615604281 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2317807655120713368} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 626c435b76e0d334f959ede8b54b07ac, type: 3} + m_Name: + m_EditorClassIdentifier: + _URI: + FactText: + - {fileID: 1723009895384754658} + StringLabelFormats: + - '{0}' + Default: {fileID: 0} + Selected: {fileID: 0} + Hint: {fileID: 0} + Solution: {fileID: 0} + renderer: [] +--- !u!114 &8334482767163788216 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2317807655120713368} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a639f1d1c3cdeb42bc5a7a66401dc02, type: 3} + m_Name: + m_EditorClassIdentifier: + Meshs: + - {fileID: 6398251481098695290} + - {fileID: 8620665629189134186} + - {fileID: 2701943617241909663} + NormalOffset: + - 0.05 + - 0 + - 0.01 + AlternateNormals: 0 + _vertices: + - {x: 1, y: 3, z: 1} + - {x: 1, y: 0, z: -3} + - {x: -4, y: 0, z: -3} + - {x: -1, y: 0, z: 1} + _offset: {x: 0, y: 0.05, z: 0} +--- !u!1 &4853696702160906218 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7972877566157790116} + - component: {fileID: 2096909858734684758} + - component: {fileID: 1723009895384754658} + - component: {fileID: 1586728893263614116} + m_Layer: 16 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7972877566157790116 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4853696702160906218} + m_LocalRotation: {x: -0, y: 0.7071068, z: -0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1517323377706769618} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0.5} + m_SizeDelta: {x: 4, y: 0.5} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!23 &2096909858734684758 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4853696702160906218} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 1 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!114 &1723009895384754658 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4853696702160906218} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9541d86e2fd84c1d9990edf0852d74ab, 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: Test + 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: 4294967293 + m_fontColor: {r: 0.993, g: 1, b: 1, 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: 4 + m_fontSizeBase: 4 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 256 + 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: 0 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 1 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + _SortingLayer: 0 + _SortingLayerID: 0 + _SortingOrder: 0 + m_hasFontAssetChanged: 0 + m_renderer: {fileID: 2096909858734684758} + m_maskType: 0 +--- !u!114 &1586728893263614116 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4853696702160906218} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8cf5a358dacd3b54ab093ee289dd9ba2, type: 3} + m_Name: + m_EditorClassIdentifier: + Cam1: {fileID: 0} + Cam2: {fileID: 0} + BackUPCam: {fileID: 0} +--- !u!1 &6028669276398914237 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2267903722640728620} + m_Layer: 16 + m_Name: PolyMeshs + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2267903722640728620 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6028669276398914237} + 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: + - {fileID: 3517099398133763913} + - {fileID: 2374130608748553515} + m_Father: {fileID: 5818562496562931847} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &6247621022589904505 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4678806186037624479} + - component: {fileID: 2701943617241909663} + - component: {fileID: 4008433908760336842} + m_Layer: 16 + m_Name: PolyHighlight + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4678806186037624479 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6247621022589904505} + 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: 1 + m_Children: [] + m_Father: {fileID: 2374130608748553515} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &2701943617241909663 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6247621022589904505} + m_Mesh: {fileID: 0} +--- !u!23 &4008433908760336842 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6247621022589904505} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 8ae9adf4dc782964387385c1e8c0eb72, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!1 &6378548342073962023 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3517099398133763913} + - component: {fileID: 6398251481098695290} + - component: {fileID: 6015977261426572496} + - component: {fileID: 8352602335830303231} + - component: {fileID: 9072308735336053453} + - component: {fileID: 184519196497952346} + m_Layer: 16 + m_Name: PolyOuter + m_TagString: SnapZone + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &3517099398133763913 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6378548342073962023} + 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: 2267903722640728620} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &6398251481098695290 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6378548342073962023} + m_Mesh: {fileID: 0} +--- !u!23 &6015977261426572496 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6378548342073962023} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 8ae9adf4dc782964387385c1e8c0eb72, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!64 &8352602335830303231 +MeshCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6378548342073962023} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 4 + m_Convex: 0 + m_CookingOptions: 30 + m_Mesh: {fileID: 0} +--- !u!95 &9072308735336053453 +Animator: + serializedVersion: 4 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6378548342073962023} + m_Enabled: 1 + m_Avatar: {fileID: 0} + m_Controller: {fileID: 9100000, guid: 7f5a2c4324ecb83488857feb7887b5a7, type: 2} + m_CullingMode: 0 + m_UpdateMode: 0 + m_ApplyRootMotion: 0 + m_LinearVelocityBlending: 0 + m_StabilizeFeet: 0 + m_WarningMessage: + m_HasTransformHierarchy: 1 + m_AllowConstantClipSamplingOptimization: 1 + m_KeepAnimatorControllerStateOnDisable: 0 +--- !u!114 &184519196497952346 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6378548342073962023} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 626c435b76e0d334f959ede8b54b07ac, type: 3} + m_Name: + m_EditorClassIdentifier: + _URI: + FactText: [] + StringLabelFormats: [] + Default: {fileID: 2100000, guid: 8ae9adf4dc782964387385c1e8c0eb72, type: 2} + Selected: {fileID: 2100000, guid: 34a95baef388bb8458c97a626b732f9f, type: 2} + Hint: {fileID: 2100000, guid: 8621b710d7d1d5041bc6bfd0cc37cdff, type: 2} + Solution: {fileID: 2100000, guid: 2a003f0807acc1142965bb21bdc824f6, type: 2} + renderer: + - {fileID: 6015977261426572496} +--- !u!1 &7289674876073244909 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1517323377706769618} + - component: {fileID: 4409226297024899106} + m_Layer: 16 + m_Name: TextAnker + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1517323377706769618 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7289674876073244909} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -1.5, y: 1.525, z: -1} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 7972877566157790116} + m_Father: {fileID: 5818562496562931847} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &4409226297024899106 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7289674876073244909} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0b53a9efe2eaabd4a9ae38ae148bed9e, type: 3} + m_Name: + m_EditorClassIdentifier: + x: 1 + y: 1 + z: 1 + mesh: {fileID: 8620665629189134186} +--- !u!1 &8536634090652517107 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2374130608748553515} + - component: {fileID: 8620665629189134186} + - component: {fileID: 2279887988868225897} + m_Layer: 16 + m_Name: PolyInner + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2374130608748553515 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8536634090652517107} + 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: + - {fileID: 4678806186037624479} + m_Father: {fileID: 2267903722640728620} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &8620665629189134186 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8536634090652517107} + m_Mesh: {fileID: 0} +--- !u!23 &2279887988868225897 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8536634090652517107} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a8a7bf60a30970f469a9c9d3ae2de6ef, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} diff --git a/Assets/Resources/Prefabs/Facts/Prism.prefab.meta b/Assets/Resources/Prefabs/Facts/Prism.prefab.meta new file mode 100644 index 0000000000000000000000000000000000000000..4b979f16cbddd5931deeb36dfa3256a7f09ecf1b --- /dev/null +++ b/Assets/Resources/Prefabs/Facts/Prism.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5a1fad91749b4014a8eb28cd0b21d7a3 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Prefabs/Facts/Ring.prefab b/Assets/Resources/Prefabs/Facts/Ring.prefab index 982ebf81f8608900d60cd5ce895a6adb74d56a51..eb4cbbc9950c0f716500bbfb998ac84e9ebf0e86 100644 --- a/Assets/Resources/Prefabs/Facts/Ring.prefab +++ b/Assets/Resources/Prefabs/Facts/Ring.prefab @@ -342,7 +342,6 @@ GameObject: - component: {fileID: 4775945639457863304} - component: {fileID: 2239887596765845809} - component: {fileID: 2358573561192576705} - - component: {fileID: 7100019936063167720} m_Layer: 14 m_Name: LineHighlight m_TagString: Untagged @@ -415,23 +414,6 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!114 &7100019936063167720 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7320042660989930446} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 35327f6b479454149a20587eb03337f8, type: 3} - m_Name: - m_EditorClassIdentifier: - torusRadius: 1 - ringRadius: 0.026 - ringSegmentCount: 50 - segmentSideCount: 30 - torusMesh: {fileID: 2239887596765845809} --- !u!1 &7644263571880024739 GameObject: m_ObjectHideFlags: 0 @@ -479,11 +461,19 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 35327f6b479454149a20587eb03337f8, type: 3} m_Name: m_EditorClassIdentifier: + Meshs: + - {fileID: 6307794999199274257} + - {fileID: 213008266423099231} + - {fileID: 2239887596765845809} + NormalOffset: + - 0 + - 0.025 + - 0.024 + AlternateNormals: 0 torusRadius: 1 - ringRadius: 0.05 - ringSegmentCount: 50 - segmentSideCount: 30 - torusMesh: {fileID: 6307794999199274257} + ringRadius: 0.0544 + ringSegmentCount: 100 + segmentSideCount: 20 --- !u!114 &3963086670126537751 MonoBehaviour: m_ObjectHideFlags: 0 @@ -517,7 +507,6 @@ GameObject: - component: {fileID: 5121703917865025706} - component: {fileID: 213008266423099231} - component: {fileID: 2162055944849665559} - - component: {fileID: 8620085494464208677} m_Layer: 14 m_Name: LineInner m_TagString: Untagged @@ -590,20 +579,3 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!114 &8620085494464208677 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 8117705180640636930} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 35327f6b479454149a20587eb03337f8, type: 3} - m_Name: - m_EditorClassIdentifier: - torusRadius: 1 - ringRadius: 0.025 - ringSegmentCount: 50 - segmentSideCount: 30 - torusMesh: {fileID: 213008266423099231} diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactSpawner.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactSpawner.cs index 681d0712a89a4f93395dbb69f04365a9d4510344..a958a93c334c40f09e93282dcfd34c3e3009d6d4 100644 --- a/Assets/Scripts/InteractionEngine/FactHandling/FactSpawner.cs +++ b/Assets/Scripts/InteractionEngine/FactHandling/FactSpawner.cs @@ -1,7 +1,9 @@ using System; using System.Collections; +using System.Linq; using TMPro; using UnityEngine; +using UnityEngine.UIElements; using static CommunicationEvents; public class FactSpawner : MonoBehaviour @@ -12,6 +14,8 @@ public GameObject Ray, Angle, Ring, + Prism, + Cone, Circle; void Start() @@ -37,6 +41,12 @@ public void SpawnFactRepresentation(Fact fact) SpawnRingAndCircle(CircleFact); break; case AttachedPositionFunction AttachedPositionFunction: SpawnAttachedPositionFunction(AttachedPositionFunction); break; + case QuadFact QuadFact: + SpawnQuad(QuadFact); break; + case ConeVolumeFact ConeVolumeFact: + SpawnCone(ConeVolumeFact); break; + case TruncatedConeVolumeFact TruncatedConeVolumeFact: + SpawnTruncatedCone(TruncatedConeVolumeFact); break; default: break; }; } @@ -133,7 +143,7 @@ public void SpawnRing(CircleFact circleFact, Transform parent = null) { GameObject ring = GameObject.Instantiate(Ring, parent); - var tori = ring.GetComponentsInChildren<TorusGenerator>(); + TorusGenerator[] tori = ring.GetComponentsInChildren<TorusGenerator>(); foreach (var torus in tori) torus.torusRadius = circleFact.radius + (float)Math3d.vectorPrecission; } @@ -145,6 +155,53 @@ public void SpawnCircle(CircleFact circleFact, Transform parent = null) circle.transform.localScale = Vector3.Scale(circle.transform.localScale, circleFact.LocalScale); } + public void SpawnQuad(QuadFact fact) + { + GameObject prism = GameObject.Instantiate(Prism); + fact.WorldRepresentation = prism.GetComponentInChildren<FactObject3D>(); + fact.WorldRepresentation.Fact = fact; + + prism.transform.SetPositionAndRotation(fact.Position, fact.Rotation); + + PrismGenerator[] prisms = prism.GetComponentsInChildren<PrismGenerator>(); + foreach (var gen in prisms) + gen.Vertices = fact.Points.Select(p => p.Position).ToArray(); + } + + public void SpawnCone(ConeVolumeFact fact) + { + GameObject prism = GameObject.Instantiate(Cone); + fact.WorldRepresentation = prism.GetComponentInChildren<FactObject3D>(); + fact.WorldRepresentation.Fact = fact; + + prism.transform.SetPositionAndRotation(fact.Position, fact.Rotation); + + ConeGenerator[] prisms = prism.GetComponentsInChildren<ConeGenerator>(); + foreach (var gen in prisms) + { + gen.topPosition = fact.Point.Position - fact.Circle.Position; + gen.topRadius = 0f; + gen.bottomRadius = fact.Circle.radius; + } + } + + public void SpawnTruncatedCone(TruncatedConeVolumeFact fact) + { + GameObject prism = GameObject.Instantiate(Cone); + fact.WorldRepresentation = prism.GetComponentInChildren<FactObject3D>(); + fact.WorldRepresentation.Fact = fact; + + prism.transform.SetPositionAndRotation(fact.Position, fact.Rotation); + + ConeGenerator[] prisms = prism.GetComponentsInChildren<ConeGenerator>(); + foreach (var gen in prisms) + { + gen.topPosition = fact.CircleTop.Position - fact.CircleBase.Position; + gen.topRadius = fact.CircleTop.radius; + gen.bottomRadius = fact.CircleBase.radius; + } + } + public void AnimateNonExistingFactTrigger(Fact fact) { StartCoroutine(_BlossomAndDie(fact)); diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractAngleFact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractAngleFact.cs index 29f40959234283b74420fb120e5766049a2b823d..cab86c43fe4d6423d2e193c7051eea5a9613b68b 100644 --- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractAngleFact.cs +++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractAngleFact.cs @@ -64,7 +64,7 @@ protected AbstractAngleFact(string pid1, string pid2, string pid3, float angle, public override bool HasDependentFacts => true; /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() + protected override string[] GetDependentFactIds() => new string[] { Pid1, Pid2, Pid3 }; protected override void RecalculateTransform() diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractLineFact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractLineFact.cs index e8aca57e0428fb0c71966556fb045e9663956b16..6e9cdbc21250acff58c6b4011d3a252bb2e5e380 100644 --- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractLineFact.cs +++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractLineFact.cs @@ -87,7 +87,7 @@ protected override void RecalculateTransform() public override bool HasDependentFacts => true; /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() + protected override string[] GetDependentFactIds() => new string[] { Pid1, Pid2 }; } diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/CircleFact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/CircleFact.cs new file mode 100644 index 0000000000000000000000000000000000000000..965ef2955f3c270b85feb918dd339f3beee6b507 --- /dev/null +++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/CircleFact.cs @@ -0,0 +1,1037 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using Newtonsoft.Json; +using REST_JSON_API; + +/// <summary> +/// A Circle that is made out of a middle point, a plane and a radius +/// </summary> +public class CircleFact : FactWrappedCRTP<CircleFact> +{ + /// <summary> defining the middle point of the circle </summary> + public string PidCenter; + /// <summary> defining the base point of the circle plane </summary> + public string PidBase; + + [JsonIgnore] + public PointFact PointCenter { get => (PointFact)FactRecorder.AllFacts[PidCenter]; } + [JsonIgnore] + public PointFact PointBase { get => (PointFact)FactRecorder.AllFacts[PidBase]; } + + /// <summary> radius of the circle </summary> + public float radius; + /// <summary> normal vector of the plane </summary> + public Vector3 normal; + + /// <summary> \copydoc Fact.Fact </summary> + public CircleFact() : base() + { + this.normal = Vector3.zero; + this.PidCenter = null; + this.PidBase = null; + this.radius = 0; + } + + /// <summary> + /// Standard Constructor: + /// Initiates <see cref="PidCenter"/>, <see cref="PidBase"/>, <see cref="radius"/>,<see cref="dir1"/>,<see cref="dir2"/>, <see cref="Fact._URI"/> and creates MMT %Fact Server-Side + /// </summary> + /// <param name="pid1">sets <see cref="PidCenter"/></param> + /// <param name="pid2">sets <see cref="PidBase"/></param> + /// <param name="radius">sets <see cref="radius"/></param> + /// <param name="normal">sets <see cref="normal"/></param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public CircleFact(string pid1, string pid2, float radius, Vector3 normal, FactRecorder organizer) : base(organizer) + { + this.PidCenter = pid1; + this.PidBase = pid2; + + this.radius = radius; + this.normal = normal; + + SendToMMT(); + } + + protected override void RecalculateTransform() + { + Position = PointCenter.Position; + { //Rotation + Vector3 arbitary_not_normal = normal == Vector3.forward ? Vector3.right : Vector3.forward; + Vector3 forwoard = Vector3.Cross(arbitary_not_normal, normal); + + Rotation = Quaternion.LookRotation(forwoard, normal); + } + LocalScale = new Vector3(radius, 1, radius); + } + + /// <summary> + /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. + /// </summary> + /// <param name="Pid1">sets <see cref="PidCenter"/></param> + /// <param name="Pid2">sets <see cref="PidBase"/></param> + /// <param name="radius">sets <see cref="radius"/></param> + /// <param name="normal">sets <see cref="normal"/></param> + /// <param name="backendURI">MMT URI</param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public CircleFact(string Pid1, string Pid2, float radius, Vector3 normal, string backendURI, FactRecorder organizer) : base(organizer) + { + this.PidCenter = Pid1; + this.PidBase = Pid2; + + this.radius = radius; + this.normal = normal; + + this._URI = backendURI; + _ = this.Label; + } + + /// <summary> + /// parses the Circlefact response of the MMT-Server + /// </summary> + /// \copydoc Fact.parseFact(ScrollFact) + public new static CircleFact parseFact(MMTFact fact) + { + if (((MMTGeneralFact)fact).defines is not OMA df) + return null; + + OMA planeOMA = (OMA)df.arguments[0]; + string planeApplicant = ((OMS)planeOMA.applicant).uri; + + Vector3 normal; + // Getting the plane + // IN case of a normale plane + if (planeApplicant.Equals(MMTConstants.pointNormalPlane)) + { + //OMA pointAOMA = (OMA)planeOMA.arguments[0]; + normal = SOMDoc.MakeVector3((OMA)planeOMA.arguments[1]); + } + // In case of parametrized plane + else if (planeApplicant.Equals(MMTConstants.ParametrizedPlane)) + { + Vector3 v = SOMDoc.MakeVector3((OMA)planeOMA.arguments[1]); + Vector3 w = SOMDoc.MakeVector3((OMA)planeOMA.arguments[2]); + + normal = Vector3.Cross(v, w).normalized; + } + // incase of smth else. Shouldn't hapepen unless there is an error + else throw new ArgumentException("Invalid planeApplicant: " + planeApplicant); + + // get the mid point uri + string parse_id_M = df.arguments[1].ToString(); + string M_uri = ParsingDictionary.parseTermsToId[parse_id_M]; + string A_uri = ParsingDictionary.parseTermsToId[planeOMA.arguments[0].ToString()]; + float radius = ((OMF)df.arguments[2]).@float; + + if (!FactRecorder.AllFacts.ContainsKey(M_uri) + || !FactRecorder.AllFacts.ContainsKey(A_uri)) + return null; //If dependent facts do not exist return null + + return new CircleFact(M_uri, A_uri, radius, normal, fact.@ref.uri, StageStatic.stage.factState); + } + + /// \copydoc Fact.generateLabel + protected override string generateLabel() + => "○" + PointCenter.Label; + + /// <summary> + /// Constructs struct for right-angled MMT %Fact <see cref="AddFactResponse"/> + /// </summary> + /// <param name="Pid1"> <see cref="PidCenter"/></param> + /// <param name="p2URI"> <see cref="PidBase"/></param> + /// <param name="radius"> <see cref="radius"/></param> + /// <returns>struct for <see cref="AddFactResponse"/></returns> + public override MMTFact MakeMMTDeclaration() + { + SOMDoc[] outerArguments = new SOMDoc[] + { + //CirclePlane, + new OMA( + //PointNormalPlane, + new OMS(MMTConstants.pointNormalPlane), + //planeArgs, + new SOMDoc[] { + //base point of the circle plane?, + new OMS(PidBase), + //NormalVector, + new OMA( + //"Vector" + new OMS(MMTConstants.Tuple), + //normalArgs, + new[] { + new OMF(normal.x), + new OMF(normal.y), + new OMF(normal.z) + } + ), + } + ), + //middlePoint, + new OMS(PidCenter), + //Radius, + new OMF(radius), + }; + + // Do i need this here? doubt + SOMDoc tp = new OMS(MMTConstants.CircleType3d); + SOMDoc df = new OMA(new OMS(MMTConstants.MkCircle3d), outerArguments); + + return new MMTGeneralFact(Label, tp, df); + } + + /// \copydoc Fact.hasDependentFacts + public override bool HasDependentFacts => true; + + /// \copydoc Fact.getDependentFactIds + protected override string[] GetDependentFactIds() + => new string[] { PidCenter, PidBase }; + + /// \copydoc Fact.Equivalent(Fact, Fact) + protected override bool EquivalentWrapped(CircleFact f1, CircleFact f2) + => DependentFactsEquivalent(f1, f2) + && Math3d.IsApproximatelyEqual(f1.normal, f2.normal) + && Mathf.Approximately(f1.radius, f2.radius); + + protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) + => new CircleFact(old_to_new[this.PidCenter], old_to_new[this.PidBase], this.radius, this.normal, organizer); +} + +/// <summary> +/// A RadiusFact that corresponds to a <see cref="CircleFact">PointFacts</see> and has a float value (the actual radius). +/// </summary> +public class RadiusFact : FactWrappedCRTP<RadiusFact> +{ + /// <summary> The circle corresponding to the radius </summary> + public string Cid1; + + [JsonIgnore] + public CircleFact Circle { get => (CircleFact)FactRecorder.AllFacts[Cid1]; } + + /// <summary> The radius as a float </summary> + public float rad; + + /// <summary> \copydoc Fact.Fact </summary> + public RadiusFact() : base() + { + this.Cid1 = null; + this.rad = 0.0f; + } + + /// <summary> + /// Standard Constructor: + /// Initiates <see cref="Cid1"/> and <see cref="rad"/> + /// </summary> + /// <param name="cid1">sets <see cref="Cid1"/></param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public RadiusFact(string cid1, FactRecorder organizer) : base(organizer) + { + this.Cid1 = cid1; + this.rad = Circle.radius; + + SendToMMT(); + } + + protected override void RecalculateTransform() + { + Position = Circle.Position; + Rotation = Circle.Rotation; + } + + /// <summary> + /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. + /// </summary> + /// <param name="Cid1">sets <see cref="Cid1"/></param> + /// <param name="backendURI">MMT URI</param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public RadiusFact(string Cid1, string backendURI, FactRecorder organizer) : base(organizer) + { + this.Cid1 = Cid1; + + this._URI = backendURI; + _ = this.Label; + } + + /// \copydoc Fact.parseFact(ScrollFact) + public new static RadiusFact parseFact(MMTFact fact) + { + string CircleUri = ((OMS)((OMA)((MMTValueFact)fact).lhs).arguments[0]).uri; + + if (!FactRecorder.AllFacts.ContainsKey(CircleUri)) + return null; + + return new RadiusFact(CircleUri, fact.@ref.uri, StageStatic.stage.factState); + } + + /// \copydoc Fact.generateLabel + protected override string generateLabel() + => "r " + Circle.Label; + + /// <summary> + /// Constructs struct for not-right-angled MMT %Fact <see cref="AddFactResponse"/> + /// </summary> + /// <param name="rad"> see <see cref="rad"/></param> + /// <param name="c1URI"> see <see cref="Cid1"/></param> + + public override MMTFact MakeMMTDeclaration() + { + SOMDoc lhs = + new OMA( + new OMS(MMTConstants.RadiusCircleMetric), + new[] { + new OMS(Cid1), + } + ); + + SOMDoc valueTp = new OMS(MMTConstants.RealLit); + SOMDoc value = new OMF(rad); + + return new MMTValueFact(this.Label, lhs, valueTp, value); + } + + /// \copydoc Fact.hasDependentFacts + public override bool HasDependentFacts => true; + + /// \copydoc Fact.getDependentFactIds + protected override string[] GetDependentFactIds() + => new string[] { Cid1 }; + + /// \copydoc Fact.Equivalent(Fact, Fact) + protected override bool EquivalentWrapped(RadiusFact f1, RadiusFact f2) + => DependentFactsEquivalent(f1, f2); + + protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) + => new RadiusFact(old_to_new[this.Cid1], organizer); +} + +/// <summary> +/// Area of a <see cref="CircleFact">CircleFact</see> +/// </summary> +public class AreaCircleFact : FactWrappedCRTP<AreaCircleFact> +{ + /// <summary> the circle <see cref="CircleFact">CircleFact</see> </summary> + public string Cid1; + + [JsonIgnore] + public CircleFact Circle { get => (CircleFact)FactRecorder.AllFacts[Cid1]; } + + /// <summary> the area which is contained by the circle </summary> + public float A; + + + /// <summary> \copydoc Fact.Fact </summary> + public AreaCircleFact() : base() + { + this.Cid1 = null; + this.A = 0.0f; + } + + /// <summary> + /// Standard Constructor: + /// Initiates <see cref="Cid1"/> and creates MMT %Fact Server-Side + /// </summary> + /// <param name="cid1">sets <see cref="Cid1"/></param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public AreaCircleFact(string cid1, FactRecorder organizer) : base(organizer) + { + this.Cid1 = cid1; + + this.A = Circle.radius * Circle.radius * ((float)System.Math.PI); + + SendToMMT(); + } + + protected override void RecalculateTransform() + { + Position = Circle.Position; + Rotation = Circle.Rotation; + } + + /// <summary> + /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. + /// </summary> + /// <param name="Cid1">sets <see cref="Cid1"/></param> + /// <param name="backendURI">MMT URI</param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public AreaCircleFact(string Cid1, string backendURI, FactRecorder organizer) : base(organizer) + { + this.Cid1 = Cid1; + + this._URI = backendURI; + _ = this.Label; + } + + /// \copydoc Fact.parseFact(ScrollFact) + public new static AreaCircleFact parseFact(MMTFact fact) + { + string CircleUri = ((OMS)((OMA)((MMTValueFact)fact).lhs).arguments[0]).uri; + + if (!FactRecorder.AllFacts.ContainsKey(CircleUri)) + return null; + + return new AreaCircleFact(CircleUri, fact.@ref.uri, StageStatic.stage.factState); + } + + /// \copydoc Fact.generateLabel + protected override string generateLabel() + => "A(" + Circle.Label + ")"; + + public override MMTFact MakeMMTDeclaration() + { + SOMDoc lhs = + new OMA( + new OMS(MMTConstants.AreaCircle), + new[] { + new OMS(Cid1), + } + ); + + SOMDoc valueTp = new OMS(MMTConstants.RealLit); + SOMDoc value = new OMF(A); + + return new MMTValueFact(this.Label, lhs, valueTp, value); + } + + /// \copydoc Fact.hasDependentFacts + public override bool HasDependentFacts => true; + + /// \copydoc Fact.getDependentFactIds + protected override string[] GetDependentFactIds() + => new string[] { Cid1 }; + + /// \copydoc Fact.GetHashCode + public override int GetHashCode() + => base.GetHashCode() ^ A.GetHashCode(); + + /// \copydoc Fact.Equivalent(Fact, Fact) + protected override bool EquivalentWrapped(AreaCircleFact f1, AreaCircleFact f2) + => DependentFactsEquivalent(f1, f2); + + protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) + => new AreaCircleFact(old_to_new[this.Cid1], organizer); +} + +/// <summary> +/// A <see cref="PointFact"/> on a <see cref="CircleFact"/> +/// </summary> +public class OnCircleFact : FactWrappedCRTP<OnCircleFact> +{ + /// <summary> the point on the circle </summary> + public string Pid; + /// <summary> the circle, which the point is on </summary> + public string Cid; + + [JsonIgnore] + public PointFact Point { get => (PointFact)FactRecorder.AllFacts[Pid]; } + [JsonIgnore] + public CircleFact Circle { get => (CircleFact)FactRecorder.AllFacts[Cid]; } + + /// <summary> \copydoc Fact.Fact </summary> + public OnCircleFact() : base() + { + this.Pid = null; + this.Cid = null; + } + + /// <summary> + /// Standard Constructor: + /// Initiates <see cref="Pid"/>, <see cref="Rid"/>, <see cref="Fact._URI"/> and creates MMT %Fact Server-Side + /// </summary> + /// <param name="pid">sets <see cref="Pid"/></param> + /// <param name="cid">sets <see cref="Cid"/></param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public OnCircleFact(string pid, string cid, FactRecorder organizer) : base(organizer) + { + this.Pid = pid; + this.Cid = cid; ; + + SendToMMT(); + } + + protected override void RecalculateTransform() + { + Position = Point.Position; + Rotation = Circle.Rotation; + } + + /// <summary> + /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. + /// </summary> + /// <param name="pid">sets <see cref="Pid"/></param> + /// <param name="cid">sets <see cref="Cid"/></param> + /// <param name="uri">MMT URI</param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public OnCircleFact(string pid, string cid, string uri, FactRecorder organizer) : base(organizer) + { + this.Pid = pid; + this.Cid = cid; + this._URI = uri; + _ = this.Label; + } + + /// \copydoc Fact.parseFact(ScrollFact) + public new static OnCircleFact parseFact(MMTFact fact) + { + if (((MMTGeneralFact)fact).type is not OMA type) + return null; + + string circleUri = ((OMS)((OMA)type.arguments[0]).arguments[0]).uri; + string pointUri = ((OMS)((OMA)type.arguments[0]).arguments[1]).uri; + + if (!FactRecorder.AllFacts.ContainsKey(pointUri) + || !FactRecorder.AllFacts.ContainsKey(circleUri)) + return null; + + return new OnCircleFact(pointUri, circleUri, fact.@ref.uri, StageStatic.stage.factState); + } + + /// \copydoc Fact.generateLabel + protected override string generateLabel() + => Point.Label + "∈" + Circle.Label; + + /// \copydoc Fact.hasDependentFacts + public override bool HasDependentFacts => true; + + /// \copydoc Fact.getDependentFactIds + protected override string[] GetDependentFactIds() + => new string[] { Pid, Cid }; + + /// \copydoc Fact.Equivalent(Fact, Fact) + protected override bool EquivalentWrapped(OnCircleFact c1, OnCircleFact c2) + => DependentFactsEquivalent(c1, c2); + + protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) + => new OnCircleFact(old_to_new[this.Pid], old_to_new[this.Cid], organizer); + + public override MMTFact MakeMMTDeclaration() + { + SOMDoc tp = + new OMA( + new OMS(MMTConstants.Ded), + new[] { + new OMA( + new OMS(MMTConstants.OnCircle), + new[] { + new OMS(Cid), + new OMS(Pid), + }),}); + + SOMDoc df = null; + + return new MMTGeneralFact(Label, tp, df); + } +} + +/// <summary> +/// Angle comprised of a line and a circle +/// </summary> +public class AngleCircleLineFact : FactWrappedCRTP<AngleCircleLineFact> +{ + /// @{ <summary> + /// One <see cref="Fact.Id">Id</see> of a <see cref="RayFact">RayFact</see> and a <see cref="CircleFact">CircleFact</see> defining Angle [<see cref="Cid1"/>, <see cref="Rid2"/>]. + /// </summary> + public string Cid1, Rid2; + /// @} + + [JsonIgnore] + public AbstractLineFact Ray { get => (AbstractLineFact)FactRecorder.AllFacts[Rid2]; } + [JsonIgnore] + public CircleFact Circle { get => (CircleFact)FactRecorder.AllFacts[Cid1]; } + + //TODO? deg or rad? + [JsonIgnore] + public float angle; + + [JsonIgnore] + public Vector3 intersection; + + /// <summary> \copydoc Fact.Fact </summary> + public AngleCircleLineFact() : base() + { + this.Cid1 = null; + this.Rid2 = null; + this.angle = 0.0f; + } + + /// <summary> + /// Standard Constructor: + /// Initiates <see cref="Cid1"/>, <see cref="Rid2"/>, <see cref="angle"/> <see cref="Fact._URI"/> and creates MMT %Fact Server-Side + /// </summary> + /// <param name="cid1">sets <see cref="Cid1"/></param> + /// <param name="rid2">sets <see cref="Rid2"/></param> + /// <param name="angle"> sets the angle </param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public AngleCircleLineFact(string cid1, string rid2, FactRecorder organizer) : base(organizer) + { + this.Cid1 = cid1; + this.Rid2 = rid2; + this.angle = Math3d.AngleVectorPlane(Ray.Dir, Circle.normal).ToDegrees(); + Math3d.LinePlaneIntersection(out intersection, Ray.Point1.Position, Ray.Dir, Circle.normal, Circle.Position); + + SendToMMT(); + } + + protected override void RecalculateTransform() + { + Position = intersection; + { //Rotation + Vector3 from = (Circle.Position - Position).normalized; + + Vector3 angle_to = Math3d.IsApproximatelyEqual(intersection, Ray.Point1.Position) + ? Ray.Point2.Position + : Ray.Point1.Position; + Vector3 to = (angle_to - Position).normalized; + + Vector3 up = Vector3.Cross(to, from); + Vector3 forwoard = (from + to).normalized; + + if (up.sqrMagnitude < Math3d.vectorPrecission) + { //Angle is 180° (or 0°) + Vector3 arbitary = up.normalized == Vector3.forward ? Vector3.right : Vector3.forward; + up = Vector3.Cross(arbitary, to); + forwoard = Vector3.Cross(up, to); + } + + Rotation = Quaternion.LookRotation(forwoard, up); + } + } + + /// <summary> + /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. + /// </summary> + /// <param name="Cid1">sets <see cref="Cid1"/></param> + /// <param name="´Rid2">sets <see cref="Rid2"/></param> + /// <param name="angle"> sets the angle </param> + /// <param name="backendURI">MMT URI</param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public AngleCircleLineFact(string Cid1, string Rid2, float angle, string backendURI, FactRecorder organizer) : base(organizer) + { + this.Cid1 = Cid1; + this.Rid2 = Rid2; + this.angle = angle; + + this._URI = backendURI; + _ = this.Label; + } + + /// \copydoc Fact.parseFact(ScrollFact) + public new static AngleCircleLineFact parseFact(MMTFact fact) + { + if (((MMTValueFact)fact).lhs is not OMA lhs) + return null; + + // init it with 0 degrees, so we don't accidentally generate orthogonalfacts + // and the parsing works correctly if smb ever adds a scroll for this + float angle = 0.0f; + + if (((MMTValueFact)fact).value is OMF oMFangle) + angle = oMFangle.@float; + + string CircleUri = ((OMS)lhs.arguments[0]).uri; + string RayUri = ((OMS)lhs.arguments[1]).uri; + + if (!FactRecorder.AllFacts.ContainsKey(CircleUri) + || !FactRecorder.AllFacts.ContainsKey(RayUri)) + return null; + + return new AngleCircleLineFact(CircleUri, RayUri, angle, fact.@ref.uri, StageStatic.stage.factState); + } + + /// \copydoc Fact.generateLabel + protected override string generateLabel() + => "∠" + Circle.Label + Ray.Label; + + public override MMTFact MakeMMTDeclaration() + { + SOMDoc lhs = + new OMA( + new OMS(MMTConstants.AnglePlaneLine), + new[] { + new OMS(Cid1), + new OMS(Rid2), + } + ); + + SOMDoc valueTp = new OMS(MMTConstants.RealLit); + SOMDoc value = new OMF(angle); + + return new MMTValueFact(this.Label, lhs, valueTp, value); + } + + /// \copydoc Fact.hasDependentFacts + public override bool HasDependentFacts => true; + + /// \copydoc Fact.getDependentFactIds + protected override string[] GetDependentFactIds() + => new string[] { Cid1, Rid2 }; + + /// \copydoc Fact.Equivalent(Fact, Fact) + protected override bool EquivalentWrapped(AngleCircleLineFact f1, AngleCircleLineFact f2) + => DependentFactsEquivalent(f1, f2); + + protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) + => new AngleCircleLineFact(old_to_new[this.Cid1], old_to_new[this.Rid2], organizer); +} + +/// <summary> +/// The fact that the plane of a <see cref="CircleFact">CircleFact</see> and the line <see cref="RayFact>RayFact</see> are orthogonal +/// </summary> +public class OrthogonalCircleLineFact : FactWrappedCRTP<OrthogonalCircleLineFact> +{ + /// <summary> a <see cref="CircleFact">CircleFact</see> describing the base area </summary> + public string Cid1; + [JsonIgnore] + public CircleFact Circle { get => (CircleFact)FactRecorder.AllFacts[Cid1]; } + + /// <summary> a <see cref="RayFact">Rayfact</see> describing the line </summary> + public string Lid1; + [JsonIgnore] + public AbstractLineFact Ray { get => (AbstractLineFact)FactRecorder.AllFacts[Lid1]; } + + //TODO? deg or rad? + [JsonIgnore] + public float angle = 90f; + + [JsonIgnore] + public Vector3 intersection; + + + /// <summary> \copydoc Fact.Fact </summary> + public OrthogonalCircleLineFact() : base() + { + this.Cid1 = null; + this.Lid1 = null; + } + + /// <summary> + /// Standard Constructor: + /// Initiates members and creates MMT %Fact Server-Side + /// </summary> + /// <param name="cid1">sets <see cref="Cid1"/></param> + /// <param name="lid1">sets <see cref="Lid1"/></param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public OrthogonalCircleLineFact(string cid1, string lid1, FactRecorder organizer) : base(organizer) + { + this.Cid1 = cid1; + this.Lid1 = lid1; + Math3d.LinePlaneIntersection(out intersection, Ray.Point1.Position, Ray.Dir, Circle.normal, Circle.Position); + + SendToMMT(); + } + + protected override void RecalculateTransform() + { + Position = intersection; + { //Rotation + Vector3 from = (Circle.Position - Position).normalized; + + Vector3 angle_to = Math3d.IsApproximatelyEqual(intersection, Ray.Point1.Position) + ? Ray.Point2.Position + : Ray.Point1.Position; + Vector3 to = (angle_to - Position).normalized; + + Vector3 up = Vector3.Cross(to, from); + Vector3 forward = (from + to).normalized; + Rotation = Quaternion.LookRotation(forward, up); + } + } + + /// <summary> + /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. + /// </summary> + /// <param name="Cid1">sets <see cref="Cid1"/></param> + /// <param name="Lid1">sets <see cref="Lid1"/></param> + /// <param name="backendURI">MMT URI</param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public OrthogonalCircleLineFact(string Cid1, string Lid1, string backendURI, FactRecorder organizer) : base(organizer) + { + this.Cid1 = Cid1; + this.Lid1 = Lid1; + + this._URI = backendURI; + _ = this.Label; + } + + /// \copydoc Fact.parseFact(ScrollFact) + public new static OrthogonalCircleLineFact parseFact(MMTFact fact) + { + if (((MMTGeneralFact)fact).type is not OMA type) + return null; + + string CircleUri = ((OMS)((OMA)type.arguments[0]).arguments[0]).uri; + string LineUri = ((OMS)((OMA)type.arguments[0]).arguments[1]).uri; + + if (!FactRecorder.AllFacts.ContainsKey(CircleUri) + || !FactRecorder.AllFacts.ContainsKey(LineUri)) + return null; + + return new OrthogonalCircleLineFact(CircleUri, LineUri, fact.@ref.uri, StageStatic.stage.factState); + } + + /// \copydoc Fact.generateLabel + protected override string generateLabel() + => Circle.Label + "⊥" + Ray.Label; + + public override MMTFact MakeMMTDeclaration() + { + SOMDoc tp = new OMA( + new OMS(MMTConstants.Ded), + new[]{ + new OMA( + new OMS(MMTConstants.OrthoCircleLine), + new[] { + new OMS(Cid1), + new OMS(Lid1), + } + ), + } + ); + + SOMDoc df = null; + + return new MMTGeneralFact(this.Label, tp, df); + } + + /// \copydoc Fact.hasDependentFacts + public override bool HasDependentFacts => true; + + /// \copydoc Fact.getDependentFactIds + protected override string[] GetDependentFactIds() + => new string[] { Cid1, Lid1 }; + + /// \copydoc Fact.Equivalent(Fact, Fact) + protected override bool EquivalentWrapped(OrthogonalCircleLineFact f1, OrthogonalCircleLineFact f2) + => DependentFactsEquivalent(f1, f2); + + protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) + => new OrthogonalCircleLineFact(old_to_new[this.Cid1], old_to_new[this.Lid1], organizer); +} + +/// <summary> +/// A fact that describes, that two circles have the same size and is comprised of two <see cref="CircleFact">CircleFacts</see> +/// </summary> +public class EqualCirclesFact : FactWrappedCRTP<EqualCirclesFact> +{ + /// @{ <summary> + /// two circles that are meant to be equal in area + /// </summary> + public string Cid1, Cid2; + /// @} + + [JsonIgnore] + public CircleFact Circle1 { get => (CircleFact)FactRecorder.AllFacts[Cid1]; } + [JsonIgnore] + public CircleFact Circle2 { get => (CircleFact)FactRecorder.AllFacts[Cid2]; } + + /// <summary> \copydoc Fact.Fact </summary> + public EqualCirclesFact() : base() + { + this.Cid1 = null; + this.Cid2 = null; + } + + /// <summary> + /// Standard Constructor: + /// Initiates members and creates MMT %Fact Server-Side + /// </summary> + /// <param name="cid1">sets <see cref="Cid1"/></param> + /// <param name="cid2">sets <see cref="Cid2"/></param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public EqualCirclesFact(string cid1, string cid2, FactRecorder organizer) : base(organizer) + { + this.Cid1 = cid1; + this.Cid2 = cid2; + + SendToMMT(); + } + + protected override void RecalculateTransform() + { + Position = Circle1.Position; + Rotation = Circle1.Rotation; + } + + /// <summary> + /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. + /// </summary> + /// <param name="Cid1">sets <see cref="Cid1"/></param> + /// <param name="Cid2">sets <see cref="Cid2"/></param> + /// <param name="backendURI">MMT URI</param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public EqualCirclesFact(string Cid1, string Cid2, string backendURI, FactRecorder organizer) : base(organizer) + { + this.Cid1 = Cid1; + this.Cid2 = Cid2; + + this._URI = backendURI; + _ = this.Label; + } + + /// \copydoc Fact.parseFact(ScrollFact) + public new static EqualCirclesFact parseFact(MMTFact fact) + { + if (((MMTGeneralFact)fact).type is not OMA proof_OMA) // proof DED + return null; + + OMA parallel_circles_OMA = (OMA)proof_OMA.arguments[0]; // parallel + + string circleAUri = ((OMS)parallel_circles_OMA.arguments[0]).uri; + string circleBUri = ((OMS)parallel_circles_OMA.arguments[1]).uri; + + if (!FactRecorder.AllFacts.ContainsKey(circleAUri) + || !FactRecorder.AllFacts.ContainsKey(circleBUri)) + return null; + + return new EqualCirclesFact(circleAUri, circleBUri, fact.@ref.uri, StageStatic.stage.factState); + } + + /// \copydoc Fact.generateLabel + protected override string generateLabel() + => Circle1.Label + " ≠" + Circle2.Label; + + public override MMTFact MakeMMTDeclaration() + { + SOMDoc tp = new OMA( + new OMS(MMTConstants.Ded), + new[] { + new OMA( + new OMS(MMTConstants.EqualityCircles), + new[] { + new OMS(Cid1), + new OMS(Cid2), + } + ) + } + ); + + SOMDoc df = null; + + return new MMTGeneralFact(this.Label, tp, df); + } + + /// \copydoc Fact.hasDependentFacts + public override bool HasDependentFacts => true; + + /// \copydoc Fact.getDependentFactIds + protected override string[] GetDependentFactIds() + => new string[] { Cid1, Cid2 }; + + /// \copydoc Fact.Equivalent(Fact, Fact) + protected override bool EquivalentWrapped(EqualCirclesFact f1, EqualCirclesFact f2) + => DependentFactsEquivalent(f1, f2); + + protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) + => new EqualCirclesFact(old_to_new[this.Cid1], old_to_new[this.Cid2], organizer); +} + +/// <summary> +/// A fact that describes, that two circles have not the same size and is comprised of two <see cref="CircleFact">CircleFacts</see> +/// </summary> +public class UnEqualCirclesFact : FactWrappedCRTP<UnEqualCirclesFact> +{ + /// @{ <summary> + /// two circles that are meant to be unequal in area + /// </summary> + public string Cid1, Cid2; + /// @} + + [JsonIgnore] + public CircleFact Circle1 { get => (CircleFact)FactRecorder.AllFacts[Cid1]; } + [JsonIgnore] + public CircleFact Circle2 { get => (CircleFact)FactRecorder.AllFacts[Cid2]; } + + /// <summary> \copydoc Fact.Fact </summary> + public UnEqualCirclesFact() : base() + { + this.Cid1 = null; + this.Cid2 = null; + } + + /// <summary> + /// Standard Constructor: + /// Initiates members and creates MMT %Fact Server-Side + /// </summary> + /// <param name="cid1">sets <see cref="Cid1"/></param> + /// <param name="cid2">sets <see cref="Cid2"/></param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public UnEqualCirclesFact(string cid1, string cid2, FactRecorder organizer) : base(organizer) + { + this.Cid1 = cid1; + this.Cid2 = cid2; + + SendToMMT(); + } + + protected override void RecalculateTransform() + { + Position = Circle2.Position; + Rotation = Circle2.Rotation; + } + + /// <summary> + /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. + /// </summary> + /// <param name="Cid1">sets <see cref="Cid1"/></param> + /// <param name="Cid2">sets <see cref="Cid2"/></param> + /// <param name="backendURI">MMT URI</param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public UnEqualCirclesFact(string Cid1, string Cid2, string backendURI, FactRecorder organizer) : base(organizer) + { + this.Cid1 = Cid1; + this.Cid2 = Cid2; + + this._URI = backendURI; + _ = this.Label; + } + + /// \copydoc Fact.parseFact(ScrollFact) + public new static UnEqualCirclesFact parseFact(MMTFact fact) + { + if (((MMTGeneralFact)fact).type is not OMA proof_OMA) // proof DED + return null; + + OMA unequal_circles_OMA = (OMA)proof_OMA.arguments[0]; // unequal + + string circleAUri = ((OMS)unequal_circles_OMA.arguments[0]).uri; + string circleBUri = ((OMS)unequal_circles_OMA.arguments[1]).uri; + + if (!FactRecorder.AllFacts.ContainsKey(circleAUri) + || !FactRecorder.AllFacts.ContainsKey(circleBUri)) + return null; + + return new UnEqualCirclesFact(circleAUri, circleBUri, fact.@ref.uri, StageStatic.stage.factState); + } + + /// \copydoc Fact.generateLabel + protected override string generateLabel() + => Circle1.Label + " = " + Circle2.Label; + + public override MMTFact MakeMMTDeclaration() + { + SOMDoc tp = new OMA( + new OMS(MMTConstants.Ded), + new[] { + new OMA(new OMS(MMTConstants.UnEqualityCircles), + new[] { + new OMS(Cid1), + new OMS(Cid2), + }),}); + + SOMDoc df = null; + + return new MMTGeneralFact(this.Label, tp, df); + } + + /// \copydoc Fact.hasDependentFacts + public override bool HasDependentFacts => true; + + /// \copydoc Fact.getDependentFactIds + protected override string[] GetDependentFactIds() + => new string[] { Cid1, Cid2 }; + + /// \copydoc Fact.Equivalent(Fact, Fact) + protected override bool EquivalentWrapped(UnEqualCirclesFact f1, UnEqualCirclesFact f2) + => DependentFactsEquivalent(f1, f2); + + protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) + => new UnEqualCirclesFact(old_to_new[this.Cid1], old_to_new[this.Cid2], organizer); +} diff --git a/Assets/Scripts/InventoryStuff/PointWrapper.cs.meta b/Assets/Scripts/InteractionEngine/FactHandling/Facts/CircleFact.cs.meta similarity index 83% rename from Assets/Scripts/InventoryStuff/PointWrapper.cs.meta rename to Assets/Scripts/InteractionEngine/FactHandling/Facts/CircleFact.cs.meta index 3af2b1ec95cab1d9da9b3d31c5e358085f051b88..6b925f98b5fa1d30727608f484bd1cf2297f4019 100644 --- a/Assets/Scripts/InventoryStuff/PointWrapper.cs.meta +++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/CircleFact.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d5e5e87a22cc1714dbacaa2632c40e98 +guid: 6862429fb0d51da458debc64eb68530c MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs index 2fa46e3e84c42154f8251dc28136934ebedcfe19..e34343bef8ba59a6e2c0643ec4c45d055e65314e 100644 --- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs +++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs @@ -6,6 +6,7 @@ using JsonSubTypes; using System.Linq; using REST_JSON_API; +using System.Drawing; public static class ParsingDictionary { @@ -57,6 +58,8 @@ public static class ParsingDictionary UnEqualCirclesFact.parseFact }, { MMTConstants.ListLiteral, ListFact.parseFact }, + { MMTConstants.Wall, + QuadFact.parseFact }, }; // TODO: get rid of this @@ -92,8 +95,7 @@ public static class ParsingDictionary [JsonSubtypes.KnownSubType(typeof(FunctionCallFact), nameof(FunctionCallFact))] [JsonSubtypes.KnownSubType(typeof(ListFact), nameof(ListFact))] [JsonSubtypes.KnownSubType(typeof(TupleFact), nameof(TupleFact))] -//[JsonSubtypes.KnownSubType(typeof(FunctionFact<T0, TResult>), "FunctionFact<T0, TResult>")] //TODO: generics? => nameof does not work (generic agnostic) -//[JsonSubtypes.KnownSubType(typeof(FunctionFactFloat<Vector3>), "FunctionFact<System.Single, UnityEngine.Vector3>")] +[JsonSubtypes.KnownSubType(typeof(QuadFact), nameof(QuadFact))] public abstract class Fact { /// <summary> @@ -124,12 +126,12 @@ public abstract class Fact /// <returns> array of Fact <see cref="Id"> Ids </see> on which this Fact depends.</returns> /// <example><see cref="AngleFact"/> needs 3 <see cref="PointFact"/>s to be defined.</example> [JsonIgnore] - public string[] DependentFactIds => _DependentFactIds ??= GetGetDependentFactIds(); + public string[] DependentFactIds => _DependentFactIds ??= GetDependentFactIds(); private string[] _DependentFactIds; /// <returns> array of Fact <see cref="Id"> Ids </see> on which this Fact depends.</returns> /// <example><see cref="AngleFact"/> needs 3 <see cref="PointFact"/>s to be defined.</example> - protected abstract string[] GetGetDependentFactIds(); + protected abstract string[] GetDependentFactIds(); /// <value> /// Unique Id. e.g.: MMT URI @@ -601,7 +603,7 @@ public PointFact(Vector3 point, string uri, FactRecorder organizer) : base(organ public override bool HasDependentFacts => false; /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() + protected override string[] GetDependentFactIds() => new string[] { }; /// \copydoc Fact.GetHashCode @@ -728,7 +730,7 @@ protected override string generateLabel() public override bool HasDependentFacts => true; /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() + protected override string[] GetDependentFactIds() => new string[] { Pid, Rid }; protected override bool EquivalentWrapped(OnLineFact f1, OnLineFact f2) @@ -856,7 +858,7 @@ public override MMTFact MakeMMTDeclaration() public override bool HasDependentFacts => true; /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() + protected override string[] GetDependentFactIds() => new string[] { Lid1, Lid2 }; /// \copydoc Fact.Equivalent(Fact, Fact) @@ -868,1433 +870,110 @@ protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, F } /// <summary> -/// A Circle that is made out of a middle point, a plane and a radius +/// Used for BouncingScroll /// </summary> -public class CircleFact : FactWrappedCRTP<CircleFact> +public class QuadFact : FactWrappedCRTP<QuadFact> { - /// <summary> defining the middle point of the circle </summary> - public string Pid1; - /// <summary> defining the base point of the circle plane </summary> - public string Pid2; - - [JsonIgnore] - public PointFact Point1 { get => (PointFact)FactRecorder.AllFacts[Pid1]; } - [JsonIgnore] - public PointFact Point2 { get => (PointFact)FactRecorder.AllFacts[Pid2]; } - - /// <summary> radius of the circle </summary> - public float radius; - /// <summary> normal vector of the plane </summary> - public Vector3 normal; - - /// <summary> \copydoc Fact.Fact </summary> - public CircleFact() : base() - { - this.normal = Vector3.zero; - this.Pid1 = null; - this.Pid2 = null; - this.radius = 0; - } - - /// <summary> - /// Standard Constructor: - /// Initiates <see cref="Pid1"/>, <see cref="Pid2"/>, <see cref="radius"/>,<see cref="dir1"/>,<see cref="dir2"/>, <see cref="Fact._URI"/> and creates MMT %Fact Server-Side - /// </summary> - /// <param name="pid1">sets <see cref="Pid1"/></param> - /// <param name="pid2">sets <see cref="Pid2"/></param> - /// <param name="radius">sets <see cref="radius"/></param> - /// <param name="normal">sets <see cref="normal"/></param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public CircleFact(string pid1, string pid2, float radius, Vector3 normal, FactRecorder organizer) : base(organizer) - { - this.Pid1 = pid1; - this.Pid2 = pid2; - - this.radius = radius; - this.normal = normal; - - SendToMMT(); - } - - protected override void RecalculateTransform() - { - Position = Point1.Position; - { //Rotation - Vector3 arbitary_not_normal = normal == Vector3.forward ? Vector3.right : Vector3.forward; - Vector3 forwoard = Vector3.Cross(arbitary_not_normal, normal); - - Rotation = Quaternion.LookRotation(forwoard, normal); - } - LocalScale = new Vector3(radius, 1, radius); - } - - /// <summary> - /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. - /// </summary> - /// <param name="Pid1">sets <see cref="Pid1"/></param> - /// <param name="Pid2">sets <see cref="Pid2"/></param> - /// <param name="radius">sets <see cref="radius"/></param> - /// <param name="normal">sets <see cref="normal"/></param> - /// <param name="backendURI">MMT URI</param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public CircleFact(string Pid1, string Pid2, float radius, Vector3 normal, string backendURI, FactRecorder organizer) : base(organizer) - { - this.Pid1 = Pid1; - this.Pid2 = Pid2; - - this.radius = radius; - this.normal = normal; - - this._URI = backendURI; - _ = this.Label; - } - - /// <summary> - /// parses the Circlefact response of the MMT-Server - /// </summary> - /// \copydoc Fact.parseFact(ScrollFact) - public new static CircleFact parseFact(MMTFact fact) - { - if (((MMTGeneralFact)fact).defines is not OMA df) - return null; - - OMA planeOMA = (OMA)df.arguments[0]; - string planeApplicant = ((OMS)planeOMA.applicant).uri; - - Vector3 normal; - // Getting the plane - // IN case of a normale plane - if (planeApplicant.Equals(MMTConstants.pointNormalPlane)) - { - //OMA pointAOMA = (OMA)planeOMA.arguments[0]; - normal = SOMDoc.MakeVector3((OMA)planeOMA.arguments[1]); - } - // In case of parametrized plane - else if (planeApplicant.Equals(MMTConstants.ParametrizedPlane)) - { - Vector3 v = SOMDoc.MakeVector3((OMA)planeOMA.arguments[1]); - Vector3 w = SOMDoc.MakeVector3((OMA)planeOMA.arguments[2]); - - normal = Vector3.Cross(v, w).normalized; - } - // incase of smth else. Shouldn't hapepen unless there is an error - else throw new ArgumentException("Invalid planeApplicant: " + planeApplicant); - - // get the mid point uri - string parse_id_M = df.arguments[1].ToString(); - string M_uri = ParsingDictionary.parseTermsToId[parse_id_M]; - string A_uri = ParsingDictionary.parseTermsToId[planeOMA.arguments[0].ToString()]; - float radius = ((OMF)df.arguments[2]).@float; - - if (!FactRecorder.AllFacts.ContainsKey(M_uri) - || !FactRecorder.AllFacts.ContainsKey(A_uri)) - return null; //If dependent facts do not exist return null - - return new CircleFact(M_uri, A_uri, radius, normal, fact.@ref.uri, StageStatic.stage.factState); - } - - /// \copydoc Fact.generateLabel - protected override string generateLabel() - => "○" + Point1.Label; - - /// <summary> - /// Constructs struct for right-angled MMT %Fact <see cref="AddFactResponse"/> - /// </summary> - /// <param name="Pid1"> <see cref="Pid1"/></param> - /// <param name="p2URI"> <see cref="Pid2"/></param> - /// <param name="radius"> <see cref="radius"/></param> - /// <returns>struct for <see cref="AddFactResponse"/></returns> - public override MMTFact MakeMMTDeclaration() - { - SOMDoc[] outerArguments = new SOMDoc[] - { - //CirclePlane, - new OMA( - //PointNormalPlane, - new OMS(MMTConstants.pointNormalPlane), - //planeArgs, - new SOMDoc[] { - //base point of the circle plane?, - new OMS(Pid2), - //NormalVector, - new OMA( - //"Vector" - new OMS(MMTConstants.Tuple), - //normalArgs, - new[] { - new OMF(normal.x), - new OMF(normal.y), - new OMF(normal.z) - } - ), - } - ), - //middlePoint, - new OMS(Pid1), - //Radius, - new OMF(radius), - }; - - // Do i need this here? doubt - SOMDoc tp = new OMS(MMTConstants.CircleType3d); - SOMDoc df = new OMA(new OMS(MMTConstants.MkCircle3d), outerArguments); - - return new MMTGeneralFact(Label, tp, df); - } - - /// \copydoc Fact.hasDependentFacts - public override bool HasDependentFacts => true; - - /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() - => new string[] { Pid1, Pid2 }; - - /// \copydoc Fact.Equivalent(Fact, Fact) - protected override bool EquivalentWrapped(CircleFact f1, CircleFact f2) - => DependentFactsEquivalent(f1, f2) - && Math3d.IsApproximatelyEqual(f1.normal, f2.normal) - && Mathf.Approximately(f1.radius, f2.radius); - - protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) - => new CircleFact(old_to_new[this.Pid1], old_to_new[this.Pid2], this.radius, this.normal, organizer); -} - -/// <summary> -/// A <see cref="PointFact"/> on a <see cref="CircleFact"/> -/// </summary> -public class OnCircleFact : FactWrappedCRTP<OnCircleFact> -{ - /// <summary> the point on the circle </summary> - public string Pid; - /// <summary> the circle, which the point is on </summary> - public string Cid; - - [JsonIgnore] - public PointFact Point { get => (PointFact)FactRecorder.AllFacts[Pid]; } - [JsonIgnore] - public CircleFact Circle { get => (CircleFact)FactRecorder.AllFacts[Cid]; } - - /// <summary> \copydoc Fact.Fact </summary> - public OnCircleFact() : base() - { - this.Pid = null; - this.Cid = null; - } - - /// <summary> - /// Standard Constructor: - /// Initiates <see cref="Pid"/>, <see cref="Rid"/>, <see cref="Fact._URI"/> and creates MMT %Fact Server-Side - /// </summary> - /// <param name="pid">sets <see cref="Pid"/></param> - /// <param name="cid">sets <see cref="Cid"/></param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public OnCircleFact(string pid, string cid, FactRecorder organizer) : base(organizer) - { - this.Pid = pid; - this.Cid = cid; ; - - SendToMMT(); - } - - protected override void RecalculateTransform() - { - Position = Point.Position; - Rotation = Circle.Rotation; - } - - /// <summary> - /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. - /// </summary> - /// <param name="pid">sets <see cref="Pid"/></param> - /// <param name="cid">sets <see cref="Cid"/></param> - /// <param name="uri">MMT URI</param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public OnCircleFact(string pid, string cid, string uri, FactRecorder organizer) : base(organizer) - { - this.Pid = pid; - this.Cid = cid; - this._URI = uri; - _ = this.Label; - } - - /// \copydoc Fact.parseFact(ScrollFact) - public new static OnCircleFact parseFact(MMTFact fact) - { - if (((MMTGeneralFact)fact).type is not OMA type) - return null; - - string circleUri = ((OMS)((OMA)type.arguments[0]).arguments[0]).uri; - string pointUri = ((OMS)((OMA)type.arguments[0]).arguments[1]).uri; - - if (!FactRecorder.AllFacts.ContainsKey(pointUri) - || !FactRecorder.AllFacts.ContainsKey(circleUri)) - return null; - - return new OnCircleFact(pointUri, circleUri, fact.@ref.uri, StageStatic.stage.factState); - } - - /// \copydoc Fact.generateLabel - protected override string generateLabel() - => Point.Label + "∈" + Circle.Label; - - /// \copydoc Fact.hasDependentFacts - public override bool HasDependentFacts => true; - - /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() - => new string[] { Pid, Cid }; - - /// \copydoc Fact.Equivalent(Fact, Fact) - protected override bool EquivalentWrapped(OnCircleFact c1, OnCircleFact c2) - => DependentFactsEquivalent(c1, c2); - - protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) - => new OnCircleFact(old_to_new[this.Pid], old_to_new[this.Cid], organizer); - - public override MMTFact MakeMMTDeclaration() - { - SOMDoc tp = - new OMA( - new OMS(MMTConstants.Ded), - new[] { - new OMA( - new OMS(MMTConstants.OnCircle), - new[] { - new OMS(Cid), - new OMS(Pid), - }),}); - - SOMDoc df = null; - - return new MMTGeneralFact(Label, tp, df); - } -} - -/// <summary> -/// Angle comprised of a line and a circle -/// </summary> -public class AngleCircleLineFact : FactWrappedCRTP<AngleCircleLineFact> -{ - /// @{ <summary> - /// One <see cref="Fact.Id">Id</see> of a <see cref="RayFact">RayFact</see> and a <see cref="CircleFact">CircleFact</see> defining Angle [<see cref="Cid1"/>, <see cref="Rid2"/>]. - /// </summary> - public string Cid1, Rid2; - /// @} - - [JsonIgnore] - public AbstractLineFact Ray { get => (AbstractLineFact)FactRecorder.AllFacts[Rid2]; } - [JsonIgnore] - public CircleFact Circle { get => (CircleFact)FactRecorder.AllFacts[Cid1]; } - - //TODO? deg or rad? - [JsonIgnore] - public float angle; - - [JsonIgnore] - public Vector3 intersection; - - /// <summary> \copydoc Fact.Fact </summary> - public AngleCircleLineFact() : base() - { - this.Cid1 = null; - this.Rid2 = null; - this.angle = 0.0f; - } - - /// <summary> - /// Standard Constructor: - /// Initiates <see cref="Cid1"/>, <see cref="Rid2"/>, <see cref="angle"/> <see cref="Fact._URI"/> and creates MMT %Fact Server-Side - /// </summary> - /// <param name="cid1">sets <see cref="Cid1"/></param> - /// <param name="rid2">sets <see cref="Rid2"/></param> - /// <param name="angle"> sets the angle </param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public AngleCircleLineFact(string cid1, string rid2, FactRecorder organizer) : base(organizer) - { - this.Cid1 = cid1; - this.Rid2 = rid2; - this.angle = Math3d.AngleVectorPlane(Ray.Dir, Circle.normal).ToDegrees(); - Math3d.LinePlaneIntersection(out intersection, Ray.Point1.Position, Ray.Dir, Circle.normal, Circle.Position); - - SendToMMT(); - } - - protected override void RecalculateTransform() - { - Position = intersection; - { //Rotation - Vector3 from = (Circle.Position - Position).normalized; - - Vector3 angle_to = Math3d.IsApproximatelyEqual(intersection, Ray.Point1.Position) - ? Ray.Point2.Position - : Ray.Point1.Position; - Vector3 to = (angle_to - Position).normalized; - - Vector3 up = Vector3.Cross(to, from); - Vector3 forwoard = (from + to).normalized; - - if (up.sqrMagnitude < Math3d.vectorPrecission) - { //Angle is 180° (or 0°) - Vector3 arbitary = up.normalized == Vector3.forward ? Vector3.right : Vector3.forward; - up = Vector3.Cross(arbitary, to); - forwoard = Vector3.Cross(up, to); - } - - Rotation = Quaternion.LookRotation(forwoard, up); - } - } - - /// <summary> - /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. - /// </summary> - /// <param name="Cid1">sets <see cref="Cid1"/></param> - /// <param name="´Rid2">sets <see cref="Rid2"/></param> - /// <param name="angle"> sets the angle </param> - /// <param name="backendURI">MMT URI</param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public AngleCircleLineFact(string Cid1, string Rid2, float angle, string backendURI, FactRecorder organizer) : base(organizer) - { - this.Cid1 = Cid1; - this.Rid2 = Rid2; - this.angle = angle; - - this._URI = backendURI; - _ = this.Label; - } - - /// \copydoc Fact.parseFact(ScrollFact) - public new static AngleCircleLineFact parseFact(MMTFact fact) - { - if (((MMTValueFact)fact).lhs is not OMA lhs) - return null; - - // init it with 0 degrees, so we don't accidentally generate orthogonalfacts - // and the parsing works correctly if smb ever adds a scroll for this - float angle = 0.0f; - - if (((MMTValueFact)fact).value is OMF oMFangle) - angle = oMFangle.@float; - - string CircleUri = ((OMS)lhs.arguments[0]).uri; - string RayUri = ((OMS)lhs.arguments[1]).uri; - - if (!FactRecorder.AllFacts.ContainsKey(CircleUri) - || !FactRecorder.AllFacts.ContainsKey(RayUri)) - return null; - - return new AngleCircleLineFact(CircleUri, RayUri, angle, fact.@ref.uri, StageStatic.stage.factState); - } - - /// \copydoc Fact.generateLabel - protected override string generateLabel() - => "∠" + Circle.Label + Ray.Label; - - public override MMTFact MakeMMTDeclaration() - { - SOMDoc lhs = - new OMA( - new OMS(MMTConstants.AnglePlaneLine), - new[] { - new OMS(Cid1), - new OMS(Rid2), - } - ); - - SOMDoc valueTp = new OMS(MMTConstants.RealLit); - SOMDoc value = new OMF(angle); - - return new MMTValueFact(this.Label, lhs, valueTp, value); - } - - /// \copydoc Fact.hasDependentFacts - public override bool HasDependentFacts => true; - - /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() - => new string[] { Cid1, Rid2 }; - - /// \copydoc Fact.Equivalent(Fact, Fact) - protected override bool EquivalentWrapped(AngleCircleLineFact f1, AngleCircleLineFact f2) - => DependentFactsEquivalent(f1, f2); - - protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) - => new AngleCircleLineFact(old_to_new[this.Cid1], old_to_new[this.Rid2], organizer); -} - -/// <summary> -/// A RadiusFact that corresponds to a <see cref="CircleFact">PointFacts</see> and has a float value (the actual radius). -/// </summary> -public class RadiusFact : FactWrappedCRTP<RadiusFact> -{ - /// <summary> The circle corresponding to the radius </summary> - public string Cid1; - - [JsonIgnore] - public CircleFact Circle { get => (CircleFact)FactRecorder.AllFacts[Cid1]; } - - /// <summary> The radius as a float </summary> - public float rad; - - /// <summary> \copydoc Fact.Fact </summary> - public RadiusFact() : base() - { - this.Cid1 = null; - this.rad = 0.0f; - } - - /// <summary> - /// Standard Constructor: - /// Initiates <see cref="Cid1"/> and <see cref="rad"/> - /// </summary> - /// <param name="cid1">sets <see cref="Cid1"/></param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public RadiusFact(string cid1, FactRecorder organizer) : base(organizer) - { - this.Cid1 = cid1; - this.rad = Circle.radius; - - SendToMMT(); - } - - protected override void RecalculateTransform() - { - Position = Circle.Position; - Rotation = Circle.Rotation; - } - - /// <summary> - /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. - /// </summary> - /// <param name="Cid1">sets <see cref="Cid1"/></param> - /// <param name="backendURI">MMT URI</param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public RadiusFact(string Cid1, string backendURI, FactRecorder organizer) : base(organizer) - { - this.Cid1 = Cid1; - - this._URI = backendURI; - _ = this.Label; - } - - /// \copydoc Fact.parseFact(ScrollFact) - public new static RadiusFact parseFact(MMTFact fact) - { - string CircleUri = ((OMS)((OMA)((MMTValueFact)fact).lhs).arguments[0]).uri; - - if (!FactRecorder.AllFacts.ContainsKey(CircleUri)) - return null; - - return new RadiusFact(CircleUri, fact.@ref.uri, StageStatic.stage.factState); - } - - /// \copydoc Fact.generateLabel - protected override string generateLabel() - => "r " + Circle.Label; - - /// <summary> - /// Constructs struct for not-right-angled MMT %Fact <see cref="AddFactResponse"/> - /// </summary> - /// <param name="rad"> see <see cref="rad"/></param> - /// <param name="c1URI"> see <see cref="Cid1"/></param> - - public override MMTFact MakeMMTDeclaration() - { - SOMDoc lhs = - new OMA( - new OMS(MMTConstants.RadiusCircleMetric), - new[] { - new OMS(Cid1), - } - ); - - SOMDoc valueTp = new OMS(MMTConstants.RealLit); - SOMDoc value = new OMF(rad); - - return new MMTValueFact(this.Label, lhs, valueTp, value); - } - - /// \copydoc Fact.hasDependentFacts - public override bool HasDependentFacts => true; - - /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() - => new string[] { Cid1 }; - - /// \copydoc Fact.Equivalent(Fact, Fact) - protected override bool EquivalentWrapped(RadiusFact f1, RadiusFact f2) - => DependentFactsEquivalent(f1, f2); - - protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) - => new RadiusFact(old_to_new[this.Cid1], organizer); -} - -/// <summary> -/// Area of a <see cref="CircleFact">CircleFact</see> -/// </summary> -public class AreaCircleFact : FactWrappedCRTP<AreaCircleFact> -{ - /// <summary> the circle <see cref="CircleFact">CircleFact</see> </summary> - public string Cid1; - - [JsonIgnore] - public CircleFact Circle { get => (CircleFact)FactRecorder.AllFacts[Cid1]; } - - /// <summary> the area which is contained by the circle </summary> - public float A; - - - /// <summary> \copydoc Fact.Fact </summary> - public AreaCircleFact() : base() - { - this.Cid1 = null; - this.A = 0.0f; - } - - /// <summary> - /// Standard Constructor: - /// Initiates <see cref="Cid1"/> and creates MMT %Fact Server-Side - /// </summary> - /// <param name="cid1">sets <see cref="Cid1"/></param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public AreaCircleFact(string cid1, FactRecorder organizer) : base(organizer) - { - this.Cid1 = cid1; - - this.A = Circle.radius * Circle.radius * ((float)System.Math.PI); - - SendToMMT(); - } - - protected override void RecalculateTransform() - { - Position = Circle.Position; - Rotation = Circle.Rotation; - } - - /// <summary> - /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. - /// </summary> - /// <param name="Cid1">sets <see cref="Cid1"/></param> - /// <param name="backendURI">MMT URI</param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public AreaCircleFact(string Cid1, string backendURI, FactRecorder organizer) : base(organizer) - { - this.Cid1 = Cid1; - - this._URI = backendURI; - _ = this.Label; - } - - /// \copydoc Fact.parseFact(ScrollFact) - public new static AreaCircleFact parseFact(MMTFact fact) - { - string CircleUri = ((OMS)((OMA)((MMTValueFact)fact).lhs).arguments[0]).uri; - - if (!FactRecorder.AllFacts.ContainsKey(CircleUri)) - return null; - - return new AreaCircleFact(CircleUri, fact.@ref.uri, StageStatic.stage.factState); - } - - /// \copydoc Fact.generateLabel - protected override string generateLabel() - => "A(" + Circle.Label + ")"; - - public override MMTFact MakeMMTDeclaration() - { - SOMDoc lhs = - new OMA( - new OMS(MMTConstants.AreaCircle), - new[] { - new OMS(Cid1), - } - ); - - SOMDoc valueTp = new OMS(MMTConstants.RealLit); - SOMDoc value = new OMF(A); - - return new MMTValueFact(this.Label, lhs, valueTp, value); - } - - /// \copydoc Fact.hasDependentFacts - public override bool HasDependentFacts => true; - - /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() - => new string[] { Cid1 }; - - /// \copydoc Fact.GetHashCode - public override int GetHashCode() - => base.GetHashCode() ^ A.GetHashCode(); - - /// \copydoc Fact.Equivalent(Fact, Fact) - protected override bool EquivalentWrapped(AreaCircleFact f1, AreaCircleFact f2) - => DependentFactsEquivalent(f1, f2); - - protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) - => new AreaCircleFact(old_to_new[this.Cid1], organizer); -} - -/// <summary> -/// The volume of a cone A defined by a base area <see cref="CircleFact">CircleFact</see>, an apex <see cref="PointFact">PointFact</see> and the volume as float -/// </summary> -public class ConeVolumeFact : FactWrappedCRTP<ConeVolumeFact> -{ - /// <summary> a <see cref="CircleFact">CircleFact</see> describing the base area </summary> - public string Cid1; - [JsonIgnore] - public CircleFact Circle { get => (CircleFact)FactRecorder.AllFacts[Cid1]; } - - /// <summary> a <see cref="PointFact">PointFact</see> describing the apex point </summary> - public string Pid1; - [JsonIgnore] - public PointFact Point { get => (PointFact)FactRecorder.AllFacts[Pid1]; } - - /// <summary> the volume of the cone as a float </summary> - public float vol; - - /// <summary> \copydoc Fact.Fact </summary> - public ConeVolumeFact() : base() - { - this.Cid1 = null; - this.Pid1 = null; - this.vol = 0.0f; - } - - /// <summary> - /// Standard Constructor: - /// Initiates members and creates MMT %Fact Server-Side - /// </summary> - /// <param name="cid1">sets <see cref="Cid1"/></param> - /// <param name="pid1">sets <see cref="Pid1"/></param> - /// <param name="vol">sets <see cref="vol"/></param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public ConeVolumeFact(string cid1, string pid1, float vol, FactRecorder organizer) : base(organizer) - { - this.Cid1 = cid1; - this.Pid1 = pid1; - this.vol = vol; - - SendToMMT(); - } - - protected override void RecalculateTransform() - { - Position = Point.Position; - Rotation = Circle.Rotation; - } - - /// <summary> - /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. - /// </summary> - /// <param name="Cid1">sets <see cref="Cid1"/></param> - /// <param name="Pid1">sets <see cref="Pid1"/></param> - /// <param name="volume">sets <see cref="vol"/></param> - /// <param name="backendURI">MMT URI</param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public ConeVolumeFact(string Cid1, string Pid1, float volume, string backendURI, FactRecorder organizer) : base(organizer) - { - this.Cid1 = Cid1; - this.Pid1 = Pid1; - this.vol = volume; - - this._URI = backendURI; - _ = this.Label; - } - - /// \copydoc Fact.parseFact(ScrollFact) - public new static ConeVolumeFact parseFact(MMTFact fact) - { - if (((MMTValueFact)fact).lhs is not OMA lhs) - return null; - - string CircleUri = ((OMS)((OMA)lhs.arguments[0]).arguments[0]).uri; - string PointUri = ((OMS)((OMA)lhs.arguments[0]).arguments[1]).uri; - - float volume = 0.0f; - if (((MMTValueFact)fact).value is OMF oMFvolume) - volume = oMFvolume.@float; - - if (!FactRecorder.AllFacts.ContainsKey(CircleUri) - || !FactRecorder.AllFacts.ContainsKey(PointUri)) - return null; - - return new ConeVolumeFact(CircleUri, PointUri, volume, fact.@ref.uri, StageStatic.stage.factState); - } - - /// \copydoc Fact.generateLabel - protected override string generateLabel() - => "V(" + Circle.Label + "," + Point.Label + ")"; - - public override MMTFact MakeMMTDeclaration() - { - SOMDoc lhs = - new OMA( - new OMS(MMTConstants.VolumeCone), - - new[] { - new OMA(new OMS(MMTConstants.ConeOfCircleApex), - new[] { - new OMS(Cid1), - new OMS(Pid1), - } - ), - } - ); - - SOMDoc valueTp = new OMS(MMTConstants.RealLit); - SOMDoc value = new OMF(vol); - - return new MMTValueFact(this.Label, lhs, valueTp, value); - } - - /// \copydoc Fact.hasDependentFacts - public override bool HasDependentFacts => true; - - /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() - => new string[] { Cid1, Pid1 }; - - /// \copydoc Fact.Equivalent(Fact, Fact) - protected override bool EquivalentWrapped(ConeVolumeFact f1, ConeVolumeFact f2) - => DependentFactsEquivalent(f1, f2); - - protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) - => new ConeVolumeFact(old_to_new[this.Cid1], old_to_new[this.Pid1], this.vol, organizer); -} - -/// <summary> -/// The fact that the plane of a <see cref="CircleFact">CircleFact</see> and the line <see cref="RayFact>RayFact</see> are orthogonal -/// </summary> -public class OrthogonalCircleLineFact : FactWrappedCRTP<OrthogonalCircleLineFact> -{ - /// <summary> a <see cref="CircleFact">CircleFact</see> describing the base area </summary> - public string Cid1; - [JsonIgnore] - public CircleFact Circle { get => (CircleFact)FactRecorder.AllFacts[Cid1]; } - - /// <summary> a <see cref="RayFact">Rayfact</see> describing the line </summary> - public string Lid1; - [JsonIgnore] - public AbstractLineFact Ray { get => (AbstractLineFact)FactRecorder.AllFacts[Lid1]; } - - //TODO? deg or rad? - [JsonIgnore] - public float angle = 90f; - - [JsonIgnore] - public Vector3 intersection; - - - /// <summary> \copydoc Fact.Fact </summary> - public OrthogonalCircleLineFact() : base() - { - this.Cid1 = null; - this.Lid1 = null; - } - - /// <summary> - /// Standard Constructor: - /// Initiates members and creates MMT %Fact Server-Side - /// </summary> - /// <param name="cid1">sets <see cref="Cid1"/></param> - /// <param name="lid1">sets <see cref="Lid1"/></param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public OrthogonalCircleLineFact(string cid1, string lid1, FactRecorder organizer) : base(organizer) - { - this.Cid1 = cid1; - this.Lid1 = lid1; - Math3d.LinePlaneIntersection(out intersection, Ray.Point1.Position, Ray.Dir, Circle.normal, Circle.Position); - - SendToMMT(); - } - - protected override void RecalculateTransform() - { - Position = intersection; - { //Rotation - Vector3 from = (Circle.Position - Position).normalized; - - Vector3 angle_to = Math3d.IsApproximatelyEqual(intersection, Ray.Point1.Position) - ? Ray.Point2.Position - : Ray.Point1.Position; - Vector3 to = (angle_to - Position).normalized; - - Vector3 up = Vector3.Cross(to, from); - Vector3 forward = (from + to).normalized; - Rotation = Quaternion.LookRotation(forward, up); - } - } - - /// <summary> - /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. - /// </summary> - /// <param name="Cid1">sets <see cref="Cid1"/></param> - /// <param name="Lid1">sets <see cref="Lid1"/></param> - /// <param name="backendURI">MMT URI</param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public OrthogonalCircleLineFact(string Cid1, string Lid1, string backendURI, FactRecorder organizer) : base(organizer) - { - this.Cid1 = Cid1; - this.Lid1 = Lid1; - - this._URI = backendURI; - _ = this.Label; - } - - /// \copydoc Fact.parseFact(ScrollFact) - public new static OrthogonalCircleLineFact parseFact(MMTFact fact) - { - if (((MMTGeneralFact)fact).type is not OMA type) - return null; - - string CircleUri = ((OMS)((OMA)type.arguments[0]).arguments[0]).uri; - string LineUri = ((OMS)((OMA)type.arguments[0]).arguments[1]).uri; - - if (!FactRecorder.AllFacts.ContainsKey(CircleUri) - || !FactRecorder.AllFacts.ContainsKey(LineUri)) - return null; - - return new OrthogonalCircleLineFact(CircleUri, LineUri, fact.@ref.uri, StageStatic.stage.factState); - } - - /// \copydoc Fact.generateLabel - protected override string generateLabel() - => Circle.Label + "⊥" + Ray.Label; - - public override MMTFact MakeMMTDeclaration() - { - SOMDoc tp = new OMA( - new OMS(MMTConstants.Ded), - new[]{ - new OMA( - new OMS(MMTConstants.OrthoCircleLine), - new[] { - new OMS(Cid1), - new OMS(Lid1), - } - ), - } - ); - - SOMDoc df = null; - - return new MMTGeneralFact(this.Label, tp, df); - } - - /// \copydoc Fact.hasDependentFacts - public override bool HasDependentFacts => true; - - /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() - => new string[] { Cid1, Lid1 }; - - /// \copydoc Fact.Equivalent(Fact, Fact) - protected override bool EquivalentWrapped(OrthogonalCircleLineFact f1, OrthogonalCircleLineFact f2) - => DependentFactsEquivalent(f1, f2); - - protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) - => new OrthogonalCircleLineFact(old_to_new[this.Cid1], old_to_new[this.Lid1], organizer); -} - -/// <summary> -/// The volume of a cone A defined by a base area <see cref="CircleFact">CircleFact</see>, a top area <see cref="CircleFact">CircleFact</see> and the volume as float -/// </summary> -public class TruncatedConeVolumeFact : FactWrappedCRTP<TruncatedConeVolumeFact> -{ - /// <summary> a <see cref="CircleFact">CircleFact</see> describing the base area </summary> - public string Cid1; - [JsonIgnore] - public CircleFact Circle1 { get => (CircleFact)FactRecorder.AllFacts[Cid1]; } - - /// <summary> a <see cref="CircleFact">CircleFact</see> describing the top area </summary> - public string Cid2; + /// <summary> Defining Corners; Order is Cyclic; + /// <see cref="PointFact"/>.<see cref="Fact.Id">Id</see> </summary> + public string[] Pids; [JsonIgnore] - public CircleFact Circle2 { get => (CircleFact)FactRecorder.AllFacts[Cid2]; } - - /// <summary> the volume of Truncated the cone as a float </summary> - public float vol; - /// <summary> a proof that both circles have not the same size </summary> - public string unequalCirclesProof; - /// <summary> OMA proof that the two circles are parallel </summary> - public OMA proof; - - - /// <summary> \copydoc Fact.Fact </summary> - public TruncatedConeVolumeFact() : base() - { - this.Cid1 = null; - this.Cid2 = null; - this.vol = 0.0f; - this.unequalCirclesProof = null; - this.proof = null; - } - - /// <summary> - /// Standard Constructor: - /// Initiates members and creates MMT %Fact Server-Side - /// </summary> - /// <param name="cid1">sets <see cref="Cid1"/></param> - /// <param name="cid2">sets <see cref="Cid2"/></param> - /// <param name="vol">sets <see cref="vol"/></param> - /// <param name="proof">sets <see cref="proof"/></param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public TruncatedConeVolumeFact(string cid1, string cid2, float vol, string unequalproof, OMA proof, FactRecorder organizer) : base(organizer) - { - this.Cid1 = cid1; - this.Cid2 = cid2; - this.proof = proof; - this.unequalCirclesProof = unequalproof; - this.vol = vol; - - SendToMMT(); - } - - protected override void RecalculateTransform() - { - Position = Circle2.Position; - Rotation = Circle2.Rotation; - } - - /// <summary> - /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. - /// </summary> - /// <param name="Cid1">sets <see cref="Cid1"/></param> - /// <param name="Cid2">sets <see cref="Cid2"/></param> - /// <param name="volume">sets <see cref="vol"/></param> - /// <param name="proof">sets <see cref="proof"/></param> - /// <param name="backendURI">MMT URI</param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public TruncatedConeVolumeFact(string Cid1, string Cid2, float volume, string unequalproof, OMA proof, string backendURI, FactRecorder organizer) : base(organizer) - { - this.Cid1 = Cid1; - this.Cid2 = Cid2; - this.vol = volume; - this.proof = proof; - this.unequalCirclesProof = unequalproof; - - this._URI = backendURI; - _ = this.Label; - } - - /// \copydoc Fact.parseFact(ScrollFact) - public new static TruncatedConeVolumeFact parseFact(MMTFact fact) - { - string Circle1Uri = ((OMS)((OMA)((OMA)((MMTValueFact)fact).lhs).arguments[0]).arguments[0]).uri; - string Circle2Uri = ((OMS)((OMA)((OMA)((MMTValueFact)fact).lhs).arguments[0]).arguments[1]).uri; - float volume = ((OMF)((MMTValueFact)fact).value).@float; - - string UnEqualCirclesProof = ((OMS)(((OMA)((OMA)((MMTValueFact)fact).lhs).arguments[0]).arguments[2])).uri; - OMA proof = (OMA)(((OMA)((OMA)((MMTValueFact)fact).lhs).arguments[0]).arguments[3]); - - if (!FactRecorder.AllFacts.ContainsKey(Circle1Uri) - || !FactRecorder.AllFacts.ContainsKey(Circle2Uri)) - return null; - - return new TruncatedConeVolumeFact(Circle1Uri, Circle2Uri, volume, UnEqualCirclesProof, proof, fact.@ref.uri, StageStatic.stage.factState); - } - - /// \copydoc Fact.generateLabel - protected override string generateLabel() - => "V(" + Circle1.Label + "," + Circle2.Label + ")"; - - public override MMTFact MakeMMTDeclaration() - { - SOMDoc lhs = - new OMA( - new OMS(MMTConstants.TruncatedVolumeCone), - new SOMDoc[] { - new OMS(Cid1), - new OMS(Cid2), - new OMS(unequalCirclesProof), - proof, - } - ); - - SOMDoc valueTp = new OMS(MMTConstants.RealLit); - SOMDoc value = new OMF(vol); - - return new MMTValueFact(this.Label, lhs, valueTp, value); + public PointFact[] Points { + get => _Points ??= Pids.Select(pid => (PointFact)FactRecorder.AllFacts[pid]).ToArray(); } + private PointFact[] _Points; - /// \copydoc Fact.hasDependentFacts - public override bool HasDependentFacts => true; - - /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() - => new string[] { Cid1, Cid2 }; - - /// \copydoc Fact.Equivalent(Fact, Fact) - protected override bool EquivalentWrapped(TruncatedConeVolumeFact f1, TruncatedConeVolumeFact f2) - => DependentFactsEquivalent(f1, f2); - - protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) - => new TruncatedConeVolumeFact(old_to_new[this.Cid1], old_to_new[this.Cid2], this.vol, old_to_new[this.unequalCirclesProof], this.proof, organizer); -} - -/// <summary> -/// The volume of a cylinder defined by a base area <see cref="CircleFact">CircleFact</see>, a top area <see cref="CircleFact">CircleFact</see> and the volume as float -/// </summary> -public class CylinderVolumeFact : FactWrappedCRTP<CylinderVolumeFact> -{ - /// <summary> a <see cref="CircleFact">CircleFact</see> describing the base area </summary> - public string Cid1; - [JsonIgnore] - public CircleFact Circle1 { get => (CircleFact)FactRecorder.AllFacts[Cid1]; } - - /// <summary> a <see cref="CircleFact">CircleFact</see> describing the top area </summary> - public string Cid2; [JsonIgnore] - public CircleFact Circle2 { get => (CircleFact)FactRecorder.AllFacts[Cid2]; } - - /// <summary> the volume of the cylinder as a float </summary> - public float vol; - /// <summary> a proof that both circles have the same size </summary> - public string equalCirclesProof; - /// <summary> OMA proof that the two circles are parallel </summary> - public OMA proof; + public Vector3 Normal; /// <summary> \copydoc Fact.Fact </summary> - public CylinderVolumeFact() : base() - { - this.Cid1 = null; - this.Cid2 = null; - this.vol = 0.0f; - this.proof = null; - this.equalCirclesProof = null; - } + public QuadFact() : base() { } /// <summary> /// Standard Constructor: - /// Initiates members and creates MMT %Fact Server-Side + /// Initiates <see cref="Pids"/> and creates MMT %Fact Server-Side /// </summary> - /// <param name="cid1">sets <see cref="Cid1"/></param> - /// <param name="cid2">sets <see cref="Cid2"/></param> - /// <param name="vol">sets <see cref="vol"/></param> - /// <param name="proof">sets <see cref="proof"/></param> + /// <param name="pid_corners">sets <see cref="Pids"/></param> /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public CylinderVolumeFact(string cid1, string cid2, float vol, string eqProof, OMA proof, FactRecorder organizer) : base(organizer) + public QuadFact(string[] pid_corners, FactRecorder organizer) : base(organizer) { - this.Cid1 = cid1; - this.Cid2 = cid2; - this.proof = proof; - this.equalCirclesProof = eqProof; - this.vol = vol; - + Init(pid_corners); SendToMMT(); } - protected override void RecalculateTransform() - { - Position = Circle2.Position; - Rotation = Circle2.Rotation; - } - /// <summary> /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. /// </summary> - /// <param name="Cid1">sets <see cref="Cid1"/></param> - /// <param name="Cid2">sets <see cref="Cid2"/></param> - /// <param name="volume">sets <see cref="vol"/></param> - /// <param name="proof">sets <see cref="proof"/></param> - /// <param name="backendURI">MMT URI</param> + /// <param name="pid_corners">sets <see cref="Pids"/></param> + /// <param name="uri">MMT URI</param> /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public CylinderVolumeFact(string Cid1, string Cid2, float volume, string eqProof, OMA proof, string backendURI, FactRecorder organizer) : base(organizer) + public QuadFact(string[] pid_corners, string uri, FactRecorder organizer) : base(organizer) { - this.Cid1 = Cid1; - this.Cid2 = Cid2; - this.vol = volume; - this.proof = proof; - this.equalCirclesProof = eqProof; + Init(pid_corners); - this._URI = backendURI; + this._URI = uri; _ = this.Label; } - /// \copydoc Fact.parseFact(ScrollFact) - public new static CylinderVolumeFact parseFact(MMTFact fact) + private void Init(string[] pid_corners) { - string Circle1Uri = ((OMS)((OMA)((OMA)((MMTValueFact)fact).lhs).arguments[0]).arguments[0]).uri; - string Circle2Uri = ((OMS)((OMA)((OMA)((MMTValueFact)fact).lhs).arguments[0]).arguments[1]).uri; - float volume = ((OMF)((MMTValueFact)fact).value).@float; - string EqualCirclesProof = ((OMS)(((OMA)((OMA)((MMTValueFact)fact).lhs).arguments[0]).arguments[2])).uri; - - OMA proof = (OMA)(((OMA)((OMA)((MMTValueFact)fact).lhs).arguments[0]).arguments[3]); - - if (!FactRecorder.AllFacts.ContainsKey(Circle1Uri) - || !FactRecorder.AllFacts.ContainsKey(Circle2Uri)) - return null; - - return new CylinderVolumeFact(Circle1Uri, Circle2Uri, volume, EqualCirclesProof, proof, fact.@ref.uri, StageStatic.stage.factState); - } - - /// \copydoc Fact.generateLabel - protected override string generateLabel() - => "V(" + Circle1.Label + "," + Circle2.Label + ")"; + Pids = pid_corners; - public override MMTFact MakeMMTDeclaration() - { - SOMDoc lhs = - new OMA( - new OMS(MMTConstants.CylinderVolume), - - new SOMDoc[] { - new OMS(Cid1), - new OMS(Cid2), - new OMS(equalCirclesProof), - proof, - } + Normal = Vector3.Cross( + Points[0].Point - Points[1].Point, + Points[0].Point - Points[2].Point ); - SOMDoc valueTp = new OMS(MMTConstants.RealLit); - SOMDoc value = new OMF(vol); - - return new MMTValueFact(this.Label, lhs, valueTp, value); - } - - /// \copydoc Fact.hasDependentFacts - public override bool HasDependentFacts => true; - - /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() - => new string[] { Cid1, Cid2, equalCirclesProof }; - - /// \copydoc Fact.Equivalent(Fact, Fact) - protected override bool EquivalentWrapped(CylinderVolumeFact f1, CylinderVolumeFact f2) - => DependentFactsEquivalent(f1, f2); - - protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) - => new CylinderVolumeFact(old_to_new[this.Cid1], old_to_new[this.Cid2], this.vol, old_to_new[this.equalCirclesProof], this.proof, organizer); -} - -/// <summary> -/// A fact that describes, that two circles have the same size and is comprised of two <see cref="CircleFact">CircleFacts</see> -/// </summary> -public class EqualCirclesFact : FactWrappedCRTP<EqualCirclesFact> -{ - /// @{ <summary> - /// two circles that are meant to be equal in area - /// </summary> - public string Cid1, Cid2; - /// @} - - [JsonIgnore] - public CircleFact Circle1 { get => (CircleFact)FactRecorder.AllFacts[Cid1]; } - [JsonIgnore] - public CircleFact Circle2 { get => (CircleFact)FactRecorder.AllFacts[Cid2]; } - - /// <summary> \copydoc Fact.Fact </summary> - public EqualCirclesFact() : base() - { - this.Cid1 = null; - this.Cid2 = null; - } - - /// <summary> - /// Standard Constructor: - /// Initiates members and creates MMT %Fact Server-Side - /// </summary> - /// <param name="cid1">sets <see cref="Cid1"/></param> - /// <param name="cid2">sets <see cref="Cid2"/></param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public EqualCirclesFact(string cid1, string cid2, FactRecorder organizer) : base(organizer) - { - this.Cid1 = cid1; - this.Cid2 = cid2; - - SendToMMT(); - } - - protected override void RecalculateTransform() - { - Position = Circle1.Position; - Rotation = Circle1.Rotation; - } - - /// <summary> - /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. - /// </summary> - /// <param name="Cid1">sets <see cref="Cid1"/></param> - /// <param name="Cid2">sets <see cref="Cid2"/></param> - /// <param name="backendURI">MMT URI</param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public EqualCirclesFact(string Cid1, string Cid2, string backendURI, FactRecorder organizer) : base(organizer) - { - this.Cid1 = Cid1; - this.Cid2 = Cid2; - - this._URI = backendURI; - _ = this.Label; + if (Mathf.Approximately(0, Vector3.Dot(Normal, Points[0].Point - Points[3].Point))) + throw new ArgumentException("All Points must lie on the same Plane!"); } /// \copydoc Fact.parseFact(ScrollFact) - public new static EqualCirclesFact parseFact(MMTFact fact) + public new static QuadFact parseFact(MMTFact fact) { - if (((MMTGeneralFact)fact).type is not OMA proof_OMA) // proof DED - return null; - - OMA parallel_circles_OMA = (OMA)proof_OMA.arguments[0]; // parallel - - string circleAUri = ((OMS)parallel_circles_OMA.arguments[0]).uri; - string circleBUri = ((OMS)parallel_circles_OMA.arguments[1]).uri; - - if (!FactRecorder.AllFacts.ContainsKey(circleAUri) - || !FactRecorder.AllFacts.ContainsKey(circleBUri)) - return null; - - return new EqualCirclesFact(circleAUri, circleBUri, fact.@ref.uri, StageStatic.stage.factState); + throw new NotImplementedException(); } - /// \copydoc Fact.generateLabel - protected override string generateLabel() - => Circle1.Label + " ≠" + Circle2.Label; - public override MMTFact MakeMMTDeclaration() { SOMDoc tp = new OMA( - new OMS(MMTConstants.Ded), - new[] { - new OMA( - new OMS(MMTConstants.EqualityCircles), - new[] { - new OMS(Cid1), - new OMS(Cid2), - } - ) - } - ); - + new OMS(MMTConstants.Wall), + Pids.Select(pid => new OMS(pid)).ToArray() + ); SOMDoc df = null; - return new MMTGeneralFact(this.Label, tp, df); - } - - /// \copydoc Fact.hasDependentFacts - public override bool HasDependentFacts => true; - - /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() - => new string[] { Cid1, Cid2 }; - - /// \copydoc Fact.Equivalent(Fact, Fact) - protected override bool EquivalentWrapped(EqualCirclesFact f1, EqualCirclesFact f2) - => DependentFactsEquivalent(f1, f2); - - protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) - => new EqualCirclesFact(old_to_new[this.Cid1], old_to_new[this.Cid2], organizer); -} - -/// <summary> -/// A fact that describes, that two circles have not the same size and is comprised of two <see cref="CircleFact">CircleFacts</see> -/// </summary> -public class UnEqualCirclesFact : FactWrappedCRTP<UnEqualCirclesFact> -{ - /// @{ <summary> - /// two circles that are meant to be unequal in area - /// </summary> - public string Cid1, Cid2; - /// @} - - [JsonIgnore] - public CircleFact Circle1 { get => (CircleFact)FactRecorder.AllFacts[Cid1]; } - [JsonIgnore] - public CircleFact Circle2 { get => (CircleFact)FactRecorder.AllFacts[Cid2]; } - - /// <summary> \copydoc Fact.Fact </summary> - public UnEqualCirclesFact() : base() - { - this.Cid1 = null; - this.Cid2 = null; - } - - /// <summary> - /// Standard Constructor: - /// Initiates members and creates MMT %Fact Server-Side - /// </summary> - /// <param name="cid1">sets <see cref="Cid1"/></param> - /// <param name="cid2">sets <see cref="Cid2"/></param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public UnEqualCirclesFact(string cid1, string cid2, FactRecorder organizer) : base(organizer) - { - this.Cid1 = cid1; - this.Cid2 = cid2; - - SendToMMT(); - } - - protected override void RecalculateTransform() - { - Position = Circle2.Position; - Rotation = Circle2.Rotation; - } - - /// <summary> - /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. - /// </summary> - /// <param name="Cid1">sets <see cref="Cid1"/></param> - /// <param name="Cid2">sets <see cref="Cid2"/></param> - /// <param name="backendURI">MMT URI</param> - /// <param name="organizer">sets <see cref="Fact._Facts"/></param> - public UnEqualCirclesFact(string Cid1, string Cid2, string backendURI, FactRecorder organizer) : base(organizer) - { - this.Cid1 = Cid1; - this.Cid2 = Cid2; - - this._URI = backendURI; - _ = this.Label; + return new MMTGeneralFact(Label, tp, df); } - /// \copydoc Fact.parseFact(ScrollFact) - public new static UnEqualCirclesFact parseFact(MMTFact fact) + protected override bool EquivalentWrapped(QuadFact f1, QuadFact f2) { - if (((MMTGeneralFact)fact).type is not OMA proof_OMA) // proof DED - return null; - - OMA unequal_circles_OMA = (OMA)proof_OMA.arguments[0]; // unequal - - string circleAUri = ((OMS)unequal_circles_OMA.arguments[0]).uri; - string circleBUri = ((OMS)unequal_circles_OMA.arguments[1]).uri; - - if (!FactRecorder.AllFacts.ContainsKey(circleAUri) - || !FactRecorder.AllFacts.ContainsKey(circleBUri)) - return null; - - return new UnEqualCirclesFact(circleAUri, circleBUri, fact.@ref.uri, StageStatic.stage.factState); - } + if(f1.Points.Length != f2.Points.Length) + return false; - /// \copydoc Fact.generateLabel - protected override string generateLabel() - => Circle1.Label + " = " + Circle2.Label; + int i = 0; + for (; i < f2.Points.Length; i++) // 1st incedence + if (f2.Points[i].Equivalent(f1.Points[0])) + break; - public override MMTFact MakeMMTDeclaration() - { - SOMDoc tp = new OMA( - new OMS(MMTConstants.Ded), - new[] { - new OMA(new OMS(MMTConstants.UnEqualityCircles), - new[] { - new OMS(Cid1), - new OMS(Cid2), - }),}); + if (i == f2.Points.Length) // no match + return false; - SOMDoc df = null; + for (int j = 1; j < f2.Points.Length; j++) // cyclic match + if (!f2.Points[(i + j) % f2.Points.Length].Equivalent(f1.Points[j])) + return false; - return new MMTGeneralFact(this.Label, tp, df); + return true; } - /// \copydoc Fact.hasDependentFacts public override bool HasDependentFacts => true; - /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() - => new string[] { Cid1, Cid2 }; + protected override string[] GetDependentFactIds() + => Pids; - /// \copydoc Fact.Equivalent(Fact, Fact) - protected override bool EquivalentWrapped(UnEqualCirclesFact f1, UnEqualCirclesFact f2) - => DependentFactsEquivalent(f1, f2); + protected override void RecalculateTransform() { } - protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) - => new UnEqualCirclesFact(old_to_new[this.Cid1], old_to_new[this.Cid2], organizer); + protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) + => new QuadFact(Pids.Select(pid => old_to_new[pid]).ToArray(), organizer); } #pragma warning disable // Testing... @@ -2364,7 +1043,7 @@ protected override string generateLabel() public override bool HasDependentFacts => false; /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() + protected override string[] GetDependentFactIds() => new string[] { }; /// \copydoc Fact.GetHashCode diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs index cdda3745718dc8ece334841a82422f3b5326fe01..92e2c5d57e6cfb43edebe8710f77a582e5475040 100644 --- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs +++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using UnityEngine; using Newtonsoft.Json; -using System.Linq.Expressions; using System.Linq; using REST_JSON_API; @@ -46,7 +45,7 @@ public object Call(float t) public override bool HasDependentFacts => true; - protected override string[] GetGetDependentFactIds() + protected override string[] GetDependentFactIds() => new[] { func_id, arg_func_id }; protected override bool EquivalentWrapped(FunctionCallFact f1, FunctionCallFact f2) @@ -147,7 +146,7 @@ public override bool HasDependentFacts => false; /// \copydoc Fact.getDependentFactIds - protected override string[] GetGetDependentFactIds() + protected override string[] GetDependentFactIds() => new string[] { }; /// \copydoc Fact.GetHashCode @@ -261,7 +260,7 @@ public override MMTFact MakeMMTDeclaration() public override bool HasDependentFacts => true; - protected override string[] GetGetDependentFactIds() + protected override string[] GetDependentFactIds() => new string[] { fid }.ShallowCloneAppend(func_calls_ids); //=> new string[] { fid, func_calls_list_id }; diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/MMTTypes.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/MMTTypes.cs index adc880b49b6207ea94ee838f6dc305028c5cd29b..204229589803bf0b092bdb09f9867b9c37540c75 100644 --- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/MMTTypes.cs +++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/MMTTypes.cs @@ -169,7 +169,7 @@ public override MMTFact MakeMMTDeclaration() return new MMTGeneralFact(Label, ListType, List); } - protected override string[] GetGetDependentFactIds() + protected override string[] GetDependentFactIds() => lids.Where(lid => lid != null).ToArray(); protected override void RecalculateTransform() { } @@ -259,7 +259,7 @@ public override MMTFact MakeMMTDeclaration() return new MMTGeneralFact(Label, Tupel.SOMDocType(), Tupel); } - protected override string[] GetGetDependentFactIds() + protected override string[] GetDependentFactIds() => lids.Where(lid => lid != null).ToArray(); protected override void RecalculateTransform() { } diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/VolumeFacts.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/VolumeFacts.cs new file mode 100644 index 0000000000000000000000000000000000000000..347dffe9098e27613b63ca36bb0fcbaa6169e44c --- /dev/null +++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/VolumeFacts.cs @@ -0,0 +1,402 @@ +using System.Collections.Generic; +using Newtonsoft.Json; +using REST_JSON_API; + +/// <summary> +/// The volume of a cone A defined by a base area <see cref="CircleFact">CircleFact</see>, an apex <see cref="PointFact">PointFact</see> and the volume as float +/// </summary> +public class ConeVolumeFact : FactWrappedCRTP<ConeVolumeFact> +{ + /// <summary> a <see cref="CircleFact">CircleFact</see> describing the base area </summary> + public string Cid1; + [JsonIgnore] + public CircleFact Circle { get => (CircleFact)FactRecorder.AllFacts[Cid1]; } + + /// <summary> a <see cref="PointFact">PointFact</see> describing the apex point </summary> + public string Pid1; + [JsonIgnore] + public PointFact Point { get => (PointFact)FactRecorder.AllFacts[Pid1]; } + + /// <summary> the volume of the cone as a float </summary> + public float vol; + + /// <summary> \copydoc Fact.Fact </summary> + public ConeVolumeFact() : base() + { + this.Cid1 = null; + this.Pid1 = null; + this.vol = 0.0f; + } + + /// <summary> + /// Standard Constructor: + /// Initiates members and creates MMT %Fact Server-Side + /// </summary> + /// <param name="cid1">sets <see cref="Cid1"/></param> + /// <param name="pid1">sets <see cref="Pid1"/></param> + /// <param name="vol">sets <see cref="vol"/></param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public ConeVolumeFact(string cid1, string pid1, float vol, FactRecorder organizer) : base(organizer) + { + this.Cid1 = cid1; + this.Pid1 = pid1; + this.vol = vol; + + SendToMMT(); + } + + protected override void RecalculateTransform() + { + Position = Point.Position; + Rotation = Circle.Rotation; + } + + /// <summary> + /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. + /// </summary> + /// <param name="Cid1">sets <see cref="Cid1"/></param> + /// <param name="Pid1">sets <see cref="Pid1"/></param> + /// <param name="volume">sets <see cref="vol"/></param> + /// <param name="backendURI">MMT URI</param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public ConeVolumeFact(string Cid1, string Pid1, float volume, string backendURI, FactRecorder organizer) : base(organizer) + { + this.Cid1 = Cid1; + this.Pid1 = Pid1; + this.vol = volume; + + this._URI = backendURI; + _ = this.Label; + } + + /// \copydoc Fact.parseFact(ScrollFact) + public new static ConeVolumeFact parseFact(MMTFact fact) + { + if (((MMTValueFact)fact).lhs is not OMA lhs) + return null; + + string CircleUri = ((OMS)((OMA)lhs.arguments[0]).arguments[0]).uri; + string PointUri = ((OMS)((OMA)lhs.arguments[0]).arguments[1]).uri; + + float volume = 0.0f; + if (((MMTValueFact)fact).value is OMF oMFvolume) + volume = oMFvolume.@float; + + if (!FactRecorder.AllFacts.ContainsKey(CircleUri) + || !FactRecorder.AllFacts.ContainsKey(PointUri)) + return null; + + return new ConeVolumeFact(CircleUri, PointUri, volume, fact.@ref.uri, StageStatic.stage.factState); + } + + /// \copydoc Fact.generateLabel + protected override string generateLabel() + => "V(" + Circle.Label + "," + Point.Label + ")"; + + public override MMTFact MakeMMTDeclaration() + { + SOMDoc lhs = + new OMA( + new OMS(MMTConstants.VolumeCone), + + new[] { + new OMA(new OMS(MMTConstants.ConeOfCircleApex), + new[] { + new OMS(Cid1), + new OMS(Pid1), + } + ), + } + ); + + SOMDoc valueTp = new OMS(MMTConstants.RealLit); + SOMDoc value = new OMF(vol); + + return new MMTValueFact(this.Label, lhs, valueTp, value); + } + + /// \copydoc Fact.hasDependentFacts + public override bool HasDependentFacts => true; + + /// \copydoc Fact.getDependentFactIds + protected override string[] GetDependentFactIds() + => new string[] { Cid1, Pid1 }; + + /// \copydoc Fact.Equivalent(Fact, Fact) + protected override bool EquivalentWrapped(ConeVolumeFact f1, ConeVolumeFact f2) + => DependentFactsEquivalent(f1, f2); + + protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) + => new ConeVolumeFact(old_to_new[this.Cid1], old_to_new[this.Pid1], this.vol, organizer); +} + +/// <summary> +/// The volume of a cone A defined by a base area <see cref="CircleFact">CircleFact</see>, a top area <see cref="CircleFact">CircleFact</see> and the volume as float +/// </summary> +public class TruncatedConeVolumeFact : FactWrappedCRTP<TruncatedConeVolumeFact> +{ + /// <summary> a <see cref="CircleFact">CircleFact</see> describing the base area </summary> + public string CidBase; + [JsonIgnore] + public CircleFact CircleBase { get => (CircleFact)FactRecorder.AllFacts[CidBase]; } + + /// <summary> a <see cref="CircleFact">CircleFact</see> describing the top area </summary> + public string CidTop; + [JsonIgnore] + public CircleFact CircleTop { get => (CircleFact)FactRecorder.AllFacts[CidTop]; } + + /// <summary> the volume of Truncated the cone as a float </summary> + [JsonIgnore] + public float vol; + /// <summary> a proof that both circles have not the same size </summary> + public string unequalCirclesProof; + /// <summary> OMA proof that the two circles are parallel </summary> + public OMA proof; + + + /// <summary> \copydoc Fact.Fact </summary> + public TruncatedConeVolumeFact() : base() + { + this.CidBase = null; + this.CidTop = null; + this.vol = 0.0f; + this.unequalCirclesProof = null; + this.proof = null; + } + + /// <summary> + /// Standard Constructor: + /// Initiates members and creates MMT %Fact Server-Side + /// </summary> + /// <param name="cid1">sets <see cref="CidBase"/></param> + /// <param name="cid2">sets <see cref="CidTop"/></param> + /// <param name="vol">sets <see cref="vol"/></param> + /// <param name="proof">sets <see cref="proof"/></param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public TruncatedConeVolumeFact(string cid1, string cid2, float vol, string unequalproof, OMA proof, FactRecorder organizer) : base(organizer) + { + this.CidBase = cid1; + this.CidTop = cid2; + this.proof = proof; + this.unequalCirclesProof = unequalproof; + this.vol = vol; + + SendToMMT(); + } + + protected override void RecalculateTransform() + { + Position = CircleTop.Position; + Rotation = CircleTop.Rotation; + } + + /// <summary> + /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. + /// </summary> + /// <param name="Cid1">sets <see cref="CidBase"/></param> + /// <param name="Cid2">sets <see cref="CidTop"/></param> + /// <param name="volume">sets <see cref="vol"/></param> + /// <param name="proof">sets <see cref="proof"/></param> + /// <param name="backendURI">MMT URI</param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public TruncatedConeVolumeFact(string Cid1, string Cid2, float volume, string unequalproof, OMA proof, string backendURI, FactRecorder organizer) : base(organizer) + { + this.CidBase = Cid1; + this.CidTop = Cid2; + this.vol = volume; + this.proof = proof; + this.unequalCirclesProof = unequalproof; + + this._URI = backendURI; + _ = this.Label; + } + + /// \copydoc Fact.parseFact(ScrollFact) + public new static TruncatedConeVolumeFact parseFact(MMTFact fact) + { + string Circle1Uri = ((OMS)((OMA)((OMA)((MMTValueFact)fact).lhs).arguments[0]).arguments[0]).uri; + string Circle2Uri = ((OMS)((OMA)((OMA)((MMTValueFact)fact).lhs).arguments[0]).arguments[1]).uri; + float volume = ((OMF)((MMTValueFact)fact).value).@float; + + string UnEqualCirclesProof = ((OMS)(((OMA)((OMA)((MMTValueFact)fact).lhs).arguments[0]).arguments[2])).uri; + OMA proof = (OMA)(((OMA)((OMA)((MMTValueFact)fact).lhs).arguments[0]).arguments[3]); + + if (!FactRecorder.AllFacts.ContainsKey(Circle1Uri) + || !FactRecorder.AllFacts.ContainsKey(Circle2Uri)) + return null; + + return new TruncatedConeVolumeFact(Circle1Uri, Circle2Uri, volume, UnEqualCirclesProof, proof, fact.@ref.uri, StageStatic.stage.factState); + } + + /// \copydoc Fact.generateLabel + protected override string generateLabel() + => "V(" + CircleBase.Label + "," + CircleTop.Label + ")"; + + public override MMTFact MakeMMTDeclaration() + { + SOMDoc lhs = + new OMA( + new OMS(MMTConstants.TruncatedVolumeCone), + new SOMDoc[] { + new OMS(CidBase), + new OMS(CidTop), + new OMS(unequalCirclesProof), + proof, + } + ); + + SOMDoc valueTp = new OMS(MMTConstants.RealLit); + SOMDoc value = new OMF(vol); + + return new MMTValueFact(this.Label, lhs, valueTp, value); + } + + /// \copydoc Fact.hasDependentFacts + public override bool HasDependentFacts => true; + + /// \copydoc Fact.getDependentFactIds + protected override string[] GetDependentFactIds() + => new string[] { CidBase, CidTop }; + + /// \copydoc Fact.Equivalent(Fact, Fact) + protected override bool EquivalentWrapped(TruncatedConeVolumeFact f1, TruncatedConeVolumeFact f2) + => DependentFactsEquivalent(f1, f2); + + protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) + => new TruncatedConeVolumeFact(old_to_new[this.CidBase], old_to_new[this.CidTop], this.vol, old_to_new[this.unequalCirclesProof], this.proof, organizer); +} + +/// <summary> +/// The volume of a cylinder defined by a base area <see cref="CircleFact">CircleFact</see>, a top area <see cref="CircleFact">CircleFact</see> and the volume as float +/// </summary> +public class CylinderVolumeFact : FactWrappedCRTP<CylinderVolumeFact> +{ + /// <summary> a <see cref="CircleFact">CircleFact</see> describing the base area </summary> + public string Cid1; + [JsonIgnore] + public CircleFact Circle1 { get => (CircleFact)FactRecorder.AllFacts[Cid1]; } + + /// <summary> a <see cref="CircleFact">CircleFact</see> describing the top area </summary> + public string Cid2; + [JsonIgnore] + public CircleFact Circle2 { get => (CircleFact)FactRecorder.AllFacts[Cid2]; } + + /// <summary> the volume of the cylinder as a float </summary> + public float vol; + /// <summary> a proof that both circles have the same size </summary> + public string equalCirclesProof; + /// <summary> OMA proof that the two circles are parallel </summary> + public OMA proof; + + /// <summary> \copydoc Fact.Fact </summary> + public CylinderVolumeFact() : base() + { + this.Cid1 = null; + this.Cid2 = null; + this.vol = 0.0f; + this.proof = null; + this.equalCirclesProof = null; + } + + /// <summary> + /// Standard Constructor: + /// Initiates members and creates MMT %Fact Server-Side + /// </summary> + /// <param name="cid1">sets <see cref="Cid1"/></param> + /// <param name="cid2">sets <see cref="Cid2"/></param> + /// <param name="vol">sets <see cref="vol"/></param> + /// <param name="proof">sets <see cref="proof"/></param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public CylinderVolumeFact(string cid1, string cid2, float vol, string eqProof, OMA proof, FactRecorder organizer) : base(organizer) + { + this.Cid1 = cid1; + this.Cid2 = cid2; + this.proof = proof; + this.equalCirclesProof = eqProof; + this.vol = vol; + + SendToMMT(); + } + + protected override void RecalculateTransform() + { + Position = Circle2.Position; + Rotation = Circle2.Rotation; + } + + /// <summary> + /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_. + /// </summary> + /// <param name="Cid1">sets <see cref="Cid1"/></param> + /// <param name="Cid2">sets <see cref="Cid2"/></param> + /// <param name="volume">sets <see cref="vol"/></param> + /// <param name="proof">sets <see cref="proof"/></param> + /// <param name="backendURI">MMT URI</param> + /// <param name="organizer">sets <see cref="Fact._Facts"/></param> + public CylinderVolumeFact(string Cid1, string Cid2, float volume, string eqProof, OMA proof, string backendURI, FactRecorder organizer) : base(organizer) + { + this.Cid1 = Cid1; + this.Cid2 = Cid2; + this.vol = volume; + this.proof = proof; + this.equalCirclesProof = eqProof; + + this._URI = backendURI; + _ = this.Label; + } + + /// \copydoc Fact.parseFact(ScrollFact) + public new static CylinderVolumeFact parseFact(MMTFact fact) + { + string Circle1Uri = ((OMS)((OMA)((OMA)((MMTValueFact)fact).lhs).arguments[0]).arguments[0]).uri; + string Circle2Uri = ((OMS)((OMA)((OMA)((MMTValueFact)fact).lhs).arguments[0]).arguments[1]).uri; + float volume = ((OMF)((MMTValueFact)fact).value).@float; + string EqualCirclesProof = ((OMS)(((OMA)((OMA)((MMTValueFact)fact).lhs).arguments[0]).arguments[2])).uri; + + OMA proof = (OMA)(((OMA)((OMA)((MMTValueFact)fact).lhs).arguments[0]).arguments[3]); + + if (!FactRecorder.AllFacts.ContainsKey(Circle1Uri) + || !FactRecorder.AllFacts.ContainsKey(Circle2Uri)) + return null; + + return new CylinderVolumeFact(Circle1Uri, Circle2Uri, volume, EqualCirclesProof, proof, fact.@ref.uri, StageStatic.stage.factState); + } + + /// \copydoc Fact.generateLabel + protected override string generateLabel() + => "V(" + Circle1.Label + "," + Circle2.Label + ")"; + + public override MMTFact MakeMMTDeclaration() + { + SOMDoc lhs = + new OMA( + new OMS(MMTConstants.CylinderVolume), + + new SOMDoc[] { + new OMS(Cid1), + new OMS(Cid2), + new OMS(equalCirclesProof), + proof, + } + ); + + SOMDoc valueTp = new OMS(MMTConstants.RealLit); + SOMDoc value = new OMF(vol); + + return new MMTValueFact(this.Label, lhs, valueTp, value); + } + + /// \copydoc Fact.hasDependentFacts + public override bool HasDependentFacts => true; + + /// \copydoc Fact.getDependentFactIds + protected override string[] GetDependentFactIds() + => new string[] { Cid1, Cid2, equalCirclesProof }; + + /// \copydoc Fact.Equivalent(Fact, Fact) + protected override bool EquivalentWrapped(CylinderVolumeFact f1, CylinderVolumeFact f2) + => DependentFactsEquivalent(f1, f2); + + protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactRecorder organizer) + => new CylinderVolumeFact(old_to_new[this.Cid1], old_to_new[this.Cid2], this.vol, old_to_new[this.equalCirclesProof], this.proof, organizer); +} \ No newline at end of file diff --git a/Assets/Scripts/InventoryStuff/PythagorasScript.cs.meta b/Assets/Scripts/InteractionEngine/FactHandling/Facts/VolumeFacts.cs.meta similarity index 83% rename from Assets/Scripts/InventoryStuff/PythagorasScript.cs.meta rename to Assets/Scripts/InteractionEngine/FactHandling/Facts/VolumeFacts.cs.meta index d103391a54d7b560a25e62dcf0a525e66a54ef9c..7a4644ed38caf8df47e00b59cc98b55525301476 100644 --- a/Assets/Scripts/InventoryStuff/PythagorasScript.cs.meta +++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/VolumeFacts.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 413dcae9856bd794ab03d29210561c57 +guid: 4ffde2f4d1b634a4e9e8e98b8b01ca64 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/InteractionEngine/WorldCursor.cs b/Assets/Scripts/InteractionEngine/WorldCursor.cs index b5689c10c562b974ddfea34bd2259b0d500f29b9..746c97c592598b3f30f4a410a91b271b961b769c 100644 --- a/Assets/Scripts/InteractionEngine/WorldCursor.cs +++ b/Assets/Scripts/InteractionEngine/WorldCursor.cs @@ -92,12 +92,12 @@ void Update() else if (fact is CircleFact circleFact) { var projPlane = - Math3d.ProjectPointOnPlane(circleFact.normal, circleFact.Point1.Point, Hits[i].point); + Math3d.ProjectPointOnPlane(circleFact.normal, circleFact.PointCenter.Point, Hits[i].point); - var circleDistance = projPlane - circleFact.Point1.Point; + var circleDistance = projPlane - circleFact.PointCenter.Point; if (circleDistance.magnitude >= circleFact.radius) { - projPlane = circleFact.Point1.Point + circleDistance.normalized * circleFact.radius; + projPlane = circleFact.PointCenter.Point + circleDistance.normalized * circleFact.radius; Hits[i].normal = circleDistance.normalized; } diff --git a/Assets/Scripts/InventoryStuff/PointWrapper.cs b/Assets/Scripts/InventoryStuff/PointWrapper.cs deleted file mode 100644 index a8da0acd5943d0d223f7cd13b2eaa03b34e2e9b5..0000000000000000000000000000000000000000 --- a/Assets/Scripts/InventoryStuff/PointWrapper.cs +++ /dev/null @@ -1,6 +0,0 @@ -using UnityEngine; - -public class PointWrapper : MonoBehaviour -{ - public Fact point; -} diff --git a/Assets/Scripts/InventoryStuff/PythagorasScript.cs b/Assets/Scripts/InventoryStuff/PythagorasScript.cs deleted file mode 100644 index 0b7537d1d9fce9776263e1d6b0c02cfaffbd0775..0000000000000000000000000000000000000000 --- a/Assets/Scripts/InventoryStuff/PythagorasScript.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -public class PythagorasScript : MonoBehaviour -{ - private Dictionary<string, Fact> items = new Dictionary<string, Fact>(); - - public void putFact(string name, Fact obj) - { - if (this.items.ContainsKey(name)) - { - this.items.Remove(name); - } - this.items.Add(name, obj); - } - - public void doMagic() - { - Dictionary<string, Fact>.Enumerator enumerator = this.items.GetEnumerator(); - while (enumerator.MoveNext()) - { - Debug.Log(enumerator.Current.Key + " is mapped to " + enumerator.Current.Value); - } - } -} diff --git a/Assets/Scripts/InventoryStuff/ToggleRotateImage.cs b/Assets/Scripts/InventoryStuff/ToggleRotateImage.cs index 84a91bdd19ec5b2bb3ca82f63cbef986d78c1c88..3c893c1023de43904f33fa1d0946615534550a36 100644 --- a/Assets/Scripts/InventoryStuff/ToggleRotateImage.cs +++ b/Assets/Scripts/InventoryStuff/ToggleRotateImage.cs @@ -6,10 +6,7 @@ public class ToggleRotateImage : MonoBehaviour { [SerializeField] Transform targetGraphic; Toggle _toggle; - Toggle toggle - { - get { return _toggle ?? (_toggle = GetComponent<Toggle>()); } - } + Toggle toggle => _toggle ??= GetComponent<Toggle>(); void Awake() { diff --git a/Assets/Scripts/MMTServer/CommunicationProtocoll/MMTConstants.cs b/Assets/Scripts/MMTServer/CommunicationProtocoll/MMTConstants.cs index 61695802a6f93b2cde7a0971b153ba80d011a451..d2c3fe51bbff7b0fccd38bd28a2497847c48a287 100644 --- a/Assets/Scripts/MMTServer/CommunicationProtocoll/MMTConstants.cs +++ b/Assets/Scripts/MMTServer/CommunicationProtocoll/MMTConstants.cs @@ -7,6 +7,7 @@ namespace REST_JSON_API public static class MMTConstants { public static readonly string Point = "http://mathhub.info/MitM/core/geometry?3DGeometry?point"; + public static readonly string Wall = "?wall"; public static readonly string LineType = "http://mathhub.info/MitM/core/geometry?Geometry/Common?line_type"; public static readonly string LineOf = "http://mathhub.info/MitM/core/geometry?Geometry/Common?lineOf"; diff --git a/Assets/Scripts/MeshGenerator/BoundingPositioning.cs b/Assets/Scripts/MeshGenerator/BoundingPositioning.cs new file mode 100644 index 0000000000000000000000000000000000000000..0805001d41f19ae75e4af3887603c2ef160a1f66 --- /dev/null +++ b/Assets/Scripts/MeshGenerator/BoundingPositioning.cs @@ -0,0 +1,37 @@ +using UnityEngine; + +public class BoundingPositioning : MonoBehaviour +{ + public Anker x = Anker.center; + public Anker y = Anker.center; + public Anker z = Anker.center; + + public MeshFilter mesh = null; + + public enum Anker + { + min = 0, center = 1, max = 2 + } + + private void OnValidate() => UpdatePosition(); + private void Awake() => UpdatePosition(); + + private void UpdatePosition() + { + if (mesh == null + || mesh.sharedMesh == null) + return; + + Vector3[] bounds = { + mesh.sharedMesh.bounds.min, + mesh.sharedMesh.bounds.center, + mesh.sharedMesh.bounds.max, + }; + + transform.position = new Vector3( + bounds[(int)x][0], + bounds[(int)y][1], + bounds[(int)z][2] + ); + } +} diff --git a/Assets/Scripts/MeshGenerator/BoundingPositioning.cs.meta b/Assets/Scripts/MeshGenerator/BoundingPositioning.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..0ceb274da7a6c9adc7ee7ba396e684aa2f46c357 --- /dev/null +++ b/Assets/Scripts/MeshGenerator/BoundingPositioning.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b53a9efe2eaabd4a9ae38ae148bed9e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/MeshGenerator/CircleGenerator.cs b/Assets/Scripts/MeshGenerator/CircleGenerator.cs index c07a99c8b781fc2cecc3b98dd291178457b68bcd..5f8e3b70e2598908e1ea01991ee59914240c0a32 100644 --- a/Assets/Scripts/MeshGenerator/CircleGenerator.cs +++ b/Assets/Scripts/MeshGenerator/CircleGenerator.cs @@ -1,7 +1,6 @@ using System; -using System.Collections.Generic; -using UnityEngine; using System.Linq; +using UnityEngine; public class CircleGenerator : ShapeGenerator { @@ -11,28 +10,11 @@ public class CircleGenerator : ShapeGenerator [Header("Technical")] [Range(3,1000)] public int sideCount = 500; - - [Header("Parts")] - public List<MeshFilter> circleMesh; #endregion InspectorVariables #region Implementation - protected override void GenerateShape() - { - foreach (MeshFilter filter in circleMesh) - { - if (filter == null) continue; - - var circle = CreateCircle(radius, sideCount); - - if (filter.sharedMesh != null) - filter.sharedMesh.Clear(); - filter.mesh = CreateMesh(circle); - - if (filter.transform.TryGetComponent(out MeshCollider meshCol)) - meshCol.sharedMesh = filter.sharedMesh; - } - } + protected override (Vector3[] vertices, int[] triangles) GenerateTopology() + => CreateCircle(radius, sideCount); /// <summary> /// Creates circle vertecies and triangles around the midPoint at (0,0,0) @@ -40,18 +22,19 @@ protected override void GenerateShape() /// <param name="points"></param> /// <param name="invert"></param> /// <returns></returns> - static (Vector3[], int[]) CreateCircle(float radius, int sideCount, bool invert = false) + public static (Vector3[], int[]) CreateCircle(float radius, int sideCount, Vector3 offset, bool invert = false) { - Vector3[] vertices = GetCirclePoints(radius, sideCount).Union(new Vector3[] { Vector3.zero }).ToArray(); - int[] triangles = new int[(vertices.Length - 1) * 3]; - int vertLen = vertices.Length; - for (int i = 0; i < vertLen-1; i++) - { - triangles[i * 3 + 0] = vertLen-1; // midPoint - triangles[i * 3 + 1] = i; - triangles[i * 3 + 2] = (i + 1) % (vertLen-1); - } - return (vertices, invert ? triangles.Reverse().ToArray() : triangles); + Vector3[] edge = GetCirclePoints(radius, sideCount); + Vector3[] vertices = + new Vector3[] { offset } + .AppendRange(edge) + .Append(edge[0]) + .ToArray(); + + return CreatePlane(vertices, invert); } + + public static (Vector3[], int[]) CreateCircle(float radius, int sideCount, bool invert = false) + => CreateCircle(radius, sideCount, Vector3.zero, invert); #endregion Implementation } diff --git a/Assets/Scripts/MeshGenerator/ConeGenerator.cs b/Assets/Scripts/MeshGenerator/ConeGenerator.cs index 73cc683360f1c588a9765645aa395ea5824a5fc0..ebc95111e39c11e369f3eb94069e60a4908da894 100644 --- a/Assets/Scripts/MeshGenerator/ConeGenerator.cs +++ b/Assets/Scripts/MeshGenerator/ConeGenerator.cs @@ -1,82 +1,56 @@ using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; using System.Linq; +using UnityEngine; public class ConeGenerator : ShapeGenerator { #region InspectorVariables [Header("Cone values")] - [Range(0,100)] public float bottomRadius = 1f; - [Range(0,100)] public float topRadius = 0f; + [Range(0, 100)] public float bottomRadius = 1f; + [Range(0, 100)] public float topRadius = 0f; public Vector3 topPosition = new Vector3(0, 1f, 0); [Header("Technical")] - [Range(3,1000)] public int sideCount = 500; - public bool generateTop = true; - public bool generateBottom = false; - - [Header("Parts")] - public MeshFilter topMesh; - public MeshFilter sideMesh; - public MeshFilter bottomMesh; + [Range(3,1000)] + public int sideCount = 500; #endregion InspectorVariables #region Implementation - protected override void GenerateShape() + protected override (Vector3[] vertices, int[] triangles) GenerateTopology() { - Vector3[] bottomCircle = GetCirclePoints(bottomRadius, sideCount); - Vector3[] topCircle = GetCirclePoints(topRadius, sideCount, topPosition); + Vector3[] top_circle = new[] { topPosition }; + Vector3[] bottom_circle = new[] { Vector3.zero }; - if (sideMesh == null || topMesh == null || bottomMesh == null) - return; + int[] top_boundary = new int[] { 0 }; + int[] bottom_boundary = new int[] { 0 }; - //side - if (sideMesh.sharedMesh != null) - sideMesh.sharedMesh.Clear(); - sideMesh.mesh = CreateMesh(CreateConeSide(sideCount, bottomCircle, topCircle)); - - //top - if (topMesh.sharedMesh != null) - topMesh.sharedMesh.Clear(); - if (generateTop) - topMesh.mesh = CreateMesh(CreatePlane(topCircle, false)); - - //bottom - if (bottomMesh.sharedMesh != null) - bottomMesh.sharedMesh.Clear(); - if (generateBottom) - bottomMesh.mesh = CreateMesh(CreatePlane(bottomCircle, true)); - } - - private static (Vector3[], int[]) CreateConeSide(int sideCount, Vector3[] bottomCircle, Vector3[] topCircle) - { - Vector3[] vertices = new Vector3[sideCount * 4]; - int[] triangles = new int[sideCount * 6]; - - //generate vertices - for (int i = 0; i < sideCount; i++) + if (topRadius > 0f) { - vertices[i * 4] = bottomCircle[i]; - vertices[i * 4 + 1] = bottomCircle[(i + 1) % sideCount]; - vertices[i * 4 + 2] = topCircle[i]; - vertices[i * 4 + 3] = topCircle[(i + 1) % sideCount]; - } + Vector3[] edge = GetCirclePoints(topRadius, sideCount, topPosition); + top_circle = top_circle + .AppendRange(edge) + .Append(edge[0]) + .ToArray(); - //generate triangles - for (int t = 0, i = 0; t < triangles.Length; t += 6, i += 4) + top_boundary = Enumerable.Range(1, edge.Length).ToArray(); + } + if (bottomRadius > 0f) { - triangles[t] = i; - triangles[t + 1] = i + 1; - triangles[t + 2] = i + 2; + Vector3[] edge = GetCirclePoints(bottomRadius, sideCount); + bottom_circle = bottom_circle + .AppendRange(edge) + .Append(edge[0]) + .ToArray(); - triangles[t + 3] = i + 1; - triangles[t + 4] = i + 3; - triangles[t + 5] = i + 2; + bottom_boundary = Enumerable.Range(1, edge.Length).ToArray(); } - return (vertices, triangles); + return CreatePrism( + CreatePlane(top_circle), + CreatePlane(bottom_circle, true), + top_boundary, + bottom_boundary + ); } #endregion Implementation } diff --git a/Assets/Scripts/MeshGenerator/PlaneGenerator.cs b/Assets/Scripts/MeshGenerator/PlaneGenerator.cs new file mode 100644 index 0000000000000000000000000000000000000000..6d89d16dd78b27932a71dd35d018c0095e6ef09e --- /dev/null +++ b/Assets/Scripts/MeshGenerator/PlaneGenerator.cs @@ -0,0 +1,24 @@ +using UnityEngine; + +public class PlaneGenerator : ShapeGenerator +{ + #region InspectorVariables + [Header("Plane values")] + [SerializeField] + protected Vector3[] _vertices; + public Vector3[] Vertices + { + get => _vertices.Clone() as Vector3[]; + set + { + _vertices = value; + GenerateShapeForAll(); + } + } + #endregion InspectorVariables + + #region Implementation + protected override (Vector3[] vertices, int[] triangles) GenerateTopology() + => CreatePlane(_vertices); + #endregion Implementation +} \ No newline at end of file diff --git a/Assets/Scripts/MeshGenerator/PlaneGenerator.cs.meta b/Assets/Scripts/MeshGenerator/PlaneGenerator.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..603ca4b52a69c7c647fe3f3a0d4787b9a21bfb82 --- /dev/null +++ b/Assets/Scripts/MeshGenerator/PlaneGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f599175127741c14f97241d989002207 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/MeshGenerator/PrismGenerator.cs b/Assets/Scripts/MeshGenerator/PrismGenerator.cs new file mode 100644 index 0000000000000000000000000000000000000000..9a0c646baa672da1851003a0c13ebd50e8360cce --- /dev/null +++ b/Assets/Scripts/MeshGenerator/PrismGenerator.cs @@ -0,0 +1,36 @@ +using System.Linq; +using UnityEngine; + +public class PrismGenerator : PlaneGenerator +{ + #region InspectorVariables + [Header("Plane values")] + [SerializeField] + private Vector3 _offset; + public Vector3 Offset + { + get => _offset; + set + { + _offset = value; + GenerateShapeForAll(); + } + } + #endregion InspectorVariables + + #region Implementation + protected override (Vector3[] vertices, int[] triangles) GenerateTopology() + { + (Vector3[] vertices, int[] triangles) plane = CreatePlane(_vertices); + Vector3 center = CreateMesh(plane).bounds.center; + + return CreatePrism( + (plane.vertices.Select(v => v + _offset).ToArray() + , plane.triangles), + (plane.vertices.Select(v => v).ToArray() + , plane.triangles.Reverse().ToArray()), + null, null + ); + } + #endregion Implementation +} \ No newline at end of file diff --git a/Assets/Scripts/MeshGenerator/PrismGenerator.cs.meta b/Assets/Scripts/MeshGenerator/PrismGenerator.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..5265c9a4b186d26d14a9c7ace1ea72c834536119 --- /dev/null +++ b/Assets/Scripts/MeshGenerator/PrismGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2a639f1d1c3cdeb42bc5a7a66401dc02 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/MeshGenerator/ShapeGenerator.cs b/Assets/Scripts/MeshGenerator/ShapeGenerator.cs index b7309740d44bdaadf2fc29a945825c48cea7ce39..2ce160f9cc95cdff58e72f43f023a1d4c9e8b821 100644 --- a/Assets/Scripts/MeshGenerator/ShapeGenerator.cs +++ b/Assets/Scripts/MeshGenerator/ShapeGenerator.cs @@ -1,32 +1,79 @@ +using System; +using System.Collections.Generic; using System.Linq; +using Unity.Mathematics; using UnityEngine; public abstract class ShapeGenerator : MonoBehaviour { + #region InspectorVariables + [Header("Parts")] + public List<MeshFilter> Meshs; + public List<float> NormalOffset; + public bool AlternateNormals = false; + #endregion InspectorVariables + #region UnityMethods - void Start() => GenerateShape(); + void Start() => GenerateShapeForAll(); - #if UNITY_EDITOR +#if UNITY_EDITOR void OnValidate() { // prevent 'SendMessage cannot be called during Awake, CheckConsistency, or OnValidate' warning - UnityEditor.EditorApplication.delayCall += GenerateShape; + UnityEditor.EditorApplication.delayCall += GenerateShapeForAll; } - #endif +#endif #endregion UnityMethods - protected abstract void GenerateShape(); + protected void GenerateShapeForAll() + { + float[] _NormalOffset = new float[Meshs.Count]; + NormalOffset?.CopyTo(0, _NormalOffset, 0 + , math.min(NormalOffset.Count, Meshs.Count)); + + for (int i = 0; i < Meshs.Count; i++) + { + MeshFilter filter = Meshs[i]; + if (filter == null) + continue; + + Mesh mesh = CreateMesh(GenerateTopology()); + var normals = AlternateNormals + ? GetUnweightedNormals(mesh) + : mesh.normals; + + mesh.SetVertices( + mesh.vertices + .Zip(normals, (v, n) + => v + n * _NormalOffset[i]) + .ToList() + ); + + if (filter.sharedMesh != null) + filter.sharedMesh.Clear(); + filter.sharedMesh = mesh; + + if (filter.transform.TryGetComponent(out MeshCollider meshCol)) + meshCol.sharedMesh = filter.sharedMesh; + } + } + + protected abstract (Vector3[] vertices, int[] triangles) GenerateTopology(); #region Helper protected static Mesh CreateMesh((Vector3[] vertices, int[] triangles) meshValues) { - Mesh mesh = new Mesh(); - (mesh.vertices, mesh.triangles) = (meshValues.vertices, meshValues.triangles); + Mesh mesh = new() + { + vertices = meshValues.vertices, + triangles = meshValues.triangles + }; + mesh.Optimize(); mesh.RecalculateNormals(); //fix lighting return mesh; } - protected static Vector3[] GetCirclePoints(float circleRadius, int pointCount) + protected static Vector3[] GetCirclePoints(float circleRadius, int pointCount) => GetCirclePoints(circleRadius, pointCount, Vector3.zero); protected static Vector3[] GetCirclePoints(float circleRadius, int pointCount, Vector3 offset) @@ -35,8 +82,13 @@ protected static Vector3[] GetCirclePoints(float circleRadius, int pointCount, V float slice = (2f * Mathf.PI) / pointCount; for (int i = 0; i < pointCount; i++) { - float angle = i * slice; - circle[i] = new Vector3(circleRadius * Mathf.Sin(angle), 0, circleRadius * Mathf.Cos(angle)) + offset; + float rad_angle = i * slice; + circle[i] = + new Vector3( + circleRadius * Mathf.Sin(rad_angle), + 0, + circleRadius * Mathf.Cos(rad_angle) + ) + offset; } return circle; } @@ -47,9 +99,11 @@ protected static Vector3[] GetCirclePoints(float circleRadius, int pointCount, V /// <param name="points"></param> /// <param name="invert"></param> /// <returns></returns> - protected static (Vector3[], int[]) CreatePlane(Vector3[] points, bool invert = false) + protected static (Vector3[] vertices, int[] triangles) CreatePlane(Vector3[] vertices, bool invert = false) { - Vector3[] vertices = points; + if (vertices.Length < 3) + return (vertices, new int[0]); + int[] triangles = new int[(vertices.Length - 2) * 3]; for (int i = 1; i < vertices.Length - 1; i++) { @@ -57,7 +111,98 @@ protected static (Vector3[], int[]) CreatePlane(Vector3[] points, bool invert = triangles[(i - 1) * 3 + 1] = i; triangles[(i - 1) * 3 + 2] = (i + 1); } + return (vertices, invert ? triangles.Reverse().ToArray() : triangles); } + + protected static (Vector3[] vertices, int[] triangles) CreatePrism( + (Vector3[] vertices, int[] triangles) top, + (Vector3[] vertices, int[] triangles) bottom, + int[] boundary_top, + int[] boundary_bottom + ) + { + boundary_top ??= Enumerable.Range(0, top.vertices.Length).ToArray(); + boundary_bottom ??= Enumerable.Range(0, bottom.vertices.Length).ToArray(); + + if (boundary_top.Length != boundary_bottom.Length) + Debug.LogWarning("Arguments of different Size; Resulting mesh may be weird!"); + int max = math.max(boundary_top.Length, boundary_bottom.Length); + int tri_sum = top.triangles.Length + bottom.triangles.Length; + + Vector3[] new_vertices = top.vertices.ShallowCloneAppend(bottom.vertices); + + int[] new_triangles = new int[tri_sum + 2 * max * 3]; + top.triangles.CopyTo(new_triangles, 0); + bottom.triangles + .Select(i => i + top.vertices.Length) + .ToArray() + .CopyTo(new_triangles, top.triangles.Length); + + for (int i = 0; i < max; i++) + { + if (boundary_top.Length > 1) + { + new_triangles[tri_sum + i * 6 + 0] = boundary_top[(i + 1) % boundary_top.Length]; + new_triangles[tri_sum + i * 6 + 1] = boundary_top[i % boundary_top.Length]; + new_triangles[tri_sum + i * 6 + 2] = + top.vertices.Length + boundary_bottom[i % boundary_bottom.Length]; + } + if (boundary_bottom.Length > 1) + { + new_triangles[tri_sum + i * 6 + 3] = + top.vertices.Length + boundary_bottom[i % boundary_bottom.Length]; + new_triangles[tri_sum + i * 6 + 4] = + top.vertices.Length + boundary_bottom[(i + 1) % boundary_bottom.Length]; + new_triangles[tri_sum + i * 6 + 5] = boundary_top[(i + 1) % boundary_top.Length]; + } + } + + return (new_vertices, new_triangles); + } + + // Artefacts appear when mesh is unbalanced (e.g. many edges at one vert) + public static Vector3[] GetUnweightedNormals(Mesh mesh) + { + int[] triangles = mesh.triangles; + Vector3[] verts = mesh.vertices; + + Vector3[] normals = new Vector3[mesh.vertexCount]; + int[] weightsum = new int[mesh.vertexCount]; + + HashSet<int>[] deltas = new HashSet<int>[mesh.vertexCount]; + for (int i = 0; i < deltas.Length; i++) + deltas[i] = new(); + + for (int i = 0; i < triangles.Length; i += 3) + { + AddEdge(triangles[i + 0], triangles[i + 1]); + AddEdge(triangles[i + 0], triangles[i + 2]); + + AddEdge(triangles[i + 1], triangles[i + 0]); + AddEdge(triangles[i + 1], triangles[i + 2]); + + AddEdge(triangles[i + 2], triangles[i + 0]); + AddEdge(triangles[i + 2], triangles[i + 1]); + } + + for (int i = 0; i < normals.Length; i++) + normals[i] = (normals[i] / weightsum[i]).normalized; + + return normals; + + void AddEdge(int this_id, int other_id) + { + if (deltas[this_id].Add(other_id)) + { + Vector3 delta = (verts[this_id] - verts[other_id]).normalized; + if (Math3d.IsApproximatelyEqual(delta, Vector3.zero)) + return; + + normals[this_id] += delta; + weightsum[this_id]++; + } + } + } #endregion Helper } diff --git a/Assets/Scripts/MeshGenerator/TorusGenerator.cs b/Assets/Scripts/MeshGenerator/TorusGenerator.cs index 4ea8e96e3a6abaee0b69ef7b9d2c9fa456fd6c31..8601672bbccac243bbac8896339e76d561c07eb3 100644 --- a/Assets/Scripts/MeshGenerator/TorusGenerator.cs +++ b/Assets/Scripts/MeshGenerator/TorusGenerator.cs @@ -6,61 +6,53 @@ public class TorusGenerator : ShapeGenerator #region InspectorVariables [Header("Torus values")] [Range(0, 100)] public float torusRadius = 1f; - [Range(0, 10)] public float ringRadius = 0.1f; + [Range(0, 10)] public float ringRadius = 0.1f; [Header("Technical")] [Range(8, 150)] public int ringSegmentCount = 50; [Range(3, 100)] public int segmentSideCount = 30; - - [Header("Parts")] - public MeshFilter torusMesh; #endregion InspectorVariables #region Implementation - protected override void GenerateShape() - { - if (torusMesh == null) - return; - - if (torusMesh.sharedMesh != null) - torusMesh.sharedMesh.Clear(); - - torusMesh.mesh = CreateMesh(CreateTorus(torusRadius, ringRadius, ringSegmentCount, segmentSideCount)); - - if (torusMesh.transform.TryGetComponent(out MeshCollider meshCol)) - meshCol.sharedMesh = torusMesh.sharedMesh; - } + protected override (Vector3[] vertices, int[] triangles) GenerateTopology() + => CreateTorus(torusRadius, ringRadius, ringSegmentCount, segmentSideCount); private static (Vector3[] vertices, int[] triangles) CreateTorus(float torusRadius, float ringRadius, int ringSegmentCount, int segmentSideCount) { - Vector3[] vertices = new Vector3[ringSegmentCount * segmentSideCount * 4]; + Vector3[] vertices = new Vector3[ringSegmentCount * segmentSideCount]; int[] triangles = new int[ringSegmentCount * segmentSideCount * 6]; - //generate vertices float iStep = (2f * Mathf.PI) / ringSegmentCount; float jStep = (2f * Mathf.PI) / segmentSideCount; + + int t = 0; for (int i = 0; i < ringSegmentCount; i++) - { for (int j = 0; j < segmentSideCount; j++) { - vertices[(i * segmentSideCount + j) * 4] = GetPointOnTorus(torusRadius, ringRadius, i * iStep, j * jStep); - vertices[(i * segmentSideCount + j) * 4 + 1] = GetPointOnTorus(torusRadius, ringRadius, i * iStep, (j + 1) * jStep); - vertices[(i * segmentSideCount + j) * 4 + 2] = GetPointOnTorus(torusRadius, ringRadius, (i + 1) * iStep, j * jStep); - vertices[(i * segmentSideCount + j) * 4 + 3] = GetPointOnTorus(torusRadius, ringRadius, (i + 1) * iStep, (j + 1) * jStep); - } - } + //generate vertices + vertices[i * segmentSideCount + j] = GetPointOnTorus(torusRadius, ringRadius, i * iStep, j * jStep); - //generate triangles - for (int t = 0, i = 0; t < triangles.Length; t += 6, i += 4) - { - triangles[t] = i; - triangles[t+1] = i + 1; - triangles[t+2] = i + 2; + //generate triangles + triangles[t++] = + (i + 0) % ringSegmentCount * segmentSideCount + + (j + 0) % segmentSideCount; + triangles[t++] = + (i + 1) % ringSegmentCount * segmentSideCount + + (j + 0) % segmentSideCount; + triangles[t++] = + (i + 1) % ringSegmentCount * segmentSideCount + + (j + 1) % segmentSideCount; - triangles[t+3] = i + 1; - triangles[t+4] = i + 3; - triangles[t+5] = i + 2; - } + triangles[t++] = + (i + 1) % ringSegmentCount * segmentSideCount + + (j + 1) % segmentSideCount; + triangles[t++] = + (i + 0) % ringSegmentCount * segmentSideCount + + (j + 1) % segmentSideCount; + triangles[t++] = + (i + 0) % ringSegmentCount * segmentSideCount + + (j + 0) % segmentSideCount; + } return (vertices, triangles); } diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset index 408e5aa981a3d2e4738e6a4b162f9d15d919ff8d..200e61f66ac65754e32d641bcca9475ac1f220d3 100644 --- a/ProjectSettings/TagManager.asset +++ b/ProjectSettings/TagManager.asset @@ -28,8 +28,8 @@ TagManager: - Ray - Ring - Circle - - - - + - Plane + - Cone - TalkingZone - Tree - SnapZone