Added `EnvironmentTexturing` sample (#363)

This commit is contained in:
Mykyta Bondarenko 2019-02-07 08:10:58 +02:00 коммит произвёл Craig Dunn
Родитель 1599c1c26a
Коммит 71c2cb8fb2
40 изменённых файлов: 1541 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,23 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvironmentTexturing", "EnvironmentTexturing\EnvironmentTexturing.csproj", "{F47366FC-B94E-4A0D-8C5C-1E96A4B51BC2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|iPhoneSimulator = Debug|iPhoneSimulator
Release|iPhone = Release|iPhone
Release|iPhoneSimulator = Release|iPhoneSimulator
Debug|iPhone = Debug|iPhone
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F47366FC-B94E-4A0D-8C5C-1E96A4B51BC2}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{F47366FC-B94E-4A0D-8C5C-1E96A4B51BC2}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{F47366FC-B94E-4A0D-8C5C-1E96A4B51BC2}.Release|iPhone.ActiveCfg = Release|iPhone
{F47366FC-B94E-4A0D-8C5C-1E96A4B51BC2}.Release|iPhone.Build.0 = Release|iPhone
{F47366FC-B94E-4A0D-8C5C-1E96A4B51BC2}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{F47366FC-B94E-4A0D-8C5C-1E96A4B51BC2}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{F47366FC-B94E-4A0D-8C5C-1E96A4B51BC2}.Debug|iPhone.ActiveCfg = Debug|iPhone
{F47366FC-B94E-4A0D-8C5C-1E96A4B51BC2}.Debug|iPhone.Build.0 = Debug|iPhone
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,29 @@
using ARKit;
using Foundation;
using System;
using UIKit;
namespace EnvironmentTexturing
{
[Register("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
public override UIWindow Window { get; set; }
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
if (!ARConfiguration.IsSupported)
{
throw new NotSupportedException("ARKit is not available on this device.For apps that require ARKit " +
"for core functionality, use the `arkit` key in the key in the " +
"`UIRequiredDeviceCapabilities` section of the Info.plist to prevent " +
"the app from installing. (If the app can't be installed, this error " +
"can't be triggered in a production scenario.) " +
"In apps where AR is an additive feature, use `isSupported` to " +
"determine whether to show UI for launching AR experiences"); // For details, see https://developer.apple.com/documentation/arkit
}
return true;
}
}
}

Просмотреть файл

@ -0,0 +1,247 @@
{
"images": [
{
"filename": "NotificationIcon@2x.png",
"size": "20x20",
"scale": "2x",
"idiom": "iphone"
},
{
"filename": "NotificationIcon@3x.png",
"size": "20x20",
"scale": "3x",
"idiom": "iphone"
},
{
"filename": "Icon-Small@2x.png",
"size": "29x29",
"scale": "2x",
"idiom": "iphone"
},
{
"filename": "Icon-Small@3x.png",
"size": "29x29",
"scale": "3x",
"idiom": "iphone"
},
{
"filename": "Icon-40@2x.png",
"size": "40x40",
"scale": "2x",
"idiom": "iphone"
},
{
"filename": "Icon-40@3x.png",
"size": "40x40",
"scale": "3x",
"idiom": "iphone"
},
{
"filename": "Icon-60@2x.png",
"size": "60x60",
"scale": "2x",
"idiom": "iphone"
},
{
"filename": "Icon-60@3x.png",
"size": "60x60",
"scale": "3x",
"idiom": "iphone"
},
{
"size": "20x20",
"scale": "1x",
"idiom": "ipad"
},
{
"size": "20x20",
"scale": "2x",
"idiom": "ipad"
},
{
"filename": "Icon-Small.png",
"size": "29x29",
"scale": "1x",
"idiom": "ipad"
},
{
"filename": "Icon-Small@2x.png",
"size": "29x29",
"scale": "2x",
"idiom": "ipad"
},
{
"filename": "Icon-40.png",
"size": "40x40",
"scale": "1x",
"idiom": "ipad"
},
{
"filename": "Icon-40@2x.png",
"size": "40x40",
"scale": "2x",
"idiom": "ipad"
},
{
"filename": "Icon-83.5@2x.png",
"size": "83.5x83.5",
"scale": "2x",
"idiom": "ipad"
},
{
"filename": "Icon-76.png",
"size": "76x76",
"scale": "1x",
"idiom": "ipad"
},
{
"filename": "Icon-76@2x.png",
"size": "76x76",
"scale": "2x",
"idiom": "ipad"
},
{
"filename": "ios-marketing.png",
"size": "1024x1024",
"scale": "1x",
"idiom": "ios-marketing"
},
{
"size": "60x60",
"scale": "2x",
"idiom": "car"
},
{
"size": "60x60",
"scale": "3x",
"idiom": "car"
},
{
"role": "notificationCenter",
"size": "24x24",
"subtype": "38mm",
"scale": "2x",
"idiom": "watch"
},
{
"role": "notificationCenter",
"size": "27.5x27.5",
"subtype": "42mm",
"scale": "2x",
"idiom": "watch"
},
{
"role": "companionSettings",
"size": "29x29",
"scale": "2x",
"idiom": "watch"
},
{
"role": "companionSettings",
"size": "29x29",
"scale": "3x",
"idiom": "watch"
},
{
"role": "appLauncher",
"size": "40x40",
"subtype": "38mm",
"scale": "2x",
"idiom": "watch"
},
{
"role": "appLauncher",
"size": "44x44",
"subtype": "40mm",
"scale": "2x",
"idiom": "watch"
},
{
"role": "appLauncher",
"size": "50x50",
"subtype": "44mm",
"scale": "2x",
"idiom": "watch"
},
{
"role": "quickLook",
"size": "86x86",
"subtype": "38mm",
"scale": "2x",
"idiom": "watch"
},
{
"role": "quickLook",
"size": "98x98",
"subtype": "42mm",
"scale": "2x",
"idiom": "watch"
},
{
"role": "quickLook",
"size": "108x108",
"subtype": "44mm",
"scale": "2x",
"idiom": "watch"
},
{
"size": "1024x1024",
"scale": "1x",
"idiom": "watch-marketing"
},
{
"size": "16x16",
"scale": "1x",
"idiom": "mac"
},
{
"size": "16x16",
"scale": "2x",
"idiom": "mac"
},
{
"size": "32x32",
"scale": "1x",
"idiom": "mac"
},
{
"size": "32x32",
"scale": "2x",
"idiom": "mac"
},
{
"size": "128x128",
"scale": "1x",
"idiom": "mac"
},
{
"size": "128x128",
"scale": "2x",
"idiom": "mac"
},
{
"size": "256x256",
"scale": "1x",
"idiom": "mac"
},
{
"size": "256x256",
"scale": "2x",
"idiom": "mac"
},
{
"size": "512x512",
"scale": "1x",
"idiom": "mac"
},
{
"size": "512x512",
"scale": "2x",
"idiom": "mac"
}
],
"info": {
"version": 1,
"author": "xcode"
}
}

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.0 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.0 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 12 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 12 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 25 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 18 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 22 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.9 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.0 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 653 KiB

Просмотреть файл

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Просмотреть файл

@ -0,0 +1,95 @@
{
"images": [
{
"idiom": "universal"
},
{
"scale": "1x",
"idiom": "universal"
},
{
"filename": "refresh@2x.png",
"scale": "2x",
"idiom": "universal"
},
{
"filename": "refresh@3x.png",
"scale": "3x",
"idiom": "universal"
},
{
"idiom": "iphone"
},
{
"scale": "1x",
"idiom": "iphone"
},
{
"scale": "2x",
"idiom": "iphone"
},
{
"subtype": "retina4",
"scale": "2x",
"idiom": "iphone"
},
{
"scale": "3x",
"idiom": "iphone"
},
{
"idiom": "ipad"
},
{
"scale": "1x",
"idiom": "ipad"
},
{
"scale": "2x",
"idiom": "ipad"
},
{
"idiom": "watch"
},
{
"scale": "2x",
"idiom": "watch"
},
{
"screenWidth": "{130,145}",
"scale": "2x",
"idiom": "watch"
},
{
"screenWidth": "{146,165}",
"scale": "2x",
"idiom": "watch"
},
{
"idiom": "mac"
},
{
"scale": "1x",
"idiom": "mac"
},
{
"scale": "2x",
"idiom": "mac"
},
{
"idiom": "car"
},
{
"scale": "2x",
"idiom": "car"
},
{
"scale": "3x",
"idiom": "car"
}
],
"info": {
"version": 1,
"author": "xcode"
}
}

Двоичные данные
ios11/EnvironmentTexturing/EnvironmentTexturing/Assets.xcassets/restart.imageset/refresh@2x.png поставляемый Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.4 KiB

Двоичные данные
ios11/EnvironmentTexturing/EnvironmentTexturing/Assets.xcassets/restart.imageset/refresh@3x.png поставляемый Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.0 KiB

Просмотреть файл

@ -0,0 +1,95 @@
{
"images": [
{
"idiom": "universal"
},
{
"scale": "1x",
"idiom": "universal"
},
{
"filename": "refreshPressed@2x.png",
"scale": "2x",
"idiom": "universal"
},
{
"filename": "refreshPressed@3x.png",
"scale": "3x",
"idiom": "universal"
},
{
"idiom": "iphone"
},
{
"scale": "1x",
"idiom": "iphone"
},
{
"scale": "2x",
"idiom": "iphone"
},
{
"subtype": "retina4",
"scale": "2x",
"idiom": "iphone"
},
{
"scale": "3x",
"idiom": "iphone"
},
{
"idiom": "ipad"
},
{
"scale": "1x",
"idiom": "ipad"
},
{
"scale": "2x",
"idiom": "ipad"
},
{
"idiom": "watch"
},
{
"scale": "2x",
"idiom": "watch"
},
{
"screenWidth": "{130,145}",
"scale": "2x",
"idiom": "watch"
},
{
"screenWidth": "{146,165}",
"scale": "2x",
"idiom": "watch"
},
{
"idiom": "mac"
},
{
"scale": "1x",
"idiom": "mac"
},
{
"scale": "2x",
"idiom": "mac"
},
{
"idiom": "car"
},
{
"scale": "2x",
"idiom": "car"
},
{
"scale": "3x",
"idiom": "car"
}
],
"info": {
"version": 1,
"author": "xcode"
}
}

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 858 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.3 KiB

Просмотреть файл

@ -0,0 +1,6 @@
<?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>
</dict>
</plist>

Просмотреть файл

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
<ProjectGuid>{F47366FC-B94E-4A0D-8C5C-1E96A4B51BC2}</ProjectGuid>
<ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Exe</OutputType>
<RootNamespace>EnvironmentTexturing</RootNamespace>
<AssemblyName>EnvironmentTexturing</AssemblyName>
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
<DefineConstants>DEBUG;ENABLE_TEST_CLOUD;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchDebug>true</MtouchDebug>
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
<MtouchFastDev>true</MtouchFastDev>
<MtouchProfiling>true</MtouchProfiling>
<IOSDebuggerPort>39833</IOSDebuggerPort>
<MtouchLink>None</MtouchLink>
<MtouchArch>x86_64</MtouchArch>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhone\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchUseLlvm>true</MtouchUseLlvm>
<MtouchFloat32>true</MtouchFloat32>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchArch>ARM64</MtouchArch>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhoneSimulator\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
<MtouchLink>None</MtouchLink>
<MtouchArch>x86_64</MtouchArch>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhone\Debug</OutputPath>
<DefineConstants>DEBUG;ENABLE_TEST_CLOUD;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<DeviceSpecificBuild>true</DeviceSpecificBuild>
<MtouchDebug>true</MtouchDebug>
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
<MtouchFastDev>true</MtouchFastDev>
<MtouchProfiling>true</MtouchProfiling>
<MtouchFloat32>true</MtouchFloat32>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<IOSDebuggerPort>23417</IOSDebuggerPort>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchArch>ARM64</MtouchArch>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="Xamarin.iOS" />
</ItemGroup>
<ItemGroup>
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Contents.json" />
<ImageAsset Include="Assets.xcassets\Contents.json" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Icon-40.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Icon-40%402x.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Icon-40%403x.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Icon-60%402x.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Icon-60%403x.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Icon-76.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Icon-76%402x.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Icon-83.5%402x.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\ios-marketing.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\NotificationIcon%402x.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\NotificationIcon%403x.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Icon-Small.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Icon-Small%402x.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Icon-Small%403x.png" />
<ImageAsset Include="Assets.xcassets\restart.imageset\Contents.json" />
<ImageAsset Include="Assets.xcassets\restart.imageset\refresh%402x.png" />
<ImageAsset Include="Assets.xcassets\restart.imageset\refresh%403x.png" />
<ImageAsset Include="Assets.xcassets\restartPressed.imageset\Contents.json" />
<ImageAsset Include="Assets.xcassets\restartPressed.imageset\refreshPressed%402x.png" />
<ImageAsset Include="Assets.xcassets\restartPressed.imageset\refreshPressed%403x.png" />
</ItemGroup>
<ItemGroup>
<Folder Include="Assets.xcassets\restart.imageset\" />
<Folder Include="Assets.xcassets\restartPressed.imageset\" />
<Folder Include="art.scnassets\" />
</ItemGroup>
<ItemGroup>
<InterfaceDefinition Include="LaunchScreen.storyboard" />
<InterfaceDefinition Include="Main.storyboard" />
</ItemGroup>
<ItemGroup>
<None Include="Info.plist" />
<None Include="Entitlements.plist" />
</ItemGroup>
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="AppDelegate.cs" />
<Compile Include="ViewController.cs" />
<Compile Include="ViewController.designer.cs">
<DependentUpon>ViewController.cs</DependentUpon>
</Compile>
<Compile Include="Utilities.cs" />
</ItemGroup>
<ItemGroup>
<SceneKitAsset Include="art.scnassets\sharedImages\Shadow.png" />
<SceneKitAsset Include="art.scnassets\sharedImages\environment.jpg" />
<SceneKitAsset Include="art.scnassets\sphere\sphere.scn" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
</Project>

Просмотреть файл

@ -0,0 +1,50 @@
<?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>CFBundleName</key>
<string>EnvironmentTexturing</string>
<key>CFBundleIdentifier</key>
<string>com.xamarin.environment-texturing</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>MinimumOSVersion</key>
<string>12.0</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
<string>arkit</string>
</array>
<key>UIRequiresFullScreen</key>
<true/>
<key>UIStatusBarHidden</key>
<true/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/AppIcon.appiconset</string>
<key>NSCameraUsageDescription</key>
<string>The camera is used for augmenting reality</string>
</dict>
</plist>

Просмотреть файл

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Xamarin" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XQd-ZS-0Mt">
<rect key="frame" x="116.5" y="319.5" width="142" height="48"/>
<fontDescription key="fontDescription" type="system" pointSize="40"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="XQd-ZS-0Mt" firstAttribute="centerY" secondItem="kmA-MZ-dQI" secondAttribute="centerY" id="mYb-lN-8dd"/>
<constraint firstItem="XQd-ZS-0Mt" firstAttribute="centerX" secondItem="kmA-MZ-dQI" secondAttribute="centerX" id="ma5-fb-C6t"/>
</constraints>
<viewLayoutGuide key="safeArea" id="kmA-MZ-dQI"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>

Просмотреть файл

@ -0,0 +1,15 @@
using UIKit;
namespace EnvironmentTexturing
{
public class Application
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, "AppDelegate");
}
}
}

