-
Notifications
You must be signed in to change notification settings - Fork 133
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This PR introduces visionOS windowed rendering for Babylon Native. NativeXr plugin integration will be a separate PR. ### Recording https://github.com/user-attachments/assets/8cf0104b-3267-4fa7-9361-7351637cf114
- Loading branch information
1 parent
1bc427c
commit fdcd2f9
Showing
14 changed files
with
475 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import UIKit | ||
|
||
/** | ||
* A very simple gesture recognizer. All that it does is to emulate the functionality found in other platforms | ||
*/ | ||
class UIBabylonGestureRecognizer: UIGestureRecognizer { | ||
// Callback for touch down events | ||
private let _onTouchDown: (Int32, Int32, Int32)->Void | ||
// Callback for touch movement events | ||
private let _onTouchMove: (Int32, Int32, Int32)->Void | ||
// Callback for touch up events | ||
private let _onTouchUp: (Int32, Int32, Int32)->Void | ||
// Table to track hashes of active touches | ||
private var _activeTouchIds: Array<Int> = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1] | ||
|
||
public init(target: Any?, onTouchDown: @escaping(Int32, Int32, Int32)->Void, onTouchMove: @escaping(Int32, Int32, Int32)->Void, onTouchUp: @escaping(Int32, Int32, Int32)->Void) { | ||
_onTouchDown = onTouchDown | ||
_onTouchMove = onTouchMove | ||
_onTouchUp = onTouchUp | ||
|
||
super.init(target: target, action: nil) | ||
} | ||
|
||
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) { | ||
super.touchesBegan(touches, with: event) | ||
|
||
for touch in touches { | ||
guard let deviceSlot = _activeTouchIds.firstIndex(of: -1) else { continue } | ||
_activeTouchIds[deviceSlot] = touch.hash | ||
let loc = touch.location(in: view) | ||
|
||
_onTouchDown(Int32(deviceSlot), Int32(loc.x), Int32(loc.y)) | ||
} | ||
} | ||
|
||
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) { | ||
super.touchesMoved(touches, with: event) | ||
|
||
for touch in touches { | ||
guard let deviceSlot = _activeTouchIds.firstIndex(of: touch.hash) else { continue } | ||
let loc = touch.location(in: view) | ||
|
||
_onTouchMove(Int32(deviceSlot), Int32(loc.x), Int32(loc.y)) | ||
} | ||
} | ||
|
||
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) { | ||
super.touchesEnded(touches, with: event) | ||
|
||
for touch in touches { | ||
guard let deviceSlot = _activeTouchIds.firstIndex(of: touch.hash) else { continue } | ||
let loc = touch.location(in: view) | ||
|
||
_onTouchUp(Int32(deviceSlot), Int32(loc.x), Int32(loc.y)) | ||
_activeTouchIds[deviceSlot] = -1 | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import SwiftUI | ||
|
||
class MetalView: UIView { | ||
override init(frame: CGRect) { | ||
super.init(frame: frame) | ||
self.backgroundColor = .clear | ||
} | ||
|
||
required init?(coder: NSCoder) { | ||
fatalError("init(coder:) has not been implemented") | ||
} | ||
|
||
func setupMetalLayer() { | ||
guard let bridge = LibNativeBridge.sharedInstance() else { return } | ||
|
||
if bridge.metalLayer != nil { | ||
return | ||
} | ||
|
||
self.addGestureRecognizer( | ||
UIBabylonGestureRecognizer( | ||
target: self, | ||
onTouchDown: bridge.setTouchDown, | ||
onTouchMove: bridge.setTouchMove, | ||
onTouchUp: bridge.setTouchUp | ||
) | ||
) | ||
metalLayer.pixelFormat = .bgra8Unorm | ||
metalLayer.framebufferOnly = true | ||
|
||
bridge.metalLayer = self.metalLayer | ||
|
||
let scale = UITraitCollection.current.displayScale | ||
bridge.initialize(withWidth: Int(self.bounds.width * scale), height: Int(self.bounds.height * scale)) | ||
} | ||
|
||
var metalLayer: CAMetalLayer { | ||
return layer as! CAMetalLayer | ||
} | ||
|
||
override class var layerClass: AnyClass { | ||
return CAMetalLayer.self | ||
} | ||
|
||
override func layoutSubviews() { | ||
super.layoutSubviews() | ||
setupMetalLayer() | ||
updateDrawableSize() | ||
} | ||
|
||
private func updateDrawableSize() { | ||
let scale = UITraitCollection.current.displayScale | ||
LibNativeBridge.sharedInstance().drawableWillChangeSize(withWidth: Int(bounds.width * scale), height: Int(bounds.height * scale)) | ||
metalLayer.drawableSize = CGSize(width: bounds.width * scale, height: bounds.height * scale) | ||
} | ||
} | ||
|
||
struct MetalViewRepresentable: UIViewRepresentable { | ||
typealias UIViewType = MetalView | ||
|
||
func makeUIView(context: Context) -> MetalView { | ||
MetalView(frame: .zero) | ||
} | ||
|
||
func updateUIView(_ uiView: MetalView, context: Context) {} | ||
} | ||
|
||
|
||
@main | ||
struct ExampleApp: App { | ||
var body: some Scene { | ||
WindowGroup { | ||
MetalViewRepresentable() | ||
.frame(maxWidth: .infinity, maxHeight: .infinity) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>NSPhotoLibraryAddUsageDescription</key> | ||
<string>Need photo library permission for debug code to save photo captures</string> | ||
<key>CFBundleDevelopmentRegion</key> | ||
<string>$(DEVELOPMENT_LANGUAGE)</string> | ||
<key>CFBundleExecutable</key> | ||
<string>$(EXECUTABLE_NAME)</string> | ||
<key>CFBundleIdentifier</key> | ||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | ||
<key>CFBundleInfoDictionaryVersion</key> | ||
<string>6.0</string> | ||
<key>CFBundleName</key> | ||
<string>$(PRODUCT_NAME)</string> | ||
<key>CFBundlePackageType</key> | ||
<string>APPL</string> | ||
<key>CFBundleShortVersionString</key> | ||
<string>1.0</string> | ||
<key>CFBundleVersion</key> | ||
<string>1</string> | ||
<key>UIApplicationSceneManifest</key> | ||
<dict> | ||
<key>UIApplicationPreferredDefaultSceneSessionRole</key> | ||
<string>UIWindowSceneSessionRoleApplication</string> | ||
<key>UIApplicationSupportsMultipleScenes</key> | ||
<true/> | ||
<key>UISceneConfigurations</key> | ||
<dict/> | ||
</dict> | ||
</dict> | ||
</plist> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#import <Foundation/Foundation.h> | ||
#import <CompositorServices/CompositorServices.h> | ||
|
||
@class CAMetalLayer; | ||
|
||
@interface LibNativeBridge : NSObject | ||
|
||
@property (nonatomic, assign, getter=isInitialized) BOOL initialized; | ||
@property (nonatomic, strong) CAMetalLayer *metalLayer; | ||
|
||
+ (instancetype)sharedInstance; | ||
|
||
- (void)setTouchDown:(int)pointerId x:(int)inX y:(int)inY; | ||
- (void)setTouchMove:(int)pointerId x:(int)inX y:(int)inY; | ||
- (void)setTouchUp:(int)pointerId x:(int)inX y:(int)inY; | ||
|
||
- (void)drawableWillChangeSizeWithWidth:(NSInteger)width height:(NSInteger)height; | ||
|
||
- (bool)initializeWithWidth:(NSInteger)width height:(NSInteger)height; | ||
- (void)shutdown; | ||
- (void)render; | ||
|
||
@end | ||
|
Oops, something went wrong.