diff --git a/iOS12_Sampler/ios12 Sampler.xcodeproj/project.pbxproj b/iOS12_Sampler/ios12 Sampler.xcodeproj/project.pbxproj index 3309020..a91361b 100644 --- a/iOS12_Sampler/ios12 Sampler.xcodeproj/project.pbxproj +++ b/iOS12_Sampler/ios12 Sampler.xcodeproj/project.pbxproj @@ -7,19 +7,27 @@ objects = { /* Begin PBXBuildFile section */ - 2E04C9072B4EE2F3000B4936 /* ARImageLocator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E04C9062B4EE2F3000B4936 /* ARImageLocator.swift */; }; 2E04C9092B503318000B4936 /* StatusViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E04C9082B503318000B4936 /* StatusViewController.swift */; }; - 2E04C90B2B503A6D000B4936 /* ARImageLocator+ARSessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E04C90A2B503A6D000B4936 /* ARImageLocator+ARSessionDelegate.swift */; }; 2E15A5982B32F720001EA792 /* RectangleDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E15A5972B32F720001EA792 /* RectangleDetector.swift */; }; 2E15A59A2B32FE85001EA792 /* ARImageDetectorVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E15A5992B32FE85001EA792 /* ARImageDetectorVC.swift */; }; + 2E70214B2B8EFC4000089680 /* ARPostureDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E70214A2B8EFC4000089680 /* ARPostureDetection.swift */; }; + 2E70214F2B90A0D900089680 /* BaseCameraVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E70214E2B90A0D900089680 /* BaseCameraVC.swift */; }; + 2E7021512B90A42700089680 /* AVDetailsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E7021502B90A42700089680 /* AVDetailsVC.swift */; }; + 2E7021542B95ACA100089680 /* Int+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E7021532B95ACA100089680 /* Int+Extension.swift */; }; + 2E7021562B95ACD600089680 /* SCNVector3+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E7021552B95ACD600089680 /* SCNVector3+Extension.swift */; }; + 2E7021582B95ACF900089680 /* Simd3+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E7021572B95ACF900089680 /* Simd3+Extension.swift */; }; + 2E70215A2B95B4B600089680 /* MeshResource+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E7021592B95B4B600089680 /* MeshResource+Extension.swift */; }; + 2E70215C2B95B65B00089680 /* Float+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E70215B2B95B65B00089680 /* Float+Extension.swift */; }; 2E7503282B30640100DF78E1 /* ARSurfaceDetectionVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E7503272B30640100DF78E1 /* ARSurfaceDetectionVC.swift */; }; 2E75032B2B3079FB00DF78E1 /* Plane.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E75032A2B3079FB00DF78E1 /* Plane.swift */; }; 2E75032D2B30913E00DF78E1 /* Utility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E75032C2B30913E00DF78E1 /* Utility.swift */; }; 2E89AB4A2B46DBD8005EB695 /* ImageTrackingUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E89AB492B46DBD8005EB695 /* ImageTrackingUtility.swift */; }; 2E89AB4C2B47E11C005EB695 /* VisuallizationNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E89AB4B2B47E11C005EB695 /* VisuallizationNode.swift */; }; 2E89AB4F2B481EAA005EB695 /* FilterCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E89AB4E2B481EAA005EB695 /* FilterCell.swift */; }; + 2E90B3ED2B87636800D3DB90 /* biped_robot.usdz in Resources */ = {isa = PBXBuildFile; fileRef = 2E90B3EC2B87636800D3DB90 /* biped_robot.usdz */; }; 2E9300F62B4683DC002BF5D6 /* AlteredImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E9300F52B4683DC002BF5D6 /* AlteredImage.swift */; }; 2E9300F92B469633002BF5D6 /* StyleTransferModel.mlpackage in Sources */ = {isa = PBXBuildFile; fileRef = 2E9300F82B469633002BF5D6 /* StyleTransferModel.mlpackage */; }; + 2E962C8F2B69017200D0903D /* robot_walk_idle.usdz in Resources */ = {isa = PBXBuildFile; fileRef = 2E962C8E2B69017200D0903D /* robot_walk_idle.usdz */; }; 4904E7EB20D77386002F5210 /* ViewController+SessionInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4904E7E620D77386002F5210 /* ViewController+SessionInfo.swift */; }; 4904E7EC20D77386002F5210 /* TestRun.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4904E7E720D77386002F5210 /* TestRun.swift */; }; 4904E7ED20D77386002F5210 /* ViewController+NavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4904E7E820D77386002F5210 /* ViewController+NavigationBar.swift */; }; @@ -86,19 +94,27 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 2E04C9062B4EE2F3000B4936 /* ARImageLocator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARImageLocator.swift; sourceTree = ""; }; 2E04C9082B503318000B4936 /* StatusViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusViewController.swift; sourceTree = ""; }; - 2E04C90A2B503A6D000B4936 /* ARImageLocator+ARSessionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ARImageLocator+ARSessionDelegate.swift"; sourceTree = ""; }; 2E15A5972B32F720001EA792 /* RectangleDetector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RectangleDetector.swift; sourceTree = ""; }; 2E15A5992B32FE85001EA792 /* ARImageDetectorVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARImageDetectorVC.swift; sourceTree = ""; }; + 2E70214A2B8EFC4000089680 /* ARPostureDetection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARPostureDetection.swift; sourceTree = ""; }; + 2E70214E2B90A0D900089680 /* BaseCameraVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseCameraVC.swift; sourceTree = ""; }; + 2E7021502B90A42700089680 /* AVDetailsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVDetailsVC.swift; sourceTree = ""; }; + 2E7021532B95ACA100089680 /* Int+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Int+Extension.swift"; sourceTree = ""; }; + 2E7021552B95ACD600089680 /* SCNVector3+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SCNVector3+Extension.swift"; sourceTree = ""; }; + 2E7021572B95ACF900089680 /* Simd3+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Simd3+Extension.swift"; sourceTree = ""; }; + 2E7021592B95B4B600089680 /* MeshResource+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MeshResource+Extension.swift"; sourceTree = ""; }; + 2E70215B2B95B65B00089680 /* Float+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Float+Extension.swift"; sourceTree = ""; }; 2E7503272B30640100DF78E1 /* ARSurfaceDetectionVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARSurfaceDetectionVC.swift; sourceTree = ""; }; 2E75032A2B3079FB00DF78E1 /* Plane.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Plane.swift; sourceTree = ""; }; 2E75032C2B30913E00DF78E1 /* Utility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utility.swift; sourceTree = ""; }; 2E89AB492B46DBD8005EB695 /* ImageTrackingUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageTrackingUtility.swift; sourceTree = ""; }; 2E89AB4B2B47E11C005EB695 /* VisuallizationNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisuallizationNode.swift; sourceTree = ""; }; 2E89AB4E2B481EAA005EB695 /* FilterCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterCell.swift; sourceTree = ""; }; + 2E90B3EC2B87636800D3DB90 /* biped_robot.usdz */ = {isa = PBXFileReference; lastKnownFileType = file.usdz; path = biped_robot.usdz; sourceTree = ""; }; 2E9300F52B4683DC002BF5D6 /* AlteredImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlteredImage.swift; sourceTree = ""; }; 2E9300F82B469633002BF5D6 /* StyleTransferModel.mlpackage */ = {isa = PBXFileReference; lastKnownFileType = folder.mlpackage; path = StyleTransferModel.mlpackage; sourceTree = ""; }; + 2E962C8E2B69017200D0903D /* robot_walk_idle.usdz */ = {isa = PBXFileReference; lastKnownFileType = file.usdz; path = robot_walk_idle.usdz; sourceTree = ""; }; 4904E7E620D77386002F5210 /* ViewController+SessionInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ViewController+SessionInfo.swift"; sourceTree = ""; }; 4904E7E720D77386002F5210 /* TestRun.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestRun.swift; sourceTree = ""; }; 4904E7E820D77386002F5210 /* ViewController+NavigationBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ViewController+NavigationBar.swift"; sourceTree = ""; }; @@ -181,9 +197,7 @@ 2E04C9032B4EE267000B4936 /* Detecting Images in AR */ = { isa = PBXGroup; children = ( - 2E04C9062B4EE2F3000B4936 /* ARImageLocator.swift */, 2E04C9082B503318000B4936 /* StatusViewController.swift */, - 2E04C90A2B503A6D000B4936 /* ARImageLocator+ARSessionDelegate.swift */, ); path = "Detecting Images in AR"; sourceTree = ""; @@ -199,6 +213,26 @@ path = Utilities; sourceTree = ""; }; + 2E7021492B8EFBD500089680 /* Body Detection with AR */ = { + isa = PBXGroup; + children = ( + 2E70214A2B8EFC4000089680 /* ARPostureDetection.swift */, + ); + path = "Body Detection with AR"; + sourceTree = ""; + }; + 2E7021522B95AC7900089680 /* Extensions */ = { + isa = PBXGroup; + children = ( + 2E7021532B95ACA100089680 /* Int+Extension.swift */, + 2E7021552B95ACD600089680 /* SCNVector3+Extension.swift */, + 2E7021572B95ACF900089680 /* Simd3+Extension.swift */, + 2E7021592B95B4B600089680 /* MeshResource+Extension.swift */, + 2E70215B2B95B65B00089680 /* Float+Extension.swift */, + ); + path = Extensions; + sourceTree = ""; + }; 2E7503222B30227F00DF78E1 /* Surface Detection */ = { isa = PBXGroup; children = ( @@ -222,8 +256,8 @@ children = ( 2E89AB4D2B481E88005EB695 /* Cell */, 2E9300F72B46961D002BF5D6 /* Model */, - 2E15A5962B32F6FC001EA792 /* Utilities */, 2E15A5992B32FE85001EA792 /* ARImageDetectorVC.swift */, + 2E15A5962B32F6FC001EA792 /* Utilities */, ); path = "Tracking and altering images"; sourceTree = ""; @@ -244,6 +278,15 @@ path = Model; sourceTree = ""; }; + 2E962C6C2B67A10400D0903D /* USDZ */ = { + isa = PBXGroup; + children = ( + 2E962C8E2B69017200D0903D /* robot_walk_idle.usdz */, + 2E90B3EC2B87636800D3DB90 /* biped_robot.usdz */, + ); + path = USDZ; + sourceTree = ""; + }; 4904E7F520D7767D002F5210 /* Utility Extensions */ = { isa = PBXGroup; children = ( @@ -332,20 +375,25 @@ 4969EA8B20D109FC00F8AE9E /* ios12 Sampler */ = { isa = PBXGroup; children = ( + 2E962C6C2B67A10400D0903D /* USDZ */, 4969EA8C20D109FC00F8AE9E /* AppDelegate.swift */, + 2E70214E2B90A0D900089680 /* BaseCameraVC.swift */, 49C5720F20D269E300602C7B /* AVMainVC.swift */, + 2E7021502B90A42700089680 /* AVDetailsVC.swift */, 4969EA9020D109FC00F8AE9E /* AVSharingWorldMapVC.swift */, 4968C0E420D14B3200D384F0 /* AVChoiceVC.swift */, 4968C0E220D14B1B00D384F0 /* AVScannedObjectListVC.swift */, 4968C0E020D12FE500D384F0 /* AVReadARObjectVC.swift */, 4931C78C20D3988E002F907B /* AVTextureEnvironment.swift */, 8127E0E220D7E5B500D8CD7F /* AVImageDetaction.swift */, + 2E7021492B8EFBD500089680 /* Body Detection with AR */, 2E04C9032B4EE267000B4936 /* Detecting Images in AR */, 2E75034B2B31E00400DF78E1 /* Tracking and altering images */, 2E7503222B30227F00DF78E1 /* Surface Detection */, 4968C0E720D1569C00D384F0 /* ScanningObjectHelperController */, 4968C0E620D1561C00D384F0 /* MultiPeerHelperClass */, 4969EAC220D129A400F8AE9E /* Scanning Objects Helper Classes */, + 2E7021522B95AC7900089680 /* Extensions */, 8127E0E420D7E5F000D8CD7F /* Helper */, 4969EA9A20D109FD00F8AE9E /* Info.plist */, 4969EA9220D109FC00F8AE9E /* Main.storyboard */, @@ -510,6 +558,8 @@ 4969EA8F20D109FC00F8AE9E /* art.scnassets in Resources */, 4991D8F520D907B500BF6564 /* Loky.gif in Resources */, 4969EA9920D109FD00F8AE9E /* LaunchScreen.storyboard in Resources */, + 2E962C8F2B69017200D0903D /* robot_walk_idle.usdz in Resources */, + 2E90B3ED2B87636800D3DB90 /* biped_robot.usdz in Resources */, 4969EA9620D109FD00F8AE9E /* Assets.xcassets in Resources */, 4969EA9420D109FC00F8AE9E /* Main.storyboard in Resources */, ); @@ -536,17 +586,19 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2E70215A2B95B4B600089680 /* MeshResource+Extension.swift in Sources */, 4931C78D20D3988F002F907B /* AVTextureEnvironment.swift in Sources */, 2E89AB4F2B481EAA005EB695 /* FilterCell.swift in Sources */, 4968C0E120D12FE500D384F0 /* AVReadARObjectVC.swift in Sources */, 4968C0DA20D12AA700D384F0 /* ThresholdPinchGestureRecognizer.swift in Sources */, 4968C0DF20D12BF500D384F0 /* ViewController+ApplicationState.swift in Sources */, + 2E7021582B95ACF900089680 /* Simd3+Extension.swift in Sources */, + 2E7021542B95ACA100089680 /* Int+Extension.swift in Sources */, 49C5721020D269E300602C7B /* AVMainVC.swift in Sources */, - 2E04C90B2B503A6D000B4936 /* ARImageLocator+ARSessionDelegate.swift in Sources */, 2E9300F62B4683DC002BF5D6 /* AlteredImage.swift in Sources */, 4904E81020D776B3002F5210 /* DetectedBoundingBox.swift in Sources */, - 2E04C9072B4EE2F3000B4936 /* ARImageLocator.swift in Sources */, 4904E80E20D776B3002F5210 /* ObjectOriginAxis.swift in Sources */, + 2E70214B2B8EFC4000089680 /* ARPostureDetection.swift in Sources */, 4904E7EB20D77386002F5210 /* ViewController+SessionInfo.swift in Sources */, 4968C0CB20D12AA700D384F0 /* FlashlightButton.swift in Sources */, 2E15A5982B32F720001EA792 /* RectangleDetector.swift in Sources */, @@ -557,6 +609,7 @@ 4904E7F920D7767E002F5210 /* ARCameraTrackingState.swift in Sources */, 4969EABD20D10AAC00F8AE9E /* MultipeerSession.swift in Sources */, 2E7503282B30640100DF78E1 /* ARSurfaceDetectionVC.swift in Sources */, + 2E7021562B95ACD600089680 /* SCNVector3+Extension.swift in Sources */, 4968C0E520D14B3200D384F0 /* AVChoiceVC.swift in Sources */, 4969EA9120D109FC00F8AE9E /* AVSharingWorldMapVC.swift in Sources */, 4904E80F20D776B3002F5210 /* PointCloud+CreateVisualization.swift in Sources */, @@ -571,7 +624,9 @@ 4904E80D20D776B3002F5210 /* DetectedPointCloud.swift in Sources */, 8127E0E620D7E60100D8CD7F /* iOSDevCenters+GIF.swift in Sources */, 4904E7F820D7767E002F5210 /* Utilities.swift in Sources */, + 2E7021512B90A42700089680 /* AVDetailsVC.swift in Sources */, 2E04C9092B503318000B4936 /* StatusViewController.swift in Sources */, + 2E70214F2B90A0D900089680 /* BaseCameraVC.swift in Sources */, 4904E80820D776B3002F5210 /* ScannedObject.swift in Sources */, 4968C0E320D14B1B00D384F0 /* AVScannedObjectListVC.swift in Sources */, 4904E7EE20D77386002F5210 /* Scan.swift in Sources */, @@ -581,6 +636,7 @@ 4904E80A20D776B3002F5210 /* BoundingBox.swift in Sources */, 8127E0E320D7E5B500D8CD7F /* AVImageDetaction.swift in Sources */, 4904E80920D776B3002F5210 /* Wireframe.swift in Sources */, + 2E70215C2B95B65B00089680 /* Float+Extension.swift in Sources */, 4968C0CA20D12AA700D384F0 /* MessageLabel.swift in Sources */, 4968C0DB20D12AA700D384F0 /* ThresholdPanGestureRecognizer.swift in Sources */, 4904E80C20D776B3002F5210 /* DetectedObject.swift in Sources */, @@ -762,6 +818,7 @@ CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = K7XJG666ZW; INFOPLIST_FILE = "ios12 Sampler/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -780,6 +837,7 @@ CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = K7XJG666ZW; INFOPLIST_FILE = "ios12 Sampler/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/iOS12_Sampler/ios12 Sampler/AVDetailsVC.swift b/iOS12_Sampler/ios12 Sampler/AVDetailsVC.swift new file mode 100644 index 0000000..267e02c --- /dev/null +++ b/iOS12_Sampler/ios12 Sampler/AVDetailsVC.swift @@ -0,0 +1,43 @@ +// +// AVDetailsVC.swift +// ios12 Sampler +// +// Created by Dhruvil Vora on 29/02/24. +// Copyright © 2024 Testing. All rights reserved. +// + +import UIKit + +class AVDetailsVC: BaseCameraVC { + + @IBOutlet weak var cameraView: UIView! + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + cameraView.layer.addSublayer(prevLayer!) + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + } + + @IBAction func btnLiveImageFilterClicked(_ sender: UIButton) { + let vc = self.storyboard?.instantiateViewController(withIdentifier: "ARImageDetectorVC") as? ARImageDetectorVC + self.navigationController?.pushViewController(vc!, animated: true) + } + + @IBAction func btnSurfaceDetectionClicked(_ sender: UIButton) { + let vc = self.storyboard?.instantiateViewController(withIdentifier: "ARSurfaceDetectionVC") as? ARSurfaceDetectionVC + self.navigationController?.pushViewController(vc!, animated: true) + } + + @IBAction func btnSittingPostureClicked(_ sender: UIButton) { + let vc = self.storyboard?.instantiateViewController(withIdentifier: "ARPostureDetection") as? ARPostureDetection + self.navigationController?.pushViewController(vc!, animated: true) + } +} diff --git a/iOS12_Sampler/ios12 Sampler/AVMainVC.swift b/iOS12_Sampler/ios12 Sampler/AVMainVC.swift index 3a9ae46..951831f 100644 --- a/iOS12_Sampler/ios12 Sampler/AVMainVC.swift +++ b/iOS12_Sampler/ios12 Sampler/AVMainVC.swift @@ -9,37 +9,25 @@ import UIKit import AVFoundation -class AVMainVC: UIViewController, AVCaptureMetadataOutputObjectsDelegate { +class AVMainVC: BaseCameraVC { + + @IBOutlet weak var cameraView: UIView! - var session: AVCaptureSession? - var device: AVCaptureDevice? - var input: AVCaptureDeviceInput? - var output: AVCaptureMetadataOutput? - var prevLayer: AVCaptureVideoPreviewLayer? - - @IBOutlet weak var CameraView: UIView! - override func viewDidLoad() { super.viewDidLoad() - createSession() // Do any additional setup after loading the view. + cameraView.layer.addSublayer(prevLayer!) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - self.navigationController?.isNavigationBarHidden = true } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) - self.navigationController?.isNavigationBarHidden = false } @IBAction func btnActionWorldSharing(_ sender: Any) { - let vc = self.storyboard?.instantiateViewController(withIdentifier: "ARImageLocator") as? ARImageLocator + let vc = self.storyboard?.instantiateViewController(withIdentifier: "ARImageDetectorVC") as? ARImageDetectorVC self.navigationController?.pushViewController(vc!, animated: true) -// let vc = self.storyboard?.instantiateViewController(withIdentifier: "ARSurfaceDetectionVC") as? ARSurfaceDetectionVC -// self.navigationController?.pushViewController(vc!, animated: true) -// let vc = self.storyboard?.instantiateViewController(withIdentifier: "AVSharingWorldMapVC") as? AVSharingWorldMapVC -// self.navigationController?.pushViewController(vc!, animated: true) } @IBAction func btnActionScanAndDetectObjects(_ sender: UIButton) { @@ -54,35 +42,9 @@ class AVMainVC: UIViewController, AVCaptureMetadataOutputObjectsDelegate { let vc = self.storyboard?.instantiateViewController(withIdentifier: "AVTextureEnvironment") as? AVTextureEnvironment self.navigationController?.pushViewController(vc!, animated: true) } - func createSession() { - session = AVCaptureSession() - device = AVCaptureDevice.default(for: .video) - - var error: NSError? = nil - do { - if device != nil { - input = try AVCaptureDeviceInput(device: device!) - } - } catch { - print(error) - } - - if error == nil { - if input != nil { - session?.addInput(input!) - } - } else { - print("camera input error: \(String(describing: error))") - } - - prevLayer = AVCaptureVideoPreviewLayer(session: session!) - let del = UIApplication.shared.delegate as? AppDelegate - prevLayer?.frame = (del?.window?.frame)! - prevLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill - CameraView.layer.addSublayer(prevLayer!) - DispatchQueue.global().async { - self.session?.startRunning() - } - } + @IBAction func btnMoreClicked(_ sender: UIButton) { + let vc = self.storyboard?.instantiateViewController(withIdentifier: "AVDetailsVC") as? AVDetailsVC + self.navigationController?.pushViewController(vc!, animated: true) + } } diff --git a/iOS12_Sampler/ios12 Sampler/Base.lproj/Main.storyboard b/iOS12_Sampler/ios12 Sampler/Base.lproj/Main.storyboard index e81e1e4..dc20611 100644 --- a/iOS12_Sampler/ios12 Sampler/Base.lproj/Main.storyboard +++ b/iOS12_Sampler/ios12 Sampler/Base.lproj/Main.storyboard @@ -45,10 +45,27 @@ + + + + + + + + - + @@ -92,7 +109,7 @@ Sharing - + @@ -138,7 +155,7 @@ Texturing - + @@ -183,7 +200,7 @@ Texturing - + @@ -243,8 +260,8 @@ Detection - - + + @@ -262,7 +279,7 @@ Detection - + @@ -1342,6 +1359,272 @@ New Object + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1377,5 +1660,8 @@ New Object + + + diff --git a/iOS12_Sampler/ios12 Sampler/BaseCameraVC.swift b/iOS12_Sampler/ios12 Sampler/BaseCameraVC.swift new file mode 100644 index 0000000..a7ed723 --- /dev/null +++ b/iOS12_Sampler/ios12 Sampler/BaseCameraVC.swift @@ -0,0 +1,65 @@ +// +// BaseCameraVC.swift +// ios12 Sampler +// +// Created by Dhruvil Vora on 29/02/24. +// Copyright © 2024 Testing. All rights reserved. +// + +import UIKit +import AVFoundation + +class BaseCameraVC: UIViewController, AVCaptureMetadataOutputObjectsDelegate { + + // AVCapture variables + private var session: AVCaptureSession? + private var device: AVCaptureDevice? + private var input: AVCaptureDeviceInput? + private var output: AVCaptureMetadataOutput? + var prevLayer: AVCaptureVideoPreviewLayer? + + override func viewDidLoad() { + super.viewDidLoad() + createSession() + // Do any additional setup after loading the view. + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.navigationController?.isNavigationBarHidden = true + } + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + self.navigationController?.isNavigationBarHidden = false + } + + func createSession() { + session = AVCaptureSession() + device = AVCaptureDevice.default(for: .video) + + var error: NSError? = nil + do { + if device != nil { + input = try AVCaptureDeviceInput(device: device!) + } + } catch { + print(error) + } + + if error == nil { + if input != nil { + session?.addInput(input!) + } + } else { + print("camera input error: \(String(describing: error))") + } + + prevLayer = AVCaptureVideoPreviewLayer(session: session!) + let del = UIApplication.shared.delegate as? AppDelegate + prevLayer?.frame = (del?.window?.frame)! + prevLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill + DispatchQueue.global().async { + self.session?.startRunning() + } + } +} diff --git a/iOS12_Sampler/ios12 Sampler/Body Detection with AR/ARPostureDetection.swift b/iOS12_Sampler/ios12 Sampler/Body Detection with AR/ARPostureDetection.swift new file mode 100644 index 0000000..31e43a1 --- /dev/null +++ b/iOS12_Sampler/ios12 Sampler/Body Detection with AR/ARPostureDetection.swift @@ -0,0 +1,127 @@ +// +// ARPostureDetection.swift +// ios12 Sampler +// +// Created by Dhruvil Vora on 28/02/24. +// Copyright © 2024 Testing. All rights reserved. +// + +import UIKit +import RealityKit +import ARKit +import Combine +import SwiftUI + +class ARPostureDetection: UIViewController { + + @IBOutlet var arView: ARView! + + // The 3D character to display. + var meshEntity: ModelEntity? + var meshAnchor = AnchorEntity() + var character: BodyTrackedEntity? + + private let labelView: UILabel = { + let label = UILabel() + label.text = "Angle" + label.font = UIFont.systemFont(ofSize: 20, weight: .semibold) + label.textColor = UIColor.green + return label + }() + + override func viewDidLoad() { + loadLabel() + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + arView.session.delegate = self + + // If the iOS device doesn't support body tracking, raise a developer error for + // this unhandled case. + guard ARBodyTrackingConfiguration.isSupported else { + fatalError("This feature is only supported on devices with an A12 chip") + } + + // Run a body tracking configration. + let configuration = ARBodyTrackingConfiguration() + arView.session.run(configuration) + self.arView.scene.addAnchor(meshAnchor) + } + + private func loadLabel() { + arView.addSubview(labelView) + labelView.translatesAutoresizingMaskIntoConstraints = false + labelView.bottomAnchor.constraint(equalTo: arView.bottomAnchor, constant: -20).isActive = true + labelView.leadingAnchor.constraint(equalTo: arView.leadingAnchor, constant: 0).isActive = true + labelView.trailingAnchor.constraint(equalTo: arView.trailingAnchor, constant: 0).isActive = true + labelView.textAlignment = .center + } +} + +// MARK: ARSessionDelegate +extension ARPostureDetection: ARSessionDelegate { + func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) { + for anchor in anchors { + /// Return if there is no body det3ected + guard let bodyAnchor = anchor as? ARBodyAnchor else { return } + /// Fetch the skeleton from the bodyanchor which will provide all transforms from the joints + meshAnchor.position = Transform(matrix: bodyAnchor.transform).translation + let skeleton = bodyAnchor.skeleton + /// For this usecase we only have to consider "left_leg_joint" & "spine_7_joint" as we have to find ths sitting posture angle correctly. + guard let leftLegJointTransform = skeleton.modelTransform(for: ARSkeleton.JointName(rawValue: "left_leg_joint")), + let spine7JointJointTransform = skeleton.modelTransform(for: ARSkeleton.JointName(rawValue: "spine_7_joint")) + else { return } + /// Then find the angle between 2 position + let angle = SIMD3.angleBetween(v1: Transform(matrix: leftLegJointTransform).translation, + v2: Transform(matrix: spine7JointJointTransform).translation) + // let angle1 = Transform(matrix: leftLegJointTransform).translation + // .angle(v: Transform(matrix: spine7JointJointTransform).translation) + /// Then convert radian to degree and update the label + let radToDeg = angle * 180.0 / Float.pi + DispatchQueue.main.async { + self.labelView.text = "Angle for posture :- \(Int(radToDeg))" + } + + /// Align the anchor's orientation with bodynchor's rotataion + meshAnchor.orientation = Transform(matrix: bodyAnchor.transform).rotation + /// FInd out towards which side the face is facing + let isFacingleft = meshAnchor.orientation.imag.y.isNegative + /// Reset all orientation to its default + meshAnchor.setOrientation(simd_quatf(real: 1, imag: [0,0,0]), relativeTo: nil) + + /// If the meshEntity do not have any parent that means meshEntity is not yet added to the anchor + /// So we need to create an entity and add it to the ARAnchor + if meshEntity?.parent == nil { + guard let mesh = MeshResource.createSemiCircleMeshForAngle(angle: (radToDeg), isFacingLeft: isFacingleft) else { return } + meshEntity = generateEntityFromMesh(mesh: mesh, angle: Int(radToDeg)) + meshAnchor.addChild(meshEntity!) + } + /// so now instead of creating whole 2d shape again and again we will just update its mesh + /// according to the newly updated angle + else { + updateSemiCircleMesh(forAngle: Double(radToDeg), modelEntity: meshEntity, isFacingLeft: isFacingleft) + } + } + } +} + +/// Used to Generate/Update mesh +extension ARPostureDetection { + func updateSemiCircleMesh(forAngle: Double, modelEntity: ModelEntity?, isFacingLeft: Bool) { + guard let entity = modelEntity, + let mesh = MeshResource.createSemiCircleMeshForAngle(angle: Float(forAngle), + isFacingLeft: isFacingLeft) else { return } + entity.model?.materials[0] = SimpleMaterial(color: Int(forAngle).postureIntensityColor(), + isMetallic: false) + entity.model?.mesh = mesh + } + + func generateEntityFromMesh(mesh: MeshResource, angle: Int) -> ModelEntity { + let material = SimpleMaterial(color: angle.postureIntensityColor(), isMetallic: false) + let entity = ModelEntity(mesh: mesh, materials: [material]) + entity.setScale([0.35, 0.35, 0.35], relativeTo: nil) + return entity + } +} + diff --git a/iOS12_Sampler/ios12 Sampler/Detecting Images in AR/ARImageLocator+ARSessionDelegate.swift b/iOS12_Sampler/ios12 Sampler/Detecting Images in AR/ARImageLocator+ARSessionDelegate.swift deleted file mode 100644 index 5d65fa0..0000000 --- a/iOS12_Sampler/ios12 Sampler/Detecting Images in AR/ARImageLocator+ARSessionDelegate.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// ARImageLocator+ARSessionDelegate.swift -// ios12 Sampler -// -// Created by Dhruvil Vora on 11/01/24. -// Copyright © 2024 Testing. All rights reserved. -// - -import ARKit - -extension ARImageLocator: ARSessionDelegate { - - func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) { - /// Notify users about current tracking camera quality - statusViewController.showCameraQualityInfo(trackingState: camera.trackingState, autoHide: true) - - switch camera.trackingState { - case .notAvailable: - statusViewController.showRecommendationForCameraQuality(trackingState: camera.trackingState, - duration: 3, autoHide: false) - default: - break - } - } - -} diff --git a/iOS12_Sampler/ios12 Sampler/Detecting Images in AR/ARImageLocator.swift b/iOS12_Sampler/ios12 Sampler/Detecting Images in AR/ARImageLocator.swift deleted file mode 100644 index 0a35dcf..0000000 --- a/iOS12_Sampler/ios12 Sampler/Detecting Images in AR/ARImageLocator.swift +++ /dev/null @@ -1,173 +0,0 @@ -// -// ARImageLocator.swift -// ios12 Sampler -// -// Created by Dhruvil Vora on 10/01/24. -// Copyright © 2024 Testing. All rights reserved. -// - -import Foundation -import ARKit - -class ARImageLocator: UIViewController { - - @IBOutlet weak var sceneView: ARSCNView! - - @IBOutlet weak var blurVIew: UIVisualEffectView! - - lazy var statusViewController: StatusViewController = { - children.lazy.compactMap({ $0 as? StatusViewController }).first! - }() - - /// Need to create a serial queue for thread safety, when modifying scenekit node graph - let serialQueue = DispatchQueue(label: "\(Bundle.main.bundleIdentifier ?? "") + .serialScenekitQueue") - - /// Session accessor which is hold by sceneview - var session: ARSession { - sceneView.session - } - - var isRestartAvailable = true - - // MARK: View life cycle - override func viewDidLoad() { - super.viewDidLoad() - - sceneView.delegate = self - - // Create a new scene - let scene = SCNScene(named: "art.scnassets/ship.scn")! - sceneView.scene = scene - - sceneView.session.delegate = self - - // Hook up status view controller callback(s). - statusViewController.restartExperienceHandler = { [unowned self] in - self.restartExperience() - } - } - - override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) - /// Prevent screen from being dimmed after it's let ideal for sometime - UIApplication.shared.isIdleTimerDisabled = true - statusViewController.scheduleGenericMessage(genericMsg: "Look for an image", duration: 7.5, - autoHide: true, messageType: .cameraQualityInfo) - resetTracking() - } - - override func viewDidDisappear(_ animated: Bool) { - super.viewDidDisappear(animated) - session.pause() - } - - /// Create a new arconfig to run on a `session` - func resetTracking() { - - guard let referenceImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil) else { - fatalError("Didn't found any resourcses") - } - let config = ARWorldTrackingConfiguration() - /// Need to provide detection images - config.detectionImages = referenceImages - session.run(config, options: [.resetTracking, .removeExistingAnchors]) - } - - private func restartExperience() { - guard isRestartAvailable else { return } - isRestartAvailable = false - statusViewController.showHideResetButton(isHidden: isRestartAvailable) - statusViewController.removeAllTimers() - - DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) { [weak self] in - guard let self else { return } - self.isRestartAvailable = true - self.statusViewController.showHideResetButton(isHidden: self.isRestartAvailable) - } - } -} - -extension ARImageLocator: ARSCNViewDelegate { - func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) { - guard let imageAnchor = anchor as? ARImageAnchor else { return } - serialQueue.async { - // first create a plane from the added anchor - let plane = SCNPlane(width: imageAnchor.referenceImage.physicalSize.width, - height: imageAnchor.referenceImage.physicalSize.height) - let planeNode = SCNNode(geometry: plane) - planeNode.opacity = 0.25 - - // As SCNPlane is a 2d it is vertically oriented and the ARImageAnchor is horizontally oriented - /// So by default SCNPlane is in a 2D format whose orientation is vertical & image anchor being 3D format its - /// horizontally align so inorder to matchb with imageanchor we need to rotate the plane's angle - planeNode.eulerAngles.x = -.pi / 2 - - node.addChildNode(planeNode) - } - DispatchQueue.main.async { - let name = imageAnchor.referenceImage.name - print("Image Name :- ",name) - self.animateObject(node) - } - } - - func animateObject(_ node: SCNNode) { - - guard let nodeToAnimate = sceneView.scene.rootNode.childNode(withName: "ship", recursively: true) else { - return - } - - // let forwardAction = SCNAction.moveBy(x: 0, y: 0, z: 5, duration: 1.0) - // let rotateAction1 = SCNAction.rotateBy(x: -.pi/2,y: 0, z: 0, duration: 2.0) - // let backwardAction = SCNAction.moveBy(x: 0, y: 0, z: -5, duration: 1.0) - // let rotateAction2 = SCNAction.rotateBy(x: -.pi/2,y: 0, z: 0, duration: 2.0) - // let abc = SCNAction.group([backwardAction, rotateAction1]) - // let sequenceAction = SCNAction.sequence([forwardAction, rotateAction1, backwardAction, rotateAction2]) - - let forwardAction = SCNAction.moveBy(x: 0, y: 0, z: 5, duration: 1.0) - let rotateAction1 = SCNAction.rotateBy(x: (-.pi),y: 0, z: 0, duration: 5.0) - let backwardAction = SCNAction.moveBy(x: 0, y: 0, z: -5, duration: 1.0) - let rotateAction2 = SCNAction.rotateBy(x: .pi/2,y: 0, z: 0, duration: 2.0) - let rotation = SCNAction.rotateBy(x: 0,y: 0, z: .pi, duration: 2.0) - var verticalPosition0: CGFloat = 0.0 - // Create a custom action to update the position based on a parabolic function - let parabolicAction = SCNAction.customAction(duration: 2) { (node, elapsedTime) in - // Calculate the vertical position using a parabolic function - verticalPosition0 = 0.5 * 9.8 * pow(elapsedTime, 1) - print("vertical Pos :- ", verticalPosition0) - // Update the node's position based on the parabolic function - node.position = SCNVector3(nodeToAnimate.position.x, - Float(verticalPosition0) > 4.9 ? (9.8 - Float(verticalPosition0)) : Float(verticalPosition0), - -Float(verticalPosition0)) - } - - let parabolicBackAction = SCNAction.customAction(duration: 2) { (node, elapsedTime) in - // Calculate the vertical position using a parabolic function - let verticalPosition = -0.5 * 9.8 * pow(elapsedTime, 1) - print("vertical Pos :- ", verticalPosition) - // Update the node's position based on the parabolic function - node.position = SCNVector3(Float(node.position.x), Float(verticalPosition), node.position.z) - } - // let sequenceAction = SCNAction.sequence([forwardAction, rotateAction1, backwardAction, rotateAction1]) - - let groupAction1 = SCNAction.group([forwardAction, rotation, parabolicAction]) - let groupAction2 = SCNAction.group([rotateAction1, backwardAction]) - let sequenceAction = SCNAction.sequence([groupAction1]) - - let repeatAction = SCNAction.repeatForever(parabolicAction.reversed()) - - nodeToAnimate.runAction(repeatAction) - } - - var imageHighlightAction: SCNAction { - return .sequence([ - .wait(duration: 0.25), - .fadeOpacity(to: 0.85, duration: 0.25), - .fadeOpacity(to: 0.15, duration: 0.25), - .fadeOpacity(to: 0.85, duration: 0.25), - .fadeOut(duration: 0.5), - .removeFromParentNode() - ]) - } -} - diff --git a/iOS12_Sampler/ios12 Sampler/Extensions/Float+Extension.swift b/iOS12_Sampler/ios12 Sampler/Extensions/Float+Extension.swift new file mode 100644 index 0000000..7dcf7f3 --- /dev/null +++ b/iOS12_Sampler/ios12 Sampler/Extensions/Float+Extension.swift @@ -0,0 +1,16 @@ +// +// Float+Extension.swift +// ios12 Sampler +// +// Created by Dhruvil Vora on 04/03/24. +// Copyright © 2024 Testing. All rights reserved. +// + +import Foundation + +extension Float { + /// A boolean value indicating whether a number is negative or not + var isNegative: Bool { + return self < 0 + } +} diff --git a/iOS12_Sampler/ios12 Sampler/Extensions/Int+Extension.swift b/iOS12_Sampler/ios12 Sampler/Extensions/Int+Extension.swift new file mode 100644 index 0000000..a2a3748 --- /dev/null +++ b/iOS12_Sampler/ios12 Sampler/Extensions/Int+Extension.swift @@ -0,0 +1,32 @@ +// +// Int+Extension.swift +// ios12 Sampler +// +// Created by Dhruvil Vora on 04/03/24. +// Copyright © 2024 Testing. All rights reserved. +// + +import UIKit + +extension Int { + /// Provides a array of UInt32 from the given count + func returnArrCountInUInt32() -> [UInt32]{ + var arr = [UInt32]() + for x in 0...(self-1) { + arr.append(UInt32(x)) + } + return arr + } + + /// Provides a predefined colour based on detected angle from body posture + func postureIntensityColor() -> UIColor{ + if self <= 70 { + return .red.withAlphaComponent(0.7) + } else if (self > 70 && self <= 110) { + return .orange.withAlphaComponent(0.7) + } else if self > 110 { + return .green.withAlphaComponent(0.7) + } + return .black.withAlphaComponent(0.7) + } +} diff --git a/iOS12_Sampler/ios12 Sampler/Extensions/MeshResource+Extension.swift b/iOS12_Sampler/ios12 Sampler/Extensions/MeshResource+Extension.swift new file mode 100644 index 0000000..5b0fa8b --- /dev/null +++ b/iOS12_Sampler/ios12 Sampler/Extensions/MeshResource+Extension.swift @@ -0,0 +1,39 @@ +// +// MeshResource+Extension.swift +// ios12 Sampler +// +// Created by Dhruvil Vora on 04/03/24. +// Copyright © 2024 Testing. All rights reserved. +// + +import Foundation +import RealityKit + +extension MeshResource { + static func createSemiCircleMeshForAngle(angle: Float, isFacingLeft: Bool = false) -> MeshResource? { + guard angle > 15.0 else { return nil } + let angleCount = Int(angle/6) + var fixedAngleCount = 0 + var fixedPostitions: [SIMD3] = [] + var positions: [SIMD3] = SIMD3.getSemiCircleMesh + + if isFacingLeft { + let removalPosCount = 29 - angleCount + positions.remove(atOffsets: IndexSet(0...(removalPosCount-1))) + fixedPostitions.append(contentsOf: positions) + } else { + fixedPostitions.append(contentsOf: positions[0...(angleCount-1)]) + } + + fixedPostitions.append(.zero) + fixedAngleCount = fixedPostitions.count + + let counts: [UInt8] = [UInt8(fixedAngleCount)] + let indices: [UInt32] = fixedAngleCount.returnArrCountInUInt32() + + var meshDescriptor = MeshDescriptor() + meshDescriptor.positions = .init(fixedPostitions) + meshDescriptor.primitives = .polygons(counts, indices) + return try! MeshResource.generate(from: [meshDescriptor]) + } +} diff --git a/iOS12_Sampler/ios12 Sampler/Extensions/SCNVector3+Extension.swift b/iOS12_Sampler/ios12 Sampler/Extensions/SCNVector3+Extension.swift new file mode 100644 index 0000000..e6631e0 --- /dev/null +++ b/iOS12_Sampler/ios12 Sampler/Extensions/SCNVector3+Extension.swift @@ -0,0 +1,249 @@ +// +// SCNVector3+Extension.swift +// ios12 Sampler +// +// Created by Dhruvil Vora on 04/03/24. +// Copyright © 2024 Testing. All rights reserved. +// + +import Foundation +import CoreGraphics +import SceneKit + +extension SCNVector3 { + + // Vector Length is Zero + func isZero() -> Bool { + if self.x == 0 && self.y == 0 && self.z == 0 { + return true + } + + return false + } + + /** + Inverts vector + */ + mutating func invert() -> SCNVector3 { + self * -1 + return self + } + + /** + Calculates vector length based on Pythagoras theorem + */ + var length:Float { + get { + return sqrtf(x*x + y*y + z*z) + } + set { + self = self.unit * newValue + } + } + + /** + Calculate Length Squared of Vector + - Used to determine Longest/Shortest Vector. Faster than using v.length + */ + var lengthSquared:Float { + get { + return self.x * self.x + self.y * self.y + self.z * self.z; + } + } + + /** + Returns unit vector (aka Normalized Vector) + - v.length = 1.0 + */ + var unit:SCNVector3 { + get { + return self / self.length + } + } + + /** + Normalizes vector + - v.Length = 1.0 + */ + mutating func normalize() { + self = self.unit + } + + /** + Calculates distance to vector + */ + func distance(toVector: SCNVector3) -> Float { + return (self - toVector).length + } + + + /** + Calculates dot product to vector + */ + func dot(toVector: SCNVector3) -> Float { + return x * toVector.x + y * toVector.y + z * toVector.z + } + + /** + Calculates cross product to vector + */ + func cross(toVector: SCNVector3) -> SCNVector3 { + return SCNVector3Make(y * toVector.z - z * toVector.y, z * toVector.x - x * toVector.z, x * toVector.y - y * toVector.x) + } + + /** + Returns lerp from Vector to Vector + */ + func lerp(toVector: SCNVector3, t: Float) -> SCNVector3 { + return SCNVector3Make( + self.x + ((toVector.x - self.x) * t), + self.y + ((toVector.y - self.y) * t), + self.z + ((toVector.z - self.z) * t)) + } + + /** + Project onto Vector + */ + func project(ontoVector: SCNVector3) -> SCNVector3 { + let scale: Float = dotBetweenVectors(v1: ontoVector, v2: self) / dotBetweenVectors(v1: ontoVector, v2: ontoVector) + let v: SCNVector3 = ontoVector * scale + return v + } + + /// Get/Set Angle of Vector + mutating func rotate(angle:Float) { + let length = self.length + self.x = cos(angle) * length + self.y = sin(angle) * length + } + + + func toCGVector() -> CGVector { + return CGVector(dx: CGFloat(self.x), dy: CGFloat(self.y)) + } + +} + +/** + v1 = v2 + v3 +*/ +func +(left: SCNVector3, right: SCNVector3) -> SCNVector3 { + return SCNVector3Make(left.x + right.x, left.y + right.y, left.z + right.z) +} + +/** + v1 += v2 +*/ +func +=( left: inout SCNVector3, right: SCNVector3) { + left = left + right +} + +/** + v1 = v2 - v3 +*/ +func -(left: SCNVector3, right: SCNVector3) -> SCNVector3 { + return SCNVector3Make(left.x - right.x, left.y - right.y, left.z - right.z) +} + +/** + v1 -= v2 +*/ +func -=( left: inout SCNVector3, right: SCNVector3) { + left = left - right +} + +/** + v1 = v2 * v3 +*/ +func *(left: SCNVector3, right: SCNVector3) -> SCNVector3 { + return SCNVector3Make(left.x * right.x, left.y * right.y, left.z * right.z) +} + +/** + v1 *= v2 +*/ +func *=( left: inout SCNVector3, right: SCNVector3) { + left = left * right +} + +/** + v1 = v2 * x +*/ +func *(left: SCNVector3, right: Float) -> SCNVector3 { + return SCNVector3Make(left.x * right, left.y * right, left.z * right) +} + +/** + v *= x +*/ +func *=( left: inout SCNVector3, right: Float) { + left = SCNVector3Make(left.x * right, left.y * right, left.z * right) +} + +/** + v1 = v2 / v3 +*/ +func /(left: SCNVector3, right: SCNVector3) -> SCNVector3 { + return SCNVector3Make(left.x / right.x, left.y / right.y, left.z / right.z) +} + +/** + v1 /= v2 +*/ +func /=( left: inout SCNVector3, right: SCNVector3) { + left = SCNVector3Make(left.x / right.x, left.y / right.y, left.z / right.z) +} + +/** + v1 = v2 / x +*/ +func /(left: SCNVector3, right: Float) -> SCNVector3 { + return SCNVector3Make(left.x / right, left.y / right, left.z / right) +} + +/** + v /= x +*/ +func /=( left: inout SCNVector3, right: Float) { + left = SCNVector3Make(left.x / right, left.y / right, left.z / right) +} + +/** + v = -v +*/ +prefix func -(v: SCNVector3) -> SCNVector3 { + return v * -1 +} + +/** + Returns distance between two vectors +*/ +func distanceBetweenVectors(v1: SCNVector3, v2: SCNVector3) -> Float { + return (v2 - v1).length +} + +/** + Returns dot product between two vectors +*/ +func dotBetweenVectors(v1: SCNVector3, v2: SCNVector3) -> Float { + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z +} + +/** + Returns cross product between two vectors +*/ +func crossBetweenVectors(v1: SCNVector3, v2: SCNVector3) -> SCNVector3 { + return SCNVector3Make(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x) +} + +/** + Generate a Random Vector +*/ +func randomSCNVector3(rangeX:Float, rangeY:Float, rangeZ:Float) -> SCNVector3 { + + return SCNVector3( + x: Float(arc4random()%UInt32(rangeX)), + y: Float(arc4random()%UInt32(rangeY)), + z: Float(arc4random()%UInt32(rangeZ))) +} + diff --git a/iOS12_Sampler/ios12 Sampler/Extensions/Simd3+Extension.swift b/iOS12_Sampler/ios12 Sampler/Extensions/Simd3+Extension.swift new file mode 100644 index 0000000..cd08fda --- /dev/null +++ b/iOS12_Sampler/ios12 Sampler/Extensions/Simd3+Extension.swift @@ -0,0 +1,56 @@ +// +// Simd3+Extension.swift +// ios12 Sampler +// +// Created by Dhruvil Vora on 04/03/24. +// Copyright © 2024 Testing. All rights reserved. +// + +import Foundation +import SceneKit + +extension SIMD3 { + + static var getSemiCircleMesh: [SIMD3] { + [ + [0.8, 0.1, 0], [0.79, 0.18, 0], [0.78, 0.26, 0], [0.75, 0.43, 0], [0.725, 0.53, 0], + [0.7, 0.6, 0], [0.65, 0.7, 0], [0.6, 0.78, 0], [0.55, 0.83, 0], [0.45, 0.9, 0], + [0.4, 0.92, 0], [0.3, 0.95, 0], [0.2, 0.98, 0], [0.1, 1, 0], [0, 1, 0], + [-0.1, 1, 0], [-0.2, 0.98, 0], [-0.3, 0.95, 0], [-0.4, 0.92, 0], [-0.45, 0.9, 0], + [-0.55, 0.83, 0], [-0.6, 0.78, 0], [-0.65, 0.7, 0], [-0.7, 0.6, 0], [-0.725, 0.53, 0], + [-0.75, 0.43, 0], [-0.78, 0.26, 0], [-0.79, 0.18, 0], [-0.8, 0.1, 0] + ] + } + + var length:Float { + get { + return sqrtf(x*x + y*y + z*z) + } + } + + static func dotProduct(v1: SIMD3, v2: SIMD3) -> Float{ + return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z + } + + static func angleBetween(v1: SIMD3, v2: SIMD3) -> Float{ + let cosinus = dotProduct(v1: v1, v2: v2) / v1.length / v2.length + let angle = acos(cosinus) + return angle + } + + // Return the angle between this vector and the specified vector v + func angle(v: SIMD3) -> Float + { + // angle between 3d vectors P and Q is equal to the arc cos of their dot products over the product of + // their magnitudes (lengths). + // theta = arccos( (P • Q) / (|P||Q|) ) + let dp = dot(v) // dot product + let magProduct = length * v.length // product of lengths (magnitudes) + return acos(dp / magProduct) // DONE + } + + func dot(_ vec: SIMD3) -> Float { + return (self.x * vec.x) + (self.y * vec.y) + (self.z * vec.z) + } +} + diff --git a/iOS12_Sampler/ios12 Sampler/USDZ/biped_robot.usdz b/iOS12_Sampler/ios12 Sampler/USDZ/biped_robot.usdz new file mode 100644 index 0000000..a4ffb6b Binary files /dev/null and b/iOS12_Sampler/ios12 Sampler/USDZ/biped_robot.usdz differ diff --git a/iOS12_Sampler/ios12 Sampler/USDZ/robot_walk_idle.usdz b/iOS12_Sampler/ios12 Sampler/USDZ/robot_walk_idle.usdz new file mode 100644 index 0000000..1c6b1c0 Binary files /dev/null and b/iOS12_Sampler/ios12 Sampler/USDZ/robot_walk_idle.usdz differ diff --git a/iOS12_Sampler/ios12 Sampler/art.scnassets/robot_walk_idle.scn b/iOS12_Sampler/ios12 Sampler/art.scnassets/robot_walk_idle.scn new file mode 100644 index 0000000..d8b784b Binary files /dev/null and b/iOS12_Sampler/ios12 Sampler/art.scnassets/robot_walk_idle.scn differ diff --git a/iOS12_Sampler/ios12 Sampler/art.scnassets/ship.scn b/iOS12_Sampler/ios12 Sampler/art.scnassets/ship.scn index 89cc818..5539d8a 100644 Binary files a/iOS12_Sampler/ios12 Sampler/art.scnassets/ship.scn and b/iOS12_Sampler/ios12 Sampler/art.scnassets/ship.scn differ