Просмотреть файл

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<arscnView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" wantsMultisampling="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cmo-cF-lL4">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
</arscnView>
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="1" translatesAutoresizingMaskIntoConstraints="NO" id="uOF-4V-l3q">
<rect key="frame" x="111" y="619" width="153" height="29"/>
<segments>
<segment title="Automatic"/>
<segment title="Manual"/>
</segments>
<connections>
<action selector="ChangeTextureMode:" destination="BYZ-38-t0r" eventType="valueChanged" id="1BH-Cq-RCU"/>
</connections>
</segmentedControl>
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="L8V-02-Uxi">
<rect key="frame" x="16" y="28" width="343" height="50"/>
<subviews>
<visualEffectView opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0u6-51-bW3">
<rect key="frame" x="0.0" y="0.0" width="240" height="50"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" id="s8Y-Lt-Zbi">
<rect key="frame" x="0.0" y="0.0" width="240" height="50"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Initializing" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gV1-pH-S01">
<rect key="frame" x="8" y="8" width="224" height="34"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="gV1-pH-S01" secondAttribute="trailing" constant="8" id="9eC-J7-NdA"/>
<constraint firstAttribute="bottom" secondItem="gV1-pH-S01" secondAttribute="bottom" constant="8" id="Apt-62-Ckv"/>
<constraint firstItem="gV1-pH-S01" firstAttribute="top" secondItem="s8Y-Lt-Zbi" secondAttribute="top" constant="8" id="a8C-FA-LO1"/>
<constraint firstItem="gV1-pH-S01" firstAttribute="leading" secondItem="s8Y-Lt-Zbi" secondAttribute="leading" constant="8" id="tXg-5a-n33"/>
</constraints>
</view>
<blurEffect style="light"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="7"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</visualEffectView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="jlg-lF-4wC">
<rect key="frame" x="293" y="0.0" width="50" height="50"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="50" id="TFJ-7a-U6f"/>
<constraint firstAttribute="width" constant="50" id="yWD-zO-iTW"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="18"/>
<state key="normal" image="restart"/>
<state key="highlighted" image="restartPressed"/>
<connections>
<action selector="RestartExperience:" destination="BYZ-38-t0r" eventType="touchUpInside" id="HVH-wW-5mU"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<gestureRecognizers/>
<constraints>
<constraint firstItem="YaP-bL-CsZ" firstAttribute="bottom" secondItem="uOF-4V-l3q" secondAttribute="bottom" constant="20" id="5fG-dn-FwY"/>
<constraint firstItem="uOF-4V-l3q" firstAttribute="centerX" secondItem="YaP-bL-CsZ" secondAttribute="centerX" id="RG1-BU-GP9"/>
<constraint firstItem="L8V-02-Uxi" firstAttribute="top" secondItem="YaP-bL-CsZ" secondAttribute="top" constant="8" id="YsJ-Td-t5v"/>
<constraint firstAttribute="bottom" secondItem="cmo-cF-lL4" secondAttribute="bottom" id="aCT-bb-tqe"/>
<constraint firstItem="cmo-cF-lL4" firstAttribute="top" secondItem="8bC-Xf-vdC" secondAttribute="top" id="bxf-25-tUY"/>
<constraint firstItem="cmo-cF-lL4" firstAttribute="leading" secondItem="YaP-bL-CsZ" secondAttribute="leading" id="ktV-mB-hkM"/>
<constraint firstItem="YaP-bL-CsZ" firstAttribute="trailing" secondItem="cmo-cF-lL4" secondAttribute="trailing" id="lE1-PU-Xxj"/>
<constraint firstItem="L8V-02-Uxi" firstAttribute="leading" secondItem="YaP-bL-CsZ" secondAttribute="leading" constant="16" id="nGW-t4-M7y"/>
<constraint firstAttribute="trailing" secondItem="L8V-02-Uxi" secondAttribute="trailing" constant="16" id="tq2-M9-g5L"/>
</constraints>
<viewLayoutGuide key="safeArea" id="YaP-bL-CsZ"/>
<connections>
<outletCollection property="gestureRecognizers" destination="Wm4-wK-UeN" appends="YES" id="v3S-z0-ntW"/>
<outletCollection property="gestureRecognizers" destination="hoL-QT-DPs" appends="YES" id="PBH-B8-jDu"/>
<outletCollection property="gestureRecognizers" destination="YIu-lt-SBE" appends="YES" id="gzZ-FK-NIO"/>
</connections>
</view>
<connections>
<outlet property="sceneView" destination="cmo-cF-lL4" id="r2G-WC-vGF"/>
<outlet property="sessionInfoLabel" destination="gV1-pH-S01" id="AZD-jt-jpf"/>
<outlet property="sessionInfoView" destination="0u6-51-bW3" id="fxL-8i-W46"/>
<outlet property="textureModeSelectionControl" destination="uOF-4V-l3q" id="iSo-Rd-svQ"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
<tapGestureRecognizer id="Wm4-wK-UeN">
<connections>
<action selector="DidTap:" destination="BYZ-38-t0r" id="CbJ-2Q-fiA"/>
</connections>
</tapGestureRecognizer>
<pinchGestureRecognizer id="hoL-QT-DPs">
<connections>
<action selector="DidScale:" destination="BYZ-38-t0r" id="MI9-6U-OmB"/>
</connections>
</pinchGestureRecognizer>
<panGestureRecognizer minimumNumberOfTouches="1" id="YIu-lt-SBE">
<connections>
<action selector="DidPan:" destination="BYZ-38-t0r" id="1Nv-Vb-LyB"/>
</connections>
</panGestureRecognizer>
</objects>
</scene>
</scenes>
<resources>
<image name="restart" width="20" height="23"/>
<image name="restartPressed" width="20" height="23"/>
</resources>
</document>

