├── .gitignore ├── Assets ├── SampleProject.meta ├── SampleProject │ ├── Materials.meta │ ├── Materials │ │ ├── sample_materials.mat │ │ └── sample_materials.mat.meta │ ├── Model.meta │ ├── Model │ │ ├── Materials.meta │ │ ├── Materials │ │ │ ├── sample_theta_model.mat │ │ │ └── sample_theta_model.mat.meta │ │ ├── sample_theta_model.fbx │ │ └── sample_theta_model.fbx.meta │ ├── Prefabs.meta │ ├── Prefabs │ │ ├── ThetaSampleManager.prefab │ │ └── ThetaSampleManager.prefab.meta │ ├── Scenes.meta │ ├── Scenes │ │ ├── sample.unity │ │ └── sample.unity.meta │ ├── Scripts.meta │ └── Scripts │ │ ├── CameraControl.cs │ │ ├── CameraControl.cs.meta │ │ ├── ThetaSampleManager.cs │ │ └── ThetaSampleManager.cs.meta ├── ThetaSDK.meta └── ThetaSDK │ ├── Editor.meta │ ├── Plugins.meta │ ├── Plugins │ ├── iOS.meta │ └── iOS │ │ ├── ThetaPlugin.mm │ │ └── ThetaPlugin.mm.meta │ ├── ThetaPlugin.cs │ └── ThetaPlugin.cs.meta ├── LICENSE.txt ├── ProjectSettings ├── AudioManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset └── TimeManager.asset ├── README.md └── theta_unity_plugin.unitypackage /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | [Ll]ibrary/ 3 | [Tt]emp/ 4 | [Oo]bj/ 5 | [Bb]uild/ 6 | 7 | lib 8 | lib.meta 9 | Xcode 10 | 11 | # Autogenerated VS/MD solution and project files 12 | *.csproj 13 | *.unityproj 14 | *.sln 15 | *.suo 16 | *.tmp 17 | *.user 18 | *.userprefs 19 | *.pidb 20 | *.booproj 21 | 22 | # Unity3D generated meta files 23 | *.pidb.meta 24 | 25 | # Unity3D Generated File On Crash Reports 26 | sysinfo.txt 27 | -------------------------------------------------------------------------------- /Assets/SampleProject.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 604be9d16b5b14512b61e5f4fcbf3987 3 | folderAsset: yes 4 | timeCreated: 1430151417 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/SampleProject/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 39a325aa16c8a49f08f9604b181ead5e 3 | folderAsset: yes 4 | timeCreated: 1429991522 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/SampleProject/Materials/sample_materials.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/Assets/SampleProject/Materials/sample_materials.mat -------------------------------------------------------------------------------- /Assets/SampleProject/Materials/sample_materials.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 085b99d2b400a47f2a33704153a64dfb 3 | timeCreated: 1429991554 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/SampleProject/Model.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c214f8ad66d8f46e798fb1601a49c1d5 3 | folderAsset: yes 4 | timeCreated: 1431545384 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/SampleProject/Model/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c8044a7e829fb435aa2ddc948c0e9a58 3 | folderAsset: yes 4 | timeCreated: 1431545423 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/SampleProject/Model/Materials/sample_theta_model.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/Assets/SampleProject/Model/Materials/sample_theta_model.mat -------------------------------------------------------------------------------- /Assets/SampleProject/Model/Materials/sample_theta_model.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 03b05a91fa04442e0abe900db0365f08 3 | timeCreated: 1431545423 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/SampleProject/Model/sample_theta_model.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/Assets/SampleProject/Model/sample_theta_model.fbx -------------------------------------------------------------------------------- /Assets/SampleProject/Model/sample_theta_model.fbx.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 641b0ca25dcae4f09b4e73a09ac4d450 3 | timeCreated: 1431545423 4 | licenseType: Free 5 | ModelImporter: 6 | serializedVersion: 18 7 | fileIDToRecycleName: 8 | 100000: Camera 9 | 100002: Lamp 10 | 100004: //RootNode 11 | 100006: "\u7403" 12 | 400000: Camera 13 | 400002: Lamp 14 | 400004: //RootNode 15 | 400006: "\u7403" 16 | 2300000: "\u7403" 17 | 3300000: "\u7403" 18 | 4300000: "\u7403" 19 | materials: 20 | importMaterials: 1 21 | materialName: 0 22 | materialSearch: 1 23 | animations: 24 | legacyGenerateAnimations: 4 25 | bakeSimulation: 0 26 | optimizeGameObjects: 0 27 | motionNodeName: 28 | animationCompression: 1 29 | animationRotationError: .5 30 | animationPositionError: .5 31 | animationScaleError: .5 32 | animationWrapMode: 0 33 | extraExposedTransformPaths: [] 34 | clipAnimations: [] 35 | isReadable: 1 36 | meshes: 37 | lODScreenPercentages: [] 38 | globalScale: 1 39 | meshCompression: 0 40 | addColliders: 0 41 | importBlendShapes: 1 42 | swapUVChannels: 0 43 | generateSecondaryUV: 0 44 | useFileUnits: 1 45 | optimizeMeshForGPU: 1 46 | keepQuads: 0 47 | weldVertices: 1 48 | secondaryUVAngleDistortion: 8 49 | secondaryUVAreaDistortion: 15.000001 50 | secondaryUVHardAngle: 88 51 | secondaryUVPackMargin: 4 52 | useFileScale: 1 53 | tangentSpace: 54 | normalSmoothAngle: 60 55 | splitTangentsAcrossUV: 1 56 | normalImportMode: 0 57 | tangentImportMode: 1 58 | importAnimation: 1 59 | copyAvatar: 0 60 | humanDescription: 61 | human: [] 62 | skeleton: [] 63 | armTwist: .5 64 | foreArmTwist: .5 65 | upperLegTwist: .5 66 | legTwist: .5 67 | armStretch: .0500000007 68 | legStretch: .0500000007 69 | feetSpacing: 0 70 | rootMotionBoneName: 71 | lastHumanDescriptionAvatarSource: {instanceID: 0} 72 | animationType: 0 73 | additionalBone: 0 74 | userData: 75 | assetBundleName: 76 | assetBundleVariant: 77 | -------------------------------------------------------------------------------- /Assets/SampleProject/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 533ccdc94f41342b5aad09f62892fd66 3 | folderAsset: yes 4 | timeCreated: 1430151658 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/SampleProject/Prefabs/ThetaSampleManager.prefab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/Assets/SampleProject/Prefabs/ThetaSampleManager.prefab -------------------------------------------------------------------------------- /Assets/SampleProject/Prefabs/ThetaSampleManager.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9dd3221139f3f433888c206174253e9c 3 | timeCreated: 1430151664 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/SampleProject/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a4027d9aae63d43d09206afd85795601 3 | folderAsset: yes 4 | timeCreated: 1428937195 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/SampleProject/Scenes/sample.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/Assets/SampleProject/Scenes/sample.unity -------------------------------------------------------------------------------- /Assets/SampleProject/Scenes/sample.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 70b2ee2fdc4134ec7ad66b13eb884358 3 | timeCreated: 1428939501 4 | licenseType: Free 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/SampleProject/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 50f3a777d88114df392a4c1f5e0cf630 3 | folderAsset: yes 4 | timeCreated: 1428937145 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/SampleProject/Scripts/CameraControl.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Linq; 4 | 5 | public class CameraControl : MonoBehaviour 6 | { 7 | private float rotateSpeed = 0.1f; 8 | private float upDownSpeed = 0.1f; 9 | 10 | void Update() 11 | { 12 | int touchCount = Input.touches.Count(t => t.phase != TouchPhase.Ended && t.phase != TouchPhase.Canceled); 13 | if (touchCount == 1) 14 | { 15 | Touch touch = Input.touches.First(); 16 | switch (touch.phase) 17 | { 18 | case TouchPhase.Moved: 19 | 20 | //移動量 21 | float xDelta = touch.deltaPosition.x * rotateSpeed; 22 | float yDelta = touch.deltaPosition.y * upDownSpeed; 23 | 24 | //camera 25 | transform.Rotate(0, -xDelta, 0, Space.World); 26 | transform.Rotate(yDelta, 0, 0, Space.Self); 27 | break; 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Assets/SampleProject/Scripts/CameraControl.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba6cc9a5ac6474ea88293fddb12ca508 3 | timeCreated: 1431545573 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/SampleProject/Scripts/ThetaSampleManager.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.IO; 3 | using System.Collections; 4 | 5 | public class ThetaSampleManager : MonoBehaviour 6 | { 7 | private ThetaPlugin thetaPlugin; 8 | private string ipAddress = "192.168.1.1"; 9 | 10 | [SerializeField] 11 | public GameObject viewObject; 12 | 13 | void Start() 14 | { 15 | thetaPlugin = GetComponent (); 16 | } 17 | 18 | public void Connect () 19 | { 20 | thetaPlugin.Connect ( 21 | ipAddress, 22 | // Success 23 | () => { 24 | Debug.Log ("CONNECT:SUCCESS"); 25 | }, 26 | // Error 27 | () => { 28 | Debug.Log ("CONNECT:ERROR"); 29 | } 30 | ); 31 | 32 | 33 | SetCaptureCallback (); 34 | SetErrorCallback (); 35 | } 36 | 37 | public void DisConnect () 38 | { 39 | thetaPlugin.DisConnect ( 40 | // Success 41 | () => { 42 | Debug.Log ("DISCONNECT:SUCCESS"); 43 | }, 44 | // Error 45 | () => { 46 | Debug.Log ("DISCONNECT:ERROR"); 47 | } 48 | ); 49 | } 50 | 51 | public void Capture () 52 | { 53 | // capture 54 | thetaPlugin.Capture ( 55 | // Success 56 | () => { 57 | Debug.Log ("CAPTURE:SUCCESS"); 58 | }, 59 | // Error 60 | () => { 61 | Debug.Log ("CAPTURE:ERROR"); 62 | } 63 | ); 64 | } 65 | 66 | private void SetCaptureCallback() 67 | { 68 | // set call back method 69 | thetaPlugin.SetCallbackObjectAdd (texture => { 70 | viewObject.GetComponent().material.mainTexture = texture; 71 | }); 72 | } 73 | 74 | private void SetErrorCallback() 75 | { 76 | // set call back method 77 | thetaPlugin.SetCallbackError (error_text => { 78 | Debug.Log ("CALLBACK:ERROR"+error_text); 79 | }); 80 | } 81 | } -------------------------------------------------------------------------------- /Assets/SampleProject/Scripts/ThetaSampleManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b31bb4a02a9924e0fbc109b6c1dd2126 3 | timeCreated: 1429029474 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/ThetaSDK.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 74356fe9958aa4a3b950b50e2648737f 3 | folderAsset: yes 4 | timeCreated: 1428937138 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/ThetaSDK/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 15d817eaa985a431a882dea5c7a98622 3 | folderAsset: yes 4 | timeCreated: 1430037036 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/ThetaSDK/Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6399bd2d84398489188f99ec6a080354 3 | folderAsset: yes 4 | timeCreated: 1428937972 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/ThetaSDK/Plugins/iOS.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dddf505d14a1e40e7b7fd7a588b14fc5 3 | folderAsset: yes 4 | timeCreated: 1428938044 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/ThetaSDK/Plugins/iOS/ThetaPlugin.mm: -------------------------------------------------------------------------------- 1 | // 2 | // Theta.mm 3 | // Unity-iPhone 4 | // 5 | // Created by noshipu on 2015/04/15. 6 | // 7 | // 8 | #if UNITY_VERSION <= 434 9 | mport "iPhone_View.h" 10 | #endif 11 | 12 | // Theta API 13 | #import "PtpConnection.h" 14 | #import "PtpLogging.h" 15 | 16 | extern "C" void UnitySendMessage(const char *, const char *, const char *); 17 | 18 | inline static void dispatch_async_main(dispatch_block_t block) 19 | { 20 | dispatch_async(dispatch_get_main_queue(), block); 21 | } 22 | 23 | // define unity callback type 24 | typedef void (*ConnectSuccess)(); 25 | typedef void (*ConnectError)(); 26 | typedef void (*DisConnectSuccess)(); 27 | typedef void (*DisConnectError)(); 28 | typedef void (*CaptureSuccess)(); 29 | typedef void (*CaptureError)(); 30 | 31 | @interface ThetaPlugin : UIViewController 32 | { 33 | PtpConnection* _ptpConnection; 34 | NSString *gameObjectName; 35 | 36 | int imageWidth; 37 | int imageHeight; 38 | } 39 | @end 40 | 41 | @implementation ThetaPlugin 42 | 43 | - (id)initWithGameObjectName:(const char *)game_object_name 44 | { 45 | self = [super init]; 46 | 47 | // init ptp 48 | _ptpConnection = [[PtpConnection alloc] init]; 49 | [_ptpConnection setLoglevel:PTPIP_LOGLEVEL_WARN]; 50 | [_ptpConnection setEventListener:self]; 51 | 52 | gameObjectName = [NSString stringWithUTF8String:game_object_name]; 53 | 54 | return self; 55 | } 56 | 57 | #pragma mark - PtpIpEventListener delegates. 58 | - (void)ptpip_eventReceived:(int)code :(uint32_t)param1 :(uint32_t)param2 :(uint32_t)param3 { 59 | switch (code) { 60 | default: 61 | { 62 | dispatch_async_main(^{ 63 | NSLog(@"don`t define callback"); 64 | }); 65 | } 66 | break; 67 | 68 | case PTPIP_OBJECT_ADDED: 69 | { 70 | [_ptpConnection operateSession:^(PtpIpSession *session) { 71 | // param1 in handle 72 | [self loadObject:param1 session:session]; 73 | dispatch_async_main(^{ 74 | NSLog(@"call back add"); 75 | }); 76 | }]; 77 | } 78 | break; 79 | 80 | } 81 | } 82 | 83 | -(void)ptpip_socketError:(int)err 84 | { 85 | // If libptpip closed the socket, `closed` is non-zero. 86 | BOOL closed = PTP_CONNECTION_CLOSED(err); 87 | 88 | // PTPIP_PROTOCOL_*** or POSIX error number (errno()). 89 | err = PTP_ORIGINAL_PTPIPERROR(err); 90 | 91 | NSArray* errTexts = @[@"Socket closed", // PTPIP_PROTOCOL_SOCKET_CLOSED 92 | @"Brocken packet", // PTPIP_PROTOCOL_BROCKEN_PACKET 93 | @"Rejected", // PTPIP_PROTOCOL_REJECTED 94 | @"Invalid session id", // PTPIP_PROTOCOL_INVALID_SESSION_ID 95 | @"Invalid transaction id.", // PTPIP_PROTOCOL_INVALID_TRANSACTION_ID 96 | @"Unrecognided command", // PTPIP_PROTOCOL_UNRECOGNIZED_COMMAND 97 | @"Invalid receive state", // PTPIP_PROTOCOL_INVALID_RECEIVE_STATE 98 | @"Invalid data length", // PTPIP_PROTOCOL_INVALID_DATA_LENGTH 99 | @"Watchdog expired", // PTPIP_PROTOCOL_WATCHDOG_EXPIRED 100 | ]; 101 | NSString* desc; 102 | if ((PTPIP_PROTOCOL_SOCKET_CLOSED<=err) && (err<=PTPIP_PROTOCOL_WATCHDOG_EXPIRED)) { 103 | desc = [errTexts objectAtIndex:err-PTPIP_PROTOCOL_SOCKET_CLOSED]; 104 | } else { 105 | desc = [NSString stringWithUTF8String:strerror(err)]; 106 | } 107 | dispatch_async_main(^{ 108 | UnitySendMessage([gameObjectName UTF8String], 109 | "CallbackError", [desc UTF8String]); 110 | }); 111 | } 112 | 113 | - (void)connect:(const char *)ip_address success:(ConnectSuccess)success error:(ConnectError)error 114 | { 115 | NSString *_ip_address = [NSString stringWithUTF8String:ip_address ? ip_address : ""]; 116 | [_ptpConnection setTargetIp:_ip_address]; 117 | [_ptpConnection connect:^(BOOL connected){ 118 | if(connected) { 119 | dispatch_async_main(^{ 120 | success(); 121 | }); 122 | } 123 | else { 124 | dispatch_async_main(^{ 125 | error(); 126 | }); 127 | } 128 | }]; 129 | } 130 | 131 | - (void)disConnect:(DisConnectSuccess)success error:(DisConnectError)error 132 | { 133 | [_ptpConnection close:^{ 134 | dispatch_async_main(^{ 135 | success(); 136 | }); 137 | }]; 138 | } 139 | 140 | - (void)capture:(CaptureSuccess)success error:(CaptureError)error 141 | { 142 | // session open 143 | [_ptpConnection operateSession:^(PtpIpSession *session) { 144 | // capture 145 | BOOL rtn = [session initiateCapture]; 146 | dispatch_async_main(^{ 147 | if(rtn) { 148 | success(); 149 | }else{ 150 | error(); 151 | } 152 | }); 153 | }]; 154 | } 155 | 156 | - (void)loadObject:(uint32_t)objectHandle session:(PtpIpSession*)session 157 | { 158 | // get object informations. 159 | PtpIpObjectInfo* objectInfo = [session getObjectInfo:objectHandle]; 160 | if (!objectInfo) { 161 | return; 162 | } 163 | if (objectInfo.object_format != PTPIP_FORMAT_JPEG) { 164 | return; 165 | } 166 | 167 | // load 2048x1024 image 168 | imageWidth = 2048; 169 | imageHeight = 1024; 170 | NSMutableData* image_data = [NSMutableData data]; 171 | BOOL result = [session getResizedImageObject:objectHandle 172 | width:imageWidth 173 | height:imageHeight 174 | onStartData:^(NSUInteger totalLength) { 175 | // Callback reception. 176 | NSLog(@"getThumb(0x%08x) will received %zd bytes.", objectHandle, totalLength); 177 | } 178 | onChunkReceived:^BOOL(NSData *data) { 179 | [image_data appendData:data]; 180 | return YES; 181 | }]; 182 | 183 | if (!result) { 184 | // failed 185 | return; 186 | } 187 | 188 | dispatch_async_main(^{ 189 | // save image 190 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 191 | NSString *documentsDirectory = [paths objectAtIndex:0]; 192 | NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"tmp_pic.jpg"]; 193 | [image_data writeToFile:filePath atomically:YES]; 194 | 195 | // call unity method 196 | UnitySendMessage([gameObjectName UTF8String], 197 | "CallbackObjectAdd", MakeStringCopy([filePath UTF8String])); 198 | }); 199 | } 200 | 201 | char* MakeStringCopy (const char* string) 202 | { 203 | if (string == NULL) 204 | return NULL; 205 | 206 | char* res = (char*)malloc(strlen(string) + 1); 207 | strcpy(res, string); 208 | return res; 209 | } 210 | @end 211 | 212 | extern "C" { 213 | void *Theta_Connect(const char *ip_address, const char *game_object_name, 214 | ConnectSuccess success, ConnectError error); 215 | void Theta_DisConnect(void *instance, DisConnectSuccess success, DisConnectError error); 216 | void Theta_Capture(void *instance, CaptureSuccess success, CaptureError error); 217 | } 218 | 219 | void *Theta_Connect(const char *ip_address, const char *game_object_name, 220 | ConnectSuccess success, ConnectError error) 221 | { 222 | id instance = [[ThetaPlugin alloc] initWithGameObjectName:game_object_name]; 223 | 224 | // connection 225 | [instance connect:ip_address success:success error:error]; 226 | return (__bridge void *)(instance); 227 | } 228 | 229 | void Theta_DisConnect(void* instance, DisConnectSuccess success, DisConnectError error) { 230 | ThetaPlugin *thetaPlugin = (__bridge ThetaPlugin *)(instance); 231 | [thetaPlugin disConnect:success error:error]; 232 | } 233 | 234 | void Theta_Capture(void* instance, CaptureSuccess success, CaptureError error) { 235 | ThetaPlugin *thetaPlugin = (__bridge ThetaPlugin *)(instance); 236 | [thetaPlugin capture:success error:error]; 237 | } -------------------------------------------------------------------------------- /Assets/ThetaSDK/Plugins/iOS/ThetaPlugin.mm.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d6126d6686547423c8b57654c79309f9 3 | timeCreated: 1428938282 4 | licenseType: Free 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 1 13 | settings: {} 14 | userData: 15 | assetBundleName: 16 | assetBundleVariant: 17 | -------------------------------------------------------------------------------- /Assets/ThetaSDK/ThetaPlugin.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ThetaPlugin.cs 3 | * 4 | * Copyright (C) 2015 Noshipu 5 | * URL:https://twitter.com/noshipu 6 | * 7 | */ 8 | 9 | using UnityEngine; 10 | using System; 11 | using System.IO; 12 | using System.Collections; 13 | using System.Runtime.InteropServices; 14 | 15 | public class ThetaPlugin : MonoBehaviour 16 | { 17 | #if UNITY_IOS 18 | private IntPtr theta; 19 | 20 | [DllImport("__Internal")] 21 | private static extern IntPtr Theta_Connect (string ip_address, string game_object_name, 22 | ConnectSuccess success, ConnectError error); 23 | [DllImport("__Internal")] 24 | private static extern void Theta_DisConnect (IntPtr instance, DisConnectSuccess success, DisConnectError error); 25 | [DllImport("__Internal")] 26 | private static extern void Theta_Capture (IntPtr instance, CaptureSuccess success, CaptureError error); 27 | [DllImport("__Internal")] 28 | private static extern void Theta_Capture (IntPtr instance, LoadHandleCallback callback); 29 | 30 | // Call Back Method 31 | private delegate void ConnectSuccess (); 32 | private delegate void ConnectError (); 33 | private delegate void DisConnectSuccess (); 34 | private delegate void DisConnectError (); 35 | private delegate void CaptureSuccess (); 36 | private delegate void CaptureError (); 37 | private delegate void LoadHandleCallback (); 38 | 39 | private static Action connectSuccess; 40 | private static Action connectError; 41 | private static Action disConnectSuccess; 42 | private static Action disConnectError; 43 | private static Action captureSuccess; 44 | private static Action captureError; 45 | 46 | // theta`s call callback 47 | private Action callError; 48 | private Action callAddObject; 49 | 50 | /// 51 | /// Theta Connect Method 52 | /// 53 | /// Ip_address. 54 | /// Success Action 55 | /// Error Action 56 | public void Connect (string ip_address, Action success, Action error) 57 | { 58 | if (CheckConnectTheta ()) 59 | { 60 | if(error != null) 61 | { 62 | error(); 63 | } 64 | return; 65 | } 66 | 67 | connectSuccess = success; 68 | connectError = error; 69 | 70 | theta = Theta_Connect (ip_address, gameObject.name, ConnectCallbackSuccess, ConnectCallbackError); 71 | } 72 | 73 | /// 74 | /// Theta DisConnect Method 75 | /// 76 | /// Success Action 77 | /// Error Action 78 | public void DisConnect (Action success, Action error) 79 | { 80 | if (!CheckConnectTheta ()) 81 | { 82 | if(error != null) 83 | { 84 | error(); 85 | } 86 | return; 87 | } 88 | 89 | disConnectSuccess = success; 90 | disConnectError = error; 91 | 92 | Theta_DisConnect (theta, DisConnectCallbackSuccess, DisConnectCallbackError); 93 | theta = IntPtr.Zero; 94 | } 95 | 96 | /// 97 | /// Theta Capture Method 98 | /// 99 | /// Success Action 100 | /// Error Action 101 | public void Capture (Action success, Action error) 102 | { 103 | if (!CheckConnectTheta ()) 104 | { 105 | if(error != null) 106 | { 107 | error(); 108 | } 109 | return; 110 | } 111 | Debug.Log (theta); 112 | 113 | captureSuccess = success; 114 | captureError = error; 115 | 116 | Theta_Capture (theta, CaptureCallbackSuccess, CaptureCallbackError); 117 | } 118 | 119 | /// 120 | /// Set the callback ObjectAdd Function. 121 | /// 122 | /// callback:pram is texture 123 | public void SetCallbackObjectAdd (Action callback) 124 | { 125 | if (!CheckConnectTheta ()) 126 | { 127 | return; 128 | } 129 | callAddObject = callback; 130 | } 131 | 132 | /// 133 | /// Sets the callback error. 134 | /// 135 | /// callback:parma is error message 136 | public void SetCallbackError (Action callback) 137 | { 138 | if (!CheckConnectTheta ()) 139 | { 140 | return; 141 | } 142 | callError = callback; 143 | } 144 | 145 | // theta callback method 146 | public void CallbackObjectAdd(string image_path) 147 | { 148 | Debug.Log ("FILE PATH:"+image_path); 149 | if (callAddObject != null) 150 | { 151 | if (image_path.Length != 0) 152 | { 153 | Texture2D texture = new Texture2D (2048, 1280); 154 | byte[] imageBytes = File.ReadAllBytes(image_path); 155 | texture.LoadImage(imageBytes); 156 | callAddObject(texture); 157 | } 158 | } 159 | } 160 | public void CallbackError(string error_text) 161 | { 162 | if (callError != null) 163 | { 164 | callError(error_text); 165 | } 166 | } 167 | 168 | private bool CheckConnectTheta() 169 | { 170 | if (theta == IntPtr.Zero) 171 | { 172 | Debug.LogError("Don`t connect theta!"); 173 | return false; 174 | } 175 | 176 | return true; 177 | } 178 | 179 | // Connect Call Back Method 180 | [AOT.MonoPInvokeCallbackAttribute(typeof(ConnectSuccess))] 181 | private void ConnectCallbackSuccess () 182 | { 183 | if (connectSuccess != null) { 184 | connectSuccess (); 185 | } 186 | } 187 | [AOT.MonoPInvokeCallbackAttribute(typeof(ConnectError))] 188 | private void ConnectCallbackError () 189 | { 190 | if (connectError != null) { 191 | connectError (); 192 | } 193 | } 194 | 195 | // DisConnect Call Back Method 196 | [AOT.MonoPInvokeCallbackAttribute(typeof(DisConnectSuccess))] 197 | private void DisConnectCallbackSuccess () 198 | { 199 | if (disConnectSuccess != null) { 200 | disConnectSuccess (); 201 | } 202 | } 203 | [AOT.MonoPInvokeCallbackAttribute(typeof(DisConnectError))] 204 | private void DisConnectCallbackError () 205 | { 206 | if (disConnectError != null) { 207 | disConnectError (); 208 | } 209 | } 210 | 211 | // Capture Call Back Method 212 | [AOT.MonoPInvokeCallbackAttribute(typeof(CaptureSuccess))] 213 | private void CaptureCallbackSuccess () 214 | { 215 | if (captureSuccess != null) { 216 | captureSuccess (); 217 | } 218 | } 219 | [AOT.MonoPInvokeCallbackAttribute(typeof(CaptureError))] 220 | private void CaptureCallbackError () 221 | { 222 | if (captureError != null) { 223 | captureError (); 224 | } 225 | } 226 | #elif UNITY_ANDROID 227 | // Android logic 228 | // please wait... 229 | #endif 230 | } 231 | -------------------------------------------------------------------------------- /Assets/ThetaSDK/ThetaPlugin.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 378f631d21e52416286868012de3e5c0 3 | timeCreated: 1428939347 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 noshipu 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgement in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/ProjectSettings/NavMeshAreas.asset -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/ProjectSettings/Physics2DSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 5.0.0f4 2 | m_StandardAssetsVersion: 0 3 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### THETA Unity Plugin ver0.1 2 | 3 | ## 説明 4 | 360度カメラのTHETAのAPIをUnityから実行するプラグインです。 5 | このPluginを使用する場合、RICOH THETA SDKが必要となりますので、別途利用規約を確認し、THETAデベロッパーサイトからダウンロードお願いします。 6 | https://developers.theta360.com/ja/docs/sdk/ 7 | 8 | ## 備考 9 | API v1のみをサポートしております。v2は対応しておりません。 10 | 現在、iOSのみ対応で、一部のAPIのみの対応になります。(※順次更新予定) 11 | 接続、解除、撮影、画像の取得、エラーの取得が実装済みです。 12 | 13 | ## 動作確認環境 14 | ・Unity5 15 | ・RICOH THETA SDK for iOS ver0.3.0 16 | ・iOS8以上の端末 17 | 18 | ## 組み込み手順(iOS) 19 | (1) theta_unity_plugin.unitypackageをご自身のプロジェクトにimportしてください 20 | (2) THETA DEVELOPERS サイトにてSDKをダウンロード 21 | https://developers.theta360.com/ja/docs/sdk/ 22 | (3) Assets/ThetaSDK/Plugins/iOS/以下に、(2)でダウンロードしたlibフォルダをコピー 23 | (4) Assets/ThetaSDK/ThetaPlugin.csをゲームオブジェクトにアタッチしGetComponectして使ってください。 24 | 詳細はコードの使い方からどうぞ 25 | (5) ビルド後、Xcodeでやること 26 | ・以下のライブラリをプロジェクトに追加 27 | libiconv.dylib 28 | ImageIO.framework 29 | ・[Build Settings]->[Apple LLVM 6.0 - Language - Objective C]->[Enable Objective-CExceptions]を[Yes]に変更 30 | http://noshipu.hateblo.jp/entry/2015/04/15/023431 31 | 32 | ## コードの使い方 33 | ### コンポーネント取得 34 | `thetaPlugin = GetComponent ();` 35 | ### 基本的なAPIの呼び出し 36 | `thetaPlugin.Connect (ip_adress, ()=>{/*成功処理*/ }, ()=>{/*失敗処理*/});` 37 | ### 基本的なコールバックの設定 38 | `thetaPlugin.SetCallbackObjectAdd ((texture)=>{/*テクスチャ取得後の処理*/ });` 39 | 40 | ### Sample Project 41 | SampleProjectにて、接続、解除、撮影、画像の取得を確認することができます。 42 | 球体モデルも含まれており撮影後の画像をフリックでぐりぐり動かせます。 43 | -------------------------------------------------------------------------------- /theta_unity_plugin.unitypackage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noshipu/theta-unity-plugin/c4f64a1ae2ea813a7001af8b1884d7f9cfc5e58d/theta_unity_plugin.unitypackage --------------------------------------------------------------------------------