From 88f8ae1109b75b782403c3c6bc7da826154086c7 Mon Sep 17 00:00:00 2001 From: Max Cobb Date: Wed, 14 Jun 2023 08:02:29 +0800 Subject: [PATCH] update colors to use the unlit material trick with physically based materials --- .../FocusEntity/FocusEntity+Alignment.swift | 26 +++++++--------- Sources/FocusEntity/FocusEntity+Colored.swift | 17 ++++++---- Sources/FocusEntity/FocusEntity+Segment.swift | 31 +++++++------------ Sources/FocusEntity/FocusEntity.swift | 6 ++-- .../FocusEntity/FocusEntityComponent.swift | 10 +----- 5 files changed, 39 insertions(+), 51 deletions(-) diff --git a/Sources/FocusEntity/FocusEntity+Alignment.swift b/Sources/FocusEntity/FocusEntity+Alignment.swift index 6b0ea55..780c9ec 100644 --- a/Sources/FocusEntity/FocusEntity+Alignment.swift +++ b/Sources/FocusEntity/FocusEntity+Alignment.swift @@ -123,21 +123,19 @@ extension FocusEntity { guard let (camPos, camDir) = self.getCamVector() else { return nil } - let rcQuery = ARRaycastQuery( - origin: camPos, direction: camDir, - allowing: self.allowedRaycast, alignment: .any - ) - let results = self.arView?.session.raycast(rcQuery) ?? [] - - // 1. Check for a result on an existing plane using geometry. - if let existingPlaneUsingGeometryResult = results.first( - where: { $0.target == .existingPlaneGeometry } - ) { - return existingPlaneUsingGeometryResult + for target in self.allowedRaycasts { + let rcQuery = ARRaycastQuery( + origin: camPos, direction: camDir, + allowing: target, alignment: .any + ) + let results = self.arView?.session.raycast(rcQuery) ?? [] + + // Check for a result matching target + if let result = results.first( + where: { $0.target == target } + ) { return result } } - - // 2. As a fallback, check for a result on estimated planes. - return results.first(where: { $0.target == .estimatedPlane }) + return nil } #endif diff --git a/Sources/FocusEntity/FocusEntity+Colored.swift b/Sources/FocusEntity/FocusEntity+Colored.swift index 360b8bf..6053dfe 100644 --- a/Sources/FocusEntity/FocusEntity+Colored.swift +++ b/Sources/FocusEntity/FocusEntity+Colored.swift @@ -24,19 +24,24 @@ public extension FocusEntity { if self.fillPlane?.model?.materials.count == 0 { self.fillPlane?.model?.materials = [SimpleMaterial()] } - var modelMaterial = UnlitMaterial(color: .clear) + var modelMaterial: Material! if #available(iOS 15, macOS 12, *) { + var mat = PhysicallyBasedMaterial() switch endColor { case .color(let uikitColour): - modelMaterial.color = .init(tint: uikitColour, texture: nil) + mat.baseColor = .init(tint: .black.withAlphaComponent(uikitColour.cgColor.alpha)) + mat.emissiveColor = .init(color: uikitColour) + mat.emissiveIntensity = 2 case .texture(let tex): - modelMaterial.color = .init(tint: .white.withAlphaComponent(0.9999), texture: .init(tex)) + mat.baseColor = .init(tint: .white.withAlphaComponent(0.9999), texture: .init(tex)) @unknown default: break } + modelMaterial = mat } else { - modelMaterial.baseColor = endColor - // Necessary for transparency. - modelMaterial.tintColor = Material.Color.white.withAlphaComponent(0.995) + var mat = UnlitMaterial(color: .clear) + mat.baseColor = endColor + mat.tintColor = .white.withAlphaComponent(0.9999) + modelMaterial = mat } self.fillPlane?.model?.materials[0] = modelMaterial } diff --git a/Sources/FocusEntity/FocusEntity+Segment.swift b/Sources/FocusEntity/FocusEntity+Segment.swift index 57b39e3..2aa65e7 100644 --- a/Sources/FocusEntity/FocusEntity+Segment.swift +++ b/Sources/FocusEntity/FocusEntity+Segment.swift @@ -66,18 +66,19 @@ internal extension FocusEntity { self.corner = corner self.alignment = alignment - switch alignment { - case .vertical: - plane = ModelComponent( - mesh: .generatePlane(width: 1, depth: 1), - materials: [UnlitMaterial(color: color)] - ) - case .horizontal: - plane = ModelComponent( - mesh: .generatePlane(width: 1, depth: 1), - materials: [UnlitMaterial(color: color)] - ) + var mat: Material! + if #available(iOS 15.0, *) { + var phMat = PhysicallyBasedMaterial() + phMat.baseColor = .init(tint: .black) + phMat.emissiveColor = .init(color: color) + phMat.emissiveIntensity = 2 + mat = phMat + } else { + // Fallback on earlier versions + mat = UnlitMaterial(color: color) } + plane = ModelComponent(mesh: .generatePlane(width: 1, depth: 1), materials: [mat]) + super.init() switch alignment { @@ -86,15 +87,7 @@ internal extension FocusEntity { case .horizontal: self.scale = [Segment.length, 1, Segment.thickness] } - // self.orientation = .init(angle: .pi / 2, axis: [1, 0, 0]) self.name = name - - // let material = plane.firstMaterial! - // material.diffuse.contents = FocusSquare.primaryColor - // material.isDoubleSided = true - // material.ambient.contents = UIColor.black - // material.lightingModel = .constant - // material.emission.contents = FocusSquare.primaryColor model = plane } diff --git a/Sources/FocusEntity/FocusEntity.swift b/Sources/FocusEntity/FocusEntity.swift index ebe1808..3f63c90 100644 --- a/Sources/FocusEntity/FocusEntity.swift +++ b/Sources/FocusEntity/FocusEntity.swift @@ -37,9 +37,9 @@ public extension HasFocusEntity { set { self.focus.segments = newValue } } #if canImport(ARKit) - var allowedRaycast: ARRaycastQuery.Target { - get { self.focus.allowedRaycast } - set { self.focus.allowedRaycast = newValue } + var allowedRaycasts: [ARRaycastQuery.Target] { + get { self.focus.allowedRaycasts } + set { self.focus.allowedRaycasts = newValue } } #endif } diff --git a/Sources/FocusEntity/FocusEntityComponent.swift b/Sources/FocusEntity/FocusEntityComponent.swift index 3b29ce1..88d4bdc 100644 --- a/Sources/FocusEntity/FocusEntityComponent.swift +++ b/Sources/FocusEntity/FocusEntityComponent.swift @@ -84,7 +84,7 @@ public struct FocusEntityComponent: Component { public internal(set) var isOpen = true internal var segments: [FocusEntity.Segment] = [] #if !os(macOS) - public var allowedRaycast: ARRaycastQuery.Target = .estimatedPlane + public var allowedRaycasts: [ARRaycastQuery.Target] = [.existingPlaneGeometry, .estimatedPlane] #endif static var defaultPlane = MeshResource.generatePlane( @@ -95,13 +95,5 @@ public struct FocusEntityComponent: Component { /// - Parameter style: FocusEntityComponent Style, dictating how the FocusEntity will appear in different states. public init(style: Style) { self.style = style - // If the device has LiDAR, then default behaviour is to only allow - // existing detected planes - #if !os(macOS) - if #available(iOS 13.4, *), - ARWorldTrackingConfiguration.supportsSceneReconstruction(.mesh) { - self.allowedRaycast = .existingPlaneGeometry - } - #endif } }