Created
November 4, 2017 17:05
Star
You must be signed in to star a gist
arkit-test.py
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
# coding: utf-8 | |
from objc_util import * | |
from scene import * | |
import ui | |
import os | |
import sys | |
#from myDebugToolKit import * | |
load_framework('SceneKit') | |
load_framework('ARKit') | |
SCNView, SCNScene, SCNBox, SCNText, SCNNode, SCNLight, SCNCamera, SCNAction, UIFont = map(ObjCClass, ['SCNView', 'SCNScene', 'SCNBox', 'SCNText', 'SCNNode', 'SCNLight', 'SCNCamera', 'SCNAction', 'UIFont']) | |
class SCNVector3 (Structure): | |
_fields_ = [('x', c_float), ('y', c_float), ('z', c_float)] | |
ARWorldAlignmentGravity = 0 | |
ARWorldAlignmentGravityAndHeading = 1 | |
ARWorldAlignmentCamera = 2 | |
ARPlaneDetectionNone = 0 | |
ARPlaneDetectionHorizontal = 1 << 0 | |
ARPlaneDetectionVertical = 1 << 1 | |
ARSCNDebugOptionNone = 0 | |
ARSCNDebugOptionShowWorldOrigin = 1 << 11 | |
ARSCNDebugOptionShowFeaturePoints = 1 << 12 | |
SCNScene = ObjCClass('SCNScene') | |
ARSCNView = ObjCClass('ARSCNView') | |
ARWorldTrackingConfiguration = ObjCClass('ARWorldTrackingConfiguration') | |
ARSession = ObjCClass('ARSession') | |
UIViewController = ObjCClass('UIViewController') | |
ARPlaneAnchor = ObjCClass('ARPlaneAnchor') | |
# I should refactor te following line in a class but I need to learn more the create_objcc_class function | |
sceneview = None | |
# Here two little set up functions used by the main class | |
@on_main_thread | |
def createSampleScene(): | |
# an empty scene | |
scene = SCNScene.scene() | |
root_node = scene.rootNode() | |
cube_geometry = SCNBox.boxWithWidth_height_length_chamferRadius_(1, 1, 1, 0) | |
cube_node = SCNNode.nodeWithGeometry_(cube_geometry) | |
cube_node.setPosition((0, 0, -5)) | |
light = SCNLight.light() | |
light.setType_('omni') | |
light_node = SCNNode.node() | |
light_node.setLight_(light) | |
light_node.setPosition((1.5, 1.5, 1.5)) | |
root_node.addChildNode_(light_node) | |
root_node.addChildNode_(cube_node) | |
return scene | |
@on_main_thread | |
def createARSceneView(x, y, w, h, debug=True): | |
v = ARSCNView.alloc().initWithFrame_((CGRect(CGPoint(x, y), CGSize(w, h)))) | |
v.setShowsStatistics_(debug) | |
# Problem here... feature points are not shown.... despite the method call | |
v.setDebugOptions_(ARSCNDebugOptionShowWorldOrigin | ARSCNDebugOptionShowFeaturePoints) | |
return v | |
# Some callback definitions used by create_objc_class | |
#@on_main_thread | |
def CustomViewController_touchesBegan_withEvent_(_self, _cmd, _touches, event): | |
touches = ObjCInstance(_touches) | |
for t in touches: | |
loc = t.locationInView_(sceneview) | |
sz = ui.get_screen_size() | |
print(loc) | |
#@on_main_thread | |
def CustomViewController_viewWillAppear_(_self, _cmd, animated): | |
configuration = ARWorldTrackingConfiguration.alloc().init() | |
# Another problem here...constants aren't well communicated... (my assumption...) | |
#configuration.setPlaneDetection_ (ARPlaneDetectionHorizontal | ARPlaneDetectionVertical) | |
configuration.setWorldAlignment_(ARWorldAlignmentGravityAndHeading) | |
print(configuration) | |
session = sceneview.session() | |
session.runWithConfiguration_(configuration) | |
#@on_main_thread | |
def CustomViewController_viewDidLoad_(_self, _cmd, view): | |
print('bling') | |
#@on_main_thread | |
def CustomViewController_viewWillDisappear_(_self, _cmd, animated): | |
session = sceneview.session() | |
session.pause() | |
def MyARSCNViewDelegate_renderer_didAdd_for_(_self, _cmd, scenerenderer, node, anchor): | |
if not isinstance(anchor, (ARPlaneAnchor)): | |
return | |
print('anchor') | |
# The main class... | |
@on_main_thread | |
class MyARView(ui.View): | |
def initialize(self): | |
global sceneview | |
self.flex = 'WH' | |
screen = ui.get_screen_size() | |
# set up the scene | |
scene = createSampleScene() | |
# set up the ar scene view delegate | |
methods = [MyARSCNViewDelegate_renderer_didAdd_for_] | |
protocols = ['ARSCNViewDelegate'] | |
MyARSCNViewDelegate = create_objc_class('MyARSCNViewDelegate', NSObject, methods=methods, protocols=protocols) | |
delegate = MyARSCNViewDelegate.alloc().init() | |
# set up the ar scene view | |
sceneview = createARSceneView(0, 0, screen.width, screen.height) | |
sceneview.scene = scene | |
#sceneview.delegate = delegate | |
# set up the custom view controller | |
methods = [CustomViewController_touchesBegan_withEvent_, CustomViewController_viewWillAppear_, CustomViewController_viewDidLoad_, CustomViewController_viewWillDisappear_] | |
protocols = [] | |
CustomViewController = create_objc_class('CustomViewController', UIViewController, methods=methods, protocols=protocols) | |
cvc = CustomViewController.new().init().autorelease() | |
cvc.view = sceneview | |
# last set up | |
self_objc = ObjCInstance(self) | |
self_objc.nextResponder().addChildViewController_(cvc) | |
self_objc.addSubview_(sceneview) | |
cvc.didMoveToParentViewController_(self_objc) | |
# workaround : I need to call manually viewWillAppear as otherwise my callback is not called... | |
#cvc.viewWillAppear_(False) | |
def will_close(self): | |
session = sceneview.session() | |
session.pause() | |
@on_main_thread | |
def main(): | |
v = MyARView() | |
v.present('full_screen', hide_title_bar=True) | |
v.initialize() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment