nativescript-ar
Version:
NativeScript Augmented Reality plugin. ARKit on iOS and (with the help of Sceneform) ARCore on Android.
1,034 lines (1,033 loc) • 43.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var application = require("tns-core-modules/application");
var image_source_1 = require("tns-core-modules/image-source");
var platform_1 = require("tns-core-modules/platform");
var lazy_1 = require("tns-core-modules/utils/lazy");
var ar_common_1 = require("./ar-common");
var arbox_1 = require("./nodes/ios/arbox");
var argroup_1 = require("./nodes/ios/argroup");
var arimage_1 = require("./nodes/ios/arimage");
var armaterialfactory_1 = require("./nodes/ios/armaterialfactory");
var armodel_1 = require("./nodes/ios/armodel");
var arplane_1 = require("./nodes/ios/arplane");
var arsphere_1 = require("./nodes/ios/arsphere");
var artext_1 = require("./nodes/ios/artext");
var artube_1 = require("./nodes/ios/artube");
var aruiview_1 = require("./nodes/ios/aruiview");
var arvideo_1 = require("./nodes/ios/arvideo");
var main_queue = dispatch_get_current_queue();
var sdkVersion = lazy_1.default(function () { return parseInt(platform_1.device.sdkVersion); });
var ARState = {
planes: new Map(),
shapes: new Map(),
};
var addUIView = function (options, parentNode, sceneView, renderer) {
return new Promise(function (resolve, reject) {
var view = aruiview_1.ARUIView.create(options, sceneView, renderer);
ARState.shapes.set(view.id, view);
parentNode.addChildNode(view.ios);
resolve(view);
});
};
var addNode = function (options, parentNode, renderer) {
return new Promise(function (resolve, reject) {
var group = argroup_1.ARGroup.create(options, renderer);
ARState.shapes.set(group.id, group);
parentNode.addChildNode(group.ios);
resolve(group);
});
};
var addVideo = function (options, parentNode, renderer) {
return new Promise(function (resolve, reject) {
var video = arvideo_1.ARVideo.create(options, renderer);
ARState.shapes.set(video.id, video);
parentNode.addChildNode(video.ios);
resolve(video);
});
};
var addImage = function (options, parentNode, renderer) {
return arimage_1.ARImage.create(options, renderer).then(function (image) {
ARState.shapes.set(image.id, image);
parentNode.addChildNode(image.ios);
return image;
});
};
var addText = function (options, parentNode, renderer) {
return new Promise(function (resolve, reject) {
var text = artext_1.ARText.create(options, renderer);
ARState.shapes.set(text.id, text);
parentNode.addChildNode(text.ios);
resolve(text);
});
};
var addBox = function (options, parentNode, renderer) {
return new Promise(function (resolve, reject) {
var box = arbox_1.ARBox.create(options, renderer);
ARState.shapes.set(box.id, box);
parentNode.addChildNode(box.ios);
resolve(box);
});
};
var addPlane = function (options, parentNode) {
return new Promise(function (resolve, reject) {
var plane = arplane_1.ARPlane.createExternal(options);
ARState.shapes.set(plane.id, plane);
parentNode.addChildNode(plane.ios);
resolve(plane);
});
};
var addModel = function (options, parentNode, renderer) {
return new Promise(function (resolve, reject) {
var model = armodel_1.ARModel.create(options, renderer);
setTimeout(function () {
ARState.shapes.set(model.id, model);
});
parentNode.addChildNode(model.ios);
resolve(model);
});
};
var addSphere = function (options, parentNode, renderer) {
return new Promise(function (resolve, reject) {
var sphere = arsphere_1.ARSphere.create(options, renderer);
ARState.shapes.set(sphere.id, sphere);
parentNode.addChildNode(sphere.ios);
resolve(sphere);
});
};
var addTube = function (options, parentNode, renderer) {
return new Promise(function (resolve, reject) {
var tube = artube_1.ARTube.create(options, renderer);
ARState.shapes.set(tube.id, tube);
parentNode.addChildNode(tube.ios);
resolve(tube);
});
};
var AR = (function (_super) {
__extends(AR, _super);
function AR() {
return _super !== null && _super.apply(this, arguments) || this;
}
AR.isSupported = function () {
try {
return !!ARSCNView && NSProcessInfo.processInfo.environment.objectForKey("SIMULATOR_DEVICE_NAME") === null;
}
catch (ignore) {
return false;
}
};
AR.isImageTrackingSupported = function () {
try {
return !!ARImageTrackingConfiguration && ARImageTrackingConfiguration.isSupported;
}
catch (ignore) {
return false;
}
};
AR.isFaceTrackingSupported = function () {
try {
return !!ARFaceTrackingConfiguration && ARFaceTrackingConfiguration.isSupported;
}
catch (ignore) {
return false;
}
};
AR.prototype.setDebugLevel = function (to) {
if (!this.sceneView) {
return;
}
if (to === "WORLD_ORIGIN") {
this.sceneView.debugOptions = ARSCNDebugOptionShowWorldOrigin;
}
else if (to === "FEATURE_POINTS") {
this.sceneView.debugOptions = ARSCNDebugOptionShowFeaturePoints;
}
else if (to === "PHYSICS_SHAPES") {
this.sceneView.debugOptions = 1;
}
else {
this.sceneView.debugOptions = 0;
}
};
AR.prototype.grabScreenshot = function () {
var _this = this;
return new Promise(function (resolve, reject) {
if (_this.sceneView) {
resolve(image_source_1.fromNativeSource(_this.sceneView.snapshot()));
return;
}
reject("sceneView is not available");
});
};
AR.prototype.startRecordingVideo = function () {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.recorder) {
_this.recorder = RecordAR.alloc().initWithARSceneKit(_this.sceneView);
}
if (_this.recorder.status === 1) {
_this.recorder.record();
resolve();
}
else {
reject();
}
});
};
AR.prototype.stopRecordingVideo = function () {
var _this = this;
return new Promise(function (resolve, reject) {
_this.recorder.stop(function (nsUrl) { return resolve(nsUrl.absoluteString); });
});
};
AR.prototype.toggleStatistics = function (on) {
if (!this.sceneView) {
return;
}
this.sceneView.showsStatistics = !!on;
};
AR.prototype.setPlaneDetection = function (to) {
if (!this.sceneView) {
return;
}
var arPlaneDetection = 0;
if (to === "HORIZONTAL") {
arPlaneDetection = 1;
}
else if (to === "VERTICAL") {
arPlaneDetection = 2;
}
var config = this.configuration;
config.planeDetection = arPlaneDetection;
if (sdkVersion() >= 13) {
try {
config.frameSemantics = 3;
}
catch (ignore) {
}
}
if (this.sceneView.session.configuration) {
this.sceneView.session.runWithConfiguration(config);
}
};
AR.prototype.togglePlaneVisibility = function (on) {
var _this = this;
var material = armaterialfactory_1.ARMaterialFactory.getMaterial(this.planeMaterial);
ARState.planes.forEach(function (plane) {
plane.setMaterial(material, on ? _this.planeOpacity : 0);
});
};
AR.prototype.getCameraPosition = function () {
var p = this.sceneView.defaultCameraController.pointOfView.worldPosition;
return { x: p.x, y: p.y, z: p.z };
};
AR.prototype.getCameraRotationRad = function () {
var rot = this.sceneView.defaultCameraController.pointOfView.eulerAngles;
return { x: rot.x, y: rot.y, z: rot.z };
};
AR.prototype.getCameraRotation = function () {
var rot = this.getCameraRotationRad();
var toDeg = function (rad) {
return ((rad * (180.0 / Math.PI)) + 360) % 360;
};
return { x: toDeg(rot.x), y: toDeg(rot.y), z: toDeg(rot.z) };
};
AR.prototype.initAR = function () {
var _this = this;
if (!AR.isSupported()) {
console.log("############### AR is not supported on this device.");
return;
}
if (this.trackingMode === "IMAGE") {
if (!AR.isImageTrackingSupported()) {
console.log("############### Image tracking is not supported on this device. It's probably not running iOS 12+.");
return;
}
var imageTrackingConfig = ARImageTrackingConfiguration.new();
if (this.trackingImagesBundle) {
var trackingImages = ARReferenceImage.referenceImagesInGroupNamedBundle(this.trackingImagesBundle, null);
if (!trackingImages) {
console.log("Could not load images from bundle!");
return;
}
imageTrackingConfig.trackingImages = trackingImages;
imageTrackingConfig.maximumNumberOfTrackedImages = Math.min(trackingImages.count, 50);
}
this.configuration = imageTrackingConfig;
}
else if (this.trackingMode === "FACE") {
if (!AR.isFaceTrackingSupported()) {
console.log("############### Face tracking is not supported on this device. A device running iOS 12+ is required, with a front-facing TrueDepth camera.");
return;
}
this.configuration = ARFaceTrackingConfiguration.new();
}
else {
this.configuration = ARWorldTrackingConfiguration.new();
}
this.sceneView = ARSCNView.new();
this.sceneView.delegate = this.delegate = ARSCNViewDelegateImpl.createWithOwnerResultCallbackAndOptions(new WeakRef(this), function (data) {
}, {});
this.toggleStatistics(this.showStatistics);
this.sceneView.autoenablesDefaultLighting = true;
this.sceneView.automaticallyUpdatesLighting = true;
this.sceneView.scene.rootNode.name = "root";
var scene = SCNScene.new();
this.sceneView.scene = scene;
if (this.trackingMode === "WORLD") {
this.setPlaneDetection(this.planeDetection);
this.addBottomPlane(scene);
}
this.configuration.lightEstimationEnabled = true;
this.sceneView.session.runWithConfiguration(this.configuration);
this.sceneTapHandler = SceneTapHandlerImpl.initWithOwner(new WeakRef(this));
var tapGestureRecognizer = UITapGestureRecognizer.alloc().initWithTargetAction(this.sceneTapHandler, "tap");
tapGestureRecognizer.numberOfTapsRequired = 1;
this.sceneView.addGestureRecognizer(tapGestureRecognizer);
this.sceneLongPressHandler = SceneLongPressHandlerImpl.initWithOwner(new WeakRef(this));
var longPressGestureRecognizer = UILongPressGestureRecognizer.alloc().initWithTargetAction(this.sceneLongPressHandler, "longpress");
longPressGestureRecognizer.minimumPressDuration = 0.5;
this.sceneView.addGestureRecognizer(longPressGestureRecognizer);
this.scenePanHandler = ScenePanHandlerImpl.initWithOwner(new WeakRef(this));
var panGestureRecognizer = UIPanGestureRecognizer.alloc().initWithTargetAction(this.scenePanHandler, "pan");
panGestureRecognizer.minimumNumberOfTouches = 1;
this.sceneView.addGestureRecognizer(panGestureRecognizer);
this.sceneRotationHandler = SceneRotationHandlerImpl.initWithOwner(new WeakRef(this));
var rotationGestureRecognizer = UIRotationGestureRecognizer.alloc().initWithTargetAction(this.sceneRotationHandler, "rotate");
this.sceneView.addGestureRecognizer(rotationGestureRecognizer);
this.scenePinchHandler = ScenePinchHandlerImpl.initWithOwner(new WeakRef(this));
var pinchGestureRecognizer = UIPinchGestureRecognizer.alloc().initWithTargetAction(this.scenePinchHandler, "pinch");
this.sceneView.addGestureRecognizer(pinchGestureRecognizer);
this.sceneView.antialiasingMode = 2;
setTimeout(function () {
_this.nativeView.addSubview(_this.sceneView);
var eventData = {
eventName: ar_common_1.AR.arLoadedEvent,
object: _this,
ios: _this.sceneView
};
_this.notify(eventData);
});
};
AR.prototype.resolveParentNode = function (options) {
if (options.parentNode && options.parentNode.ios) {
return options.parentNode.ios;
}
return this.sceneView.scene.rootNode;
};
AR.prototype.addBottomPlane = function (scene) {
var bottomPlane = SCNBox.boxWithWidthHeightLengthChamferRadius(1000, 0.5, 1000, 0);
var bottomMaterial = SCNMaterial.new();
bottomMaterial.diffuse.contents = UIColor.colorWithWhiteAlpha(1.0, 0.0);
var materialArray = NSMutableArray.alloc().initWithCapacity(6);
materialArray.addObject(bottomMaterial);
bottomPlane.materials = materialArray;
var bottomNode = SCNNode.nodeWithGeometry(bottomPlane);
bottomNode.position = new ar_common_1.ARPosition(0, -25, 0);
bottomNode.physicsBody = SCNPhysicsBody.bodyWithTypeShape(2, null);
bottomNode.physicsBody.categoryBitMask = 0;
bottomNode.physicsBody.contactTestBitMask = 1;
scene.rootNode.addChildNode(bottomNode);
scene.physicsWorld.contactDelegate = this.physicsWorldContactDelegate = SCNPhysicsContactDelegateImpl.createWithOwner(new WeakRef(this));
};
AR.prototype.createNativeView = function () {
var v = _super.prototype.createNativeView.call(this);
this.initAR();
return v;
};
AR.prototype.onLayout = function (left, top, right, bottom) {
_super.prototype.onLayout.call(this, left, top, right, bottom);
if (this.sceneView) {
this.sceneView.layer.frame = this.ios.layer.bounds;
}
};
AR.prototype.sceneLongPressed = function (recognizer) {
if (recognizer.state !== 1) {
return;
}
var tapPoint = recognizer.locationInView(this.sceneView);
var hitTestResults = this.sceneView.hitTestOptions(tapPoint, {
SCNHitTestBoundingBoxOnlyKey: true,
SCNHitTestFirstFoundOnlyKey: true
});
if (hitTestResults.count === 0) {
return;
}
var hitResult = hitTestResults.firstObject;
var savedModel = this.getTargetARNodeFromSCNNode(hitResult.node, "onLongPress");
if (savedModel) {
savedModel.onLongPress({
x: tapPoint.x,
y: tapPoint.y
});
}
};
AR.prototype.getHitTargetWithProperty = function (position, property) {
var hitTestResults = this.sceneView.hitTestOptions(position, NSDictionary.dictionaryWithDictionary({
SCNHitTestBoundingBoxOnlyKey: false,
SCNHitTestFirstFoundOnlyKey: false
}));
if (hitTestResults.count === 0) {
return undefined;
}
var i = 0;
var savedModel = null;
while (hitTestResults.count > i) {
savedModel = this.getTargetARNodeFromSCNNode(hitTestResults.objectAtIndex(i).node);
if (savedModel && (!!savedModel[property])) {
return savedModel;
}
i++;
}
return undefined;
};
AR.prototype.getTargetARNodeFromSCNNode = function (node, functionName) {
if (!(node && node.name)) {
return undefined;
}
var shape = ARState.shapes.get(node.name);
if (shape && (!functionName || shape[functionName])) {
return shape;
}
return node.parentNode ? this.getTargetARNodeFromSCNNode(node.parentNode, functionName) : undefined;
};
AR.prototype.scenePanned = function (recognizer) {
var state = recognizer.state;
if (state === 5 || state === 4) {
return;
}
var position = recognizer.locationInView(null);
var translation = recognizer.translationInView(null);
if (state === 1) {
this.lastPositionForPanning = position;
var savedModel = this.getHitTargetWithProperty(position, "draggingEnabled");
if (savedModel) {
this.targetNodeForPanning = savedModel;
this.targetNodeInitialPan = this.targetNodeForPanning.getWorldPosition();
}
else {
this.targetNodeForPanning = undefined;
}
}
else if (this.targetNodeForPanning) {
if (state === 2) {
var pixelsPerMeter = 700;
var node = SCNNode.node();
node.position = this.sceneView.defaultCameraController.pointOfView.convertPositionToNode({
x: (translation.x / pixelsPerMeter),
y: -(translation.y / pixelsPerMeter),
z: 0
}, null);
node.rotation = this.sceneView.defaultCameraController.pointOfView.rotation;
var p = node.worldPosition;
var cp = this.sceneView.defaultCameraController.pointOfView.worldPosition;
var pos = this.targetNodeInitialPan;
this.targetNodeForPanning.setWorldPosition({
x: pos.x + p.x - cp.x, y: pos.y + p.y - cp.y, z: pos.z + p.z - cp.z
});
}
else if (state === 3) {
this.targetNodeForPanning = undefined;
}
}
};
AR.prototype.sceneRotated = function (recognizer) {
var state = recognizer.state;
if (state === 5 || state === 4) {
return;
}
var position = recognizer.locationInView(this.sceneView);
if (state === 1) {
var savedModel = this.getHitTargetWithProperty(position, "rotatingEnabled");
if (savedModel && savedModel.ios) {
this.targetNodeForRotating = savedModel.ios;
}
else {
this.targetNodeForRotating = undefined;
}
}
else if (this.targetNodeForRotating) {
if (state === 2) {
var previousAngles = this.targetNodeForRotating.eulerAngles;
this.targetNodeForRotating.eulerAngles = {
x: previousAngles.x,
y: previousAngles.y - recognizer.rotation,
z: previousAngles.z
};
recognizer.rotation = 0;
}
else if (state === 3) {
this.targetNodeForRotating = undefined;
}
}
};
AR.prototype.scenePinched = function (recognizer) {
var state = recognizer.state;
if (state === 5 || state === 4) {
return;
}
var position = recognizer.locationInView(this.sceneView);
if (state === 1) {
var savedModel = this.getHitTargetWithProperty(position, "scalingEnabled");
if (savedModel && savedModel.ios) {
this.targetNodeForScaling = savedModel.ios;
this.targetNodeInitialScale = this.targetNodeForScaling.scale;
}
else {
this.targetNodeForScaling = undefined;
}
}
else if (this.targetNodeForScaling) {
if (state === 2) {
this.targetNodeForScaling.scale = {
x: this.targetNodeInitialScale.x * recognizer.scale,
y: this.targetNodeInitialScale.y * recognizer.scale,
z: this.targetNodeInitialScale.z * recognizer.scale
};
}
else if (state === 3) {
this.targetNodeForScaling = undefined;
}
}
};
AR.prototype.sceneTapped = function (recognizer) {
var sceneView = recognizer.view;
var tapPoint = recognizer.locationInView(sceneView);
var hitTestResults = sceneView.hitTestOptions(tapPoint, null);
if (hitTestResults.count === 0) {
var eventData = {
eventName: ar_common_1.AR.sceneTappedEvent,
object: this,
position: {
x: tapPoint.x,
y: tapPoint.y,
z: 0
}
};
this.notify(eventData);
return;
}
var hitResult = hitTestResults.firstObject;
var node = hitResult.node;
if (node !== undefined) {
var savedModel = this.getTargetARNodeFromSCNNode(node, "onTap");
if (savedModel !== undefined) {
savedModel.onTap({
x: tapPoint.x,
y: tapPoint.y
});
return;
}
}
var planeTapResults = this.sceneView.hitTestTypes(tapPoint, 16);
if (planeTapResults.count > 0) {
var planeHitResult = planeTapResults.firstObject;
var hitResultStr = "" + planeHitResult;
var transformStart = hitResultStr.indexOf("worldTransform=<translation=(") + "worldTransform=<translation=(".length;
var transformStr = hitResultStr.substring(transformStart, hitResultStr.indexOf(")", transformStart));
var transformParts = transformStr.split(" ");
var eventData = {
eventName: ar_common_1.AR.planeTappedEvent,
object: this,
position: {
x: +transformParts[0],
y: +transformParts[1],
z: +transformParts[2]
}
};
this.notify(eventData);
}
};
AR.prototype.addUIView = function (options) {
return addUIView(options, this.resolveParentNode(options), this.sceneView, this.renderer);
};
AR.prototype.addNode = function (options) {
return addNode(options, this.resolveParentNode(options), this.renderer);
};
AR.prototype.addVideo = function (options) {
return addVideo(options, this.resolveParentNode(options), this.renderer);
};
AR.prototype.addImage = function (options) {
return addImage(options, this.resolveParentNode(options), this.renderer);
};
AR.prototype.addModel = function (options) {
return addModel(options, this.resolveParentNode(options), this.renderer);
};
AR.prototype.addPlane = function (options) {
return addPlane(options, this.resolveParentNode(options));
};
AR.prototype.addBox = function (options) {
return addBox(options, this.resolveParentNode(options), this.renderer);
};
AR.prototype.addSphere = function (options) {
return addSphere(options, this.resolveParentNode(options), this.renderer);
};
AR.prototype.addText = function (options) {
return addText(options, this.resolveParentNode(options), this.renderer);
};
AR.prototype.addTube = function (options) {
return addTube(options, this.resolveParentNode(options), this.renderer);
};
AR.prototype.trackImage = function (options) {
var set;
if (this.configuration instanceof ARImageTrackingConfiguration) {
set = NSMutableSet.setWithSet(this.configuration.trackingImages);
this.configuration.trackingImages = set;
}
else if (this.configuration instanceof ARWorldTrackingConfiguration) {
set = NSMutableSet.setWithSet(this.configuration.detectionImages);
this.configuration.detectionImages = set;
}
else {
throw "'trackImage' is only supported with trackingMode: IMAGE";
}
var name = options.name || options.image.split('/').pop().split('.').slice(0, -1).join('.');
var img;
if (options.image.indexOf('://') > 0) {
img = UIImage.imageWithData(NSData.alloc().initWithContentsOfURL(NSURL.URLWithString(options.image)));
}
else {
img = UIImage.imageNamed(options.image);
}
var refImage = ARReferenceImage.alloc().initWithCGImageOrientationPhysicalWidth(img.CGImage, 1, options.width || 1);
refImage.name = name;
set.addObject(refImage);
this.configuration.maximumNumberOfTrackedImages = Math.min(set.count, 50);
this.sceneView.session.runWithConfigurationOptions(this.configuration, 1 | 2);
if (!options.onDetectedImage) {
return;
}
this.on(ar_common_1.AR.trackingImageDetectedEvent, function (args) {
if (args.imageName === name) {
options.onDetectedImage(args);
}
});
};
AR.prototype.reset = function () {
this.configuration.planeDetection = 1;
this.sceneView.session.runWithConfigurationOptions(this.configuration, 1 | 2);
ARState.planes.forEach(function (plane) { return plane.remove(); });
ARState.planes.clear();
ARState.shapes.forEach(function (node) { return node.remove(); });
ARState.shapes.clear();
};
return AR;
}(ar_common_1.AR));
exports.AR = AR;
var ScenePinchHandlerImpl = (function (_super) {
__extends(ScenePinchHandlerImpl, _super);
function ScenePinchHandlerImpl() {
return _super !== null && _super.apply(this, arguments) || this;
}
ScenePinchHandlerImpl.initWithOwner = function (owner) {
var handler = ScenePinchHandlerImpl.new();
handler._owner = owner;
return handler;
};
ScenePinchHandlerImpl.prototype.pinch = function (args) {
this._owner.get().scenePinched(args);
};
ScenePinchHandlerImpl.ObjCExposedMethods = {
"pinch": { returns: interop.types.void, params: [interop.types.id] }
};
return ScenePinchHandlerImpl;
}(NSObject));
var SceneTapHandlerImpl = (function (_super) {
__extends(SceneTapHandlerImpl, _super);
function SceneTapHandlerImpl() {
return _super !== null && _super.apply(this, arguments) || this;
}
SceneTapHandlerImpl.initWithOwner = function (owner) {
var handler = SceneTapHandlerImpl.new();
handler._owner = owner;
return handler;
};
SceneTapHandlerImpl.prototype.tap = function (args) {
this._owner.get().sceneTapped(args);
};
SceneTapHandlerImpl.ObjCExposedMethods = {
"tap": { returns: interop.types.void, params: [interop.types.id] }
};
return SceneTapHandlerImpl;
}(NSObject));
var SceneLongPressHandlerImpl = (function (_super) {
__extends(SceneLongPressHandlerImpl, _super);
function SceneLongPressHandlerImpl() {
return _super !== null && _super.apply(this, arguments) || this;
}
SceneLongPressHandlerImpl.initWithOwner = function (owner) {
var handler = SceneLongPressHandlerImpl.new();
handler._owner = owner;
return handler;
};
SceneLongPressHandlerImpl.prototype.longpress = function (args) {
this._owner.get().sceneLongPressed(args);
};
SceneLongPressHandlerImpl.ObjCExposedMethods = {
"longpress": { returns: interop.types.void, params: [interop.types.id] }
};
return SceneLongPressHandlerImpl;
}(NSObject));
var ScenePanHandlerImpl = (function (_super) {
__extends(ScenePanHandlerImpl, _super);
function ScenePanHandlerImpl() {
return _super !== null && _super.apply(this, arguments) || this;
}
ScenePanHandlerImpl.initWithOwner = function (owner) {
var handler = ScenePanHandlerImpl.new();
handler._owner = owner;
return handler;
};
ScenePanHandlerImpl.prototype.pan = function (args) {
this._owner.get().scenePanned(args);
};
ScenePanHandlerImpl.ObjCExposedMethods = {
"pan": { returns: interop.types.void, params: [interop.types.id] }
};
return ScenePanHandlerImpl;
}(NSObject));
var SceneRotationHandlerImpl = (function (_super) {
__extends(SceneRotationHandlerImpl, _super);
function SceneRotationHandlerImpl() {
return _super !== null && _super.apply(this, arguments) || this;
}
SceneRotationHandlerImpl.initWithOwner = function (owner) {
var handler = SceneRotationHandlerImpl.new();
handler._owner = owner;
return handler;
};
SceneRotationHandlerImpl.prototype.rotate = function (args) {
this._owner.get().sceneRotated(args);
};
SceneRotationHandlerImpl.ObjCExposedMethods = {
"rotate": { returns: interop.types.void, params: [interop.types.id] }
};
return SceneRotationHandlerImpl;
}(NSObject));
var ARSCNViewDelegateImpl = (function (_super) {
__extends(ARSCNViewDelegateImpl, _super);
function ARSCNViewDelegateImpl() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.currentTrackingState = 2;
_this.hasFace = false;
return _this;
}
ARSCNViewDelegateImpl.new = function () {
try {
ARSCNViewDelegateImpl.ObjCProtocols.push(ARSCNViewDelegate);
}
catch (ignore) {
}
return _super.new.call(this);
};
ARSCNViewDelegateImpl.createWithOwnerResultCallbackAndOptions = function (owner, callback, options) {
var delegate = ARSCNViewDelegateImpl.new();
delegate.owner = owner;
delegate.options = options;
delegate.resultCallback = callback;
return delegate;
};
ARSCNViewDelegateImpl.prototype.sessionDidFailWithError = function (session, error) {
console.log(">>> sessionDidFailWithError: " + error);
};
ARSCNViewDelegateImpl.prototype.sessionWasInterrupted = function (session) {
console.log(">>> sessionWasInterrupted: The tracking session has been interrupted. The session will be reset once the interruption has completed");
};
ARSCNViewDelegateImpl.prototype.sessionInterruptionEnded = function (session) {
console.log(">>> sessionInterruptionEnded, calling reset");
this.owner.get().reset();
};
ARSCNViewDelegateImpl.prototype.sessionCameraDidChangeTrackingState = function (session, camera) {
if (this.currentTrackingState === camera.trackingState) {
return;
}
this.currentTrackingState = camera.trackingState;
var trackingState = null, limitedTrackingStateReason = null;
if (camera.trackingState === 0) {
trackingState = "Not available";
}
else if (camera.trackingState === 1) {
trackingState = "Limited";
var reason = camera.trackingStateReason;
if (reason === 2) {
limitedTrackingStateReason = "Excessive motion";
}
else if (reason === 3) {
limitedTrackingStateReason = "Insufficient features";
}
else if (reason === 1) {
limitedTrackingStateReason = "Initializing";
}
else if (reason === 0) {
limitedTrackingStateReason = "None";
}
}
else if (camera.trackingState === 2) {
trackingState = "Normal";
}
if (trackingState !== null) {
console.log("Tracking state changed to: " + trackingState);
if (limitedTrackingStateReason !== null) {
console.log("Limited tracking state reason: " + limitedTrackingStateReason);
}
}
};
ARSCNViewDelegateImpl.prototype.rendererDidAddNodeForAnchor = function (renderer, node, anchor) {
this.owner.get().renderer = renderer;
if (anchor instanceof ARPlaneAnchor) {
var owner = this.owner.get();
var plane = arplane_1.ARPlane.create(anchor, owner.planeOpacity, armaterialfactory_1.ARMaterialFactory.getMaterial(owner.planeMaterial));
ARState.planes.set(anchor.identifier.UUIDString, plane);
node.addChildNode(plane.ios);
var eventData = {
eventName: ar_common_1.AR.planeDetectedEvent,
object: owner,
plane: plane
};
owner.notify(eventData);
}
};
ARSCNViewDelegateImpl.prototype.rendererDidUpdateNodeForAnchor = function (renderer, node, anchor) {
if (anchor instanceof ARPlaneAnchor) {
var plane = ARState.planes.get(anchor.identifier.UUIDString);
if (plane) {
plane.update(anchor);
}
return;
}
var owner = this.owner.get();
if (!(anchor instanceof ARFaceAnchor)) {
if (this.hasFace) {
this.hasFace = false;
owner.notify({
eventName: ar_common_1.AR.trackingFaceDetectedEvent,
object: owner,
eventType: "LOST"
});
}
return;
}
var faceAnchor = anchor;
var eventType = "UPDATED";
if (!this.hasFace) {
this.hasFace = true;
owner.reset();
eventType = "FOUND";
}
var faceGeometry;
if (this.occlusionNode) {
faceGeometry = this.occlusionNode.geometry;
}
else {
faceGeometry = node.geometry;
}
if (faceGeometry) {
var faceAnchor_1 = anchor;
faceGeometry.updateFromFaceGeometry(faceAnchor_1.geometry);
}
var blendShapes = faceAnchor.blendShapes;
var eventData = {
eventName: ar_common_1.AR.trackingFaceDetectedEvent,
object: owner,
eventType: eventType,
properties: {
eyeBlinkLeft: blendShapes.valueForKey(ARBlendShapeLocationEyeBlinkLeft),
eyeBlinkRight: blendShapes.valueForKey(ARBlendShapeLocationEyeBlinkRight),
jawOpen: blendShapes.valueForKey(ARBlendShapeLocationJawOpen),
lookAtPoint: {
x: faceAnchor.lookAtPoint[0],
y: faceAnchor.lookAtPoint[1],
z: faceAnchor.lookAtPoint[2]
},
mouthFunnel: blendShapes.valueForKey(ARBlendShapeLocationMouthFunnel),
mouthSmileLeft: blendShapes.valueForKey(ARBlendShapeLocationMouthSmileLeft),
mouthSmileRight: blendShapes.valueForKey(ARBlendShapeLocationMouthSmileRight),
tongueOut: blendShapes.valueForKey(ARBlendShapeLocationTongueOut)
}
};
dispatch_async(main_queue, function () { return owner.notify(eventData); });
};
ARSCNViewDelegateImpl.prototype.rendererDidRemoveNodeForAnchor = function (renderer, node, anchor) {
ARState.planes.delete(anchor.identifier.UUIDString);
};
ARSCNViewDelegateImpl.prototype.rendererNodeForAnchor = function (renderer, anchor) {
var node = SCNNode.new();
var owner = this.owner.get();
var sceneViewRenderer = renderer;
if (anchor instanceof ARFaceAnchor) {
var faceGeometry = void 0;
if (owner.faceMaterial) {
faceGeometry = ARSCNFaceGeometry.faceGeometryWithDevice(sceneViewRenderer.device);
var material = faceGeometry.firstMaterial;
material.colorBufferWriteMask = 15;
material.diffuse.contents = owner.faceMaterial;
material.lightingModelName = SCNLightingModelPhysicallyBased;
node.addChildNode(SCNNode.nodeWithGeometry(faceGeometry));
}
else {
faceGeometry = ARSCNFaceGeometry.faceGeometryWithDeviceFillMesh(sceneViewRenderer.device, true);
if (faceGeometry) {
faceGeometry.firstMaterial.colorBufferWriteMask = 0;
}
}
this.occlusionNode = SCNNode.nodeWithGeometry(faceGeometry);
this.occlusionNode.renderingOrder = -1;
node.addChildNode(this.occlusionNode);
var eventData_1 = {
eventName: ar_common_1.AR.trackingFaceDetectedEvent,
object: owner,
eventType: "FOUND",
faceTrackingActions: new ARFaceTrackingActionsImpl(renderer, anchor, node, this, owner.sceneView)
};
dispatch_async(main_queue, function () { return owner.notify(eventData_1); });
}
if (!(anchor instanceof ARImageAnchor)) {
return node;
}
var imageAnchor = anchor;
var plane = SCNPlane.planeWithWidthHeight(imageAnchor.referenceImage.physicalSize.width, imageAnchor.referenceImage.physicalSize.height);
var planeNode = SCNNode.nodeWithGeometry(plane);
planeNode.eulerAngles = {
x: -3.14159265359 / 2,
y: 0,
z: 0
};
planeNode.renderingOrder = -1;
planeNode.opacity = 1;
plane.firstMaterial.diffuse.contents = UIColor.colorWithWhiteAlpha(1, 0);
var eventData = {
eventName: ar_common_1.AR.trackingImageDetectedEvent,
object: owner,
position: planeNode.position,
size: imageAnchor.referenceImage.physicalSize,
imageName: imageAnchor.referenceImage.name,
imageTrackingActions: new ARImageTrackingActionsImpl(plane, planeNode, owner.sceneView, renderer)
};
dispatch_async(main_queue, function () { return owner.notify(eventData); });
node.addChildNode(planeNode);
return node;
};
ARSCNViewDelegateImpl.ObjCProtocols = [];
return ARSCNViewDelegateImpl;
}(NSObject));
var ARImageTrackingActionsImpl = (function () {
function ARImageTrackingActionsImpl(plane, planeNode, sceneView, renderer) {
this.plane = plane;
this.planeNode = planeNode;
this.sceneView = sceneView;
this.renderer = renderer;
}
ARImageTrackingActionsImpl.prototype.playVideo = function (url, loop) {
var videoPlayer = AVPlayer.playerWithURL(NSURL.URLWithString(url));
this.plane.firstMaterial.diffuse.contents = videoPlayer;
if (loop === true) {
this.AVPlayerItemDidPlayToEndTimeNotificationObserver = application.ios.addNotificationObserver(AVPlayerItemDidPlayToEndTimeNotification, function (notification) {
if (videoPlayer.currentItem && videoPlayer.currentItem === notification.object) {
videoPlayer.seekToTime(CMTimeMake(5, 100));
videoPlayer.play();
}
});
}
videoPlayer.play();
};
ARImageTrackingActionsImpl.prototype.stopVideoLoop = function () {
if (this.AVPlayerItemDidPlayToEndTimeNotificationObserver) {
application.ios.removeNotificationObserver(this.AVPlayerItemDidPlayToEndTimeNotificationObserver, AVPlayerItemDidPlayToEndTimeNotification);
this.AVPlayerItemDidPlayToEndTimeNotificationObserver = undefined;
}
};
ARImageTrackingActionsImpl.prototype.addBox = function (options) {
return addBox(options, this.planeNode, this.renderer);
};
ARImageTrackingActionsImpl.prototype.addModel = function (options) {
return addModel(options, this.planeNode, this.renderer);
};
ARImageTrackingActionsImpl.prototype.addImage = function (options) {
return addImage(options, this.planeNode, this.renderer);
};
ARImageTrackingActionsImpl.prototype.addUIView = function (options) {
return addUIView(options, this.planeNode, this.sceneView, this.renderer);
};
ARImageTrackingActionsImpl.prototype.addNode = function (options) {
return addNode(options, this.planeNode, this.renderer);
};
return ARImageTrackingActionsImpl;
}());
var ARFaceTrackingActionsImpl = (function () {
function ARFaceTrackingActionsImpl(renderer, anchor, node, owner, sceneView) {
this.renderer = renderer;
this.anchor = anchor;
this.node = node;
this.owner = owner;
this.sceneView = sceneView;
}
ARFaceTrackingActionsImpl.prototype.addModel = function (options) {
return addModel(options, this.node, this.renderer);
};
ARFaceTrackingActionsImpl.prototype.addText = function (options) {
return addText(options, this.node, this.renderer);
};
ARFaceTrackingActionsImpl.prototype.addUIView = function (options) {
return addUIView(options, this.node, this.sceneView, this.renderer);
};
return ARFaceTrackingActionsImpl;
}());
var ARSessionDelegateImpl = (function (_super) {
__extends(ARSessionDelegateImpl, _super);
function ARSessionDelegateImpl() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.currentTrackingState = 2;
return _this;
}
ARSessionDelegateImpl.new = function () {
try {
ARSessionDelegateImpl.ObjCProtocols.push(ARSessionDelegate);
}
catch (ignore) {
}
return _super.new.call(this);
};
ARSessionDelegateImpl.createWithOwnerResultCallbackAndOptions = function (owner, callback, options) {
var delegate = ARSessionDelegateImpl.new();
delegate.owner = owner;
delegate.options = options;
delegate.resultCallback = callback;
return delegate;
};
ARSessionDelegateImpl.prototype.sessionDidUpdateFrame = function (session, frame) {
console.log("frame updated @ " + new Date().getTime());
};
ARSessionDelegateImpl.ObjCProtocols = [];
return ARSessionDelegateImpl;
}(NSObject));
var SCNPhysicsContactDelegateImpl = (function (_super) {
__extends(SCNPhysicsContactDelegateImpl, _super);
function SCNPhysicsContactDelegateImpl() {
return _super !== null && _super.apply(this, arguments) || this;
}
SCNPhysicsContactDelegateImpl.new = function () {
return _super.new.call(this);
};
SCNPhysicsContactDelegateImpl.createWithOwner = function (owner) {
var delegate = SCNPhysicsContactDelegateImpl.new();
delegate.owner = owner;
return delegate;
};
SCNPhysicsContactDelegateImpl.prototype.physicsWorldDidBeginContact = function (world, contact) {
var contactMask = contact.nodeA.physicsBody.categoryBitMask | contact.nodeB.physicsBody.categoryBitMask;
if (contactMask === (0 | 1)) {
if (contact.nodeA.physicsBody.categoryBitMask === 0) {
contact.nodeB.removeFromParentNode();
}
else {
contact.nodeA.removeFromParentNode();
}
}
};
SCNPhysicsContactDelegateImpl.prototype.physicsWorldDidEndContact = function (world, contact) {
};
SCNPhysicsContactDelegateImpl.prototype.physicsWorldDidUpdateContact = function (world, contact) {
};
SCNPhysicsContactDelegateImpl.ObjCProtocols = [SCNPhysicsContactDelegate];
return SCNPhysicsContactDelegateImpl;
}(NSObject));