Просмотреть файл

@ -0,0 +1,76 @@
using ARKit;
using CoreGraphics;
using SceneKit;
using System.Linq;
namespace EnvironmentTexturing
{
public static class CGPointExtensions
{
/// <summary>
/// Extracts the screen space point from a vector returned by SCNView.projectPoint(_:).
/// </summary>
public static CGPoint Create(this SCNVector3 vector)
{
return new CGPoint(vector.X, vector.Y);
}
}
public static class ARSCNViewExtensions
{
public static ARHitTestResult SmartHitTest(this ARSCNView self, CGPoint point)
{
// Perform the hit test.
var results = self.HitTest(point, ARHitTestResultType.ExistingPlaneUsingGeometry);
// 1. Check for a result on an existing plane using geometry.
var existingPlaneUsingGeometryResult = results.FirstOrDefault(result => result.Type == ARHitTestResultType.ExistingPlaneUsingGeometry);
if (existingPlaneUsingGeometryResult != null)
{
return existingPlaneUsingGeometryResult;
}
// 2. Check for a result on an existing plane, assuming its dimensions are infinite.
var infinitePlaneResults = self.HitTest(point, ARHitTestResultType.ExistingPlane);
var infinitePlaneResult = infinitePlaneResults.FirstOrDefault();
if (infinitePlaneResult != null)
{
return infinitePlaneResult;
}
// 3. As a final fallback, check for a result on estimated planes.
return results.FirstOrDefault(result => result.Type == ARHitTestResultType.EstimatedHorizontalPlane);
}
}
public static class NNodeExtensions
{
public static SCNVector3 GetExtents(this SCNNode self)
{
var min = default(SCNVector3);
var max = default(SCNVector3);
self.GetBoundingBox(ref min, ref max);
return max - min;
}
}
public static class NMatrix4Extensions
{
public static OpenTK.NMatrix4 CreateTranslation(SCNVector3 vector)
{
return new OpenTK.NMatrix4(new OpenTK.Vector4(1, 0, 0, vector.X),
new OpenTK.Vector4(0, 1, 0, vector.Y),
new OpenTK.Vector4(0, 0, 1, vector.Z),
new OpenTK.Vector4(0, 0, 0, 1));
}
public static SCNVector3 GetTranslation(this OpenTK.NMatrix4 self)
{
var translation = self.Column3;
return new SCNVector3(translation.X, translation.Y, translation.Z);
//return new SCNVector3(self.Column0.Z, self.Column1.Z, self.Column2.Z);
}
}
}

