Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
insearcher committed Jun 15, 2019
1 parent 79c53e8 commit 5ad4f9e
Show file tree
Hide file tree
Showing 6,821 changed files with 199,425 additions and 677 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
9 changes: 9 additions & 0 deletions Assets/UnityARKitPlugin.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions Assets/UnityARKitPlugin/ARKitRemote.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions Assets/UnityARKitPlugin/ARKitRemote/ARKITREMOTE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Unity ARKit Remote

This is a two part solution for game developers who want to iterate on ARKit apps (made with Unity ARKit Plugin) from within the Unity Editor. It consists of an iOS app (UnityARKitRemote) that provides the ARKit data from a compatible device that it is installed on, working in conjunction with a GameObject called ARKitRemoteConnection in your Unity scene for your ARKit project. This GameObject simulates ARKit working in the editor by passing data via UnityARSessionNativeInterface to the other GameObjects in the editor. The UnityARKitRemote app on the device will forward the following information to Unity scene in editor:

-The video feed coming from the device camera (separated into Y and UV textures) as provided by ARKit.
-The camera translation and rotation based on device movement
-The ARPlaneAnchor addition, removal and update events along with data about the plane affected
-Point cloud data

Requirements:
It has all the same requirements as the Unity ARKit Plugin, with an additional recommendation of using Unity 2017.1 or later, as the PlayerConnection works way better and has better UI support in that version.

Future work on this:
-HitTest API
-AR Session Configuration

Steps to using remote:

1. First download the latest Unity ARKit Plugin code that includes the Unity ARKit Remote from either bitbucket or Unity Asset Store.
2. Build the scene called UnityARKitRemote out to your compatible iOS device. You should use “Development Build” in your Build Settings. This is the only build time to iOS you will need to endure - the rest of the iterations on your project can happen in the editor. When you build out to iOS, you should change the product name and bundle identifier in the PlayerSettings to signify that it is the Unity ARKit Remote.
3. Open the scene which contains your app that uses the Unity ARKit Plugin. From the ARKitRemote folder, add the ARKitRemoteConnection prefab into the root of your scene. If you want to test it out, it has already been added to EditorTestScene in the same folder.
4. Run the UnityARKitRemote app from step 2 on your device. It should display a black screen with “Waiting for editor connection..”
5. Press play in the editor: your game window should have a green screen with “Please connect to player in the console menu” near the bottom.
6. In this step we need to connect the editor to the Unity ARKit Remote app on the device. This is where Unity 2017.1 comes in handy: it has a menu item in the Console window to “Connected player” with a dropdown of all the available players to connect to. Select the one that corresponds to your device. In Unity 5.6 variants, you have to create a Profiler window via Window/Profiler menu. And then at the top of the Profiler window, there is a dropdown “Active Profiler” from which you select your device.
7. If you were successful in step 6, you should have a button on the top part of your Game window labelled “Start Remote ARKit Session” in editor that when pressed will start the ARKit session on the device and start transmitting data to the editor. The editor should be displaying the same video as the device, as well as navigating through your scene, and it will momentarily start showing the point cloud data as well as the planes found.


8 changes: 8 additions & 0 deletions Assets/UnityARKitPlugin/ARKitRemote/ARKITREMOTE.txt.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
using UnityEngine;
using UnityEngine.Networking.PlayerConnection;
using System.Text;
using UnityEngine.XR.iOS.Utils;

#if UNITY_EDITOR

using UnityEditor.Networking.PlayerConnection;

