Compare commits
5 Commits
d569729c3c
...
developmen
| Author | SHA1 | Date | |
|---|---|---|---|
| 092897c88d | |||
| dbdc045229 | |||
| d1c8949b16 | |||
| 41ce4980d8 | |||
| d64d200f8d |
37
.gitattributes
vendored
37
.gitattributes
vendored
@@ -1,3 +1,40 @@
|
|||||||
|
# Unity YAML (escenas, prefabs, materiales, anims, metas) -> usar SmartMerge
|
||||||
|
*.unity merge=unityyamlmerge
|
||||||
|
*.prefab merge=unityyamlmerge
|
||||||
|
*.mat merge=unityyamlmerge
|
||||||
|
*.anim merge=unityyamlmerge
|
||||||
|
*.controller merge=unityyamlmerge
|
||||||
|
*.meta merge=unityyamlmerge
|
||||||
|
# Forzar tratamiento de texto y EOL
|
||||||
|
* text=auto eol=lf
|
||||||
*.jpg filter=lfs diff=lfs merge=lfs -text
|
*.jpg filter=lfs diff=lfs merge=lfs -text
|
||||||
*.fbx filter=lfs diff=lfs merge=lfs -text
|
*.fbx filter=lfs diff=lfs merge=lfs -text
|
||||||
*.png filter=lfs diff=lfs merge=lfs -text
|
*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.blend filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.obj filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.gltf filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.glb filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tga filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tif filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tiff filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.psd filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.exr filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.hdr filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.mov filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.wav filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.mp3 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.ogg filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.aac filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.mp4 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.dll filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.so filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.a filter=lfs diff=lfs merge=lfs -text
|
||||||
|
Scans/** filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.usdz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.mtl filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.ply filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.usd filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.7z filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.rar filter=lfs diff=lfs merge=lfs -text
|
||||||
|
|||||||
@@ -38,12 +38,12 @@ RenderSettings:
|
|||||||
m_ReflectionIntensity: 1
|
m_ReflectionIntensity: 1
|
||||||
m_CustomReflection: {fileID: 0}
|
m_CustomReflection: {fileID: 0}
|
||||||
m_Sun: {fileID: 0}
|
m_Sun: {fileID: 0}
|
||||||
m_IndirectSpecularColor: {r: 0.18028378, g: 0.22571412, b: 0.30692285, a: 1}
|
|
||||||
m_UseRadianceAmbientProbe: 0
|
m_UseRadianceAmbientProbe: 0
|
||||||
--- !u!157 &3
|
--- !u!157 &3
|
||||||
LightmapSettings:
|
LightmapSettings:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
serializedVersion: 12
|
serializedVersion: 13
|
||||||
|
m_BakeOnSceneLoad: 0
|
||||||
m_GISettings:
|
m_GISettings:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_BounceScale: 1
|
m_BounceScale: 1
|
||||||
@@ -133,7 +133,7 @@ GameObject:
|
|||||||
- component: {fileID: 330585547}
|
- component: {fileID: 330585547}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: Main Camera
|
m_Name: Main Camera
|
||||||
m_TagString: MainCamera
|
m_TagString: Untagged
|
||||||
m_Icon: {fileID: 0}
|
m_Icon: {fileID: 0}
|
||||||
m_NavMeshLayer: 0
|
m_NavMeshLayer: 0
|
||||||
m_StaticEditorFlags: 0
|
m_StaticEditorFlags: 0
|
||||||
@@ -250,12 +250,12 @@ MonoBehaviour:
|
|||||||
m_RequiresColorTexture: 0
|
m_RequiresColorTexture: 0
|
||||||
m_Version: 2
|
m_Version: 2
|
||||||
m_TaaSettings:
|
m_TaaSettings:
|
||||||
quality: 3
|
m_Quality: 3
|
||||||
frameInfluence: 0.1
|
m_FrameInfluence: 0.1
|
||||||
jitterScale: 1
|
m_JitterScale: 1
|
||||||
mipBias: 0
|
m_MipBias: 0
|
||||||
varianceClampScale: 0.9
|
m_VarianceClampScale: 0.9
|
||||||
contrastAdaptiveSharpening: 0
|
m_ContrastAdaptiveSharpening: 0
|
||||||
--- !u!1 &410087039
|
--- !u!1 &410087039
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -336,6 +336,9 @@ Light:
|
|||||||
m_ForceVisible: 0
|
m_ForceVisible: 0
|
||||||
m_ShadowRadius: 0
|
m_ShadowRadius: 0
|
||||||
m_ShadowAngle: 0
|
m_ShadowAngle: 0
|
||||||
|
m_LightUnit: 1
|
||||||
|
m_LuxAtDistance: 1
|
||||||
|
m_EnableSpotReflector: 1
|
||||||
--- !u!4 &410087041
|
--- !u!4 &410087041
|
||||||
Transform:
|
Transform:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ GameObject:
|
|||||||
m_Component:
|
m_Component:
|
||||||
- component: {fileID: 55455372}
|
- component: {fileID: 55455372}
|
||||||
- component: {fileID: 55455371}
|
- component: {fileID: 55455371}
|
||||||
|
- component: {fileID: 55455373}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: Directional Light
|
m_Name: Directional Light
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
@@ -216,7 +217,30 @@ Transform:
|
|||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
|
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
|
||||||
--- !u!1 &360989555
|
--- !u!114 &55455373
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 55455370}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Version: 3
|
||||||
|
m_UsePipelineSettings: 1
|
||||||
|
m_AdditionalLightsShadowResolutionTier: 2
|
||||||
|
m_LightLayerMask: 1
|
||||||
|
m_RenderingLayers: 1
|
||||||
|
m_CustomShadowLayers: 0
|
||||||
|
m_ShadowLayerMask: 1
|
||||||
|
m_ShadowRenderingLayers: 1
|
||||||
|
m_LightCookieSize: {x: 1, y: 1}
|
||||||
|
m_LightCookieOffset: {x: 0, y: 0}
|
||||||
|
m_SoftShadowQuality: 0
|
||||||
|
--- !u!1 &581552791
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
@@ -224,9 +248,261 @@ GameObject:
|
|||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
serializedVersion: 6
|
serializedVersion: 6
|
||||||
m_Component:
|
m_Component:
|
||||||
- component: {fileID: 360989558}
|
- component: {fileID: 581552792}
|
||||||
- component: {fileID: 360989557}
|
m_Layer: 0
|
||||||
- component: {fileID: 360989556}
|
m_Name: Camera Offset
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &581552792
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 581552791}
|
||||||
|
serializedVersion: 2
|
||||||
|
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: 1781544890}
|
||||||
|
m_Father: {fileID: 774907435}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!1 &607252634
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 607252637}
|
||||||
|
- component: {fileID: 607252636}
|
||||||
|
- component: {fileID: 607252635}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: AR Session
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!114 &607252635
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 607252634}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: fa850fbd5b8aded44846f96e35f1a9f5, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
--- !u!114 &607252636
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 607252634}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 3859a92a05d4f5d418cb6ca605290e74, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_AttemptUpdate: 1
|
||||||
|
m_MatchFrameRate: 1
|
||||||
|
m_TrackingMode: 2
|
||||||
|
--- !u!4 &607252637
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 607252634}
|
||||||
|
serializedVersion: 2
|
||||||
|
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: 0}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!1 &774907431
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 774907435}
|
||||||
|
- component: {fileID: 774907434}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: XR Origin
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!114 &774907434
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 774907431}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: e0cb9aa70a22847b5925ee5f067c10a9, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Camera: {fileID: 1781544897}
|
||||||
|
m_OriginBaseGameObject: {fileID: 774907431}
|
||||||
|
m_CameraFloorOffsetObject: {fileID: 581552791}
|
||||||
|
m_RequestedTrackingOriginMode: 0
|
||||||
|
m_CameraYOffset: 1.1176
|
||||||
|
--- !u!4 &774907435
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 774907431}
|
||||||
|
serializedVersion: 2
|
||||||
|
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: 825994263}
|
||||||
|
- {fileID: 581552792}
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!1 &825994262
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 825994263}
|
||||||
|
- component: {fileID: 825994267}
|
||||||
|
- component: {fileID: 825994266}
|
||||||
|
- component: {fileID: 825994265}
|
||||||
|
- component: {fileID: 825994264}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: AR Managers
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &825994263
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 825994262}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
|
m_LocalScale: {x: 10, y: 10, z: 10}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 774907435}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &825994264
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 825994262}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 968053edfd89749c48f4ea5d444abf64, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_MeshPrefab: {fileID: 0}
|
||||||
|
m_Density: 0.5
|
||||||
|
m_Normals: 1
|
||||||
|
m_Tangents: 0
|
||||||
|
m_TextureCoordinates: 0
|
||||||
|
m_Colors: 0
|
||||||
|
m_ConcurrentQueueSize: 4
|
||||||
|
--- !u!114 &825994265
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 825994262}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: fa17d122634046b4a8e23048891fafc5, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
<trackablesChanged>k__BackingField:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_RaycastPrefab: {fileID: 0}
|
||||||
|
--- !u!114 &825994266
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 825994262}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: e1760703bbd54c04488a8d10600262ab, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
<trackablesChanged>k__BackingField:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_PlanePrefab: {fileID: 0}
|
||||||
|
m_DetectionMode: -1
|
||||||
|
--- !u!114 &825994267
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 825994262}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: e0cb9aa70a22847b5925ee5f067c10a9, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Camera: {fileID: 0}
|
||||||
|
m_OriginBaseGameObject: {fileID: 825994262}
|
||||||
|
m_CameraFloorOffsetObject: {fileID: 0}
|
||||||
|
m_RequestedTrackingOriginMode: 0
|
||||||
|
m_CameraYOffset: 1.1176
|
||||||
|
--- !u!1 &1781544889
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1781544890}
|
||||||
|
- component: {fileID: 1781544897}
|
||||||
|
- component: {fileID: 1781544896}
|
||||||
|
- component: {fileID: 1781544895}
|
||||||
|
- component: {fileID: 1781544894}
|
||||||
|
- component: {fileID: 1781544893}
|
||||||
|
- component: {fileID: 1781544892}
|
||||||
|
- component: {fileID: 1781544891}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: Main Camera
|
m_Name: Main Camera
|
||||||
m_TagString: MainCamera
|
m_TagString: MainCamera
|
||||||
@@ -234,25 +510,235 @@ GameObject:
|
|||||||
m_NavMeshLayer: 0
|
m_NavMeshLayer: 0
|
||||||
m_StaticEditorFlags: 0
|
m_StaticEditorFlags: 0
|
||||||
m_IsActive: 1
|
m_IsActive: 1
|
||||||
--- !u!81 &360989556
|
--- !u!4 &1781544890
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1781544889}
|
||||||
|
serializedVersion: 2
|
||||||
|
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: 581552792}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &1781544891
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1781544889}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: b15f82cc229284894964d2d30806969d, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_HumanSegmentationStencilMode: 0
|
||||||
|
m_HumanSegmentationDepthMode: 0
|
||||||
|
m_EnvironmentDepthMode: 1
|
||||||
|
m_EnvironmentDepthTemporalSmoothing: 1
|
||||||
|
m_OcclusionPreferenceMode: 0
|
||||||
|
--- !u!114 &1781544892
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1781544889}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_RenderShadows: 1
|
||||||
|
m_RequiresDepthTextureOption: 2
|
||||||
|
m_RequiresOpaqueTextureOption: 2
|
||||||
|
m_CameraType: 0
|
||||||
|
m_Cameras: []
|
||||||
|
m_RendererIndex: -1
|
||||||
|
m_VolumeLayerMask:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 1
|
||||||
|
m_VolumeTrigger: {fileID: 0}
|
||||||
|
m_VolumeFrameworkUpdateModeOption: 2
|
||||||
|
m_RenderPostProcessing: 0
|
||||||
|
m_Antialiasing: 0
|
||||||
|
m_AntialiasingQuality: 2
|
||||||
|
m_StopNaN: 0
|
||||||
|
m_Dithering: 0
|
||||||
|
m_ClearDepth: 1
|
||||||
|
m_AllowXRRendering: 1
|
||||||
|
m_AllowHDROutput: 1
|
||||||
|
m_UseScreenCoordOverride: 0
|
||||||
|
m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_RequiresDepthTexture: 0
|
||||||
|
m_RequiresColorTexture: 0
|
||||||
|
m_Version: 2
|
||||||
|
m_TaaSettings:
|
||||||
|
m_Quality: 3
|
||||||
|
m_FrameInfluence: 0.1
|
||||||
|
m_JitterScale: 1
|
||||||
|
m_MipBias: 0
|
||||||
|
m_VarianceClampScale: 0.9
|
||||||
|
m_ContrastAdaptiveSharpening: 0
|
||||||
|
--- !u!114 &1781544893
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1781544889}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: c2fadf230d1919748a9aa21d40f74619, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_TrackingType: 0
|
||||||
|
m_UpdateType: 0
|
||||||
|
m_IgnoreTrackingState: 0
|
||||||
|
m_PositionInput:
|
||||||
|
m_UseReference: 0
|
||||||
|
m_Action:
|
||||||
|
m_Name: Position
|
||||||
|
m_Type: 0
|
||||||
|
m_ExpectedControlType: Vector3
|
||||||
|
m_Id: 1d22341e-4dd7-44bf-8c99-2f3a85960318
|
||||||
|
m_Processors:
|
||||||
|
m_Interactions:
|
||||||
|
m_SingletonActionBindings:
|
||||||
|
- m_Name:
|
||||||
|
m_Id: 12bf3a58-2acd-4a2b-8d62-744979ae84e5
|
||||||
|
m_Path: <XRHMD>/centerEyePosition
|
||||||
|
m_Interactions:
|
||||||
|
m_Processors:
|
||||||
|
m_Groups:
|
||||||
|
m_Action: Position
|
||||||
|
m_Flags: 0
|
||||||
|
- m_Name:
|
||||||
|
m_Id: a5495caa-b892-4db8-b2ef-dc080af8d77f
|
||||||
|
m_Path: <HandheldARInputDevice>/devicePosition
|
||||||
|
m_Interactions:
|
||||||
|
m_Processors:
|
||||||
|
m_Groups:
|
||||||
|
m_Action: Position
|
||||||
|
m_Flags: 0
|
||||||
|
m_Flags: 0
|
||||||
|
m_Reference: {fileID: 0}
|
||||||
|
m_RotationInput:
|
||||||
|
m_UseReference: 0
|
||||||
|
m_Action:
|
||||||
|
m_Name: Rotation
|
||||||
|
m_Type: 0
|
||||||
|
m_ExpectedControlType: Quaternion
|
||||||
|
m_Id: e9e9ac37-8193-4657-ae44-53991f390a47
|
||||||
|
m_Processors:
|
||||||
|
m_Interactions:
|
||||||
|
m_SingletonActionBindings:
|
||||||
|
- m_Name:
|
||||||
|
m_Id: f37fe228-69c0-45d4-b523-5c69a0b1379c
|
||||||
|
m_Path: <XRHMD>/centerEyeRotation
|
||||||
|
m_Interactions:
|
||||||
|
m_Processors:
|
||||||
|
m_Groups:
|
||||||
|
m_Action: Rotation
|
||||||
|
m_Flags: 0
|
||||||
|
- m_Name:
|
||||||
|
m_Id: dce2fb17-049e-4ce3-93d5-86736b049153
|
||||||
|
m_Path: <HandheldARInputDevice>/deviceRotation
|
||||||
|
m_Interactions:
|
||||||
|
m_Processors:
|
||||||
|
m_Groups:
|
||||||
|
m_Action: Rotation
|
||||||
|
m_Flags: 0
|
||||||
|
m_Flags: 0
|
||||||
|
m_Reference: {fileID: 0}
|
||||||
|
m_TrackingStateInput:
|
||||||
|
m_UseReference: 0
|
||||||
|
m_Action:
|
||||||
|
m_Name: Tracking State
|
||||||
|
m_Type: 0
|
||||||
|
m_ExpectedControlType: Integer
|
||||||
|
m_Id: 8ef3e154-d314-48e3-961f-a379d469d435
|
||||||
|
m_Processors:
|
||||||
|
m_Interactions:
|
||||||
|
m_SingletonActionBindings: []
|
||||||
|
m_Flags: 0
|
||||||
|
m_Reference: {fileID: 0}
|
||||||
|
m_PositionAction:
|
||||||
|
m_Name:
|
||||||
|
m_Type: 0
|
||||||
|
m_ExpectedControlType:
|
||||||
|
m_Id: f61998f6-4054-4f9f-b80c-de37dae3d176
|
||||||
|
m_Processors:
|
||||||
|
m_Interactions:
|
||||||
|
m_SingletonActionBindings: []
|
||||||
|
m_Flags: 0
|
||||||
|
m_RotationAction:
|
||||||
|
m_Name:
|
||||||
|
m_Type: 0
|
||||||
|
m_ExpectedControlType:
|
||||||
|
m_Id: 11600a54-9e03-48ce-aea1-5a4edddfba90
|
||||||
|
m_Processors:
|
||||||
|
m_Interactions:
|
||||||
|
m_SingletonActionBindings: []
|
||||||
|
m_Flags: 0
|
||||||
|
--- !u!114 &1781544894
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1781544889}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 816b289ef451e094f9ae174fb4cf8db0, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_UseCustomMaterial: 0
|
||||||
|
m_CustomMaterial: {fileID: 0}
|
||||||
|
--- !u!114 &1781544895
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1781544889}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 4966719baa26e4b0e8231a24d9bd491a, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_FocusMode: -1
|
||||||
|
m_LightEstimationMode: -1
|
||||||
|
m_AutoFocus: 1
|
||||||
|
m_ImageStabilization: 0
|
||||||
|
m_LightEstimation: 0
|
||||||
|
m_FacingDirection: 1
|
||||||
|
m_RenderMode: 0
|
||||||
|
--- !u!81 &1781544896
|
||||||
AudioListener:
|
AudioListener:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
m_PrefabInstance: {fileID: 0}
|
m_PrefabInstance: {fileID: 0}
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 360989555}
|
m_GameObject: {fileID: 1781544889}
|
||||||
m_Enabled: 1
|
m_Enabled: 1
|
||||||
--- !u!20 &360989557
|
--- !u!20 &1781544897
|
||||||
Camera:
|
Camera:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
m_PrefabInstance: {fileID: 0}
|
m_PrefabInstance: {fileID: 0}
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 360989555}
|
m_GameObject: {fileID: 1781544889}
|
||||||
m_Enabled: 1
|
m_Enabled: 1
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_ClearFlags: 1
|
m_ClearFlags: 2
|
||||||
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
|
m_BackGroundColor: {r: 0, g: 0, b: 0, a: 1}
|
||||||
m_projectionMatrixMode: 1
|
m_projectionMatrixMode: 1
|
||||||
m_GateFitMode: 2
|
m_GateFitMode: 2
|
||||||
m_FOVAxisMode: 0
|
m_FOVAxisMode: 0
|
||||||
@@ -273,12 +759,12 @@ Camera:
|
|||||||
y: 0
|
y: 0
|
||||||
width: 1
|
width: 1
|
||||||
height: 1
|
height: 1
|
||||||
near clip plane: 0.3
|
near clip plane: 0.1
|
||||||
far clip plane: 1000
|
far clip plane: 20
|
||||||
field of view: 60
|
field of view: 60
|
||||||
orthographic: 0
|
orthographic: 0
|
||||||
orthographic size: 5
|
orthographic size: 5
|
||||||
m_Depth: -1
|
m_Depth: 0
|
||||||
m_CullingMask:
|
m_CullingMask:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_Bits: 4294967295
|
m_Bits: 4294967295
|
||||||
@@ -293,24 +779,10 @@ Camera:
|
|||||||
m_OcclusionCulling: 1
|
m_OcclusionCulling: 1
|
||||||
m_StereoConvergence: 10
|
m_StereoConvergence: 10
|
||||||
m_StereoSeparation: 0.022
|
m_StereoSeparation: 0.022
|
||||||
--- !u!4 &360989558
|
|
||||||
Transform:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 360989555}
|
|
||||||
serializedVersion: 2
|
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
|
||||||
m_LocalPosition: {x: 0, y: 1, z: -10}
|
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
|
||||||
m_ConstrainProportionsScale: 0
|
|
||||||
m_Children: []
|
|
||||||
m_Father: {fileID: 0}
|
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
|
||||||
--- !u!1660057539 &9223372036854775807
|
--- !u!1660057539 &9223372036854775807
|
||||||
SceneRoots:
|
SceneRoots:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
m_Roots:
|
m_Roots:
|
||||||
- {fileID: 360989558}
|
|
||||||
- {fileID: 55455372}
|
- {fileID: 55455372}
|
||||||
|
- {fileID: 607252637}
|
||||||
|
- {fileID: 774907435}
|
||||||
|
|||||||
40
CHANGELOG.md
Normal file
40
CHANGELOG.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Changelog
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on **Keep a Changelog** and this project adheres to **Semantic Versioning**.
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
### Added
|
||||||
|
- OBJ/GLB exporters with Draco compression (planned)
|
||||||
|
- Furniture placement UX (snapping gizmos, align to wall) (planned)
|
||||||
|
- Semantic plane helpers (wall/floor/ceiling) (planned)
|
||||||
|
- RoomPlan native bridge behind `ROOMPLAN_ENABLED` (planned)
|
||||||
|
- Lightship object detection behind `LIGHTSHIP_ENABLED` (planned)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- TBD
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- TBD
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.1.0] - 2025-08-21
|
||||||
|
### Added
|
||||||
|
- iOS‑first project scaffolding (Unity 6.0 LTS, URP) with AR Foundation 6.x & ARKit XR Plugin 6.x.
|
||||||
|
- Modular folder layout under `Assets/_Project/` and `.asmdef` per module.
|
||||||
|
- `ScanScene` baseline: AR Session, XR Origin, AR managers (Plane/Raycast/Mesh).
|
||||||
|
- `RoomScanner` to combine AR mesh chunks into a single mesh + collider.
|
||||||
|
- `MeasureTool` for A→B distance in real meters.
|
||||||
|
- API layer: `IFurnitureApi` + `HttpFurnitureApi` + `ApiConfig` ScriptableObject.
|
||||||
|
- README with iOS build steps, contribution guidelines draft.
|
||||||
|
- Git config: `.gitignore`, LFS patterns recommended, SmartMerge guidance.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
[Unreleased]: https://example.com/compare/v0.1.0...HEAD
|
||||||
|
[0.1.0]: https://example.com/releases/tag/v0.1.0
|
||||||
128
CONTRIBUTING.md
Normal file
128
CONTRIBUTING.md
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
# Contributing Guide
|
||||||
|
|
||||||
|
Thanks for helping build **AR Room Scanner & Furnishing (iOS‑first, Unity 6.0 LTS)**. This doc explains how to set up your environment, propose changes, and keep the project healthy and fast.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
- [Project Setup](#project-setup)
|
||||||
|
- [Branching Model](#branching-model)
|
||||||
|
- [Commit Messages](#commit-messages)
|
||||||
|
- [Pull Request Checklist](#pull-request-checklist)
|
||||||
|
- [Coding Standards (C#)](#coding-standards-c)
|
||||||
|
- [Unity Guidelines](#unity-guidelines)
|
||||||
|
- [Scenes & Prefabs Rules](#scenes--prefabs-rules)
|
||||||
|
- [Feature Flags](#feature-flags)
|
||||||
|
- [API Config & Secrets](#api-config--secrets)
|
||||||
|
- [Testing](#testing)
|
||||||
|
- [Performance Budget](#performance-budget)
|
||||||
|
- [Git LFS & Large Files](#git-lfs--large-files)
|
||||||
|
- [Releases](#releases)
|
||||||
|
- [Code Review](#code-review)
|
||||||
|
- [Smart Merge](#smart-merge)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Project Setup
|
||||||
|
- **Unity**: 6.0 LTS (URP template).
|
||||||
|
- **Platform**: iOS (Metal only). Switch platform before importing heavy assets.
|
||||||
|
- **Packages**: AR Foundation 6.x, ARKit XR Plugin 6.x, (optional) XR Interaction Toolkit 3.x.
|
||||||
|
- **Folder layout** is under `Assets/_Project/...` with `.asmdef` per root module.
|
||||||
|
- Keep `Settings/` (URP and project assets) and `Packages/` committed.
|
||||||
|
- Enable **Visible Meta Files** and **Force Text Serialization**.
|
||||||
|
|
||||||
|
## Branching Model
|
||||||
|
- `main`: protected; always releasable.
|
||||||
|
- Use short‑lived branches: `feature/<topic>`, `fix/<topic>`, `chore/<topic>`.
|
||||||
|
- Rebase or squash merge to keep history clean.
|
||||||
|
- Tag releases with SemVer (e.g., `v0.1.0`).
|
||||||
|
|
||||||
|
## Commit Messages
|
||||||
|
We use **Conventional Commits**:
|
||||||
|
```
|
||||||
|
feat: add room mesh exporter (OBJ)
|
||||||
|
fix: avoid collider spike when updating sharedMesh
|
||||||
|
docs: update iOS build steps
|
||||||
|
refactor: split placement into service + controller
|
||||||
|
perf: decimate combined mesh when >3M tris
|
||||||
|
test: add domain unit tests
|
||||||
|
build: bump ARKit XR Plugin to 6.2.x
|
||||||
|
ci: cache Library on CI
|
||||||
|
revert: revert placement snapping change
|
||||||
|
```
|
||||||
|
Scope is optional (e.g., `feat(placement): ...`).
|
||||||
|
|
||||||
|
## Pull Request Checklist
|
||||||
|
- [ ] Builds in Unity Editor and exports to **Xcode**.
|
||||||
|
- [ ] Tested on **real iOS device** (LiDAR when feature needs it).
|
||||||
|
- [ ] Scene follows **hierarchy rules** (see below).
|
||||||
|
- [ ] **No per‑frame allocations** in hot paths; profiled once on device.
|
||||||
|
- [ ] `.asmdef` references minimal and correct; no upward dependencies.
|
||||||
|
- [ ] Updated **README/CHANGELOG** if user‑facing behavior changed.
|
||||||
|
- [ ] Added/updated **tests** (Domain: unit; ARRuntime/App: playmode/manual checklist).
|
||||||
|
- [ ] **No secrets** or hardcoded URLs; use `ApiConfig` ScriptableObject.
|
||||||
|
- [ ] Large binaries are tracked by **LFS**; unnecessary assets removed.
|
||||||
|
|
||||||
|
## Coding Standards (C#)
|
||||||
|
- Namespaces by module: `App.*`, `ARRuntime.*`, `Domain.*`, `Infra.*`.
|
||||||
|
- Prefer `readonly` fields, `record` for immutable DTOs, `TryGetComponent` over `FindObjectOfType`.
|
||||||
|
- Avoid `new` allocations in `Update`; reuse buffers/lists (`.Clear()`).
|
||||||
|
- Use `async/await` for API; timeouts & cancellation tokens where sensible.
|
||||||
|
- No logic in `MonoBehaviour` constructors; use `Awake/OnEnable/Start`.
|
||||||
|
- Guard nulls; avoid exceptions for control flow.
|
||||||
|
|
||||||
|
## Unity Guidelines
|
||||||
|
- One **Main Camera** under **XR Origin**.
|
||||||
|
- `ARMeshManager` **must be a child of XR Origin**.
|
||||||
|
- Keep **AR managers** grouped under a child GO (e.g., `AR Managers`).
|
||||||
|
- Update **MeshCollider.sharedMesh** only when the combined mesh changes.
|
||||||
|
- Place assets under `Assets/_Project/Art/...`; avoid dumping in root.
|
||||||
|
- Use **prefabs** for placeable furniture; include colliders at authoring time.
|
||||||
|
|
||||||
|
## Scenes & Prefabs Rules
|
||||||
|
- Scene names live in `Assets/_Project/App/Scenes/`.
|
||||||
|
- Do not reference Sample assets. Delete `SampleScene` once the project boots.
|
||||||
|
- Minimal global singletons. Prefer scene‑local controllers in `App/Controllers`.
|
||||||
|
- Prefabs: no missing scripts; default layer unless a dedicated layer is needed.
|
||||||
|
|
||||||
|
## Feature Flags
|
||||||
|
- Compile‑time defines:
|
||||||
|
- `LIGHTSHIP_ENABLED` → compiles `Detectors.Lightship/` only when set.
|
||||||
|
- `ROOMPLAN_ENABLED` → future native bridge for RoomPlan.
|
||||||
|
- Runtime toggles: ScriptableObject `ProjectFeatures` (in `Infra/Settings/`).
|
||||||
|
|
||||||
|
## API Config & Secrets
|
||||||
|
- `Infra/Settings/ApiConfig` contains the base URL and timeouts per env.
|
||||||
|
- **Do not commit secrets** or production keys.
|
||||||
|
- For iOS, additional entitlements (e.g., iCloud) should be added in Xcode per‑target, not committed if secret‑bearing.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
- **Domain**: unit tests (EditMode).
|
||||||
|
- **ARRuntime/App**: PlayMode tests + manual device checklist.
|
||||||
|
- Provide a short test plan for PRs affecting scanning/placement.
|
||||||
|
|
||||||
|
## Performance Budget
|
||||||
|
- IL2CPP, ARM64, **Metal only**.
|
||||||
|
- URP: SRP Batcher ON, MSAA 2x, mobile shadows.
|
||||||
|
- Mesh combine every **1–2 s**; consider decimation > 3M tris.
|
||||||
|
- Avoid large textures where not needed; prefer 2K for preview.
|
||||||
|
|
||||||
|
## Git LFS & Large Files
|
||||||
|
- Track large assets: `*.glb, *.gltf, *.obj, *.fbx, *.psd, *.exr, *.hdr, *.tga, *.tif`.
|
||||||
|
- Keep big room exports outside `Assets/` in a top‑level `Scans/` folder (LFS‑tracked) to reduce Unity import cost.
|
||||||
|
- Use **LFS locking** for shared binary assets when editing (`git lfs lock` / `unlock`).
|
||||||
|
|
||||||
|
## Releases
|
||||||
|
- Bump version using **SemVer** and update **CHANGELOG.md** (Keep a Changelog format).
|
||||||
|
- Tag the commit (`vX.Y.Z`) and create a GitHub Release with notes and device compatibility.
|
||||||
|
- Attach build artifacts as needed; Xcode projects are generated from Unity.
|
||||||
|
|
||||||
|
## Code Review
|
||||||
|
- At least **1 approval** (or 2 for risky changes).
|
||||||
|
- Reviewers check: compile/run on device, profiler snapshot, GC allocs, scene hierarchy, asmdef deps, docs updated.
|
||||||
|
|
||||||
|
## Smart Merge
|
||||||
|
Enable Unity SmartMerge globally:
|
||||||
|
```
|
||||||
|
git config --global merge.unityyamlmerge.name "Unity SmartMerge (YAML)"
|
||||||
|
git config --global merge.unityyamlmerge.driver "<UnityPath>/Tools/UnityYAMLMerge merge -p %O %A %B %P"
|
||||||
|
```
|
||||||
|
Ensure **Visible Meta Files** and **Force Text** are set in Unity.
|
||||||
121
ProjectSettings/SceneTemplateSettings.json
Normal file
121
ProjectSettings/SceneTemplateSettings.json
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
{
|
||||||
|
"templatePinStates": [],
|
||||||
|
"dependencyTypeInfos": [
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEngine.AnimationClip",
|
||||||
|
"defaultInstantiationMode": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEditor.Animations.AnimatorController",
|
||||||
|
"defaultInstantiationMode": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEngine.AnimatorOverrideController",
|
||||||
|
"defaultInstantiationMode": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEditor.Audio.AudioMixerController",
|
||||||
|
"defaultInstantiationMode": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEngine.ComputeShader",
|
||||||
|
"defaultInstantiationMode": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEngine.Cubemap",
|
||||||
|
"defaultInstantiationMode": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEngine.GameObject",
|
||||||
|
"defaultInstantiationMode": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEditor.LightingDataAsset",
|
||||||
|
"defaultInstantiationMode": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEngine.LightingSettings",
|
||||||
|
"defaultInstantiationMode": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEngine.Material",
|
||||||
|
"defaultInstantiationMode": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEditor.MonoScript",
|
||||||
|
"defaultInstantiationMode": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEngine.PhysicsMaterial",
|
||||||
|
"defaultInstantiationMode": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEngine.PhysicsMaterial2D",
|
||||||
|
"defaultInstantiationMode": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEngine.Rendering.PostProcessing.PostProcessProfile",
|
||||||
|
"defaultInstantiationMode": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEngine.Rendering.PostProcessing.PostProcessResources",
|
||||||
|
"defaultInstantiationMode": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEngine.Rendering.VolumeProfile",
|
||||||
|
"defaultInstantiationMode": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEditor.SceneAsset",
|
||||||
|
"defaultInstantiationMode": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEngine.Shader",
|
||||||
|
"defaultInstantiationMode": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEngine.ShaderVariantCollection",
|
||||||
|
"defaultInstantiationMode": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEngine.Texture",
|
||||||
|
"defaultInstantiationMode": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEngine.Texture2D",
|
||||||
|
"defaultInstantiationMode": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "UnityEngine.Timeline.TimelineAsset",
|
||||||
|
"defaultInstantiationMode": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"defaultDependencyTypeInfo": {
|
||||||
|
"userAdded": false,
|
||||||
|
"type": "<default_scene_template_dependencies>",
|
||||||
|
"defaultInstantiationMode": 1
|
||||||
|
},
|
||||||
|
"newSceneOverride": 0
|
||||||
|
}
|
||||||
@@ -4,5 +4,4 @@
|
|||||||
VersionControlSettings:
|
VersionControlSettings:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
m_Mode: Visible Meta Files
|
m_Mode: Visible Meta Files
|
||||||
m_CollabEditorSettings:
|
m_TrackPackagesOutsideProject: 0
|
||||||
inProgressEnabled: 1
|
|
||||||
|
|||||||
374
README.md
Normal file
374
README.md
Normal file
@@ -0,0 +1,374 @@
|
|||||||
|
# AR Room Scanner & Furnishing — **iOS-first (Unity 6.0 LTS)**
|
||||||
|
|
||||||
|
Clean, modular Unity **6.0 LTS** project focused on **iOS (ARKit)** for:
|
||||||
|
1) **Scanning** a real room on-device (LiDAR Scene Reconstruction when available)
|
||||||
|
2) **Measuring** in real-world meters
|
||||||
|
3) **Placing furniture** with collisions and snapping
|
||||||
|
4) Optional **Object Detection** (kept behind a compile flag)
|
||||||
|
5) Optional **RoomPlan** integration path (native bridge) for semantic room models
|
||||||
|
|
||||||
|
This repo is designed to be stable today and easy to evolve (upgrade to 6.1/6.2 later).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
- [Why iOS](#why-ios)
|
||||||
|
- [Folder Layout](#folder-layout)
|
||||||
|
- [Assembly Definitions & Dependencies](#assembly-definitions--dependencies)
|
||||||
|
- [Packages & Versions](#packages--versions)
|
||||||
|
- [Device Support Matrix](#device-support-matrix)
|
||||||
|
- [Getting Started](#getting-started)
|
||||||
|
- [iOS Build & Xcode Setup](#ios-build--xcode-setup)
|
||||||
|
- [Scenes & Flow](#scenes--flow)
|
||||||
|
- [Core Modules](#core-modules)
|
||||||
|
- [API Integration](#api-integration)
|
||||||
|
- [Configuration & Environments](#configuration--environments)
|
||||||
|
- [Version Control (Git, LFS, SmartMerge)](#version-control-git-lfs-smartmerge)
|
||||||
|
- [Performance Guidelines (iOS/Metal)](#performance-guidelines-iosmetal)
|
||||||
|
- [RoomPlan (future path)](#roomplan-future-path)
|
||||||
|
- [Troubleshooting](#troubleshooting)
|
||||||
|
- [Roadmap](#roadmap)
|
||||||
|
- [License](#license)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Why iOS
|
||||||
|
- **Best on-device scanning** via **ARKit Scene Reconstruction** on **LiDAR** devices (dense mesh, stable scale).
|
||||||
|
- **Consistent tracking & depth** across supported iPhones/iPads.
|
||||||
|
- Future option: **RoomPlan** (iOS 16+, LiDAR) to produce **semantic, parametric** rooms (walls/doors/windows) with accurate dimensions.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Folder Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
Assets/
|
||||||
|
_Project/
|
||||||
|
App/ # app flow & UI
|
||||||
|
Controllers/
|
||||||
|
Scenes/
|
||||||
|
Bootstrap.unity
|
||||||
|
ScanScene.unity
|
||||||
|
FurnishScene.unity
|
||||||
|
UI/
|
||||||
|
ARRuntime/ # AR runtime features (platform-agnostic via AR Foundation)
|
||||||
|
Scanning/ # mesh collection, colliders, export hooks
|
||||||
|
Measurement/ # AB ruler, heights, helpers
|
||||||
|
Placement/ # raycasts, snapping, overlap checks, physics
|
||||||
|
Art/ # in-Unity assets
|
||||||
|
Logos/
|
||||||
|
Materials/
|
||||||
|
Models/
|
||||||
|
Prefabs/
|
||||||
|
Shaders/
|
||||||
|
Textures/
|
||||||
|
Domain/ # pure business/domain (no Unity deps)
|
||||||
|
Models/
|
||||||
|
Services/
|
||||||
|
Infra/ # outside world (API, storage, settings)
|
||||||
|
Api/ # IFurnitureApi + HttpFurnitureApi + DTOs
|
||||||
|
Persistence/ # OBJ/GLB export, JSON metadata
|
||||||
|
Settings/ # ScriptableObjects (ApiConfig, ProjectFeatures)
|
||||||
|
Detectors/
|
||||||
|
Null/ # default no-op detector
|
||||||
|
Lightship/ # stub; compiled only with LIGHTSHIP_ENABLED
|
||||||
|
Tests/ # EditMode/PlayMode tests
|
||||||
|
Settings/ # URP & project assets (keep!)
|
||||||
|
XR/ # added by packages
|
||||||
|
```
|
||||||
|
|
||||||
|
**Keep `Settings/`** (URP pipeline assets & editor links).
|
||||||
|
A separate top-level `Scans/` folder (outside `Assets/`) is recommended for large exports to avoid re-import churn.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Assembly Definitions & Dependencies
|
||||||
|
|
||||||
|
Create one `.asmdef` per root module:
|
||||||
|
|
||||||
|
- `Domain` (no references)
|
||||||
|
- `Infra` → references `Domain`
|
||||||
|
- `ARRuntime` → references `Domain`
|
||||||
|
- `App` → references `ARRuntime`, `Infra`, `Domain`
|
||||||
|
- `Detectors.Lightship` → references `Infra`, `Domain` with **define constraint** `LIGHTSHIP_ENABLED`
|
||||||
|
- `Tests` → references as needed
|
||||||
|
|
||||||
|
**Dependency direction**
|
||||||
|
`App → (ARRuntime, Infra, Domain)`
|
||||||
|
`ARRuntime → Domain`
|
||||||
|
`Infra → Domain`
|
||||||
|
`Domain` depends on nothing
|
||||||
|
|
||||||
|
This keeps compile times low and prevents “upward” coupling.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Packages & Versions
|
||||||
|
- **Unity**: 6.0 LTS (URP template)
|
||||||
|
- **AR Foundation**: 6.x
|
||||||
|
- **ARKit XR Plugin**: 6.x
|
||||||
|
- (Optional) XR Interaction Toolkit 3.x
|
||||||
|
- TextMesh Pro (built-in)
|
||||||
|
|
||||||
|
> Pin package versions in `Packages/manifest.json` once the project compiles cleanly.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Device Support Matrix
|
||||||
|
|
||||||
|
| Capability | Requirement | Notes |
|
||||||
|
|---|---|---|
|
||||||
|
| ARKit basic tracking | iPhone 8+ / iOS 13+ (practical: iOS 15+) | Non-LiDAR devices won’t produce dense meshes. |
|
||||||
|
| **Scene Reconstruction (meshing)** | **LiDAR** devices (e.g., iPhone 12 Pro+, 13 Pro+, 14 Pro/Pro Max, 15 Pro/Pro Max; iPad Pro 2020+) | AR Foundation exposes meshes via `ARMeshManager`. |
|
||||||
|
| Environment Depth / People Occlusion | Device-dependent | Used for occlusion realism; works best on LiDAR. |
|
||||||
|
| **RoomPlan** (future) | iOS 16+, **LiDAR** | Generates semantic room model via native SDK. |
|
||||||
|
|
||||||
|
We gracefully **fall back**: if no LiDAR mesh is available, we still support plane detection + measurements.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
1) **Switch to iOS**
|
||||||
|
`File → Build Settings → iOS → Switch Platform`.
|
||||||
|
|
||||||
|
2) **Install packages** (Window → Package Manager)
|
||||||
|
- AR Foundation 6.x
|
||||||
|
- ARKit XR Plugin 6.x
|
||||||
|
- (Optional) XR Interaction Toolkit 3.x
|
||||||
|
|
||||||
|
3) **Project Settings (iOS)**
|
||||||
|
- **Player → iOS**
|
||||||
|
- Scripting Backend: **IL2CPP**
|
||||||
|
- Target Architectures: **ARM64**
|
||||||
|
- Graphics APIs: **Metal** (only)
|
||||||
|
- Minimum iOS Version: **15+** recommended (RoomPlan needs 16+)
|
||||||
|
- Camera Usage Description (Info.plist): e.g., _“AR scanning requires camera access.”_
|
||||||
|
- Photo Library Add Usage Description (if you export files to Photos)
|
||||||
|
- Motion Usage Description (only if you use CoreMotion; otherwise omit)
|
||||||
|
- **XR Plug-in Management → iOS**
|
||||||
|
- Enable **ARKit**
|
||||||
|
- In ARKit settings, enable **Environment Depth** (and People Occlusion if needed)
|
||||||
|
- **URP**
|
||||||
|
- SRP Batcher: **ON**
|
||||||
|
- MSAA: **2x**
|
||||||
|
- Mobile-friendly shadows
|
||||||
|
|
||||||
|
4) **Scenes**
|
||||||
|
- Create `Bootstrap.unity`, `ScanScene.unity`, `FurnishScene.unity` under `Assets/_Project/App/Scenes/`.
|
||||||
|
|
||||||
|
5) **First run**
|
||||||
|
- Add `Bootstrap` and `ScanScene` to Build Settings (Bootstrap first).
|
||||||
|
- Build to Xcode, set signing, run on device.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## iOS Build & Xcode Setup
|
||||||
|
|
||||||
|
1) **Build in Unity** → generates an Xcode project.
|
||||||
|
2) **Xcode**
|
||||||
|
- Select your **Team** & Provisioning profile
|
||||||
|
- Ensure **Camera** privacy string is present (Unity will add based on Player Settings)
|
||||||
|
- In “Signing & Capabilities”, you typically **don’t** need extra entitlements for ARKit beyond camera; add **Files (iCloud)** only if you export to Files app.
|
||||||
|
3) **Run on device** (USB).
|
||||||
|
4) If you see a black camera feed: check Privacy strings, ensure real device (not Simulator), and that `Requires ARKit` is set (Unity: Player → iOS → “Requires ARKit”).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Scenes & Flow
|
||||||
|
|
||||||
|
### Scene Descriptions (TL;DR)
|
||||||
|
|
||||||
|
- **Bootstrap.unity** — Minimal entry scene. Initializes global settings (URP assets, `ProjectFeatures`, `ApiConfig`), handles one-time bootstrapping, and programmatically loads `ScanScene`. No AR logic or heavy UI here.
|
||||||
|
- **ScanScene.unity** — Scanning & measuring. Contains AR Session, XR Origin, AR Plane/Raycast/Mesh Managers, and the camera with AR Camera Manager + AR Occlusion. Merges AR mesh chunks into a single mesh (RoomScanner), enables A→B measurements in meters (MeasureTool), and can optionally export the room mesh.
|
||||||
|
- **FurnishScene.unity** — Furniture placement. Fetches items from the backend via `IFurnitureApi`, performs raycasts to floor/walls with snapping, runs overlap/collision checks before placement, uses occlusion for realism, and hosts the move/rotate/align UX.
|
||||||
|
|
||||||
|
|
||||||
|
### `Bootstrap.unity`
|
||||||
|
Minimal loader that switches to the first “real” scene:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.SceneManagement;
|
||||||
|
|
||||||
|
public class Bootstrap : MonoBehaviour
|
||||||
|
{
|
||||||
|
[SerializeField] string firstScene = "ScanScene";
|
||||||
|
void Start() => SceneManager.LoadScene(firstScene, LoadSceneMode.Single);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `ScanScene.unity` (first milestone)
|
||||||
|
**Hierarchy (suggested)**
|
||||||
|
|
||||||
|
```
|
||||||
|
AR Session
|
||||||
|
XR Origin
|
||||||
|
└─ Camera Offset
|
||||||
|
└─ Main Camera (tag: MainCamera)
|
||||||
|
AR Managers (child of XR Origin)
|
||||||
|
├─ AR Plane Manager
|
||||||
|
├─ AR Raycast Manager
|
||||||
|
└─ AR Mesh Manager # must be under XR Origin in ARF 6
|
||||||
|
RoomMesh (MeshFilter + MeshRenderer + MeshCollider)
|
||||||
|
RoomScanner (script) # combines AR chunks into RoomMesh
|
||||||
|
MeasureLine (LineRenderer)
|
||||||
|
MeasureTool (script) # tap A→B distances in meters
|
||||||
|
```
|
||||||
|
|
||||||
|
On the **Main Camera** (child of XR Origin): add **AR Camera Manager** and **AR Occlusion Manager**.
|
||||||
|
|
||||||
|
### `FurnishScene.unity` (next milestone)
|
||||||
|
- Placement raycasts and snapping to **floor/walls**
|
||||||
|
- Overlap checks / colliders to prevent interpenetration
|
||||||
|
- Occlusion enabled for realism
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Core Modules
|
||||||
|
|
||||||
|
### `ARRuntime/Scanning` — RoomScanner
|
||||||
|
- Polls `ARMeshManager.meshes` and **combines** all chunks into a single mesh every N seconds.
|
||||||
|
- Assigns that mesh to `RoomMesh`’s `MeshFilter` and `MeshCollider`.
|
||||||
|
- The combined mesh is in **meters** (Unity units = meters), so measuring is straightforward.
|
||||||
|
|
||||||
|
### `ARRuntime/Measurement` — MeasureTool
|
||||||
|
- Touch once = point A, touch again = point B.
|
||||||
|
- Draws a line (`LineRenderer`) and shows **meters** to 2 decimals.
|
||||||
|
- Uses `Physics.Raycast` against the combined collider or against detected planes.
|
||||||
|
|
||||||
|
### `ARRuntime/Placement`
|
||||||
|
- Raycast from screen to floor/wall planes or to the combined mesh.
|
||||||
|
- Snap by projecting onto a plane’s normal.
|
||||||
|
- Prevent collisions with `Physics.OverlapBox/Sphere` before placing.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## API Integration
|
||||||
|
|
||||||
|
Interface-first, so the app logic doesn’t depend on a concrete client:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Infra/Api/IFurnitureApi.cs
|
||||||
|
public interface IFurnitureApi
|
||||||
|
{
|
||||||
|
Task<IReadOnlyList<Furniture>> GetVariantsAsync(IEnumerable<string> ids);
|
||||||
|
Task<IReadOnlyList<Furniture>> SearchAsync(string query, int page = 1, int pageSize = 20);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Infra/Api/HttpFurnitureApi.cs
|
||||||
|
public sealed class HttpFurnitureApi : IFurnitureApi
|
||||||
|
{
|
||||||
|
private readonly HttpClient _http;
|
||||||
|
private readonly ApiConfig _cfg;
|
||||||
|
|
||||||
|
public HttpFurnitureApi(HttpClient http, ApiConfig cfg) { _http = http; _cfg = cfg; }
|
||||||
|
|
||||||
|
public async Task<IReadOnlyList<Furniture>> GetVariantsAsync(IEnumerable<string> ids)
|
||||||
|
{
|
||||||
|
var url = $"{_cfg.BaseUrl}/api/v1/FurnitureVariant/GetByIds";
|
||||||
|
using var resp = await _http.PostAsJsonAsync(url, ids);
|
||||||
|
resp.EnsureSuccessStatusCode();
|
||||||
|
return await resp.Content.ReadFromJsonAsync<List<Furniture>>() ?? new();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IReadOnlyList<Furniture>> SearchAsync(string query, int page = 1, int pageSize = 20)
|
||||||
|
{
|
||||||
|
var url = $"{_cfg.BaseUrl}/api/v1/FurnitureVariant/Search?query={Uri.EscapeDataString(query)}&page={page}&pageSize={pageSize}";
|
||||||
|
return await _http.GetFromJsonAsync<List<Furniture>>(url) ?? new();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Config**: `Infra/Settings/ApiConfig` (ScriptableObject) with `BaseUrl`, timeouts, and environment selectors (DEV/QA/PROD).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration & Environments
|
||||||
|
|
||||||
|
Create a `ProjectFeatures` ScriptableObject (in `Infra/Settings/`) with toggles:
|
||||||
|
- `useMeshing` (on by default)
|
||||||
|
- `useOcclusion` (environment/people)
|
||||||
|
- `useObjectDetection` (off; Lightship behind `LIGHTSHIP_ENABLED`)
|
||||||
|
- `enableExports` (to write OBJ/GLB to app storage)
|
||||||
|
|
||||||
|
This lets QA test different combinations without code changes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Version Control (Git, LFS, SmartMerge)
|
||||||
|
|
||||||
|
- Keep **text/YAML** in Git (scenes, prefabs, materials, `.meta`, `ProjectSettings/`, `Packages/`).
|
||||||
|
- Track **large binaries** (GLB/OBJ/FBX/PSDs/EXR/8K textures) with **Git LFS**.
|
||||||
|
- Enable **Unity Smart Merge** for clean scene/prefab merges.
|
||||||
|
|
||||||
|
(We also recommend a top-level `Scans/` folder, LFS-tracked, for big room exports.)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Performance Guidelines (iOS/Metal)
|
||||||
|
|
||||||
|
- **Metal only**, IL2CPP, ARM64.
|
||||||
|
- URP: **SRP Batcher ON**, **MSAA 2×**, mobile shadows.
|
||||||
|
- Avoid per-frame allocations; reuse buffers.
|
||||||
|
- Combine mesh at **intervals** (1–2 s) rather than every frame.
|
||||||
|
- Update `MeshCollider.sharedMesh` **only when merged mesh changes** to avoid spikes.
|
||||||
|
- Consider decimation for very large meshes if triangle count exceeds target thresholds.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## RoomPlan (future path)
|
||||||
|
|
||||||
|
If you need clean, semantic floorplans and furniture categories:
|
||||||
|
- Implement a **native iOS plugin** (Swift/Obj-C) that runs RoomPlan (iOS 16+, LiDAR).
|
||||||
|
- Export **USDZ/USDA/OBJ/GLTF** or RoomPlan **JSON**; import into Unity via `Infra/Persistence`.
|
||||||
|
- Provide an adapter `IRoomImporter` so `App` can switch between **Scene Reconstruction mesh** and **RoomPlan semantic model** at runtime/build time.
|
||||||
|
|
||||||
|
Keep all RoomPlan code behind a **`ROOMPLAN_ENABLED`** define if you prefer the same pattern as Lightship.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
- **Popup: “An ARMeshManager must be a child of an XROrigin.”**
|
||||||
|
Move `ARMeshManager` under **XR Origin** (not on the same GO).
|
||||||
|
|
||||||
|
- **Black camera feed**
|
||||||
|
Real device only (no Simulator), **Camera** usage string present, `Requires ARKit` ticked, provisioning OK.
|
||||||
|
|
||||||
|
- **No mesh appears**
|
||||||
|
Device may not have LiDAR; fall back to planes & depth. Ensure ARKit Scene Reconstruction is supported on the test device.
|
||||||
|
|
||||||
|
- **Raycast doesn’t hit**
|
||||||
|
Ensure `RoomMesh` has a **MeshCollider** and that you merged at least once. Check layers.
|
||||||
|
|
||||||
|
- **Build fails in Xcode**
|
||||||
|
Clear Derived Data, check signing, ensure Metal is the only graphics API.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
- ✅ iOS-first scanning (Scene Reconstruction), measuring, placement skeleton
|
||||||
|
- ⏳ Exporters (OBJ/GLB + Draco), thumbnails, metadata (`units`, `bbox`, triangle count)
|
||||||
|
- ⏳ Furniture placement UX (snapping gizmos, grid, rotation/align to wall)
|
||||||
|
- ⏳ Semantic planes (wall/floor/ceiling) classification helpers
|
||||||
|
- ⏳ RoomPlan native bridge (optional feature flag)
|
||||||
|
- ⏳ Lightship detection re-enable (compile flag)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
TBD — choose a license that suits your distribution model (MIT/Apache-2.0/Proprietary).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Quick Start (TL;DR)
|
||||||
|
1. Open in Unity **6.0 LTS**, switch to **iOS**.
|
||||||
|
2. Install **AR Foundation 6.x** + **ARKit XR Plugin 6.x**.
|
||||||
|
3. Player: **IL2CPP / ARM64 / Metal**, iOS 15+, Camera privacy string.
|
||||||
|
4. XR Plug-in Management: **ARKit ON**, enable Environment Depth.
|
||||||
|
5. Open **ScanScene** → Run on a **LiDAR** device → tap two points to measure in meters.
|
||||||
|
6. Move to **FurnishScene** for placement once scanning feels good.
|
||||||
Reference in New Issue
Block a user