Просмотреть файл

@ -0,0 +1,477 @@
using ARKit;
using CoreFoundation;
using CoreGraphics;
using Foundation;
using SceneKit;
using System;
using UIKit;
namespace EnvironmentTexturing
{
/// <summary>
/// Main view controller for the AR experience.
/// </summary>
public partial class ViewController : UIViewController, IARSCNViewDelegate, IARSessionDelegate
{
// Model of shiny sphere that is added to the scene
private SCNNode virtualObjectModel;
// Environment Texturing Configuration
// The virtual object that the user interacts with in the scene.
private SCNNode virtualObject;
// An environment probe for shading that virtual object.
private AREnvironmentProbeAnchor environmentProbeAnchor;
// A fallback environment probe encompassing the whole scene.
private AREnvironmentProbeAnchor sceneEnvironmentProbeAnchor;
// Place environment probes manually or allow ARKit to place them automatically.
private AREnvironmentTexturing currentTexturingMode = AREnvironmentTexturing.Automatic;
// Indicates whether manually placed probes need updating.
private bool requiresProbeRefresh = true;
// Tracks timing of manual probe updates to prevent updating too frequently.
private double lastProbeAnchorUpdateTime;
// Indicates whether ARKit has provided an environment texture.
private bool isEnvironmentTextureAvailable;
// The latest screen touch position when a pan gesture is active
private CGPoint? lastPanTouchPosition;
protected ViewController(IntPtr handle) : base(handle) { }
public override void ViewDidLoad()
{
base.ViewDidLoad();
this.InitializeVirtualObjectModel();
this.sceneView.Delegate = this;
this.sceneView.Session.Delegate = this;
switch (this.currentTexturingMode)
{
case AREnvironmentTexturing.Manual:
this.textureModeSelectionControl.SelectedSegment = 1;
break;
case AREnvironmentTexturing.Automatic:
this.textureModeSelectionControl.SelectedSegment = 0;
break;
default:
throw new Exception("This app supports only manual and automatic environment texturing.");
}
}
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
// Prevent the screen from dimming to avoid interrupting the AR experience.
UIApplication.SharedApplication.IdleTimerDisabled = true;
// Start the AR session with automatic environment texturing.
this.sceneView.Session.Run(new ARWorldTrackingConfiguration
{
PlaneDetection = ARPlaneDetection.Horizontal,
EnvironmentTexturing = AREnvironmentTexturing.Automatic
});
}
public override void ViewDidDisappear(bool animated)
{
base.ViewDidDisappear(animated);
this.sceneView.Session.Pause();
}
#region Session management
partial void ChangeTextureMode(UISegmentedControl sender)
{
if (sender.SelectedSegment == 0)
{
this.currentTexturingMode = AREnvironmentTexturing.Automatic;
this.environmentProbeAnchor?.Dispose();
this.environmentProbeAnchor = null;
}
else
{
this.currentTexturingMode = AREnvironmentTexturing.Manual;
this.requiresProbeRefresh = true;
}
// Remove anchors and change texturing mode
this.ResetTracking(true);
}
partial void RestartExperience(NSObject sender)
{
if (this.virtualObject != null)
{
this.virtualObject.RemoveFromParentNode();
this.virtualObject = null;
}
this.ResetTracking();
}
/// <summary>
/// Runs the session with a new AR configuration to change modes or reset the experience.
/// </summary>
private void ResetTracking(bool changeTextureMode = false)
{
var configuration = new ARWorldTrackingConfiguration();
configuration.PlaneDetection = ARPlaneDetection.Horizontal;
configuration.EnvironmentTexturing = this.currentTexturingMode;
var session = this.sceneView.Session;
if (changeTextureMode)
{
// Remove existing environment probe anchors.
if (session.CurrentFrame?.Anchors != null)
{
foreach (var anchor in session.CurrentFrame.Anchors)
{
session.RemoveAnchor(anchor);
}
}
// Don't reset tracking when changing modes in the same session.
session.Run(configuration);
}
else
{
session.Run(configuration, ARSessionRunOptions.ResetTracking | ARSessionRunOptions.RemoveExistingAnchors);
}
this.isEnvironmentTextureAvailable = false;
this.sceneEnvironmentProbeAnchor?.Dispose();
this.sceneEnvironmentProbeAnchor = null;
configuration.Dispose();
session.Dispose();
}
/// <summary>
/// Updates the UI to provide feedback on the state of the AR experience.
/// </summary>
private void UpdateSessionInfoLabel(ARCamera camera)
{
string message = null;
switch (camera.TrackingState)
{
case ARTrackingState.NotAvailable:
message = "Tracking Unavailable";
break;
case ARTrackingState.Limited:
switch (camera.TrackingStateReason)
{
case ARTrackingStateReason.ExcessiveMotion:
message = "Tracking Limited\nExcessive motion - Try slowing down your movement, or reset the session.";
break;
case ARTrackingStateReason.InsufficientFeatures:
message = "Tracking Limited\nLow detail - Try pointing at a flat surface, or reset the session.";
break;
case ARTrackingStateReason.Initializing:
message = "Initializing";
break;
case ARTrackingStateReason.Relocalizing:
message = "Recovering from interruption";
break;
}
break;
case ARTrackingState.Normal:
if (this.virtualObject == null)
{
if (this.isEnvironmentTextureAvailable)
{
message = "Tap to place a sphere, then tap or drag to move it or pinch to scale it.";
}
else
{
message = "Generating environment texture.";
}
}
break;
}
// Show the message, or hide the label if there's no message.
DispatchQueue.MainQueue.DispatchAsync(() =>
{
if (this.sessionInfoLabel.Text != message)
{
UIView.Animate(0.25d, () =>
{
this.sessionInfoLabel.Text = message;
if (!string.IsNullOrEmpty(message))
{
this.sessionInfoView.Alpha = 1;
}
else
{
this.sessionInfoView.Alpha = 0;
}
});
}
});
}
#endregion
#region Environment Texturing
private void UpdateEnvironmentProbe(double time)
{
// Update the probe only if the object has been moved or scaled,
// only when manually placed, not too often.
if (this.virtualObject != null &&
this.currentTexturingMode == AREnvironmentTexturing.Manual &&
time - this.lastProbeAnchorUpdateTime >= 1d &&
this.requiresProbeRefresh)
{
// Remove existing probe anchor, if any.
var probeAnchor = this.environmentProbeAnchor;
if (probeAnchor != null)
{
this.sceneView.Session.RemoveAnchor(probeAnchor);
this.environmentProbeAnchor.Dispose();
this.environmentProbeAnchor = null;
}
// Make sure the probe encompasses the object and provides some surrounding area to appear in reflections.
var extent = SCNVector3.Multiply(this.virtualObject.GetExtents(), this.virtualObject.Scale);
extent.X *= 3; // Reflect an area 3x the width of the object.
extent.Z *= 3; // Reflect an area 3x the depth of the object.
// Also include some vertical area around the object, but keep the bottom of the probe at the
// bottom of the object so that it captures the real-world surface underneath.
var verticalOffset = new SCNVector3(0, extent.Y, 0);
var transform = NMatrix4Extensions.CreateTranslation(this.virtualObject.Position + verticalOffset);
extent.Y *= 2;
// Create the new environment probe anchor and add it to the session.
probeAnchor = new AREnvironmentProbeAnchor(transform, new OpenTK.NVector3(extent.X, extent.Y, extent.Z));
this.sceneView.Session.AddAnchor(probeAnchor);
// Remember state to prevent updating the environment probe too often.
this.environmentProbeAnchor = probeAnchor;
this.lastProbeAnchorUpdateTime = CoreAnimation.CAAnimation.CurrentMediaTime();
this.requiresProbeRefresh = false;
}
}
private void UpdateSceneEnvironmentProbe(ARFrame frame)
{
if (this.sceneEnvironmentProbeAnchor == null && this.currentTexturingMode == AREnvironmentTexturing.Manual)
{
// Create an environment probe anchor with room-sized extent to act as fallback when the probe anchor of
// an object is removed and added during translation and scaling
this.sceneEnvironmentProbeAnchor = new AREnvironmentProbeAnchor("sceneProbe", OpenTK.NMatrix4.Identity, new OpenTK.NVector3(5f, 5f, 5f));
this.sceneView.Session.AddAnchor(this.sceneEnvironmentProbeAnchor);
}
}
#endregion
#region IARSCNViewDelegate
[Export("renderer:updateAtTime:")]
public void Update(ISCNSceneRenderer renderer, double timeInSeconds)
{
this.UpdateEnvironmentProbe(timeInSeconds);
}
[Export("renderer:didUpdateNode:forAnchor:")]
public void DidUpdateNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
{
// Check for whether any environment textures have been generated.
if (anchor is AREnvironmentProbeAnchor envProbeAnchor && !this.isEnvironmentTextureAvailable)
{
this.isEnvironmentTextureAvailable = envProbeAnchor.EnvironmentTexture != null;
}
}
#endregion
#region ARSessionObserver
[Export("session:cameraDidChangeTrackingState:")]
public void CameraDidChangeTrackingState(ARSession session, ARCamera camera)
{
var frame = session.CurrentFrame;
if (frame == null)
{
throw new Exception("ARSession should have an ARFrame");
}
this.UpdateSessionInfoLabel(camera);
frame.Dispose();
}
[Export("session:didFailWithError:")]
public void DidFail(ARSession session, NSError error)
{
this.ResetTracking();
}
[Export("sessionShouldAttemptRelocalization:")]
public bool ShouldAttemptRelocalization(ARSession session)
{
return true;
}
#endregion
#region IARSessionDelegate
[Export("session:didUpdateFrame:")]
public void DidUpdateFrame(ARSession session, ARFrame frame)
{
this.UpdateSceneEnvironmentProbe(frame);
this.UpdateSessionInfoLabel(frame.Camera);
frame.Dispose();
}
#endregion
#region Virtual Object gesture interaction
partial void DidPan(UIPanGestureRecognizer gesture)
{
if (this.virtualObject != null)
{
switch (gesture.State)
{
case UIGestureRecognizerState.Changed:
var translation = gesture.TranslationInView(this.sceneView);
var previousPosition = this.lastPanTouchPosition ?? CGPointExtensions.Create(this.sceneView.ProjectPoint(this.virtualObject.Position));
// Calculate the new touch position
var currentPosition = new CGPoint(previousPosition.X + translation.X, previousPosition.Y + translation.Y);
using (var hitTestResult = this.sceneView.SmartHitTest(currentPosition))
{
if (hitTestResult != null)
{
this.virtualObject.Position = hitTestResult.WorldTransform.GetTranslation();
// Refresh the probe as the object keeps moving
this.requiresProbeRefresh = true;
}
}
this.lastPanTouchPosition = currentPosition;
// reset the gesture's translation
gesture.SetTranslation(CGPoint.Empty, this.sceneView);
break;
default:
// Clear the current position tracking.
this.lastPanTouchPosition = null;
break;
}
}
}
partial void DidTap(UITapGestureRecognizer gesture)
{
// Allow placing objects only when ARKit tracking is in a good state for hit testing,
// and environment texture is available (to prevent undesirable changes in reflected texture).
var camera = this.sceneView.Session.CurrentFrame?.Camera;
if (camera != null && camera.TrackingState == ARTrackingState.Normal && this.isEnvironmentTextureAvailable)
{
var touchLocation = gesture.LocationInView(this.sceneView);
if (this.virtualObject != null)
{
using (var hitTestResult = this.sceneView.SmartHitTest(touchLocation))
{
if (hitTestResult != null)
{
// Teleport the object to wherever the user touched the screen.
this.virtualObject.Position = hitTestResult.WorldTransform.GetTranslation();
// Update the environment probe anchor when object is teleported.
this.requiresProbeRefresh = true;
}
}
}
else
{
// Add the object to the scene at the tap location.
DispatchQueue.DefaultGlobalQueue.DispatchAsync(() =>
{
this.Place(this.virtualObjectModel, touchLocation);
// Newly added object requires an environment probe anchor.
this.requiresProbeRefresh = true;
});
}
camera.Dispose();
}
}
partial void DidScale(UIPinchGestureRecognizer gesture)
{
if (this.virtualObject != null && gesture.State == UIGestureRecognizerState.Changed)
{
var newScale = SCNVector3.Multiply(this.virtualObject.Scale, (float)gesture.Scale);
this.virtualObject.Scale = newScale;
gesture.Scale = 1f;
// Realistic reflections require an environment probe extent based on the size of the object,
// so update the environment probe when the object is resized.
this.requiresProbeRefresh = true;
}
}
private void Place(SCNNode node, CGPoint location)
{
using (var hitTestResult = this.sceneView.SmartHitTest(location))
{
if (hitTestResult != null)
{
this.sceneView.Scene.RootNode.AddChildNode(node);
this.virtualObject = node;// Remember that the object has been placed.
node.Position = hitTestResult.WorldTransform.GetTranslation();
// Update the status UI to indicate the newly placed object.
var frame = this.sceneView.Session.CurrentFrame;
if (frame != null)
{
this.UpdateSessionInfoLabel(frame.Camera);
}
}
}
}
#endregion
private void InitializeVirtualObjectModel()
{
var sceneUrl = NSBundle.MainBundle.GetUrlForResource("sphere", "scn", "art.scnassets/sphere");
if (sceneUrl != null)
{
var referenceNode = SCNReferenceNode.CreateFromUrl(sceneUrl);
if (referenceNode != null)
{
referenceNode.Load();
this.virtualObjectModel = referenceNode;
}
}
if (this.virtualObjectModel == null)
{
throw new Exception("can't load virtual object");
}
}
}
}