namespace UnityEngine.XR.iOS
{
public class ARKitFaceTrackingRemoteConnection : MonoBehaviour
{
[Header("AR FaceTracking Config Options")]
public bool enableLightEstimation = true;

[Header("Run Options")]
public bool resetTracking = true;
public bool removeExistingAnchors = true;

EditorConnection editorConnection ;

int currentPlayerID = -1;
string guimessage = "none";

Texture2D remoteScreenYTex;
Texture2D remoteScreenUVTex;

bool bTexturesInitialized;

// Use this for initialization
void Start () {

bTexturesInitialized = false;


editorConnection = EditorConnection.instance;
editorConnection.Initialize ();
editorConnection.RegisterConnection (PlayerConnected);
editorConnection.RegisterDisconnection (PlayerDisconnected);
editorConnection.Register (ConnectionMessageIds.updateCameraFrameMsgId, UpdateCameraFrame);
editorConnection.Register (ConnectionMessageIds.addFaceAnchorMsgeId, AddFaceAnchor);
editorConnection.Register (ConnectionMessageIds.updateFaceAnchorMsgeId, UpdateFaceAnchor);
editorConnection.Register (ConnectionMessageIds.removePlaneAnchorMsgeId, RemoveFaceAnchor);
editorConnection.Register (ConnectionMessageIds.screenCaptureYMsgId, ReceiveRemoteScreenYTex);
editorConnection.Register (ConnectionMessageIds.screenCaptureUVMsgId, ReceiveRemoteScreenUVTex);

}

void PlayerConnected(int playerID)
{
currentPlayerID = playerID;

}

void OnGUI()
{

if (!bTexturesInitialized)
{
if (currentPlayerID != -1) {
guimessage = "Connected to ARKit Remote device : " + currentPlayerID.ToString ();

if (GUI.Button (new Rect ((Screen.width / 2) - 200, (Screen.height / 2) - 200, 400, 100), "Start Remote ARKit FaceTracking Session"))
{
SendInitToPlayer ();
}
}
else
{
guimessage = "Please connect to player in the console menu";
}

GUI.Box (new Rect ((Screen.width / 2) - 200, (Screen.height / 2) + 100, 400, 50), guimessage);
}

}

void PlayerDisconnected(int playerID)
{
if (currentPlayerID == playerID) {
currentPlayerID = -1;
}
}

void OnDestroy()
{
#if UNITY_2017_1_OR_NEWER
if(editorConnection != null) {
editorConnection.DisconnectAll ();
}
#endif
}


void InitializeTextures(UnityARCamera camera)
{
int yWidth = camera.videoParams.yWidth;
int yHeight = camera.videoParams.yHeight;
int uvWidth = yWidth / 2;
int uvHeight = yHeight / 2;
if (remoteScreenYTex == null || remoteScreenYTex.width != yWidth || remoteScreenYTex.height != yHeight) {
if (remoteScreenYTex) {
Destroy (remoteScreenYTex);
}
remoteScreenYTex = new Texture2D (yWidth, yHeight, TextureFormat.R8, false, true);
}
if (remoteScreenUVTex == null || remoteScreenUVTex.width != uvWidth || remoteScreenUVTex.height != uvHeight) {
if (remoteScreenUVTex) {
Destroy (remoteScreenUVTex);
}
remoteScreenUVTex = new Texture2D (uvWidth, uvHeight, TextureFormat.RG16, false, true);
}

bTexturesInitialized = true;
}

void UpdateCameraFrame(MessageEventArgs mea)
{
serializableUnityARCamera serCamera = mea.data.Deserialize<serializableUnityARCamera> ();

UnityARCamera scamera = new UnityARCamera ();
scamera = serCamera;

InitializeTextures (scamera);

UnityARSessionNativeInterface.SetStaticCamera (scamera);
UnityARSessionNativeInterface.RunFrameUpdateCallbacks ();
}

void AddFaceAnchor(MessageEventArgs mea)
{
serializableUnityARFaceAnchor serFaceAnchor = mea.data.Deserialize<serializableUnityARFaceAnchor> ();

ARFaceAnchor arFaceAnchor = serFaceAnchor;
UnityARSessionNativeInterface.RunAddAnchorCallbacks (arFaceAnchor);
}

void UpdateFaceAnchor(MessageEventArgs mea)
{
serializableUnityARFaceAnchor serFaceAnchor = mea.data.Deserialize<serializableUnityARFaceAnchor> ();

ARFaceAnchor arFaceAnchor = serFaceAnchor;
UnityARSessionNativeInterface.RunUpdateAnchorCallbacks (arFaceAnchor);
}

void RemoveFaceAnchor(MessageEventArgs mea)
{
serializableUnityARFaceAnchor serFaceAnchor = mea.data.Deserialize<serializableUnityARFaceAnchor> ();

ARFaceAnchor arFaceAnchor = serFaceAnchor;
UnityARSessionNativeInterface.RunRemoveAnchorCallbacks (arFaceAnchor);
}

void ReceiveRemoteScreenYTex(MessageEventArgs mea)
{
if (!bTexturesInitialized)
return;
remoteScreenYTex.LoadRawTextureData(CompressionHelper.ByteArrayDecompress(mea.data));
remoteScreenYTex.Apply ();
UnityARVideo arVideo = Camera.main.GetComponent<UnityARVideo>();
if (arVideo) {
arVideo.SetYTexure(remoteScreenYTex);
}

}

void ReceiveRemoteScreenUVTex(MessageEventArgs mea)
{
if (!bTexturesInitialized)
return;
remoteScreenUVTex.LoadRawTextureData(CompressionHelper.ByteArrayDecompress(mea.data));
remoteScreenUVTex.Apply ();
UnityARVideo arVideo = Camera.main.GetComponent<UnityARVideo>();
if (arVideo) {
arVideo.SetUVTexure(remoteScreenUVTex);
}

}


void SendInitToPlayer()
{

//we're going to reuse ARSessionConfiguration and only use its lightestimation field.

serializableFromEditorMessage sfem = new serializableFromEditorMessage ();
sfem.subMessageId = SubMessageIds.editorInitARKitFaceTracking;
serializableARSessionConfiguration ssc = new serializableARSessionConfiguration (UnityARAlignment.UnityARAlignmentCamera, UnityARPlaneDetection.None, false, enableLightEstimation, true);
UnityARSessionRunOption roTracking = resetTracking ? UnityARSessionRunOption.ARSessionRunOptionResetTracking : 0;
UnityARSessionRunOption roAnchors = removeExistingAnchors ? UnityARSessionRunOption.ARSessionRunOptionRemoveExistingAnchors : 0;
sfem.arkitConfigMsg = new serializableARKitInit (ssc, roTracking | roAnchors);
SendToPlayer (ConnectionMessageIds.fromEditorARKitSessionMsgId, sfem);
}

void SendToPlayer(System.Guid msgId, byte[] data)
{
editorConnection.Send (msgId, data);
}

public void SendToPlayer(System.Guid msgId, object serializableObject)
{
byte[] arrayToSend = serializableObject.SerializeToByteArray ();
SendToPlayer (msgId, arrayToSend);
}


// Update is called once per frame
void Update () {

}

}
}
#endif

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 5ad4f9e

Please sign in to comment.