Просмотреть файл

@ -0,0 +1,65 @@
// WARNING
//
// This file has been generated automatically by Visual Studio to store outlets and
// actions made in the UI designer. If it is removed, they will be lost.
// Manual changes to this file may not be handled correctly.
//
using Foundation;
using System.CodeDom.Compiler;
namespace EnvironmentTexturing
{
[Register ("ViewController")]
partial class ViewController
{
[Outlet]
ARKit.ARSCNView sceneView { get; set; }
[Outlet]
UIKit.UILabel sessionInfoLabel { get; set; }
[Outlet]
UIKit.UIVisualEffectView sessionInfoView { get; set; }
[Outlet]
UIKit.UISegmentedControl textureModeSelectionControl { get; set; }
[Action ("ChangeTextureMode:")]
partial void ChangeTextureMode (UIKit.UISegmentedControl sender);
[Action ("DidPan:")]
partial void DidPan (UIKit.UIPanGestureRecognizer gesture);
[Action ("DidScale:")]
partial void DidScale (UIKit.UIPinchGestureRecognizer gesture);
[Action ("DidTap:")]
partial void DidTap (UIKit.UITapGestureRecognizer gesture);
[Action ("RestartExperience:")]
partial void RestartExperience (Foundation.NSObject sender);
void ReleaseDesignerOutlets ()
{
if (sceneView != null) {
sceneView.Dispose ();
sceneView = null;
}
if (sessionInfoLabel != null) {
sessionInfoLabel.Dispose ();
sessionInfoLabel = null;
}
if (sessionInfoView != null) {
sessionInfoView.Dispose ();
sessionInfoView = null;
}
if (textureModeSelectionControl != null) {
textureModeSelectionControl.Dispose ();
textureModeSelectionControl = null;
}
}
}
}

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 922 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.2 MiB

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,8 @@
Copyright © 2018 Apple Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Просмотреть файл

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<SampleMetadata>
<ID>8fddf9fb-3018-4301-8336-43d388038f38</ID>
<IsFullApplication>false</IsFullApplication>
<Brief>Use ARKit to generate environment probe textures from camera imagery and render reflective virtual objects.</Brief>
<SupportedPlatforms>iOS</SupportedPlatforms>
<Level>Intermediate</Level>
<Tags>ARKit, iOS12</Tags>
<Gallery>true</Gallery>
</SampleMetadata>

Просмотреть файл

@ -0,0 +1,29 @@
Adding Realistic Reflections to an AR Experience
============
Use ARKit to generate environment probe textures from camera imagery and render reflective virtual objects.
![Cases](Screenshots/screenshot-1.png)
This app provides a simple AR experience demonstrating the environment texturing features in ARKit 2 and SceneKit. After you build and run the app, explore your surroundings in the camera view. Then, tap a nearby horizontal surface to place a virtual object: a mirror-finish sphere. After you place the object, you can drag it around or tap to move it to another location. You can also pinch to make the object bigger or smaller.
Build Requirements
-------
Xamarin.iOS 12.0, Xcode 10.0 and two or more iOS devices with A9 or later processors.
Related Links
-------
- [Original sample](https://developer.apple.com/documentation/arkit/adding_realistic_reflections_to_an_ar_experience).
- [Documentation](https://developer.apple.com/documentation/arkit/arenvironmentprobeanchor)
License
-------
Xamarin port changes are released under the MIT license.
Author
------
Ported to Xamarin.iOS by Mykyta Bondarenko

Двоичные данные
ios11/EnvironmentTexturing/Screenshots/screenshot-1.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.3 MiB