ZEDManager.cs 130 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339
  1. using UnityEngine;
  2. using System;
  3. using System.Threading;
  4. using UnityEngine.XR;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. /// <summary>
  8. /// The central script of the ZED Unity plugin, and the primary way a developer can interact with the camera.
  9. /// It sets up and closes connection to the ZED, adjusts parameters based on user settings, enables/disables/handles
  10. /// features like tracking, and holds numerous useful properties, methods, and callbacks.
  11. /// </summary>
  12. /// <remarks>
  13. /// ZEDManager is attached to the root objects in the ZED_Rig_Mono and ZED_Rig_Stereo prefabs.
  14. /// If using ZED_Rig_Stereo, it will set isStereoRig to true, which triggers several behaviors unique to stereo pass-through AR.
  15. /// </remarks>
  16. public class ZEDManager : MonoBehaviour, IZEDManager
  17. {
  18. /// <summary>
  19. /// Static function to get instance of the ZEDManager with a given camera_ID. See sl.ZED_CAMERA_ID for the available choices.
  20. /// </summary>
  21. public static object grabLock;
  22. static ZEDManager[] ZEDManagerInstance = null;
  23. public static ZEDManager GetInstance(sl.ZED_CAMERA_ID _id)
  24. {
  25. if (ZEDManagerInstance == null)
  26. return null;
  27. else
  28. return ZEDManagerInstance[(int)_id];
  29. }
  30. /// <summary>
  31. /// Static function to get all ZEDManagers that have been properly instantiated.
  32. /// <para>Cameras may not necessarily be connected, if they haven't finished connecting, have disconnected,
  33. /// or if no camera is available.</para>
  34. /// </summary>
  35. /// <returns></returns>
  36. public static List<ZEDManager> GetInstances()
  37. {
  38. List<ZEDManager> instances = new List<ZEDManager>();
  39. for (int i = 0; i < (int)sl.Constant.MAX_CAMERA_PLUGIN; i++)
  40. {
  41. ZEDManager instance = GetInstance((sl.ZED_CAMERA_ID)i);
  42. if (instance != null)
  43. instances.Add(instance);
  44. }
  45. return instances;
  46. }
  47. /// <summary>
  48. /// For advanced debugging. Default false. Set true for the Unity wrapper to log all SDK calls to a new file
  49. /// at C:/ProgramData/stereolabs/SL_Unity_wrapper.txt. This helps find issues that may occur within
  50. /// the protected .dll, but can decrease performance.
  51. /// </summary>
  52. private bool wrapperVerbose = true;
  53. /// <summary>
  54. /// Current instance of the ZED Camera, which handles calls to the Unity wrapper .dll.
  55. /// </summary>
  56. public sl.ZEDCamera zedCamera = null;
  57. /////////////////////////////////////////////////////////////////////////
  58. ///////////////////////// Camera Settings ///////////////////////////////
  59. /////////////////////////////////////////////////////////////////////////
  60. /// <summary>
  61. /// Resolution setting for all images retrieved from the camera. Higher resolution means lower framerate.
  62. /// HD720 is strongly recommended for pass-through AR.
  63. /// </summary>
  64. /// <summary>
  65. /// Camera ID
  66. /// </summary>
  67. [HideInInspector]
  68. public sl.ZED_CAMERA_ID cameraID = sl.ZED_CAMERA_ID.CAMERA_ID_01;
  69. /// <summary>
  70. /// The accuracy of depth calculations. Higher settings mean more accurate occlusion and lighting but costs performance.
  71. /// Note there's a significant jump in performance cost between QUALITY and ULTRA modes.
  72. /// </summary>
  73. /*[Tooltip("The accuracy of depth calculations. Higher settings mean more accurate occlusion and lighting but costs performance.")]*/
  74. [HideInInspector]
  75. public sl.DEPTH_MODE depthMode = sl.DEPTH_MODE.PERFORMANCE;
  76. /// <summary>
  77. /// Input Type in SDK (USB, SVO or Stream)
  78. /// </summary>
  79. [HideInInspector]
  80. public sl.INPUT_TYPE inputType = sl.INPUT_TYPE.INPUT_TYPE_USB;
  81. /// <summary>
  82. /// Camera Resolution
  83. /// </summary>
  84. [HideInInspector]
  85. public sl.RESOLUTION resolution = sl.RESOLUTION.HD720;
  86. /// <summary>
  87. /// Targeted FPS, based on the resolution. VGA = 100, HD720 = 60, HD1080 = 30, HD2K = 15.
  88. /// </summary>
  89. [HideInInspector]
  90. public int FPS = 60;
  91. /// <summary>
  92. /// SVO Input FileName
  93. /// </summary>
  94. [HideInInspector]
  95. public string svoInputFileName = "";
  96. /// <summary>
  97. /// Optional opencv calib file
  98. /// </summary>
  99. public string opencvCalibFile = "";
  100. /// <summary>
  101. /// SVO loop back option
  102. /// </summary>
  103. [HideInInspector]
  104. public bool svoLoopBack = true;
  105. /// <summary>
  106. /// SVO loop back option
  107. /// </summary>
  108. [HideInInspector]
  109. public bool svoRealTimeMode = false;
  110. /// <summary>
  111. /// Current frame being read from the SVO. Doesn't apply when recording.
  112. /// </summary>
  113. [HideInInspector]
  114. [SerializeField]
  115. private int currentFrame = 0;
  116. /// <summary>
  117. /// Current frame being read from the SVO. Doesn't apply when recording.
  118. /// </summary>
  119. public int CurrentFrame
  120. {
  121. get
  122. {
  123. return currentFrame;
  124. }
  125. set
  126. {
  127. currentFrame = value;
  128. }
  129. }
  130. /// <summary>
  131. /// Total number of frames in a loaded SVO.
  132. /// </summary>
  133. [HideInInspector]
  134. [SerializeField]
  135. private int numberFrameMax = 0;
  136. /// <summary>
  137. /// Total number of frames in a loaded SVO.
  138. /// </summary>
  139. public int NumberFrameMax
  140. {
  141. set
  142. {
  143. numberFrameMax = value;
  144. }
  145. get
  146. {
  147. return numberFrameMax;
  148. }
  149. }
  150. [HideInInspector]
  151. [SerializeField]
  152. public bool pauseSVOReading = false;
  153. [HideInInspector]
  154. public bool pauseLiveReading = false;
  155. /// <summary>
  156. /// Ask a new frame is in pause (SVO only)
  157. /// </summary>
  158. [HideInInspector]
  159. public bool NeedNewFrameGrab = false;
  160. /// <summary>
  161. /// Streaming Input IP (v2.8)
  162. /// </summary>
  163. [HideInInspector]
  164. public string streamInputIP = "127.0.0.1";
  165. /// <summary>
  166. /// Streaming Input Port (v2.8)
  167. /// </summary>
  168. [HideInInspector]
  169. public int streamInputPort = 30000;
  170. #if ZED_HDRP
  171. /////////////////////////////////////////////////////////////////////////
  172. ///////////////////////// SRP Lighting //////////////////////////////////
  173. /////////////////////////////////////////////////////////////////////////
  174. public enum shaderType
  175. {
  176. Lit,
  177. Unlit,
  178. Greenscreen_Lit,
  179. Greenscreen_Unlit,
  180. DontChange
  181. }
  182. /// <summary>
  183. ///
  184. /// </summary>
  185. [HideInInspector]
  186. public shaderType srpShaderType = shaderType.Lit;
  187. /// <summary>
  188. /// How much the ZED image should light itself via emission.
  189. /// Setting to zero is most realistic, but requires you to emulate the real-world lighting conditions within Unity. Higher settings cause the image\
  190. /// to be uniformly lit, but light and shadow effects are less visible.
  191. /// </summary>
  192. [HideInInspector]
  193. public float selfIllumination = 0.5f;
  194. /// <summary>
  195. ///
  196. /// </summary>
  197. [HideInInspector]
  198. public bool applyZEDNormals = false;
  199. #endif
  200. /////////////////////////////////////////////////////////////////////////
  201. ///////////////////////// Motion Tracking ///////////////////////////////
  202. /////////////////////////////////////////////////////////////////////////
  203. /// <summary>
  204. /// If enabled, the ZED will move/rotate itself using its own inside-out tracking.
  205. /// If false, the camera tracking will move with the VR HMD if connected and available.
  206. /// <para>Normally, ZEDManager's GameObject will move according to the tracking. But if in AR pass-through mode,
  207. /// then the Camera_eyes object in ZED_Rig_Stereo will move while this object stays still. </para>
  208. /// </summary>
  209. [HideInInspector]
  210. public bool enableTracking = true;
  211. /// <summary>
  212. /// Enables the spatial memory. Will detect and correct tracking drift by remembering features and anchors in the environment,
  213. /// but may cause visible jumps when it happens.
  214. /// </summary>
  215. [HideInInspector]
  216. public bool enableSpatialMemory = true;
  217. /// <summary>
  218. /// If using Spatial Memory, you can specify a path to an existing .area file to start with some memory already loaded.
  219. /// .area files are created by scanning a scene with ZEDSpatialMappingManager and saving the scan.
  220. /// </summary>
  221. [HideInInspector]
  222. public string pathSpatialMemory;
  223. /// <summary>
  224. /// Estimate initial position by detecting the floor.
  225. /// </summary>
  226. [HideInInspector]
  227. public bool estimateInitialPosition = true;
  228. public bool EstimateInitialPosition => estimateInitialPosition;
  229. /// <summary>
  230. /// If true, tracking is enabled but doesn't move after initializing.
  231. /// </summary>
  232. [HideInInspector]
  233. public bool trackingIsStatic = false;
  234. /////////////////////////////////////////////////////////////////////////
  235. ///////////////////////// Spatial Mapping ///////////////////////////////
  236. /////////////////////////////////////////////////////////////////////////
  237. /// <summary>
  238. /// Resolution setting for the scan. A higher resolution creates more submeshes and uses more memory, but is more accurate.
  239. /// </summary>
  240. [HideInInspector]
  241. public ZEDSpatialMapping.RESOLUTION mappingResolutionPreset = ZEDSpatialMapping.RESOLUTION.MEDIUM;
  242. /// <summary>
  243. /// Maximum distance geometry can be from the camera to be scanned. Geometry scanned from farther away will be less accurate.
  244. /// </summary>
  245. [HideInInspector]
  246. public ZEDSpatialMapping.RANGE mappingRangePreset = ZEDSpatialMapping.RANGE.MEDIUM;
  247. /// <summary>
  248. /// Whether mesh filtering is needed.
  249. /// </summary>
  250. [HideInInspector]
  251. public bool isMappingFilteringEnable = false;
  252. /// <summary>
  253. /// Whether surface textures will be scanned and applied. Note that texturing will add further delay to the post-scan finalizing period.
  254. /// </summary>
  255. [HideInInspector]
  256. public bool isMappingTextured = false;
  257. /// <summary>
  258. /// Whether to save the mesh .obj and .area files once the scan is finished.
  259. /// </summary>
  260. [HideInInspector]
  261. public bool saveMeshWhenOver = false;
  262. /// <summary>
  263. /// Path to save the .obj and .area files.
  264. /// </summary>
  265. [HideInInspector]
  266. public string meshPath = "Assets/ZEDMesh.obj";
  267. /// <summary>
  268. /// Filtering setting. More filtering results in fewer faces in the mesh, reducing both file size and accuracy.
  269. /// </summary>
  270. [HideInInspector]
  271. public sl.FILTER meshFilterParameters;
  272. /// <summary>
  273. /// Instance of the ZEDSpatialMapping class that handles the actual spatial mapping implementation within Unity.
  274. /// </summary>
  275. [HideInInspector]
  276. private ZEDSpatialMapping spatialMapping = null;
  277. public ZEDSpatialMapping GetSpatialMapping { get { return spatialMapping; } }
  278. /// <summary>
  279. /// Whether the spatial mapping is currently scanning.
  280. /// </summary>
  281. public bool IsMappingRunning { get { return spatialMapping != null ? spatialMapping.IsRunning() : false; } }
  282. /// <summary>
  283. /// List of the processed submeshes. This list isn't filled until StopSpatialMapping() is called.
  284. /// </summary>
  285. public List<ZEDSpatialMapping.Chunk> MappingChunkList { get { return spatialMapping != null ? spatialMapping.ChunkList : null; } }
  286. /// <summary>
  287. /// Whether the mesh update thread is running.
  288. /// </summary>
  289. public bool IsMappingUpdateThreadRunning { get { return spatialMapping != null ? spatialMapping.IsUpdateThreadRunning : false; } }
  290. /// <summary>
  291. /// Whether the spatial mapping was running but has been paused (not stopped) by the user.
  292. /// </summary>
  293. public bool IsMappingPaused { get { return spatialMapping != null ? spatialMapping.IsPaused : false; } }
  294. /// <summary>
  295. /// Whether the mesh is in the texturing stage of finalization.
  296. /// </summary>
  297. public bool IsMappingTexturingRunning { get { return spatialMapping != null ? spatialMapping.IsTexturingRunning : false; } }
  298. /// <summary>
  299. /// Gets a boolean value indicating whether the spatial mapping display is enabled.
  300. /// </summary>
  301. public bool IsSpatialMappingDisplay { get { return spatialMapping != null ? spatialMapping.display : false; } }
  302. /// <summary>
  303. /// Gets a boolean value indicating whether the spatial mapping has chunks
  304. /// </summary>
  305. public bool SpatialMappingHasChunks { get { return spatialMapping != null ? spatialMapping.Chunks.Count > 0 : false; } }
  306. /////////////////////////////////////////////////////////////////////////
  307. //////////////////////// Object Detection //////////////////////////////
  308. /////////////////////////////////////////////////////////////////////////
  309. /// <summary>
  310. /// Sync the Object on the image.
  311. /// </summary>
  312. [HideInInspector]
  313. public bool objectDetectionImageSyncMode = false;
  314. /// <summary>
  315. /// Whether to track objects across multiple frames using the ZED's position relative to the floor.
  316. /// Requires tracking to be on. It's also recommended to enable Estimate Initial Position to find the floor.
  317. /// </summary>
  318. [HideInInspector]
  319. public bool objectDetectionTracking = true;
  320. /// <summary>
  321. /// Whether to calculate 2D masks for each object, showing exactly which pixels within the 2D bounding box are the object.
  322. /// Requires more performance, so do not enable unless needed.
  323. /// </summary>
  324. [HideInInspector]
  325. public bool objectDetection2DMask = false;
  326. /// <summary>
  327. /// Choose what detection model to use in the Object detection module
  328. /// </summary>
  329. [HideInInspector]
  330. public sl.DETECTION_MODEL objectDetectionModel = sl.DETECTION_MODEL.MULTI_CLASS_BOX;
  331. public sl.DETECTION_MODEL ObjectDetectionModel => objectDetectionModel;
  332. /// <summary>
  333. /// Defines if the body fitting will be applied
  334. /// </summary>
  335. [HideInInspector]
  336. public bool objectDetectionBodyFitting = true;
  337. /// <summary>
  338. /// Defines a upper depth range for detections.
  339. /// </summary>
  340. [HideInInspector]
  341. public float objectDetectionMaxRange = 40.0f;
  342. /// <summary>
  343. /// Defines a upper depth range for detections.
  344. /// </summary>
  345. [HideInInspector]
  346. public sl.OBJECT_FILTERING_MODE objectDetectionFilteringMode = sl.OBJECT_FILTERING_MODE.NMS3D;
  347. [HideInInspector]
  348. public sl.BODY_FORMAT objectDetectionBodyFormat = sl.BODY_FORMAT.POSE_34;
  349. [HideInInspector]
  350. public sl.BODY_FORMAT bodyFormat = sl.BODY_FORMAT.POSE_34;
  351. /// <summary>
  352. /// Detection sensitivity. Represents how sure the SDK must be that an object exists to report it. Ex: If the threshold is 80, then only objects
  353. /// where the SDK is 80% sure or greater will appear in the list of detected objects.
  354. /// </summary>
  355. [HideInInspector]
  356. public int SK_personDetectionConfidenceThreshold = 50;
  357. /// <summary>
  358. /// Detection sensitivity. Represents how sure the SDK must be that an object exists to report it. Ex: If the threshold is 80, then only objects
  359. /// where the SDK is 80% sure or greater will appear in the list of detected objects.
  360. /// </summary>
  361. [HideInInspector]
  362. public int OD_personDetectionConfidenceThreshold = 60;
  363. /// <summary>
  364. /// Detection sensitivity. Represents how sure the SDK must be that an object exists to report it. Ex: If the threshold is 80, then only objects
  365. /// where the SDK is 80% sure or greater will appear in the list of detected objects.
  366. /// </summary>
  367. [HideInInspector]
  368. public int vehicleDetectionConfidenceThreshold = 60;
  369. /// <summary>
  370. /// Detection sensitivity. Represents how sure the SDK must be that an object exists to report it. Ex: If the threshold is 80, then only objects
  371. /// where the SDK is 80% sure or greater will appear in the list of detected objects.
  372. /// </summary>
  373. [HideInInspector]
  374. public int bagDetectionConfidenceThreshold = 60;
  375. /// <summary>
  376. /// Detection sensitivity. Represents how sure the SDK must be that an object exists to report it. Ex: If the threshold is 80, then only objects
  377. /// where the SDK is 80% sure or greater will appear in the list of detected objects.
  378. /// </summary>
  379. [HideInInspector]
  380. public int animalDetectionConfidenceThreshold = 60;
  381. /// <summary>
  382. /// Detection sensitivity. Represents how sure the SDK must be that an object exists to report it. Ex: If the threshold is 80, then only objects
  383. /// where the SDK is 80% sure or greater will appear in the list of detected objects.
  384. /// </summary>
  385. [HideInInspector]
  386. public int electronicsDetectionConfidenceThreshold = 60;
  387. /// <summary>
  388. /// Detection sensitivity. Represents how sure the SDK must be that an object exists to report it. Ex: If the threshold is 80, then only objects
  389. /// where the SDK is 80% sure or greater will appear in the list of detected objects.
  390. /// </summary>
  391. [HideInInspector]
  392. public int fruitVegetableDetectionConfidenceThreshold = 60;
  393. /// <summary>
  394. /// Detection sensitivity. Represents how sure the SDK must be that an object exists to report it. Ex: If the threshold is 80, then only objects
  395. /// where the SDK is 80% sure or greater will appear in the list of detected objects.
  396. /// </summary>
  397. [HideInInspector]
  398. public int sportDetectionConfidenceThreshold = 60;
  399. /// <summary>
  400. /// Whether to detect people during object detection.
  401. /// </summary>
  402. [HideInInspector]
  403. public bool objectClassPersonFilter = true;
  404. /// <summary>
  405. /// Whether to detect vehicles during object detection.
  406. /// </summary>
  407. [HideInInspector]
  408. public bool objectClassVehicleFilter = true;
  409. /// <summary>
  410. /// Whether to detect bags during object detection.
  411. /// </summary>
  412. [HideInInspector]
  413. public bool objectClassBagFilter = true;
  414. /// <summary>
  415. /// Whether to detect animals during object detection.
  416. /// </summary>
  417. [HideInInspector]
  418. public bool objectClassAnimalFilter = true;
  419. /// <summary>
  420. /// Whether to detect electronics during object detection.
  421. /// </summary>
  422. [HideInInspector]
  423. public bool objectClassElectronicsFilter = true;
  424. /// <summary>
  425. /// Whether to detect fruits and vegetables during object detection.
  426. /// </summary>
  427. [HideInInspector]
  428. public bool objectClassFruitVegetableFilter = true;
  429. /// <summary>
  430. /// Whether to detect sport related objects during object detection.
  431. /// </summary>
  432. [HideInInspector]
  433. public bool objectClassSportFilter = true;
  434. /// <summary>
  435. /// Whether the object detection module has been activated successfully.
  436. /// </summary>
  437. private bool objectDetectionRunning = false;
  438. /// <summary>
  439. /// Whether the object detection module has been activated successfully.
  440. /// </summary>
  441. public bool IsObjectDetectionRunning { get { return objectDetectionRunning; } }
  442. /// <summary>
  443. /// Set to true when there is not a fresh frame of detected objects waiting for processing, meaning we can retrieve the next one.
  444. /// </summary>
  445. private bool requestobjectsframe = true;
  446. /// <summary>
  447. /// Set to true when a new frame of detected objects has been retrieved in the image acquisition thread, ready for the main thread to process.
  448. /// </summary>
  449. private bool newobjectsframeready = false;
  450. /// <summary>
  451. /// Last object detection frame detected by the SDK. This data comes straight from the C++ SDK; see detectionFrame for an abstracted version
  452. /// with many helper functions for use inside Unity.
  453. /// </summary>
  454. private sl.ObjectsFrameSDK objectsFrameSDK = new sl.ObjectsFrameSDK();
  455. /// <summary>
  456. /// Last object detection frame detected by the SDK. This data comes straight from the C++ SDK; see GetDetectionFrame for an abstracted version
  457. /// with many helper functions for use inside Unity.
  458. /// </summary>
  459. public sl.ObjectsFrameSDK GetSDKObjectsFrame { get { return objectsFrameSDK; } }
  460. /// <summary>
  461. /// Timestamp of the most recent object frame fully processed. This is used to calculate the FPS of the object detection module.
  462. /// </summary>
  463. private ulong lastObjectFrameTimeStamp = 0;
  464. /// <summary>
  465. /// Frame rate at which the object detection module is running. Only reports performance; changing this value has no effect on detection.
  466. /// </summary>
  467. private float objDetectionModuleFPS = 15.0f;
  468. /// <summary>
  469. /// Last object detection frame detected by the SDK, in the form of a DetectionFrame instance which has many helper functions for use in Unity.
  470. /// </summary>
  471. private DetectionFrame detectionFrame;
  472. /// <summary>
  473. /// Last object detection frame detected by the SDK, in the form of a DetectionFrame instance which has many helper functions for use in Unity.
  474. /// </summary>
  475. public DetectionFrame GetDetectionFrame { get { return detectionFrame; } }
  476. /// <summary>
  477. /// Delegate for events that take an object detection frame straight from the SDK (not abstracted).
  478. /// </summary>
  479. public delegate void onNewDetectionTriggerSDKDelegate(sl.ObjectsFrameSDK objFrame);
  480. /// <summary>
  481. /// Event that's called whenever the Object Detection module detects a new frame.
  482. /// Includes data straight from the C++ SDK. See OnObjectDetection/DetectionFrame for an abstracted version that has many helper functions
  483. /// that makes it easier to use in Unity.
  484. /// </summary>
  485. public event onNewDetectionTriggerSDKDelegate OnObjectDetection_SDKData;
  486. /// <summary>
  487. /// Delegate for events that take an object detection frame, in the form of a DetectionFrame object which has helper functions.
  488. /// </summary>
  489. public delegate void onNewDetectionTriggerDelegate(DetectionFrame objFrame);
  490. /// <summary>
  491. /// Event that's called whenever the Object Detection module detects a new frame.
  492. /// Supplies data in the form of a DetectionFrame instance, which has many helper functions for use in Unity.
  493. /// </summary>
  494. public event onNewDetectionTriggerDelegate OnObjectDetection;
  495. private sl.dll_ObjectDetectionRuntimeParameters od_runtime_params = new sl.dll_ObjectDetectionRuntimeParameters();
  496. /////////////////////////////////////////////////////////////////////////
  497. ///////////////////////////// Rendering ///////////////////////////////////
  498. /////////////////////////////////////////////////////////////////////////
  499. /// <summary>
  500. /// Rendering paths available to the ZED with the corresponding Unity rendering path.
  501. /// </summary>
  502. public enum ZEDRenderingMode
  503. {
  504. FORWARD = RenderingPath.Forward,
  505. DEFERRED = RenderingPath.DeferredShading
  506. };
  507. /// <summary>
  508. /// When enabled, the real world can occlude (cover up) virtual objects that are behind it.
  509. /// Otherwise, virtual objects will appear in front.
  510. /// </summary>
  511. [HideInInspector]
  512. public bool depthOcclusion = true;
  513. /// <summary>
  514. /// Enables post-processing effects on virtual objects that blends them in with the real world.
  515. /// </summary>
  516. [HideInInspector]
  517. public bool postProcessing = true;
  518. /// <summary>
  519. /// Field version of CameraBrightness property.
  520. /// </summary>
  521. [SerializeField]
  522. [HideInInspector]
  523. private int m_cameraBrightness = 100;
  524. /// Brightness of the final real-world image. Default is 100. Lower to darken the environment in a realistic-looking way.
  525. /// This is a rendering setting that doesn't affect the raw input from the camera.
  526. /// </summary>
  527. public int CameraBrightness
  528. {
  529. get { return m_cameraBrightness; }
  530. set
  531. {
  532. if (m_cameraBrightness == value) return;
  533. m_cameraBrightness = value;
  534. if (OnCamBrightnessChange != null)
  535. OnCamBrightnessChange(m_cameraBrightness);
  536. }
  537. }
  538. /// <summary>
  539. /// Whether to enable the new color/gamma curve added to the ZED SDK in v3.0. Exposes more detail in darker regions
  540. /// and removes a slight red bias.
  541. /// </summary>
  542. [HideInInspector]
  543. [SerializeField]
  544. public bool enableImageEnhancement = true;
  545. /// Field version of MaxDepthRange property.
  546. /// </summary>
  547. [SerializeField]
  548. private float m_maxDepthRange = 40f;
  549. /// <summary>
  550. /// Maximum depth at which the camera will display the real world, in meters. Pixels further than this value will be invisible.
  551. /// </summary>
  552. [HideInInspector]
  553. public float MaxDepthRange
  554. {
  555. get { return m_maxDepthRange; }
  556. set
  557. {
  558. if (m_maxDepthRange == value) return;
  559. m_maxDepthRange = value;
  560. if (OnMaxDepthChange != null)
  561. OnMaxDepthChange(m_maxDepthRange);
  562. }
  563. }
  564. /////////////////////////////////////////////////////////////////////////
  565. ///////////////////////// Recording Module //////////////////////////////
  566. /////////////////////////////////////////////////////////////////////////
  567. /// <summary>
  568. /// SVO Output file name
  569. /// </summary>
  570. [HideInInspector]
  571. public string svoOutputFileName = "Assets/Recording.svo";
  572. /// <summary>
  573. /// SVO Compression mode used for recording
  574. /// </summary>
  575. [HideInInspector]
  576. public sl.SVO_COMPRESSION_MODE svoOutputCompressionMode = sl.SVO_COMPRESSION_MODE.H264_BASED;
  577. /// <summary>
  578. /// SVO specific bitrate in KBits/s
  579. /// Default : 0 = internal bitrate
  580. /// </summary>
  581. [HideInInspector]
  582. public int svoOutputBitrate = 0;
  583. /// <summary>
  584. /// SVO specific FPS
  585. /// Default : 0 = Camera FPS
  586. /// </summary>
  587. [HideInInspector]
  588. public int svoOutputTargetFPS = 0;
  589. /// <summary>
  590. /// If input is streaming, then set to direct-dump into SVO file (false) or decoding/re-encoding (true).
  591. /// Recommended to leave at false to save an encoding session.
  592. /// </summary>
  593. public bool svoOutputTranscodeStreaming = false;
  594. /// <summary>
  595. /// Indicates if frame must be recorded
  596. /// </summary>
  597. [HideInInspector]
  598. public bool needRecordFrame = false;
  599. /////////////////////////////////////////////////////////////////////////
  600. ///////////////////////// Streaming Module //////////////////////////////
  601. /////////////////////////////////////////////////////////////////////////
  602. /// <summary>
  603. /// Enable/Disable Streaming module
  604. /// </summary>
  605. [HideInInspector]
  606. public bool enableStreaming = false;
  607. /// <summary>
  608. /// Status of streaming request
  609. /// </summary>
  610. private bool isStreamingEnable = false;
  611. /// <summary>
  612. /// Codec used for Streaming
  613. /// </summary>
  614. [HideInInspector]
  615. public sl.STREAMING_CODEC streamingCodec = sl.STREAMING_CODEC.AVCHD_BASED;
  616. /// <summary>
  617. /// port used for Streaming
  618. /// </summary>
  619. [HideInInspector]
  620. public int streamingPort = 30000;
  621. /// <summary>
  622. /// bitrate used for Streaming
  623. /// </summary>
  624. [HideInInspector]
  625. public int bitrate = 8000;
  626. /// <summary>
  627. /// gop size used for Streaming
  628. /// </summary>
  629. [HideInInspector]
  630. public int gopSize = -1;
  631. /// <summary>
  632. /// Enable/Disable adaptative bitrate
  633. /// </summary>
  634. [HideInInspector]
  635. public bool adaptativeBitrate = false;
  636. /// <summary>
  637. /// Enable/Disable adaptative bitrate
  638. /// </summary>
  639. [HideInInspector]
  640. public int chunkSize = 8096;
  641. /// <summary>
  642. /// Set a specific target for the streaming framerate
  643. /// </summary>
  644. [HideInInspector]
  645. public int streamingTargetFramerate = 0;
  646. /////////////////////////////////////////////////////////////////////////
  647. ///////////////////////// Advanced control /////////////////////////////
  648. /////////////////////////////////////////////////////////////////////////
  649. ///
  650. /// <summary>
  651. /// True to make the ZED image fade from black when the application starts.
  652. /// </summary>
  653. [HideInInspector]
  654. public bool fadeInOnStart = true;
  655. /// <summary>
  656. /// True to apply DontDestroyOnLoad() on the ZED rig in Awake(), preserving it between scenes.
  657. /// </summary>
  658. [HideInInspector]
  659. public bool dontDestroyOnLoad = false;
  660. /// <summary>
  661. /// Grey Out Skybox on Start", "True to set the background to a neutral gray when the scene starts.
  662. /// Recommended for AR so that lighting on virtual objects better matches the real world.
  663. /// </summary>
  664. [HideInInspector]
  665. public bool greySkybox = true;
  666. /// <summary>
  667. /// Field version of confidenceThreshold property.
  668. /// </summary>
  669. [SerializeField]
  670. [HideInInspector]
  671. private int m_confidenceThreshold = 100;
  672. /// <summary>
  673. /// How tolerant the ZED SDK is to low confidence values. Lower values filter more pixels.
  674. /// </summary>
  675. public int confidenceThreshold
  676. {
  677. get
  678. {
  679. return m_confidenceThreshold;
  680. }
  681. set
  682. {
  683. if (value == m_confidenceThreshold) return;
  684. m_confidenceThreshold = Mathf.RoundToInt(Mathf.Clamp(value, 0, 100));
  685. if (Application.isPlaying && zedReady)
  686. {
  687. runtimeParameters.confidenceThreshold = m_confidenceThreshold;
  688. }
  689. }
  690. }
  691. [SerializeField]
  692. [HideInInspector]
  693. private int m_textureConfidenceThreshold = 100;
  694. /// <summary>
  695. /// How tolerant the ZED SDK is to low confidence values. Lower values filter more pixels.
  696. /// </summary>
  697. public int textureConfidenceThreshold
  698. {
  699. get
  700. {
  701. return m_textureConfidenceThreshold;
  702. }
  703. set
  704. {
  705. if (value == m_textureConfidenceThreshold) return;
  706. m_textureConfidenceThreshold = Mathf.RoundToInt(Mathf.Clamp(value, 0, 100));
  707. if (Application.isPlaying && zedReady)
  708. {
  709. runtimeParameters.textureConfidenceThreshold = m_textureConfidenceThreshold;
  710. }
  711. }
  712. }
  713. /// <summary>
  714. /// Options for enabling the depth measurement map for the right camera. Costs performance if on, even if not used.
  715. /// </summary>
  716. public enum RightDepthEnabledMode
  717. {
  718. /// <summary>
  719. /// Right depth measure will be enabled if a ZEDRenderingPlane component set to the right eye is detected as a child of
  720. /// ZEDManager's GameObject, as in the ZED rig prefabs.
  721. /// </summary>
  722. AUTO,
  723. /// <summary>
  724. /// Right depth measure is disabled.
  725. /// </summary>
  726. OFF,
  727. /// <summary>
  728. /// Right depth measure is enabled.
  729. /// </summary>
  730. ON
  731. }
  732. /// <summary>
  733. /// Whether to enable depth measurements from the right camera. Required for depth effects in AR pass-through, but requires performance even if not used.
  734. /// Auto enables it only if a ZEDRenderingPlane component set to the right eye is detected as a child of ZEDManager's GameObject (as in the ZED rig prefabs.)
  735. /// </summary>
  736. [HideInInspector]
  737. public RightDepthEnabledMode enableRightDepthMeasure = RightDepthEnabledMode.AUTO;
  738. /// <summary>
  739. /// Delegate for OnCamBrightnessChange, which is used to update shader properties when the brightness setting changes.
  740. /// </summary>
  741. public delegate void onCamBrightnessChangeDelegate(int newVal);
  742. /// <summary>
  743. /// Event fired when the camera brightness setting is changed. Used to update shader properties.
  744. /// </summary>
  745. public event onCamBrightnessChangeDelegate OnCamBrightnessChange;
  746. /// <summary>
  747. /// Delegate for OnCamBrightnessChange, which is used to update shader properties when the max depth setting changes.
  748. /// </summary>
  749. public delegate void onMaxDepthChangeDelegate(float newVal);
  750. /// <summary>
  751. /// Event fired when the max depth setting is changed. Used to update shader properties.
  752. /// </summary>
  753. public event onMaxDepthChangeDelegate OnMaxDepthChange;
  754. /// <summary>
  755. /// Whether to show the hidden camera rig used in stereo AR mode to prepare images for HMD output.
  756. /// </summary>
  757. [SerializeField]
  758. [HideInInspector]
  759. private bool showarrig = false;
  760. /// <summary>
  761. /// Whether to show the hidden camera rig used in stereo AR mode to prepare images for HMD output.
  762. /// <para>This is rarely needed, but can be useful for understanding how the ZED output works.</para>
  763. /// </summary>
  764. public bool showARRig
  765. {
  766. get
  767. {
  768. return showarrig;
  769. }
  770. set
  771. {
  772. if (Application.isPlaying && showarrig != value && zedRigDisplayer != null)
  773. {
  774. zedRigDisplayer.hideFlags = value ? HideFlags.None : HideFlags.HideInHierarchy;
  775. }
  776. showarrig = value;
  777. }
  778. }
  779. private float maxdepthrange = 40f;
  780. public float maxDepthRange
  781. {
  782. get
  783. {
  784. return maxdepthrange;
  785. }
  786. set
  787. {
  788. maxdepthrange = Mathf.Clamp(value, 0, 40);
  789. if (Application.isPlaying)
  790. {
  791. setRenderingSettings();
  792. }
  793. }
  794. }
  795. /// <summary>
  796. /// If true, and you are using a ZED2 or ZED Mini, IMU fusion uses data from the camera's IMU to improve tracking results.
  797. /// </summary>
  798. [HideInInspector]
  799. public bool enableIMUFusion = true;
  800. /// <summary>
  801. /// If true, the ZED SDK will subtly adjust the ZED's calibration during runtime to account for heat and other factors.
  802. /// Reasons to disable this are rare.
  803. /// </summary>
  804. [HideInInspector]
  805. public bool enableSelfCalibration = true;
  806. /////////////////////////////////////////////////////////////////////////
  807. ///////////////////////// Video Settings ////////////////////////////////
  808. /////////////////////////////////////////////////////////////////////////
  809. //Controls for the ZED's video settings (brightness, saturation, exposure, etc.)
  810. /// <summary>
  811. /// Behavior options for how the ZED's video settings (brightness, saturation, etc.) are applied when the ZED first connects.
  812. /// </summary>
  813. public enum VideoSettingsInitMode
  814. {
  815. /// <summary>
  816. /// Camera will be assigned video settings set in ZEDManager's Inspector before running the scene.
  817. /// </summary>
  818. Custom,
  819. /// <summary>
  820. /// Camera will load settings last applied to the ZED. May have been from a source outside Unity.
  821. /// This is the default behavior in the ZED SDK and most ZED apps.
  822. /// </summary>
  823. LoadFromSDK,
  824. /// <summary>
  825. /// Camera will load default video settings.
  826. /// </summary>
  827. Default
  828. }
  829. /// <summary>
  830. /// How the ZED's video settings (brightness, saturation, etc.) are applied when the ZED first connects.
  831. /// </summary>
  832. public VideoSettingsInitMode videoSettingsInitMode = VideoSettingsInitMode.Custom;
  833. /// <summary>
  834. /// Brightness setting for the ZED camera itself.
  835. /// Serialized value is applied to the camera on start when videoSettingsInitMode is set to Custom.
  836. /// </summary>
  837. [SerializeField]
  838. private int videoBrightness = 4;
  839. /// <summary>
  840. /// Contrast setting for the ZED camera itself.
  841. /// Serialized value is applied to the camera on start when videoSettingsInitMode is set to Custom.
  842. /// </summary>
  843. [SerializeField]
  844. private int videoContrast = 4;
  845. /// <summary>
  846. /// Hue setting for the ZED camera itself.
  847. /// Serialized value is applied to the camera on start when videoSettingsInitMode is set to Custom.
  848. /// </summary>
  849. [SerializeField]
  850. private int videoHue = 0;
  851. /// <summary>
  852. /// Saturation setting for the ZED camera itself.
  853. /// Serialized value is applied to the camera on start when videoSettingsInitMode is set to Custom.
  854. /// </summary>
  855. [SerializeField]
  856. private int videoSaturation = 4;
  857. /// <summary>
  858. /// Auto gain/exposure setting for the ZED camera itself.
  859. /// Serialized value is applied to the camera on start when videoSettingsInitMode is set to Custom.
  860. /// </summary>
  861. [SerializeField]
  862. private bool videoAutoGainExposure = true;
  863. /// <summary>
  864. /// Gain setting for the ZED camera itself.
  865. /// Serialized value is applied to the camera on start when videoSettingsInitMode is set to Custom and videoAutoGainExposure is false.
  866. /// </summary>
  867. [SerializeField]
  868. private int videoGain = 10;
  869. /// <summary>
  870. /// Exposure setting for the ZED camera itself.
  871. /// Serialized value is applied to the camera on start when videoSettingsInitMode is set to Custom and videoAutoGainExposure is false.
  872. /// </summary>
  873. [SerializeField]
  874. public int videoExposure = 100;
  875. /// <summary>
  876. /// Auto White Balance setting for the ZED camera itself.
  877. /// Serialized value is applied to the camera on start when videoSettingsInitMode is set to Custom.
  878. /// </summary>
  879. [SerializeField]
  880. private bool videoAutoWhiteBalance = true;
  881. /// <summary>
  882. /// White Balance temperature setting for the ZED camera itself.
  883. /// Serialized value is applied to the camera on start when videoSettingsInitMode is set to Custom and videoAutoWhiteBalance is false.
  884. /// </summary>
  885. [SerializeField]
  886. private int videoWhiteBalance = 3200;
  887. /// <summary>
  888. /// Sharpness setting for the ZED camera itself.
  889. /// Serialized value is applied to the camera on start when videoSettingsInitMode is set to Custom.
  890. /// </summary>
  891. [SerializeField]
  892. private int videoSharpness = 3;
  893. /// <summary>
  894. /// Sharpness setting for the ZED camera itself.
  895. /// Serialized value is applied to the camera on start when videoSettingsInitMode is set to Custom.
  896. /// </summary>
  897. [SerializeField]
  898. private int videoGamma = 5;
  899. /// <summary>
  900. /// Whether the LED on the ZED camera is on.
  901. /// Serialized value is applied to the camera on start when videoSettingsInitMode is set to Custom.
  902. /// </summary>
  903. [SerializeField]
  904. private bool videoLEDStatus = true;
  905. /////////////////////////////////////////////////////////////////////////
  906. ///////////////////////// Status Report /////////////////////////////////
  907. /////////////////////////////////////////////////////////////////////////
  908. //Strings used for the Status display in the Inspector.
  909. [Header("Status")]
  910. /// <summary>
  911. /// The camera model (ZED or ZED-M).
  912. /// </summary>
  913. [ReadOnly("Camera S/N")] [HideInInspector] public string cameraModel = "-";
  914. /// <summary>
  915. /// The camera serial number.
  916. /// </summary>
  917. [ReadOnly("Camera S/N")] [HideInInspector] public string cameraSerialNumber = "-";
  918. /// <summary>
  919. /// The camera firmware version
  920. /// </summary>
  921. [ReadOnly("Camera Firmware")] [HideInInspector] public string cameraFirmware = "-";
  922. /// <summary>
  923. /// Version of the installed ZED SDK, for display in the Inspector.
  924. /// </summary>
  925. [ReadOnly("Version")] [HideInInspector] public string versionZED = "-";
  926. /// <summary>
  927. /// How many frames per second the engine is rendering, for display in the Inspector.
  928. /// </summary>
  929. [ReadOnly("Engine FPS")] [HideInInspector] public string engineFPS = "-";
  930. /// <summary>
  931. /// How many images per second are received from the ZED, for display in the Inspector.
  932. /// </summary>
  933. [ReadOnly("Camera FPS")] [HideInInspector] public string cameraFPS = "-";
  934. /// <summary>
  935. /// The connected VR headset, if any, for display in the Inspector.
  936. /// </summary>
  937. [ReadOnly("HMD Device")] [HideInInspector] public string HMDDevice = "-";
  938. /// <summary>
  939. /// Whether the ZED's tracking is on, off, or searching (lost position, trying to recover) for display in the Inspector.
  940. /// </summary>
  941. [ReadOnly("Tracking State")] [HideInInspector] public string trackingState = "-";
  942. /// <summary>
  943. /// Object detection framerate
  944. /// </summary>
  945. [ReadOnly("Object Detection FPS")] [HideInInspector] public string objectDetectionFPS = "-";
  946. ////////////////////////////
  947. //////// Private ///////////
  948. ////////////////////////////
  949. /// <summary>
  950. /// Initialization parameters used to start the ZED. Holds settings that can't be changed at runtime
  951. /// (resolution, depth mode, .SVO path, etc.).
  952. /// </summary>
  953. private sl.InitParameters initParameters;
  954. /// <summary>
  955. /// Runtime parameters used to grab a new image. Settings can change each frame, but are lower level
  956. /// (sensing mode, point cloud, if depth is enabled, etc.).
  957. /// </summary>
  958. private sl.RuntimeParameters runtimeParameters;
  959. /// <summary>
  960. /// Enables the ZED SDK's depth stabilizer, which improves depth accuracy and stability. There's rarely a reason to disable this.
  961. /// </summary>
  962. private bool depthStabilizer = true;
  963. /// <summary>
  964. /// Indicates if Sensors( IMU,...) is needed/required. For most applications, it is required.
  965. /// Sensors are transmitted through USB2.0 lines. If USB2 is not available (USB3.0 only extension for example), set it to false.
  966. /// </summary>
  967. private bool sensorsRequired = false;
  968. /// <summary>
  969. /// Set the camera in Flip mode
  970. /// </summary>
  971. private sl.FLIP_MODE cameraFlipMode = sl.FLIP_MODE.AUTO;
  972. /// <summary>
  973. /// Whether the camera is currently being tracked using the ZED's inside-out tracking.
  974. /// </summary>ccvv
  975. private bool isZEDTracked = false;
  976. /// <summary>
  977. /// Whether the ZED's inside-out tracking has been activated.
  978. /// </summary>
  979. private bool isTrackingEnable = false;
  980. /// <summary>
  981. /// Whether the camera is tracked in any way (ZED's tracking or a VR headset's tracking).
  982. /// </summary>
  983. private bool isCameraTracked = false;
  984. /// <summary>
  985. /// Public accessor for whether the camera is tracked in any way (ZED's tracking or a VR headset's tracking).
  986. /// </summary>
  987. public bool IsCameraTracked
  988. {
  989. get { return isCameraTracked; }
  990. }
  991. /// <summary>
  992. /// Whether the camera has a new frame available.
  993. /// </summary>
  994. private bool isNewFrameGrabbed = false;
  995. /// <summary>
  996. /// Public accessor for whether the camera has a new frame available.
  997. /// </summary>
  998. public bool IsNewFrameGrabbed
  999. {
  1000. get { return isNewFrameGrabbed; }
  1001. }
  1002. /// <summary>
  1003. /// Orientation last returned by the ZED's tracking.
  1004. /// </summary>
  1005. private Quaternion zedOrientation = Quaternion.identity;
  1006. /// <summary>
  1007. /// Position last returned by the ZED's tracking.
  1008. /// </summary>
  1009. private Vector3 zedPosition = Vector3.zero;
  1010. /// <summary>
  1011. /// If Estimate Initial Position is true and we're in SVO mode with Loop enabled, we'll want to cache our first pose to initialPosition and initialRotation.
  1012. /// This flag lets us know if we've done that yet so we can only assign them on the first tracked frame.
  1013. /// </summary>
  1014. private bool initialPoseCached = false;
  1015. /// <summary>
  1016. /// Position of the camera (zedRigRoot) when the scene starts. Not used in Stereo AR.
  1017. /// </summary>
  1018. private Vector3 initialPosition = new Vector3();
  1019. /// <summary>
  1020. /// Orientation of the camera (zedRigRoot) when the scene starts. Not used in Stereo AR.
  1021. /// </summary>
  1022. private Quaternion initialRotation = Quaternion.identity;
  1023. /// <summary>
  1024. /// Sensing mode: STANDARD or FILL. FILL corrects for missing depth values.
  1025. /// Almost always better to use FILL, since we need depth without holes for proper occlusion.
  1026. /// </summary>
  1027. [SerializeField]
  1028. [HideInInspector]
  1029. public sl.SENSING_MODE sensingMode = sl.SENSING_MODE.FILL;
  1030. /// <summary>
  1031. /// Rotation offset used to retrieve the tracking with a rotational offset.
  1032. /// </summary>
  1033. private Quaternion rotationOffset;
  1034. /// <summary>
  1035. /// Position offset used to retrieve the tracking with a positional offset.
  1036. /// </summary>
  1037. private Vector3 positionOffset;
  1038. /// <summary>
  1039. /// Enables pose smoothing during drift correction. Leave it to true.
  1040. /// </summary>
  1041. private bool enablePoseSmoothing = true;
  1042. [HideInInspector]
  1043. public sl.ERROR_CODE ZEDGrabError = sl.ERROR_CODE.FAILURE;
  1044. #if UNITY_EDITOR
  1045. /// <summary>
  1046. /// The engine FPS, updated every frame.
  1047. /// </summary>
  1048. private float fps_engine = 90.0f;
  1049. #endif
  1050. /// <summary>
  1051. /// Recording state
  1052. /// </summary>
  1053. private bool isRecording = false;
  1054. ///////////////////////////////////////
  1055. /////////// Static States /////////////
  1056. ///////////////////////////////////////
  1057. /// <summary>
  1058. /// Whether AR mode is activated.
  1059. /// </summary>
  1060. private bool isStereoRig = false;
  1061. /// <summary>
  1062. /// Whether AR mode is activated. Assigned by ZEDManager.CheckStereoMode() in Awake().
  1063. /// Will be true if the ZED_Rig_Stereo prefab (or a similarly-structured prefab) is used.
  1064. /// </summary>
  1065. public bool IsStereoRig
  1066. {
  1067. get { return isStereoRig; }
  1068. }
  1069. /// <summary>
  1070. /// Checks if the ZED has finished initializing.
  1071. /// </summary>
  1072. private bool zedReady = false;
  1073. /// <summary>
  1074. /// Checks if the ZED has finished initializing.
  1075. /// </summary>
  1076. public bool IsZEDReady
  1077. {
  1078. get { return zedReady; }
  1079. }
  1080. /// <summary>
  1081. /// Flag set to true if the camera was connected and the wasn't anymore.
  1082. /// Causes ZEDDisconnected() to be called each frame, which attemps to restart it.
  1083. /// </summary>
  1084. private bool isDisconnected = false;
  1085. /// <summary>
  1086. /// Current state of tracking: On, Off, or Searching (lost tracking, trying to recover). Used by anti-drift.
  1087. /// </summary>
  1088. private sl.TRACKING_STATE zedtrackingState = sl.TRACKING_STATE.TRACKING_OFF;
  1089. /// <summary>
  1090. /// Current state of tracking: On, Off, or Searching (lost tracking, trying to recover). Used by anti-drift.
  1091. /// </summary>
  1092. public sl.TRACKING_STATE ZEDTrackingState
  1093. {
  1094. get { return zedtrackingState; }
  1095. }
  1096. /// <summary>
  1097. /// First position registered after the tracking has started (whether via ZED or a VR HMD).
  1098. /// </summary>
  1099. public Vector3 OriginPosition { get; private set; }
  1100. /// <summary>
  1101. /// First rotation/orientation registered after the tracking has started (whether via ZED or a VR HMD).
  1102. /// </summary>
  1103. public Quaternion OriginRotation { get; private set; }
  1104. /// <summary>
  1105. /// In AR pass-through mode, whether to compare the ZED's IMU data against the reported position of
  1106. /// the VR headset. This helps compensate for drift and should usually be left on.
  1107. /// However, in some setups, like when using a custom mount, this can cause tracking errors.
  1108. /// </summary><remarks>
  1109. /// Read more about the potential errors here: https://support.stereolabs.com/hc/en-us/articles/360026482413
  1110. /// </remarks>
  1111. public bool setIMUPriorInAR = true;
  1112. /// <summary>
  1113. /// If true, the ZED rig will enter 'pass-through' mode if it detects a stereo rig - at least two cameras as children with ZEDRenderingPlane
  1114. /// components, each with a different eye) - and a VR headset is connected. If false, it will never enter pass-through mode.
  1115. /// </summary>
  1116. public bool allowARPassThrough = true;
  1117. ///////////////////////////////////////////////////
  1118. [HideInInspector] public Quaternion gravityRotation = Quaternion.identity;
  1119. [HideInInspector] public Vector3 ZEDSyncPosition;
  1120. [HideInInspector] public Vector3 HMDSyncPosition;
  1121. [HideInInspector] public Quaternion ZEDSyncRotation;
  1122. [HideInInspector] public Quaternion HMDSyncRotation;
  1123. /// <summary>
  1124. /// Image acquisition thread.
  1125. /// </summary>
  1126. private Thread threadGrab = null;
  1127. /// <summary>
  1128. /// State of the image acquisition thread.
  1129. /// </summary>
  1130. private bool running = false;
  1131. /// <summary>
  1132. /// Initialization thread.
  1133. /// </summary>
  1134. private Thread threadOpening = null;
  1135. /// <summary>
  1136. /// Result of the latest attempt to initialize the ZED.
  1137. /// </summary>
  1138. private sl.ERROR_CODE lastInitStatus = sl.ERROR_CODE.ERROR_CODE_LAST;
  1139. public sl.ERROR_CODE LastInitStatus { get { return lastInitStatus; } }
  1140. /// <summary>
  1141. /// State of the ZED initialization thread.
  1142. /// </summary>
  1143. private bool openingLaunched;
  1144. /// <summary>
  1145. /// Wait Handle used to safely tell the init thread to shut down.
  1146. /// </summary>
  1147. EventWaitHandle initQuittingHandle;
  1148. /// <summary>
  1149. /// When true, the init thread will close early instead of completing all its connection attempts.
  1150. /// Set to true when the application is closed before a camera finishes its initialization.
  1151. /// </summary>
  1152. private bool forceCloseInit = false;
  1153. /// <summary>
  1154. /// Tracking initialization thread. Used as the tracking takes some time to start.
  1155. /// </summary>
  1156. private Thread trackerThread = null;
  1157. ///////////////////////////////////////////
  1158. ////// Camera and Player Transforms //////
  1159. ///////////////////////////////////////////
  1160. /// <summary>
  1161. /// Transform of the left camera in the ZED rig.
  1162. /// </summary>
  1163. private Transform camLeftTransform = null;
  1164. /// <summary>
  1165. /// Transform of the right camera in the ZED rig. Only exists in a stereo rig (like ZED_Rig_Stereo).
  1166. /// </summary>
  1167. private Transform camRightTransform = null;
  1168. /// <summary>
  1169. /// Contains the position of the player's head, which is different from the ZED's position in AR mode.
  1170. /// But its position relative to the ZED does not change during use (it's a rigid transform).
  1171. /// In ZED_Rig_Mono, this will be the root ZED_Rig_Mono object. In ZED_Rig_Stereo, this is Camera_eyes.
  1172. /// </summary>
  1173. private Transform zedRigRoot = null;
  1174. /// <summary>
  1175. /// Left camera in the ZED rig. Also the "main" camera if in ZED_Rig_Mono.
  1176. /// </summary>
  1177. private Camera cameraLeft;
  1178. /// <summary>
  1179. /// Right camera of the ZED rig. Only exists in a stereo rig (like ZED_Rig_Stereo).
  1180. /// </summary>
  1181. private Camera cameraRight;
  1182. /// <summary>
  1183. /// Gets the center transform, which is the transform moved by the tracker in AR mode.
  1184. /// This is the root object in ZED_Rig_Mono, and Camera_eyes in ZED_Rig_Stereo.
  1185. /// </summary>
  1186. public Transform GetZedRootTansform()
  1187. {
  1188. return zedRigRoot;
  1189. }
  1190. /// <summary>
  1191. /// Returns the left ZED camera transform. If there is no left camera but there is a right camera,
  1192. /// returns the right camera transform instead.
  1193. /// </summary>
  1194. /// <returns></returns>
  1195. public Transform GetMainCameraTransform()
  1196. {
  1197. if (camLeftTransform) return camLeftTransform;
  1198. else if (camRightTransform) return camRightTransform;
  1199. else return null;
  1200. }
  1201. /// <summary>
  1202. /// Gets the left camera transform in the ZED rig. It's best to use this one as it's available in all configurations.
  1203. /// </summary>
  1204. public Transform GetLeftCameraTransform()
  1205. {
  1206. return camLeftTransform;
  1207. }
  1208. /// <summary>
  1209. /// Get the right camera transform in the ZED rig. Only available in the stereo rig (ZED_Rig_Stereo).
  1210. /// </summary>
  1211. public Transform GetRightCameraTransform()
  1212. {
  1213. return camRightTransform;
  1214. }
  1215. /// <summary>
  1216. /// Returns the left ZED camera. If there is no left camera but there is a right camera,
  1217. /// returns the right camera instead.
  1218. /// </summary>
  1219. /// <returns></returns>
  1220. public Camera GetMainCamera()
  1221. {
  1222. if (cameraLeft) return cameraLeft;
  1223. else if (cameraRight) return cameraRight;
  1224. else return null;
  1225. }
  1226. /// <summary>
  1227. /// Gets the left camera in the ZED rig. Both ZED_Rig_Mono and ZED_Rig_Stereo have a left camera by default.
  1228. /// </summary>
  1229. public Camera GetLeftCamera()
  1230. {
  1231. if (cameraLeft == null && camLeftTransform != null)
  1232. cameraLeft = camLeftTransform.GetComponent<Camera>();
  1233. return cameraLeft;
  1234. }
  1235. /// <summary>
  1236. /// Get the right camera in the ZED rig. Only available in the stereo rig (ZED_Rig_Stereo) unless configured otherwise.
  1237. /// </summary>
  1238. public Camera GetRightCamera()
  1239. {
  1240. if (cameraRight == null && camRightTransform != null)
  1241. cameraRight = camRightTransform.GetComponent<Camera>();
  1242. return cameraRight;
  1243. }
  1244. #pragma warning disable 414
  1245. /// <summary>
  1246. /// Save the foldout options as it was used last time
  1247. /// </summary>
  1248. [SerializeField]
  1249. [HideInInspector]
  1250. private bool advancedPanelOpen = false;
  1251. [SerializeField]
  1252. [HideInInspector]
  1253. private bool spatialMappingFoldoutOpen = false;
  1254. [SerializeField]
  1255. [HideInInspector]
  1256. private bool objectDetectionFoldoutOpen = false;
  1257. [SerializeField]
  1258. [HideInInspector]
  1259. private bool recordingFoldoutOpen = false;
  1260. [SerializeField]
  1261. [HideInInspector]
  1262. private bool streamingOutFoldoutOpen = false;
  1263. [SerializeField]
  1264. [HideInInspector]
  1265. private bool camControlFoldoutOpen = false;
  1266. #pragma warning restore 414
  1267. /////////////////////////////////////
  1268. ////// Timestamps //////
  1269. /////////////////////////////////////
  1270. /// <summary>
  1271. /// Timestamp of the last ZED image grabbed. Textures from this grab may not have updated yet.
  1272. /// </summary>
  1273. private ulong cameraTimeStamp = 0;
  1274. /// <summary>
  1275. /// Timestamp of the last ZED image grabbed. Textures from this grab may not have updated yet.
  1276. /// </summary>
  1277. public ulong CameraTimeStamp
  1278. {
  1279. get { return cameraTimeStamp; }
  1280. }
  1281. /// <summary>
  1282. /// Timestamp of the images used to create the current textures.
  1283. /// </summary>
  1284. private ulong imageTimeStamp = 0;
  1285. /// <summary>
  1286. /// Timestamp of the images used to create the current textures.
  1287. /// </summary>
  1288. public ulong ImageTimeStamp
  1289. {
  1290. get { return imageTimeStamp; }
  1291. }
  1292. /// <summary>
  1293. /// Whether the grabbing thread should grab a new frame from the ZED SDK.
  1294. /// True unless the last grabbed frame hasn't been applied yet, or the ZED isn't initialized.
  1295. /// </summary>
  1296. private bool requestNewFrame = false;
  1297. /// <summary>
  1298. /// Whether a new frame has been grabbed from the ZED SDK that needs to be updated.
  1299. /// </summary>
  1300. private bool newFrameAvailable = false;
  1301. /////////////////////////////////////
  1302. ////// Layers for ZED //////
  1303. /////////////////////////////////////
  1304. /// <summary>
  1305. /// Layer assigned to the cameras and objects of a (normally hidden) AR camera rig created to handle
  1306. /// pass-through AR. This allows the cameras to see nothing but two canvas objects with the final MR images.
  1307. /// </summary>
  1308. [HideInInspector]
  1309. public int arLayer
  1310. {
  1311. get
  1312. {
  1313. return ZEDLayers.arlayer;
  1314. }
  1315. }
  1316. [SerializeField]
  1317. [HideInInspector]
  1318. //private int arlayer = 30;
  1319. /////////////////////////////////////
  1320. ////// ZED specific events //////
  1321. /////////////////////////////////////
  1322. /// <summary>
  1323. /// Delegate for OnZEDReady.
  1324. /// </summary>
  1325. public delegate void OnZEDManagerReady();
  1326. /// <summary>
  1327. /// Called when the ZED has finished initializing successfully.
  1328. /// Used by many scripts to run startup logic that requires that the ZED is active.
  1329. /// </summary>
  1330. public event OnZEDManagerReady OnZEDReady;
  1331. /// <summary>
  1332. /// Delegate for OnZEDDisconnected.
  1333. /// </summary>
  1334. public delegate void OnZEDManagerDisconnected();
  1335. /// <summary>
  1336. /// Event called when ZED was running but became disconnected.
  1337. /// </summary>
  1338. public event OnZEDManagerDisconnected OnZEDDisconnected;
  1339. /// <summary>
  1340. /// Delegate for new Frame grabbed for external module update
  1341. /// </summary>
  1342. public delegate void OnGrabAction();
  1343. /// <summary>
  1344. /// Event called when ZED has grabbed a new frame.
  1345. /// </summary>
  1346. public event OnGrabAction OnGrab;
  1347. #region CHECK_AR
  1348. private bool hasXRDevice()
  1349. {
  1350. #if UNITY_2020_1_OR_NEWER
  1351. var xrDisplaySubsystems = new List<XRDisplaySubsystem>();
  1352. SubsystemManager.GetInstances<XRDisplaySubsystem>(xrDisplaySubsystems);
  1353. foreach (var xrDisplay in xrDisplaySubsystems)
  1354. {
  1355. if (xrDisplay.running)
  1356. {
  1357. return true;
  1358. }
  1359. }
  1360. return false;
  1361. #else
  1362. return XRDevice.isPresent;
  1363. #endif
  1364. }
  1365. /// <summary>
  1366. /// Checks if this GameObject is a stereo rig. Requires a child object called 'Camera_eyes' and
  1367. /// two cameras as children of that object, one with stereoTargetEye set to Left, the other two Right.
  1368. /// Regardless, sets references to leftCamera and (if relevant) rightCamera.
  1369. /// </summary>
  1370. private void CheckStereoMode()
  1371. {
  1372. zedRigRoot = gameObject.transform; //The object moved by tracking. By default it's this Transform. May get changed.
  1373. bool devicePresent = hasXRDevice(); //May not need.
  1374. //Set first left eye
  1375. Component[] cams = gameObject.GetComponentsInChildren<Camera>();
  1376. //Camera firstmonocam = null;
  1377. List<Camera> monocams = new List<Camera>();
  1378. foreach (Camera cam in cams)
  1379. {
  1380. switch (cam.stereoTargetEye)
  1381. {
  1382. case StereoTargetEyeMask.Left:
  1383. if (!cameraLeft)
  1384. {
  1385. cameraLeft = cam;
  1386. camLeftTransform = cam.transform;
  1387. }
  1388. break;
  1389. case StereoTargetEyeMask.Right:
  1390. if (!cameraRight)
  1391. {
  1392. cameraRight = cam;
  1393. camRightTransform = cam.transform;
  1394. }
  1395. break;
  1396. case StereoTargetEyeMask.None:
  1397. monocams.Add(cam);
  1398. break;
  1399. case StereoTargetEyeMask.Both:
  1400. default:
  1401. break;
  1402. }
  1403. }
  1404. //If the left camera or right camera haven't been assigned via stereo target eyes, search the monocams
  1405. //based on their ZEDRenderingPlane assignments.
  1406. //This won't affect whether the rig is in stereo mode, but allows the cameras to be accessed via GetLeftCamera() and GetRightCamera().
  1407. if (cameraLeft == null || cameraRight == null)
  1408. {
  1409. foreach (Camera cam in monocams)
  1410. {
  1411. ZEDRenderingPlane rendplane = cam.gameObject.GetComponent<ZEDRenderingPlane>();
  1412. if (!rendplane) continue;
  1413. if (!cameraLeft && (rendplane.viewSide == ZEDRenderingPlane.ZED_CAMERA_SIDE.LEFT || rendplane.viewSide == ZEDRenderingPlane.ZED_CAMERA_SIDE.LEFT_FORCE))
  1414. {
  1415. cameraLeft = cam;
  1416. camLeftTransform = cam.transform;
  1417. }
  1418. else if (!cameraRight && (rendplane.viewSide == ZEDRenderingPlane.ZED_CAMERA_SIDE.RIGHT || rendplane.viewSide == ZEDRenderingPlane.ZED_CAMERA_SIDE.RIGHT_FORCE))
  1419. {
  1420. cameraRight = cam;
  1421. camRightTransform = cam.transform;
  1422. }
  1423. }
  1424. }
  1425. if (camLeftTransform && camRightTransform && cameraLeft.stereoTargetEye == StereoTargetEyeMask.Left) //We found both a left- and right-eye camera.
  1426. {
  1427. if (camLeftTransform.transform.parent != null)
  1428. {
  1429. zedRigRoot = camLeftTransform.parent; //Make the camera's parent object (Camera_eyes in the ZED_Rig_Stereo prefab) the new zedRigRoot to be tracked.
  1430. }
  1431. if (hasXRDevice() && allowARPassThrough)
  1432. {
  1433. isStereoRig = true;
  1434. }
  1435. else
  1436. {
  1437. isStereoRig = false;
  1438. //If there's no VR headset, then cameras set to Left and Right won't display in Unity. Set them both to None.
  1439. if (cameraLeft) cameraLeft.stereoTargetEye = StereoTargetEyeMask.None;
  1440. if (cameraRight) cameraRight.stereoTargetEye = StereoTargetEyeMask.None;
  1441. }
  1442. }
  1443. else //Not all conditions for a stereo rig were met.
  1444. {
  1445. isStereoRig = false;
  1446. if (camLeftTransform)
  1447. {
  1448. Camera caml = camLeftTransform.gameObject.GetComponent<Camera>();
  1449. cameraLeft = caml;
  1450. if (camLeftTransform.transform.parent != null)
  1451. zedRigRoot = camLeftTransform.parent;
  1452. }
  1453. else
  1454. {
  1455. zedRigRoot = transform;
  1456. }
  1457. }
  1458. }
  1459. #endregion
  1460. /// <summary>
  1461. /// Sets the target GameObject and all its children to the specified layer.
  1462. /// </summary>
  1463. /// <param name="go">Target GameObject.</param>
  1464. /// <param name="layerNumber">Layer that the GameObject and all children will be set to.</param>
  1465. public static void SetLayerRecursively(GameObject go, int layerNumber)
  1466. {
  1467. if (go == null) return;
  1468. foreach (Transform trans in go.GetComponentsInChildren<Transform>(true))
  1469. {
  1470. trans.gameObject.layer = layerNumber;
  1471. }
  1472. }
  1473. /// <summary>
  1474. /// Stops the initialization and grabbing threads.
  1475. /// </summary>
  1476. public void Destroy()
  1477. {
  1478. running = false;
  1479. //In case the opening thread is still running.
  1480. if (threadOpening != null)
  1481. {
  1482. initQuittingHandle.Reset();
  1483. forceCloseInit = true;
  1484. initQuittingHandle.Set();
  1485. threadOpening.Join();
  1486. threadOpening = null;
  1487. }
  1488. //Shut down the image grabbing thread.
  1489. if (threadGrab != null)
  1490. {
  1491. threadGrab.Join();
  1492. threadGrab = null;
  1493. }
  1494. if (IsMappingRunning)
  1495. StopSpatialMapping();
  1496. Thread.Sleep(10);
  1497. }
  1498. /// <summary>
  1499. /// Called by Unity when the application is closed.
  1500. /// Also called by Reset() to properly start from a 'clean slate.'
  1501. /// </summary>
  1502. private void OnApplicationQuit()
  1503. {
  1504. CloseManager();
  1505. //sl.ZEDCamera.UnloadPlugin();
  1506. //If this was the last camera to close, make sure all instances are closed.
  1507. bool notlast = false;
  1508. foreach (ZEDManager manager in ZEDManagerInstance)
  1509. {
  1510. if (manager != null && manager.IsZEDReady == true)
  1511. {
  1512. notlast = true;
  1513. break;
  1514. }
  1515. }
  1516. if (notlast == false)
  1517. {
  1518. sl.ZEDCamera.UnloadPlugin();
  1519. }
  1520. }
  1521. private void CloseManager()
  1522. {
  1523. if (spatialMapping != null)
  1524. spatialMapping.Dispose();
  1525. if (IsObjectDetectionRunning)
  1526. {
  1527. StopObjectDetection();
  1528. }
  1529. #if !ZED_HDRP && !ZED_URP
  1530. ClearRendering();
  1531. #endif
  1532. zedReady = false;
  1533. OnCamBrightnessChange -= SetCameraBrightness;
  1534. OnMaxDepthChange -= SetMaxDepthRange;
  1535. Destroy(); //Close the grab and initialization threads.
  1536. if (zedCamera != null)
  1537. {
  1538. if (isRecording)
  1539. {
  1540. zedCamera.DisableRecording();
  1541. }
  1542. zedCamera.Destroy();
  1543. zedCamera = null;
  1544. }
  1545. #if UNITY_EDITOR //Prevents building the app otherwise.
  1546. //Restore the AR layers that were hidden, if necessary.
  1547. if (!showarrig)
  1548. {
  1549. LayerMask layerNumberBinary = (1 << arLayer); //Convert layer index into binary number.
  1550. UnityEditor.Tools.visibleLayers |= (layerNumberBinary);
  1551. }
  1552. #endif
  1553. sl.ZEDCamera.UnloadInstance((int)cameraID);
  1554. }
  1555. #if !ZED_HDRP && !ZED_URP
  1556. private void ClearRendering()
  1557. {
  1558. if (camLeftTransform != null)
  1559. {
  1560. ZEDRenderingPlane leftRenderingPlane = camLeftTransform.GetComponent<ZEDRenderingPlane>();
  1561. if (leftRenderingPlane)
  1562. {
  1563. leftRenderingPlane.Clear();
  1564. }
  1565. }
  1566. if (IsStereoRig)
  1567. {
  1568. ZEDRenderingPlane rightRenderingPlane = GetRightCameraTransform().GetComponent<ZEDRenderingPlane>();
  1569. rightRenderingPlane.Clear();
  1570. }
  1571. }
  1572. #endif
  1573. /// <summary>
  1574. /// Sets up starting properties and starts the ZED initialization co-routine.
  1575. /// </summary>
  1576. void Awake()
  1577. {
  1578. // If never initialized, init the array of instances linked to each ZEDManager that could be created.
  1579. if (ZEDManagerInstance == null)
  1580. {
  1581. ZEDManagerInstance = new ZEDManager[(int)sl.Constant.MAX_CAMERA_PLUGIN];
  1582. for (int i = 0; i < (int)sl.Constant.MAX_CAMERA_PLUGIN; i++)
  1583. ZEDManagerInstance[i] = null;
  1584. }
  1585. initialPosition = transform.localPosition;
  1586. initialRotation = transform.localRotation;
  1587. zedReady = false;
  1588. ZEDManagerInstance[(int)cameraID] = this;
  1589. zedCamera = new sl.ZEDCamera();
  1590. if (dontDestroyOnLoad) DontDestroyOnLoad(transform.root); //If you want the ZED rig not to be destroyed when loading a scene.
  1591. //Set first few parameters for initialization. This will get passed to the ZED SDK when initialized.
  1592. initParameters = new sl.InitParameters();
  1593. initParameters.resolution = resolution;
  1594. initParameters.cameraFPS = FPS;
  1595. initParameters.cameraDeviceID = (int)cameraID;
  1596. initParameters.depthMode = depthMode;
  1597. initParameters.depthStabilization = depthStabilizer;
  1598. initParameters.sensorsRequired = sensorsRequired;
  1599. initParameters.depthMaximumDistance = 40.0f; // 40 meters should be enough for all applications
  1600. initParameters.cameraImageFlip = (int)cameraFlipMode;
  1601. initParameters.enableImageEnhancement = enableImageEnhancement;
  1602. initParameters.cameraDisableSelfCalib = !enableSelfCalibration;
  1603. initParameters.optionalOpencvCalibrationFile = opencvCalibFile;
  1604. //Check if this rig is a stereo rig. Will set isStereoRig accordingly.
  1605. CheckStereoMode();
  1606. //Set initialization parameters that may change depending on what was done in CheckStereoMode().
  1607. isZEDTracked = enableTracking;
  1608. zedPosition = initialPosition;
  1609. zedOrientation = initialRotation;
  1610. lastInitStatus = sl.ERROR_CODE.ERROR_CODE_LAST;
  1611. bool res = zedCamera.CreateCamera((int)cameraID, wrapperVerbose);
  1612. if (!res)
  1613. {
  1614. Debug.LogError("ZEDManager on " + gameObject.name + " couldn't connect to camera: " + cameraID +
  1615. ". Check if another ZEDManager is already connected.");
  1616. this.gameObject.SetActive(false);
  1617. return;
  1618. }
  1619. initParameters.inputType = inputType;
  1620. if (inputType == sl.INPUT_TYPE.INPUT_TYPE_USB)
  1621. {
  1622. }
  1623. else if (inputType == sl.INPUT_TYPE.INPUT_TYPE_SVO)
  1624. {
  1625. initParameters.pathSVO = svoInputFileName;
  1626. initParameters.svoRealTimeMode = svoRealTimeMode;
  1627. }
  1628. else if (inputType == sl.INPUT_TYPE.INPUT_TYPE_STREAM)
  1629. {
  1630. initParameters.ipStream = streamInputIP;
  1631. initParameters.portStream = (ushort)streamInputPort;
  1632. }
  1633. versionZED = "[SDK]: " + sl.ZEDCamera.GetSDKVersion().ToString() + " [Plugin]: " + sl.ZEDCamera.PluginVersion.ToString();
  1634. //Behavior specific to AR pass-through mode.
  1635. if (isStereoRig)
  1636. {
  1637. //Creates a hidden camera rig that handles final output to the headset.
  1638. GameObject o = CreateZEDRigDisplayer();
  1639. if (!showarrig) o.hideFlags = HideFlags.HideInHierarchy;
  1640. o.transform.parent = transform;
  1641. initParameters.depthMinimumDistance = 0.1f; //Allow depth calculation to very close objects.
  1642. //For the Game/output window, mirror the headset view using a custom script that avoids stretching.
  1643. CreateMirror();
  1644. }
  1645. //Determine if we should enable the right depth measurement, which costs performance but is needed for pass-through AR.
  1646. switch (enableRightDepthMeasure)
  1647. {
  1648. case RightDepthEnabledMode.AUTO:
  1649. default:
  1650. if (isStereoRig) //If so, we've already determined we have both a left and right ZEDRenderingPlane, so skip the lookups.
  1651. {
  1652. initParameters.enableRightSideMeasure = true;
  1653. }
  1654. else
  1655. {
  1656. foreach (ZEDRenderingPlane renderplane in GetComponentsInChildren<ZEDRenderingPlane>())
  1657. {
  1658. //If we have any ZEDRenderingPlanes that are looking through the right side, enable the measurements.
  1659. if (renderplane.viewSide == ZEDRenderingPlane.ZED_CAMERA_SIDE.RIGHT ||
  1660. renderplane.viewSide == ZEDRenderingPlane.ZED_CAMERA_SIDE.RIGHT_FORCE)
  1661. {
  1662. initParameters.enableRightSideMeasure = true;
  1663. break;
  1664. }
  1665. }
  1666. }
  1667. break;
  1668. case RightDepthEnabledMode.OFF:
  1669. initParameters.enableRightSideMeasure = false;
  1670. break;
  1671. case RightDepthEnabledMode.ON:
  1672. initParameters.enableRightSideMeasure = true;
  1673. break;
  1674. }
  1675. //Starts a coroutine that initializes the ZED without freezing the game.
  1676. lastInitStatus = sl.ERROR_CODE.ERROR_CODE_LAST;
  1677. openingLaunched = false;
  1678. StartCoroutine(InitZED());
  1679. OnCamBrightnessChange += SetCameraBrightness; //Subscribe event for adjusting brightness setting.
  1680. OnMaxDepthChange += SetMaxDepthRange;
  1681. //Create Module Object
  1682. //Create the spatial mapping module object (even if not used necessarly)
  1683. spatialMapping = new ZEDSpatialMapping(transform, this);
  1684. }
  1685. void Start()
  1686. {
  1687. //adjust layers for multiple camera
  1688. //setLayersForMultiCamera ();
  1689. }
  1690. #region INITIALIZATION
  1691. //const int MAX_OPENING_TRIES = 10;
  1692. private uint numberTriesOpening = 0;/// Counter of tries to open the ZED
  1693. /// <summary>
  1694. /// ZED opening function. Should be called in the initialization thread (threadOpening).
  1695. /// </summary>
  1696. private void OpenZEDInBackground()
  1697. {
  1698. openingLaunched = true;
  1699. int timeout = 0;
  1700. do
  1701. {
  1702. initQuittingHandle.WaitOne(0); //Makes sure we haven't been turned off early, which only happens in Destroy() from OnApplicationQuit().
  1703. if (forceCloseInit) break;
  1704. lastInitStatus = zedCamera.Init(ref initParameters);
  1705. timeout++;
  1706. numberTriesOpening++;
  1707. } while (lastInitStatus != sl.ERROR_CODE.SUCCESS);
  1708. }
  1709. /// <summary>
  1710. /// Initialization coroutine.
  1711. /// </summary>
  1712. private System.Collections.IEnumerator InitZED()
  1713. {
  1714. zedReady = false;
  1715. if (!openingLaunched)
  1716. {
  1717. initQuittingHandle = new EventWaitHandle(true, EventResetMode.ManualReset);
  1718. threadOpening = new Thread(new ThreadStart(OpenZEDInBackground)); //Assign thread.
  1719. threadOpening.Start();
  1720. }
  1721. while (lastInitStatus != sl.ERROR_CODE.SUCCESS)
  1722. {
  1723. yield return new WaitForSeconds(0.3f);
  1724. }
  1725. //ZED has initialized successfully.
  1726. if (lastInitStatus == sl.ERROR_CODE.SUCCESS)
  1727. {
  1728. threadOpening.Join();
  1729. //Initialize the tracking thread, AR initial transforms and SVO read/write as needed.
  1730. ZEDReady();
  1731. //If using tracking, wait until the tracking thread has been initialized.
  1732. while (enableTracking && !isTrackingEnable)
  1733. {
  1734. yield return new WaitForSeconds(0.5f);
  1735. }
  1736. //Tells all the listeners that the ZED is ready! :)
  1737. if (OnZEDReady != null)
  1738. {
  1739. OnZEDReady();
  1740. }
  1741. //Make sure the screen is at 16:9 aspect ratio or close. Warn the user otherwise.
  1742. float ratio = (float)Screen.width / (float)Screen.height;
  1743. float target = 16.0f / 9.0f;
  1744. if (Mathf.Abs(ratio - target) > 0.01)
  1745. {
  1746. Debug.LogWarning(ZEDLogMessage.Error2Str(ZEDLogMessage.ERROR.SCREEN_RESOLUTION));
  1747. }
  1748. //get informations from camera (S/N, firmware, model...)
  1749. cameraModel = zedCamera.GetCameraModel().ToString();
  1750. cameraFirmware = zedCamera.GetCameraFirmwareVersion().ToString() + "-" + zedCamera.GetSensorsFirmwareVersion().ToString();
  1751. cameraSerialNumber = zedCamera.GetZEDSerialNumber().ToString();
  1752. if (inputType == sl.INPUT_TYPE.INPUT_TYPE_SVO)
  1753. {
  1754. numberFrameMax = zedCamera.GetSVONumberOfFrames();
  1755. }
  1756. // If streaming has been switched on before play
  1757. if (enableStreaming && !isStreamingEnable)
  1758. {
  1759. lock (zedCamera.grabLock)
  1760. {
  1761. sl.ERROR_CODE err = zedCamera.EnableStreaming(streamingCodec, (uint)bitrate, (ushort)streamingPort, gopSize, adaptativeBitrate, chunkSize, streamingTargetFramerate);
  1762. if (err == sl.ERROR_CODE.SUCCESS)
  1763. {
  1764. isStreamingEnable = true;
  1765. }
  1766. else
  1767. {
  1768. enableStreaming = false;
  1769. isStreamingEnable = false;
  1770. }
  1771. }
  1772. }
  1773. //If not already launched, launch the image grabbing thread.
  1774. if (!running)
  1775. {
  1776. running = true;
  1777. requestNewFrame = true;
  1778. threadGrab = new Thread(new ThreadStart(ThreadedZEDGrab));
  1779. threadGrab.Start();
  1780. }
  1781. zedReady = true;
  1782. isDisconnected = false; //In case we just regained connection.
  1783. setRenderingSettings(); //Find the ZEDRenderingPlanes in the rig and configure them.
  1784. AdjustZEDRigCameraPosition(); //If in AR mode, move cameras to proper offset relative to zedRigRoot.
  1785. }
  1786. }
  1787. /// <summary>
  1788. /// Adjust camera(s) relative to zedRigRoot transform, which is what is moved each frame. Called at start of tracking.
  1789. /// <para>In AR mode, offset is each camera's position relative to center of the user's head. Otherwise, cameras are just spaced
  1790. /// by the camera's baseline/IPD, or no offset is applied if there's just one camera. </para>
  1791. /// </summary>
  1792. void AdjustZEDRigCameraPosition()
  1793. {
  1794. //Vector3 rightCameraOffset = new Vector3(zedCamera.Baseline, 0.0f, 0.0f);
  1795. if (isStereoRig && hasXRDevice()) //Using AR pass-through mode.
  1796. {
  1797. //zedRigRoot transform (origin of the global camera) is placed on the HMD headset. Therefore, we move the
  1798. //camera in front of it by offsetHmdZEDPosition to compensate for the ZED's position on the headset.
  1799. //If values are wrong, tweak calibration file created in ZEDMixedRealityPlugin.
  1800. camLeftTransform.localPosition = arRig.HmdToZEDCalibration.translation;
  1801. camLeftTransform.localRotation = arRig.HmdToZEDCalibration.rotation;
  1802. if (camRightTransform) camRightTransform.localPosition = camLeftTransform.localPosition + new Vector3(zedCamera.Baseline, 0.0f, 0.0f); //Space the eyes apart.
  1803. if (camRightTransform) camRightTransform.localRotation = camLeftTransform.localRotation;
  1804. }
  1805. else if (camLeftTransform && camRightTransform) //Using stereo rig, but no VR headset.
  1806. {
  1807. //When no VR HMD is available, simply put the origin at the left camera.
  1808. camLeftTransform.localPosition = Vector3.zero;
  1809. camLeftTransform.localRotation = Quaternion.identity;
  1810. camRightTransform.localPosition = new Vector3(zedCamera.Baseline, 0.0f, 0.0f); //Space the eyes apart.
  1811. camRightTransform.localRotation = Quaternion.identity;
  1812. }
  1813. else //Using mono rig (ZED_Rig_Mono). No offset needed.
  1814. {
  1815. if (GetMainCameraTransform())
  1816. {
  1817. GetMainCameraTransform().localPosition = Vector3.zero;
  1818. GetMainCameraTransform().localRotation = Quaternion.identity;
  1819. }
  1820. }
  1821. }
  1822. /// <summary>
  1823. /// Find the ZEDRenderingPlane components in the ZED rig and set their rendering settings
  1824. /// (rendering path, shader values, etc.) for left and right cameras. Also activate/deactivate depth occlusions.
  1825. /// </summary>
  1826. void setRenderingSettings()
  1827. {
  1828. ZEDRenderingPlane leftRenderingPlane = null;
  1829. if (GetLeftCameraTransform() != null)
  1830. {
  1831. leftRenderingPlane = GetLeftCameraTransform().GetComponent<ZEDRenderingPlane>();
  1832. if (leftRenderingPlane)
  1833. {
  1834. leftRenderingPlane.SetPostProcess(postProcessing);
  1835. GetLeftCameraTransform().GetComponent<Camera>().renderingPath = RenderingPath.UsePlayerSettings;
  1836. SetCameraBrightness(m_cameraBrightness);
  1837. cameraLeft.cullingMask &= ~(1 << zedCamera.TagInvisibleToZED);
  1838. }
  1839. }
  1840. ZEDRenderingPlane rightRenderingPlane = null;
  1841. if (GetRightCameraTransform() != null)
  1842. {
  1843. rightRenderingPlane = GetRightCameraTransform().GetComponent<ZEDRenderingPlane>();
  1844. if (rightRenderingPlane)
  1845. {
  1846. rightRenderingPlane.SetPostProcess(postProcessing);
  1847. cameraRight.renderingPath = RenderingPath.UsePlayerSettings;
  1848. cameraRight.cullingMask &= ~(1 << zedCamera.TagInvisibleToZED);
  1849. }
  1850. }
  1851. SetCameraBrightness(m_cameraBrightness);
  1852. SetMaxDepthRange(m_maxDepthRange);
  1853. #if ZED_HDRP
  1854. SetSelfIllumination(selfIllumination);
  1855. SetBoolValueOnPlaneMaterials("_ApplyZEDNormals", applyZEDNormals);
  1856. #endif
  1857. Camera maincam = GetMainCamera();
  1858. if (maincam != null)
  1859. {
  1860. ZEDRenderingMode renderingPath = (ZEDRenderingMode)maincam.actualRenderingPath;
  1861. //Make sure we're in either forward or deferred rendering. Default to forward otherwise.
  1862. if (renderingPath != ZEDRenderingMode.FORWARD && renderingPath != ZEDRenderingMode.DEFERRED)
  1863. {
  1864. Debug.LogError("[ZED Plugin] Only Forward and Deferred Shading rendering path are supported");
  1865. if (cameraLeft) cameraLeft.renderingPath = RenderingPath.Forward;
  1866. if (cameraRight) cameraRight.renderingPath = RenderingPath.Forward;
  1867. }
  1868. //Set depth occlusion.
  1869. if (renderingPath == ZEDRenderingMode.FORWARD)
  1870. {
  1871. if (leftRenderingPlane)
  1872. leftRenderingPlane.ManageKeywordPipe(!depthOcclusion, "NO_DEPTH");
  1873. if (rightRenderingPlane)
  1874. rightRenderingPlane.ManageKeywordPipe(!depthOcclusion, "NO_DEPTH");
  1875. }
  1876. else if (renderingPath == ZEDRenderingMode.DEFERRED)
  1877. {
  1878. if (leftRenderingPlane)
  1879. leftRenderingPlane.ManageKeywordDeferredMat(!depthOcclusion, "NO_DEPTH");
  1880. if (rightRenderingPlane)
  1881. rightRenderingPlane.ManageKeywordDeferredMat(!depthOcclusion, "NO_DEPTH");
  1882. }
  1883. }
  1884. }
  1885. #endregion
  1886. #region IMAGE_ACQUIZ
  1887. /// <summary>
  1888. /// Continuously grabs images from the ZED. Runs on its own thread.
  1889. /// </summary>
  1890. private void ThreadedZEDGrab()
  1891. {
  1892. runtimeParameters = new sl.RuntimeParameters();
  1893. runtimeParameters.sensingMode = sensingMode;
  1894. runtimeParameters.enableDepth = true;
  1895. runtimeParameters.confidenceThreshold = confidenceThreshold;
  1896. runtimeParameters.textureConfidenceThreshold = textureConfidenceThreshold;
  1897. runtimeParameters.removeSaturatedAreas = true;
  1898. //Don't change this reference frame. If we need normals in the world frame, better to do the conversion ourselves.
  1899. runtimeParameters.measure3DReferenceFrame = sl.REFERENCE_FRAME.CAMERA;
  1900. while (running)
  1901. {
  1902. if (zedCamera == null)
  1903. return;
  1904. if (runtimeParameters.sensingMode != sensingMode) runtimeParameters.sensingMode = sensingMode;
  1905. AcquireImages();
  1906. }
  1907. }
  1908. /// <summary>
  1909. /// Grabs images from the ZED SDK and updates tracking, FPS and timestamp values.
  1910. /// Called from ThreadedZEDGrab() in a separate thread.
  1911. /// </summary>
  1912. private void AcquireImages()
  1913. {
  1914. if (requestNewFrame && zedReady)
  1915. {
  1916. if (inputType == sl.INPUT_TYPE.INPUT_TYPE_SVO)
  1917. {
  1918. //handle pause
  1919. if (NeedNewFrameGrab && pauseSVOReading)
  1920. {
  1921. ZEDGrabError = zedCamera.Grab(ref runtimeParameters);
  1922. NeedNewFrameGrab = false;
  1923. }
  1924. else if (!pauseSVOReading)
  1925. ZEDGrabError = zedCamera.Grab(ref runtimeParameters);
  1926. currentFrame = zedCamera.GetSVOPosition();
  1927. }
  1928. else if (!pauseLiveReading)
  1929. {
  1930. ZEDGrabError = zedCamera.Grab(ref runtimeParameters);
  1931. }
  1932. lock (zedCamera.grabLock)
  1933. {
  1934. if (ZEDGrabError == sl.ERROR_CODE.CAMERA_NOT_DETECTED)
  1935. {
  1936. Debug.Log("Camera not detected or disconnected.");
  1937. isDisconnected = true;
  1938. Thread.Sleep(10);
  1939. requestNewFrame = false;
  1940. }
  1941. else if (ZEDGrabError == sl.ERROR_CODE.SUCCESS)
  1942. {
  1943. #if UNITY_EDITOR
  1944. float camera_fps = zedCamera.GetCameraFPS();
  1945. cameraFPS = camera_fps.ToString() + " FPS";
  1946. #endif
  1947. //Update object detection here if using object sync.
  1948. if (objectDetectionRunning && objectDetectionImageSyncMode == true && requestobjectsframe)
  1949. {
  1950. RetrieveObjectDetectionFrame();
  1951. }
  1952. //Get position of camera
  1953. if (isTrackingEnable)
  1954. {
  1955. zedtrackingState = zedCamera.GetPosition(ref zedOrientation, ref zedPosition, sl.TRACKING_FRAME.LEFT_EYE);
  1956. //zedtrackingState = sl.TRACKING_STATE.TRACKING_OK;
  1957. if (inputType == sl.INPUT_TYPE.INPUT_TYPE_SVO && svoLoopBack == true && initialPoseCached == false)
  1958. {
  1959. initialPosition = zedPosition;
  1960. initialRotation = zedOrientation;
  1961. initialPoseCached = true;
  1962. }
  1963. }
  1964. else
  1965. {
  1966. zedtrackingState = sl.TRACKING_STATE.TRACKING_OFF;
  1967. }
  1968. // Indicate that a new frame is available and pause the thread until a new request is called
  1969. newFrameAvailable = true;
  1970. requestNewFrame = false;
  1971. }
  1972. else
  1973. Thread.Sleep(1);
  1974. }
  1975. }
  1976. else
  1977. {
  1978. //To avoid "overheating."
  1979. Thread.Sleep(1);
  1980. }
  1981. }
  1982. #endregion
  1983. /// <summary>
  1984. /// Initialize the SVO, and launch the thread to initialize tracking. Called once the ZED
  1985. /// is initialized successfully.
  1986. /// </summary>
  1987. private void ZEDReady()
  1988. {
  1989. //Apply camera settings based on user preference.
  1990. InitVideoSettings(videoSettingsInitMode);
  1991. FPS = (int)zedCamera.GetRequestedCameraFPS();
  1992. if (enableTracking)
  1993. {
  1994. trackerThread = new Thread(EnableTrackingThreaded);
  1995. trackerThread.Start();
  1996. }
  1997. else if (estimateInitialPosition)
  1998. {
  1999. sl.ERROR_CODE err = zedCamera.EstimateInitialPosition(ref initialRotation, ref initialPosition);
  2000. if (zedCamera.GetCameraModel() != sl.MODEL.ZED)
  2001. zedCamera.GetInternalIMUOrientation(ref initialRotation, sl.TIME_REFERENCE.IMAGE);
  2002. if (err != sl.ERROR_CODE.SUCCESS)
  2003. Debug.LogWarning("Failed to estimate initial camera position");
  2004. }
  2005. if (enableTracking)
  2006. trackerThread.Join();
  2007. if (isStereoRig && hasXRDevice())
  2008. {
  2009. ZEDMixedRealityPlugin.Pose pose = arRig.InitTrackingAR();
  2010. OriginPosition = pose.translation;
  2011. OriginRotation = pose.rotation;
  2012. if (!zedCamera.IsHmdCompatible && zedCamera.IsCameraReady)
  2013. Debug.LogWarning("WARNING: AR Passtrough with a ZED is not recommended. Consider using ZED Mini, designed for this purpose.");
  2014. }
  2015. else
  2016. {
  2017. OriginPosition = initialPosition;
  2018. OriginRotation = initialRotation;
  2019. }
  2020. //Set the original transform for the Rig
  2021. zedRigRoot.localPosition = OriginPosition;
  2022. zedRigRoot.localRotation = OriginRotation;
  2023. }
  2024. /// <summary>
  2025. /// Initializes the ZED's inside-out tracking. Started as a separate thread in OnZEDReady.
  2026. /// </summary>
  2027. void EnableTrackingThreaded()
  2028. {
  2029. lock (zedCamera.grabLock)
  2030. {
  2031. //If using spatial memory and given a path to a .area file, make sure that path is valid.
  2032. if (enableSpatialMemory && pathSpatialMemory != "" && !System.IO.File.Exists(pathSpatialMemory))
  2033. {
  2034. Debug.Log("Specified path to .area file '" + pathSpatialMemory + "' does not exist. Ignoring.");
  2035. pathSpatialMemory = "";
  2036. }
  2037. sl.ERROR_CODE err = (zedCamera.EnableTracking(ref zedOrientation, ref zedPosition, enableSpatialMemory,
  2038. enablePoseSmoothing, estimateInitialPosition, trackingIsStatic, enableIMUFusion, pathSpatialMemory));
  2039. //Now enable the tracking with the proper parameters.
  2040. if (!(enableTracking = (err == sl.ERROR_CODE.SUCCESS)))
  2041. {
  2042. throw new Exception(ZEDLogMessage.Error2Str(ZEDLogMessage.ERROR.TRACKING_NOT_INITIALIZED));
  2043. }
  2044. else
  2045. {
  2046. isTrackingEnable = true;
  2047. }
  2048. }
  2049. }
  2050. #if ZED_HDRP
  2051. public bool GetChosenSRPMaterial(out Material srpMat)
  2052. {
  2053. switch(srpShaderType)
  2054. {
  2055. case shaderType.Lit:
  2056. srpMat = Resources.Load<Material>("Materials/Lighting/Mat_ZED_HDRP_Lit");
  2057. if (srpMat == null)
  2058. {
  2059. Debug.LogError("Couldn't find material in Resources. Path: " + "Materials/Lighting/Mat_ZED_HDRP_Lit");
  2060. return false;
  2061. }
  2062. else return true;
  2063. case shaderType.Unlit:
  2064. srpMat = Resources.Load<Material>("Materials/Unlit/Mat_ZED_Unlit_RawInput");
  2065. if (srpMat == null)
  2066. {
  2067. Debug.LogError("Couldn't find material in Resources. Path: " + "Materials/Unlit/Mat_ZED_Unlit_RawInput");
  2068. return false;
  2069. }
  2070. else return true;
  2071. case shaderType.Greenscreen_Lit:
  2072. srpMat = Resources.Load<Material>("Materials/Lighting/Mat_ZED_Greenscreen_HDRP_Lit");
  2073. if (srpMat == null)
  2074. {
  2075. Debug.LogError("Couldn't find material in Resources. Path: " + "Materials/Lighting/Mat_ZED_Greenscreen_HDRP_Lit");
  2076. return false;
  2077. }
  2078. else return true;
  2079. case shaderType.Greenscreen_Unlit:
  2080. srpMat = Resources.Load<Material>("Materials/Unlit/Mat_ZED_Greenscreen_Unlit");
  2081. if (srpMat == null)
  2082. {
  2083. Debug.LogError("Couldn't find material in Resources. Path: " + "Materials/Unlit/Mat_ZED_Greenscreen_Unlit");
  2084. return false;
  2085. }
  2086. else return true;
  2087. case shaderType.DontChange:
  2088. default:
  2089. srpMat = null;
  2090. return false;
  2091. }
  2092. }
  2093. #endif
  2094. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2095. ////////////////////////////////////////////////////////// ENGINE UPDATE REGION /////////////////////////////////////////////////////////////////////////////
  2096. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2097. #region ENGINE_UPDATE
  2098. /// <summary>
  2099. /// If a new frame is available, this function retrieves the images and updates the Unity textures. Called in Update().
  2100. /// </summary>
  2101. public void UpdateImages()
  2102. {
  2103. if (zedCamera == null)
  2104. return;
  2105. if (newFrameAvailable) //ThreadedZEDGrab()/AcquireImages() grabbed images we haven't updated yet.
  2106. {
  2107. lock (zedCamera.grabLock)
  2108. {
  2109. zedCamera.RetrieveTextures(); //Tell the wrapper to compute the textures.
  2110. zedCamera.UpdateTextures(); //Tell the wrapper to update the textures.
  2111. imageTimeStamp = zedCamera.GetImagesTimeStamp();
  2112. }
  2113. //For external module ... Trigger the capture done event.
  2114. if (OnGrab != null)
  2115. OnGrab();
  2116. //SVO and loop back ? --> reset position if needed
  2117. if (zedCamera.GetInputType() == sl.INPUT_TYPE.INPUT_TYPE_SVO && svoLoopBack)
  2118. {
  2119. int maxSVOFrame = zedCamera.GetSVONumberOfFrames();
  2120. if (zedCamera.GetSVOPosition() >= maxSVOFrame - (svoRealTimeMode ? 2 : 1))
  2121. {
  2122. zedCamera.SetSVOPosition(0);
  2123. if (enableTracking)
  2124. {
  2125. if (!(enableTracking = (zedCamera.ResetTracking(initialRotation, initialPosition) == sl.ERROR_CODE.SUCCESS)))
  2126. {
  2127. Debug.LogError("ZED Tracking disabled: Not available during SVO playback when Loop is enabled.");
  2128. }
  2129. }
  2130. zedRigRoot.localPosition = initialPosition;
  2131. zedRigRoot.localRotation = initialRotation;
  2132. }
  2133. }
  2134. requestNewFrame = true; //Lets ThreadedZEDGrab/AcquireImages() start grabbing again.
  2135. newFrameAvailable = false;
  2136. }
  2137. }
  2138. /// <summary>
  2139. /// Gets the tracking position from the ZED and updates zedRigRoot's position. Also updates the AR tracking if enabled.
  2140. /// Only called in Live (not SVO playback) mode. Called in Update().
  2141. /// </summary>
  2142. private void UpdateTracking()
  2143. {
  2144. if (!zedReady)
  2145. return;
  2146. if (isZEDTracked) //ZED inside-out tracking is enabled and initialized.
  2147. {
  2148. Quaternion r;
  2149. Vector3 v;
  2150. isCameraTracked = true;
  2151. if (hasXRDevice() && isStereoRig) //AR pass-through mode.
  2152. {
  2153. if (calibrationHasChanged) //If the HMD offset calibration file changed during runtime.
  2154. {
  2155. AdjustZEDRigCameraPosition(); //Re-apply the ZED's offset from the VR headset.
  2156. calibrationHasChanged = false;
  2157. }
  2158. arRig.ExtractLatencyPose(imageTimeStamp); //Find what HMD's pose was at ZED image's timestamp for latency compensation.
  2159. arRig.AdjustTrackingAR(zedPosition, zedOrientation, out r, out v, setIMUPriorInAR);
  2160. zedRigRoot.localRotation = r;
  2161. zedRigRoot.localPosition = v;
  2162. //Debug.DrawLine(new Vector3(0, 0.05f, 0), (r * Vector3.one * 5) + new Vector3(0, 0.05f, 0), Color.red);
  2163. //Debug.DrawLine(Vector3.zero, zedOrientation * Vector3.one * 5, Color.green);
  2164. ZEDSyncPosition = v;
  2165. ZEDSyncRotation = r;
  2166. HMDSyncPosition = arRig.LatencyPose().translation;
  2167. HMDSyncRotation = arRig.LatencyPose().rotation;
  2168. }
  2169. else //Not AR pass-through mode.
  2170. {
  2171. zedRigRoot.localRotation = zedOrientation;
  2172. if (!ZEDSupportFunctions.IsVector3NaN(zedPosition))
  2173. zedRigRoot.localPosition = zedPosition;
  2174. }
  2175. }
  2176. else if (hasXRDevice() && isStereoRig) //ZED tracking is off but HMD tracking is on. Fall back to that.
  2177. {
  2178. isCameraTracked = true;
  2179. arRig.ExtractLatencyPose(imageTimeStamp); //Find what HMD's pose was at ZED image's timestamp for latency compensation.
  2180. zedRigRoot.localRotation = arRig.LatencyPose().rotation;
  2181. zedRigRoot.localPosition = arRig.LatencyPose().translation;
  2182. }
  2183. else //The ZED is not tracked by itself or an HMD.
  2184. isCameraTracked = false;
  2185. }
  2186. /// <summary>
  2187. /// Stores the HMD's current pose. Used in AR mode for latency compensation.
  2188. /// Pose will be applied to final canvases when a new image's timestamp matches
  2189. /// the time when this is called.
  2190. /// </summary>
  2191. void UpdateHmdPose()
  2192. {
  2193. if (IsStereoRig && hasXRDevice())
  2194. arRig.CollectPose(); //Save headset pose with current timestamp.
  2195. }
  2196. /// <summary>
  2197. /// Updates images, collects HMD poses for latency correction, and applies tracking.
  2198. /// Called by Unity each frame.
  2199. /// </summary>
  2200. void Update()
  2201. {
  2202. //Check if ZED is disconnected; invoke event and call function if so.
  2203. if (isDisconnected)
  2204. {
  2205. if (OnZEDDisconnected != null)
  2206. OnZEDDisconnected(); //Invoke event. Used for GUI message and pausing ZEDRenderingPlanes.
  2207. ZEDDisconnected(); //Tries to reset the camera.
  2208. return;
  2209. }
  2210. // Then update all modules
  2211. UpdateImages(); //Image is updated first so we have its timestamp for latency compensation.
  2212. UpdateHmdPose(); //Store the HMD's pose at the current timestamp.
  2213. UpdateTracking(); //Apply position/rotation changes to zedRigRoot.
  2214. UpdateObjectsDetection(); //Update od if activated
  2215. UpdateMapping(); //Update mapping if activated
  2216. /// If in Unity Editor, update the ZEDManager status list
  2217. #if UNITY_EDITOR
  2218. //Update strings used for di splaying stats in the Inspector.
  2219. if (zedCamera != null)
  2220. {
  2221. float frame_drop_count = zedCamera.GetFrameDroppedPercent();
  2222. float CurrentTickFPS = 1.0f / Time.deltaTime;
  2223. fps_engine = (fps_engine + CurrentTickFPS) / 2.0f;
  2224. engineFPS = fps_engine.ToString("F0") + " FPS";
  2225. if (frame_drop_count > 30 && fps_engine < 45)
  2226. engineFPS += "WARNING: Low engine framerate detected";
  2227. if (isZEDTracked)
  2228. trackingState = ZEDTrackingState.ToString();
  2229. else if (hasXRDevice() && isStereoRig)
  2230. trackingState = "HMD Tracking";
  2231. else
  2232. trackingState = "Camera Not Tracked";
  2233. }
  2234. #endif
  2235. }
  2236. public void LateUpdate()
  2237. {
  2238. if (IsStereoRig)
  2239. {
  2240. arRig.LateUpdateHmdRendering(); //Update textures on final AR rig for output to the headset.
  2241. }
  2242. }
  2243. #endregion
  2244. /// <summary>
  2245. /// Event called when camera is disconnected
  2246. /// </summary>
  2247. void ZEDDisconnected()
  2248. {
  2249. cameraFPS = "Disconnected";
  2250. isDisconnected = true;
  2251. if (zedReady)
  2252. {
  2253. Reset(); //Cache tracking, turn it off and turn it back on again.
  2254. }
  2255. }
  2256. private void OnDestroy()
  2257. {
  2258. //OnApplicationQuit();
  2259. CloseManager();
  2260. }
  2261. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2262. //////////////////////////////////////////////////////// SPATIAL MAPPING REGION /////////////////////////////////////////////////////////////////////////////
  2263. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2264. #region MAPPING_MODULE
  2265. /// <summary>
  2266. /// Tells ZEDSpatialMapping to begin a new scan. This clears the previous scan from the scene if there is one.
  2267. /// </summary>
  2268. public void StartSpatialMapping()
  2269. {
  2270. transform.position = Vector3.zero;
  2271. transform.rotation = Quaternion.identity;
  2272. spatialMapping.StartStatialMapping(sl.SPATIAL_MAP_TYPE.MESH, mappingResolutionPreset, mappingRangePreset, isMappingTextured);
  2273. }
  2274. /// <summary>
  2275. /// Ends the current spatial mapping. Once called, the current mesh will be filtered, textured (if enabled) and saved (if enabled),
  2276. /// and a mesh collider will be added.
  2277. /// </summary>
  2278. public void StopSpatialMapping()
  2279. {
  2280. if (spatialMapping != null)
  2281. {
  2282. if (saveMeshWhenOver)
  2283. SaveMesh(meshPath);
  2284. spatialMapping.StopStatialMapping();
  2285. }
  2286. }
  2287. /// <summary>
  2288. /// Updates the filtering parameters and call the ZEDSpatialMapping instance's Update() function.
  2289. /// </summary>
  2290. private void UpdateMapping()
  2291. {
  2292. if (spatialMapping != null)
  2293. {
  2294. //if (IsMappingUpdateThreadRunning)
  2295. if (spatialMapping.IsRunning())
  2296. {
  2297. spatialMapping.filterParameters = meshFilterParameters;
  2298. spatialMapping.Update();
  2299. }
  2300. }
  2301. }
  2302. /// <summary>
  2303. /// Toggles whether to display the mesh or not.
  2304. /// </summary>
  2305. /// <param name="state"><c>True</c> to make the mesh visible, <c>false</c> to make it invisible. </param>
  2306. public void SwitchDisplayMeshState(bool state)
  2307. {
  2308. if (spatialMapping != null)
  2309. spatialMapping.SwitchDisplayMeshState(state);
  2310. }
  2311. public void ClearAllMeshes()
  2312. {
  2313. if (spatialMapping != null)
  2314. spatialMapping.ClearAllMeshes();
  2315. }
  2316. /// <summary>
  2317. /// Pauses the current scan.
  2318. /// </summary>
  2319. /// <param name="state"><c>True</c> to pause the scanning, <c>false</c> to unpause it.</param>
  2320. public void SwitchPauseState(bool state)
  2321. {
  2322. if (spatialMapping != null)
  2323. spatialMapping.SwitchPauseState(state);
  2324. }
  2325. /// <summary>
  2326. /// Saves the mesh into a 3D model (.obj, .ply or .bin) file. Also saves an .area file for spatial memory for better tracking.
  2327. /// Calling this will end the spatial mapping if it's running. Note it can take a significant amount of time to finish.
  2328. /// </summary>
  2329. /// <param name="meshPath">Path where the mesh and .area files will be saved.</param>
  2330. public void SaveMesh(string meshPath = "ZEDMeshObj.obj")
  2331. {
  2332. spatialMapping.RequestSaveMesh(meshPath);
  2333. }
  2334. /// <summary>
  2335. /// Loads a mesh and spatial memory data from a file.
  2336. /// If scanning is running, it will be stopped. Existing scans in the scene will be cleared.
  2337. /// </summary>
  2338. /// <param name="meshPath">Path to the 3D mesh file (.obj, .ply or .bin) to load.</param>
  2339. /// <returns><c>True</c> if successfully loaded, <c>false</c> otherwise.</returns>
  2340. public bool LoadMesh(string meshPath = "ZEDMeshObj.obj")
  2341. {
  2342. //Cache the save setting and set to false, to avoid overwriting the mesh file during the load.
  2343. bool oldSaveWhenOver = saveMeshWhenOver;
  2344. saveMeshWhenOver = false;
  2345. gravityRotation = Quaternion.identity;
  2346. spatialMapping.SetMeshRenderer();
  2347. bool loadresult = spatialMapping.LoadMesh(meshPath);
  2348. saveMeshWhenOver = oldSaveWhenOver; //Restoring old setting.
  2349. return loadresult;
  2350. }
  2351. #endregion
  2352. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2353. //////////////////////////////////////////////////////// OBJECT DETECTION REGION //////////////////////////////////////////////////////////////////////////////
  2354. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2355. #region OBJECT_DETECTION
  2356. /// <summary>
  2357. /// True when the object detection coroutine is in the process of starting.
  2358. /// Used to prevent object detection from being launched multiple times at once, which causes instability.
  2359. /// </summary>
  2360. private bool odIsStarting = false;
  2361. /// <summary>
  2362. /// Starts the ZED object detection.
  2363. /// <para>Note: This will lock the main thread for a moment, which may appear to be a freeze.</para>
  2364. /// </summary>
  2365. public void StartObjectDetection()
  2366. {
  2367. sl.AI_Model_status AiModelStatus = sl.ZEDCamera.CheckAIModelStatus(sl.ZEDCamera.cvtDetection(objectDetectionModel));
  2368. if (!AiModelStatus.optimized)
  2369. {
  2370. Debug.LogError("The Model * " + objectDetectionModel.ToString() + " * has not been downloaded/optimized. Use the ZED Diagnostic tool to download/optimze all the AI model you plan to use.");
  2371. // return;
  2372. }
  2373. //We start a coroutine so we can delay actually starting the detection.
  2374. //This is because the main thread is locked for awhile when you call this, appearing like a freeze.
  2375. //This time lets us deliver a log message to the user indicating that this is expected.
  2376. StartCoroutine(startObjectDetection());
  2377. }
  2378. /// <summary>
  2379. /// <summary>
  2380. /// Starts the object detection module after a two-frame delay, allowing us to deliver a log message
  2381. /// to the user indicating that what appears to be a freeze is actually expected and will pass.
  2382. /// </summary>
  2383. /// <returns></returns>
  2384. private IEnumerator startObjectDetection()
  2385. {
  2386. if (odIsStarting == true)
  2387. {
  2388. Debug.LogError("Tried to start Object Detection while it was already starting. Do you have two scripts trying to start it?");
  2389. yield break;
  2390. }
  2391. if (objectDetectionRunning)
  2392. {
  2393. Debug.LogWarning("Tried to start Object Detection while it was already running.");
  2394. }
  2395. if (zedCamera != null)
  2396. {
  2397. odIsStarting = true;
  2398. Debug.LogWarning("Starting Object Detection. This may take a moment.");
  2399. bool oldpausestate = pauseSVOReading; //The two frame delay will cause you to miss some SVO frames if playing back from an SVO, unless we pause.
  2400. pauseSVOReading = true;
  2401. yield return null;
  2402. pauseSVOReading = oldpausestate;
  2403. sl.dll_ObjectDetectionParameters od_param = new sl.dll_ObjectDetectionParameters();
  2404. od_param.imageSync = objectDetectionImageSyncMode;
  2405. od_param.enableObjectTracking = objectDetectionTracking;
  2406. od_param.enable2DMask = objectDetection2DMask;
  2407. od_param.detectionModel = objectDetectionModel;
  2408. od_param.maxRange = objectDetectionMaxRange;
  2409. od_param.filteringMode = objectDetectionFilteringMode;
  2410. if (objectDetectionBodyFormat == sl.BODY_FORMAT.POSE_34 && objectDetectionBodyFitting == false && (objectDetectionModel == sl.DETECTION_MODEL.HUMAN_BODY_ACCURATE || objectDetectionModel == sl.DETECTION_MODEL.HUMAN_BODY_MEDIUM
  2411. || objectDetectionModel == sl.DETECTION_MODEL.HUMAN_BODY_FAST))
  2412. {
  2413. Debug.LogWarning("sl.BODY_FORMAT.POSE_34 is chosen, Skeleton Tracking will automatically enable body fitting");
  2414. objectDetectionBodyFitting = true;
  2415. }
  2416. od_param.bodyFormat = objectDetectionBodyFormat;
  2417. od_param.enableBodyFitting = objectDetectionBodyFitting;
  2418. od_runtime_params.object_confidence_threshold = new int[(int)sl.OBJECT_CLASS.LAST];
  2419. od_runtime_params.object_confidence_threshold[(int)sl.OBJECT_CLASS.PERSON] = (objectDetectionModel == sl.DETECTION_MODEL.HUMAN_BODY_ACCURATE || objectDetectionModel == sl.DETECTION_MODEL.HUMAN_BODY_FAST || objectDetectionModel == sl.DETECTION_MODEL.HUMAN_BODY_MEDIUM) ? SK_personDetectionConfidenceThreshold : OD_personDetectionConfidenceThreshold;
  2420. od_runtime_params.object_confidence_threshold[(int)sl.OBJECT_CLASS.VEHICLE] = vehicleDetectionConfidenceThreshold;
  2421. od_runtime_params.object_confidence_threshold[(int)sl.OBJECT_CLASS.BAG] = bagDetectionConfidenceThreshold;
  2422. od_runtime_params.object_confidence_threshold[(int)sl.OBJECT_CLASS.ANIMAL] = animalDetectionConfidenceThreshold;
  2423. od_runtime_params.object_confidence_threshold[(int)sl.OBJECT_CLASS.ELECTRONICS] = electronicsDetectionConfidenceThreshold;
  2424. od_runtime_params.object_confidence_threshold[(int)sl.OBJECT_CLASS.FRUIT_VEGETABLE] = fruitVegetableDetectionConfidenceThreshold;
  2425. od_runtime_params.object_confidence_threshold[(int)sl.OBJECT_CLASS.SPORT] = sportDetectionConfidenceThreshold;
  2426. od_runtime_params.objectClassFilter = new int[(int)sl.OBJECT_CLASS.LAST];
  2427. od_runtime_params.objectClassFilter[(int)sl.OBJECT_CLASS.PERSON] = Convert.ToInt32(objectClassPersonFilter);
  2428. od_runtime_params.objectClassFilter[(int)sl.OBJECT_CLASS.VEHICLE] = Convert.ToInt32(objectClassVehicleFilter);
  2429. od_runtime_params.objectClassFilter[(int)sl.OBJECT_CLASS.BAG] = Convert.ToInt32(objectClassBagFilter);
  2430. od_runtime_params.objectClassFilter[(int)sl.OBJECT_CLASS.ANIMAL] = Convert.ToInt32(objectClassAnimalFilter);
  2431. od_runtime_params.objectClassFilter[(int)sl.OBJECT_CLASS.ELECTRONICS] = Convert.ToInt32(objectClassElectronicsFilter);
  2432. od_runtime_params.objectClassFilter[(int)sl.OBJECT_CLASS.FRUIT_VEGETABLE] = Convert.ToInt32(objectClassFruitVegetableFilter);
  2433. od_runtime_params.objectClassFilter[(int)sl.OBJECT_CLASS.SPORT] = Convert.ToInt32(objectClassSportFilter);
  2434. System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); //Time how long the loading takes so we can tell the user.
  2435. watch.Start();
  2436. sl.ERROR_CODE err = zedCamera.EnableObjectsDetection(ref od_param);
  2437. if (err == sl.ERROR_CODE.SUCCESS)
  2438. {
  2439. Debug.Log("Object Detection module started in " + watch.Elapsed.Seconds + " seconds.");
  2440. objectDetectionRunning = true;
  2441. }
  2442. else
  2443. {
  2444. Debug.Log("Object Detection failed to start. (Error: " + err + " )");
  2445. objectDetectionRunning = false;
  2446. }
  2447. watch.Stop();
  2448. odIsStarting = false;
  2449. }
  2450. }
  2451. /// <summary>
  2452. /// Stops the object detection.
  2453. /// </summary>
  2454. public void StopObjectDetection()
  2455. {
  2456. if (zedCamera != null && running)
  2457. {
  2458. zedCamera.DisableObjectsDetection();
  2459. objectDetectionRunning = false;
  2460. }
  2461. }
  2462. /// <summary>
  2463. /// Updates the objects detection by triggering the detection event
  2464. /// </summary>
  2465. public void UpdateObjectsDetection()
  2466. {
  2467. if (!objectDetectionRunning) return;
  2468. //Update the runtime parameters in case the user made changes.
  2469. od_runtime_params.object_confidence_threshold = new int[(int)sl.OBJECT_CLASS.LAST];
  2470. od_runtime_params.object_confidence_threshold[(int)sl.OBJECT_CLASS.PERSON] = (objectDetectionModel == sl.DETECTION_MODEL.HUMAN_BODY_ACCURATE || objectDetectionModel == sl.DETECTION_MODEL.HUMAN_BODY_FAST) ? SK_personDetectionConfidenceThreshold : OD_personDetectionConfidenceThreshold;
  2471. od_runtime_params.object_confidence_threshold[(int)sl.OBJECT_CLASS.VEHICLE] = vehicleDetectionConfidenceThreshold;
  2472. od_runtime_params.object_confidence_threshold[(int)sl.OBJECT_CLASS.BAG] = bagDetectionConfidenceThreshold;
  2473. od_runtime_params.object_confidence_threshold[(int)sl.OBJECT_CLASS.ANIMAL] = animalDetectionConfidenceThreshold;
  2474. od_runtime_params.object_confidence_threshold[(int)sl.OBJECT_CLASS.ELECTRONICS] = electronicsDetectionConfidenceThreshold;
  2475. od_runtime_params.object_confidence_threshold[(int)sl.OBJECT_CLASS.FRUIT_VEGETABLE] = fruitVegetableDetectionConfidenceThreshold;
  2476. od_runtime_params.objectClassFilter = new int[(int)sl.OBJECT_CLASS.LAST];
  2477. od_runtime_params.objectClassFilter[(int)sl.OBJECT_CLASS.PERSON] = Convert.ToInt32(objectClassPersonFilter);
  2478. od_runtime_params.objectClassFilter[(int)sl.OBJECT_CLASS.VEHICLE] = Convert.ToInt32(objectClassVehicleFilter);
  2479. od_runtime_params.objectClassFilter[(int)sl.OBJECT_CLASS.BAG] = Convert.ToInt32(objectClassBagFilter);
  2480. od_runtime_params.objectClassFilter[(int)sl.OBJECT_CLASS.ANIMAL] = Convert.ToInt32(objectClassAnimalFilter);
  2481. od_runtime_params.objectClassFilter[(int)sl.OBJECT_CLASS.ELECTRONICS] = Convert.ToInt32(objectClassElectronicsFilter);
  2482. od_runtime_params.objectClassFilter[(int)sl.OBJECT_CLASS.FRUIT_VEGETABLE] = Convert.ToInt32(objectClassFruitVegetableFilter);
  2483. if (objectDetectionImageSyncMode == false) RetrieveObjectDetectionFrame(); //If true, this is called in the AcquireImages function in the image acquisition thread.
  2484. if (newobjectsframeready)
  2485. {
  2486. lock (zedCamera.grabLock)
  2487. {
  2488. float objdetect_fps = 1000000000.0f / (objectsFrameSDK.timestamp - lastObjectFrameTimeStamp);
  2489. objDetectionModuleFPS = (objDetectionModuleFPS + objdetect_fps) / 2.0f;
  2490. objectDetectionFPS = objDetectionModuleFPS.ToString("F1") + " FPS";
  2491. lastObjectFrameTimeStamp = objectsFrameSDK.timestamp;
  2492. ///Trigger the event that holds the raw data, and pass the whole objects frame.
  2493. if (OnObjectDetection_SDKData != null)
  2494. {
  2495. OnObjectDetection_SDKData(objectsFrameSDK);
  2496. }
  2497. //If there are any subscribers to the non-raw data, create that data and publish the event.
  2498. if (OnObjectDetection != null)
  2499. {
  2500. DetectionFrame oldoframe = detectionFrame; //Cache so we can clean it up once we're done setting up the new one.
  2501. //DetectionFrame oframe = new DetectionFrame(objectsFrame, this);
  2502. detectionFrame = new DetectionFrame(objectsFrameSDK, this);
  2503. OnObjectDetection(detectionFrame);
  2504. if (oldoframe != null) oldoframe.CleanUpAllObjects();
  2505. }
  2506. //Now that all events have been sent out, it's safe to let the image acquisition thread detect more objects.
  2507. requestobjectsframe = true;
  2508. newobjectsframeready = false;
  2509. }
  2510. }
  2511. }
  2512. /// <summary>
  2513. /// Requests the latest object detection frame information. If it's new, it'll fill the objectsFrame object
  2514. /// with the new frame info, set requestobjectsframe to false, and set newobjectsframeready to true.
  2515. /// </summary>
  2516. private void RetrieveObjectDetectionFrame()
  2517. {
  2518. sl.ObjectsFrameSDK oframebuffer = new sl.ObjectsFrameSDK();
  2519. sl.ERROR_CODE res = zedCamera.RetrieveObjectsDetectionData(ref od_runtime_params, ref oframebuffer);
  2520. if (res == sl.ERROR_CODE.SUCCESS && oframebuffer.isNew != 0)
  2521. {
  2522. if (objectDetection2DMask)
  2523. {
  2524. //Release memory from masks.
  2525. for (int i = 0; i < objectsFrameSDK.numObject; i++)
  2526. {
  2527. sl.ZEDMat oldmat = new sl.ZEDMat(objectsFrameSDK.objectData[i].mask);
  2528. oldmat.Free();
  2529. }
  2530. }
  2531. objectsFrameSDK = oframebuffer;
  2532. requestobjectsframe = false;
  2533. newobjectsframeready = true;
  2534. }
  2535. }
  2536. /// <summary>
  2537. /// Switchs the state of the object detection pause.
  2538. /// </summary>
  2539. /// <param name="state">If set to <c>true</c> state, the object detection will pause. It will resume otherwise</param>
  2540. public void SwitchObjectDetectionPauseState(bool state)
  2541. {
  2542. if (zedCamera != null)
  2543. {
  2544. if (objectDetectionRunning)
  2545. zedCamera.PauseObjectsDetection(state);
  2546. }
  2547. }
  2548. #endregion
  2549. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2550. ////////////////////////////////////////////////////////////////////// AR REGION //////////////////////////////////////////////////////////////////////////////
  2551. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2552. #region AR_CAMERAS
  2553. /// <summary>
  2554. /// Stereo rig that adjusts images from ZED_Rig_Stereo to look correct in the HMD.
  2555. /// <para>Hidden by default as it rarely needs to be changed.</para>
  2556. /// </summary>
  2557. [HideInInspector]
  2558. public GameObject zedRigDisplayer;
  2559. private ZEDMixedRealityPlugin arRig;
  2560. /// <summary>
  2561. /// Create a GameObject to display the ZED in an headset (ZED-M Only).
  2562. /// </summary>
  2563. /// <returns></returns>
  2564. private GameObject CreateZEDRigDisplayer()
  2565. {
  2566. //Make sure we don't already have one, such as if the camera disconnected and reconnected.
  2567. if (zedRigDisplayer != null) Destroy(zedRigDisplayer);
  2568. zedRigDisplayer = new GameObject("ZEDRigDisplayer");
  2569. arRig = zedRigDisplayer.AddComponent<ZEDMixedRealityPlugin>();
  2570. /*Screens left and right */
  2571. GameObject centerScreen = GameObject.CreatePrimitive(PrimitiveType.Quad);
  2572. centerScreen.name = "Quad";
  2573. MeshRenderer meshCenterScreen = centerScreen.GetComponent<MeshRenderer>();
  2574. meshCenterScreen.lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off;
  2575. meshCenterScreen.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off;
  2576. meshCenterScreen.receiveShadows = false;
  2577. meshCenterScreen.motionVectorGenerationMode = MotionVectorGenerationMode.ForceNoMotion;
  2578. meshCenterScreen.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
  2579. meshCenterScreen.sharedMaterial = Resources.Load("Materials/Unlit/Mat_ZED_Unlit") as Material;
  2580. centerScreen.layer = arLayer;
  2581. GameObject.Destroy(centerScreen.GetComponent<MeshCollider>());
  2582. /*Camera left and right*/
  2583. GameObject camCenter = new GameObject("camera");
  2584. camCenter.transform.SetParent(zedRigDisplayer.transform);
  2585. Camera cam = camCenter.AddComponent<Camera>();
  2586. cam.renderingPath = RenderingPath.Forward;//Minimal overhead
  2587. cam.clearFlags = CameraClearFlags.Color;
  2588. cam.backgroundColor = Color.black;
  2589. cam.stereoTargetEye = StereoTargetEyeMask.Both; //Temporary setting to fix loading screen issue.
  2590. cam.cullingMask = 1 << arLayer;
  2591. cam.allowHDR = false;
  2592. cam.allowMSAA = false;
  2593. cam.depth = camRightTransform.GetComponent<Camera>().depth;
  2594. HideFromWrongCameras.RegisterZEDCam(cam);
  2595. HideFromWrongCameras hider = centerScreen.AddComponent<HideFromWrongCameras>();
  2596. hider.SetRenderCamera(cam);
  2597. hider.showInNonZEDCameras = false;
  2598. SetLayerRecursively(camCenter, arLayer);
  2599. //Hide camera in editor.
  2600. #if UNITY_EDITOR
  2601. if (!showarrig)
  2602. {
  2603. LayerMask layerNumberBinary = (1 << arLayer); //Convert layer index into binary number.
  2604. LayerMask flippedVisibleLayers = ~UnityEditor.Tools.visibleLayers;
  2605. UnityEditor.Tools.visibleLayers = ~(flippedVisibleLayers | layerNumberBinary);
  2606. }
  2607. #endif
  2608. centerScreen.transform.SetParent(zedRigDisplayer.transform);
  2609. arRig.finalCameraCenter = camCenter;
  2610. arRig.ZEDEyeLeft = camLeftTransform.gameObject;
  2611. arRig.ZEDEyeRight = camRightTransform.gameObject;
  2612. arRig.quadCenter = centerScreen.transform;
  2613. ZEDMixedRealityPlugin.OnHmdCalibChanged += CalibrationHasChanged;
  2614. if (hasXRDevice())
  2615. {
  2616. #if UNITY_2019_1_OR_NEWER
  2617. HMDDevice = XRSettings.loadedDeviceName;
  2618. #else
  2619. HMDDevice = XRDevice.model;
  2620. #endif
  2621. }
  2622. return zedRigDisplayer;
  2623. }
  2624. #endregion
  2625. #region MIRROR
  2626. private ZEDMirror mirror = null;
  2627. private GameObject mirrorContainer = null;
  2628. void CreateMirror()
  2629. {
  2630. GameObject camLeft;
  2631. Camera camL;
  2632. if (mirrorContainer == null)
  2633. {
  2634. mirrorContainer = new GameObject("Mirror");
  2635. mirrorContainer.hideFlags = HideFlags.HideInHierarchy;
  2636. camLeft = new GameObject("MirrorCamera");
  2637. camLeft.hideFlags = HideFlags.HideInHierarchy;
  2638. mirror = camLeft.AddComponent<ZEDMirror>();
  2639. mirror.manager = this;
  2640. camL = camLeft.AddComponent<Camera>();
  2641. }
  2642. else
  2643. {
  2644. camLeft = mirror.gameObject;
  2645. camL = camLeft.GetComponent<Camera>();
  2646. }
  2647. camLeft.transform.parent = mirrorContainer.transform;
  2648. camL.stereoTargetEye = StereoTargetEyeMask.None;
  2649. camL.renderingPath = RenderingPath.Forward;//Minimal overhead
  2650. camL.clearFlags = CameraClearFlags.Color;
  2651. camL.backgroundColor = Color.black;
  2652. camL.cullingMask = 0; //It should see nothing. It gets its final image entirely from a Graphics.Blit call in ZEDMirror.
  2653. camL.allowHDR = false;
  2654. camL.allowMSAA = false;
  2655. camL.useOcclusionCulling = false;
  2656. camL.depth = cameraLeft.GetComponent<Camera>().depth; //Make sure it renders after the left cam so we can copy texture from latest frame.
  2657. }
  2658. #endregion
  2659. /// <summary>
  2660. /// Closes out the current stream, then starts it up again while maintaining tracking data.
  2661. /// Used when the zed becomes unplugged, or you want to change a setting at runtime that
  2662. /// requires re-initializing the camera.
  2663. /// </summary>
  2664. public void Reset()
  2665. {
  2666. //Save tracking
  2667. if (enableTracking && isTrackingEnable)
  2668. {
  2669. zedCamera.GetPosition(ref zedOrientation, ref zedPosition);
  2670. }
  2671. CloseManager();
  2672. openingLaunched = false;
  2673. running = false;
  2674. numberTriesOpening = 0;
  2675. forceCloseInit = false;
  2676. Awake();
  2677. }
  2678. public void Reboot()
  2679. {
  2680. //Save tracking
  2681. if (enableTracking && isTrackingEnable)
  2682. {
  2683. zedCamera.GetPosition(ref zedOrientation, ref zedPosition);
  2684. }
  2685. int sn = zedCamera.GetZEDSerialNumber();
  2686. CloseManager();
  2687. openingLaunched = false;
  2688. running = false;
  2689. numberTriesOpening = 0;
  2690. forceCloseInit = false;
  2691. bool isCameraAvailable = false;
  2692. Thread.Sleep(1000);
  2693. sl.ERROR_CODE err = sl.ZEDCamera.Reboot(sn);
  2694. if (err == sl.ERROR_CODE.SUCCESS)
  2695. {
  2696. int count = 0;
  2697. // Check if the camera is available before trying to re open it
  2698. while (!isCameraAvailable && count < 30)
  2699. {
  2700. count++;
  2701. sl.DeviceProperties[] devices = sl.ZEDCamera.GetDeviceList(out int nbDevices);
  2702. for (int i = 0; i < nbDevices; i++)
  2703. {
  2704. if (sn == devices[i].sn)
  2705. {
  2706. isCameraAvailable = true;
  2707. break;
  2708. }
  2709. }
  2710. Thread.Sleep(500);
  2711. }
  2712. }
  2713. if (isCameraAvailable)
  2714. {
  2715. Debug.LogWarning("Reboot successful.");
  2716. Awake();
  2717. }
  2718. else
  2719. {
  2720. Debug.LogWarning("Unable to reboot correctly.");
  2721. #if UNITY_EDITOR
  2722. UnityEditor.EditorApplication.isPlaying = false;
  2723. #else
  2724. Application.Quit();
  2725. #endif
  2726. }
  2727. }
  2728. public void InitVideoSettings(VideoSettingsInitMode mode)
  2729. {
  2730. if (!zedCamera.IsCameraReady)
  2731. {
  2732. Debug.LogError("Tried to apply camera settings before ZED camera was ready.");
  2733. return;
  2734. }
  2735. switch (mode)
  2736. {
  2737. case VideoSettingsInitMode.Custom:
  2738. ApplyLocalVideoSettingsToZED();
  2739. return;
  2740. case VideoSettingsInitMode.LoadFromSDK:
  2741. default:
  2742. //This is the SDK's default behavior, so we don't need to specify anything. Just apply the ZED's values locally.
  2743. GetCurrentVideoSettings();
  2744. return;
  2745. case VideoSettingsInitMode.Default:
  2746. zedCamera.ResetCameraSettings();
  2747. GetCurrentVideoSettings();
  2748. return;
  2749. }
  2750. }
  2751. private void GetCurrentVideoSettings()
  2752. {
  2753. //Sets all the video setting values to the ones currently applied to the ZED.
  2754. videoBrightness = zedCamera.GetCameraSettings(sl.CAMERA_SETTINGS.BRIGHTNESS);
  2755. videoContrast = zedCamera.GetCameraSettings(sl.CAMERA_SETTINGS.CONTRAST);
  2756. videoHue = zedCamera.GetCameraSettings(sl.CAMERA_SETTINGS.HUE);
  2757. videoSaturation = zedCamera.GetCameraSettings(sl.CAMERA_SETTINGS.SATURATION);
  2758. videoSharpness = zedCamera.GetCameraSettings(sl.CAMERA_SETTINGS.SHARPNESS);
  2759. videoGamma = zedCamera.GetCameraSettings(sl.CAMERA_SETTINGS.GAMMA);
  2760. videoAutoGainExposure = zedCamera.GetCameraSettings(sl.CAMERA_SETTINGS.AEC_AGC) == 1 ? true : false;
  2761. if (!videoAutoGainExposure)
  2762. {
  2763. videoGain = zedCamera.GetCameraSettings(sl.CAMERA_SETTINGS.GAIN);
  2764. videoExposure = zedCamera.GetCameraSettings(sl.CAMERA_SETTINGS.EXPOSURE);
  2765. }
  2766. videoAutoWhiteBalance = zedCamera.GetCameraSettings(sl.CAMERA_SETTINGS.AUTO_WHITEBALANCE) == 1 ? true : false;
  2767. if (!videoAutoWhiteBalance)
  2768. {
  2769. videoWhiteBalance = zedCamera.GetCameraSettings(sl.CAMERA_SETTINGS.WHITEBALANCE);
  2770. }
  2771. videoLEDStatus = zedCamera.GetCameraSettings(sl.CAMERA_SETTINGS.LED_STATUS) == 1 ? true : false;
  2772. }
  2773. private void ApplyLocalVideoSettingsToZED()
  2774. {
  2775. zedCamera.SetCameraSettings(sl.CAMERA_SETTINGS.BRIGHTNESS, videoBrightness);
  2776. zedCamera.SetCameraSettings(sl.CAMERA_SETTINGS.CONTRAST, videoContrast);
  2777. zedCamera.SetCameraSettings(sl.CAMERA_SETTINGS.HUE, videoHue);
  2778. zedCamera.SetCameraSettings(sl.CAMERA_SETTINGS.SATURATION, videoSaturation);
  2779. zedCamera.SetCameraSettings(sl.CAMERA_SETTINGS.SHARPNESS, videoSharpness);
  2780. zedCamera.SetCameraSettings(sl.CAMERA_SETTINGS.GAMMA, videoGamma);
  2781. zedCamera.SetCameraSettings(sl.CAMERA_SETTINGS.AEC_AGC, videoAutoGainExposure ? 1 : 0);
  2782. if (!videoAutoGainExposure)
  2783. {
  2784. zedCamera.SetCameraSettings(sl.CAMERA_SETTINGS.GAIN, videoGain);
  2785. zedCamera.SetCameraSettings(sl.CAMERA_SETTINGS.EXPOSURE, videoExposure);
  2786. }
  2787. zedCamera.SetCameraSettings(sl.CAMERA_SETTINGS.AUTO_WHITEBALANCE, videoAutoWhiteBalance ? 1 : 0);
  2788. if (!videoAutoWhiteBalance)
  2789. {
  2790. zedCamera.SetCameraSettings(sl.CAMERA_SETTINGS.WHITEBALANCE, videoWhiteBalance);
  2791. }
  2792. zedCamera.SetCameraSettings(sl.CAMERA_SETTINGS.LED_STATUS, 1);
  2793. }
  2794. #region EventHandler
  2795. /// <summary>
  2796. /// Changes the real-world brightness by setting the brightness value in the shaders.
  2797. /// </summary>
  2798. /// <param name="newVal">New brightness value to be applied. Should be between 0 and 100.</param>
  2799. public void SetCameraBrightness(int newVal)
  2800. {
  2801. SetFloatValueOnPlaneMaterials("_ZEDFactorAffectReal", newVal / 100f);
  2802. }
  2803. #if ZED_HDRP
  2804. public void SetSelfIllumination(float newVal)
  2805. {
  2806. SetFloatValueOnPlaneMaterials("_SelfIllumination", newVal);
  2807. }
  2808. #endif
  2809. /// <summary>
  2810. /// Sets the maximum depth range of real-world objects. Pixels further than this range are discarded.
  2811. /// </summary>
  2812. /// <param name="newVal">Furthest distance, in meters, that the camera will display pixels for. Should be between 0 and 20.</param>
  2813. public void SetMaxDepthRange(float newVal)
  2814. {
  2815. if (newVal < 0 || newVal > 40)
  2816. {
  2817. Debug.LogWarning("Tried to set max depth range to " + newVal + "m. Must be within 0m and 40m.");
  2818. newVal = Mathf.Clamp(newVal, 0, 40);
  2819. }
  2820. SetFloatValueOnPlaneMaterials("_MaxDepth", newVal);
  2821. }
  2822. /// <summary>
  2823. /// Sets a value of a float property on the material(s) rendering the ZED image.
  2824. /// Used to set things like brightness and maximum depth.
  2825. /// </summary>
  2826. /// <param name="propertyname">Name of value/property within Shader. </param>
  2827. /// <param name="newvalue">New value for the specified property.</param>
  2828. private void SetFloatValueOnPlaneMaterials(string propertyname, float newvalue)
  2829. {
  2830. foreach (ZEDRenderingPlane renderPlane in GetComponentsInChildren<ZEDRenderingPlane>())
  2831. {
  2832. Material rendmat;
  2833. if (renderPlane.ActualRenderingPath == RenderingPath.Forward) rendmat = renderPlane.canvas.GetComponent<Renderer>().material;
  2834. else if (renderPlane.ActualRenderingPath == RenderingPath.DeferredShading) rendmat = renderPlane.deferredMat;
  2835. else
  2836. {
  2837. Debug.LogError("Can't set " + propertyname + " value for Rendering Path " + renderPlane.ActualRenderingPath +
  2838. ": only Forward and DeferredShading are supported.");
  2839. return;
  2840. }
  2841. rendmat.SetFloat(propertyname, newvalue);
  2842. }
  2843. }
  2844. private void SetBoolValueOnPlaneMaterials(string propertyname, bool newvalue)
  2845. {
  2846. foreach (ZEDRenderingPlane renderPlane in GetComponentsInChildren<ZEDRenderingPlane>())
  2847. {
  2848. Material rendmat;
  2849. MeshRenderer rend = renderPlane.canvas.GetComponent<MeshRenderer>();
  2850. if (!rend) continue;
  2851. rendmat = rend.material;
  2852. rendmat.SetInt(propertyname, newvalue ? 1 : 0);
  2853. }
  2854. }
  2855. /// <summary>
  2856. /// Flag set to true when the HMD-to-ZED calibration file has changed during runtime.
  2857. /// Causes values from the new file to be applied during Update().
  2858. /// </summary>
  2859. private bool calibrationHasChanged = false;
  2860. /// <summary>
  2861. /// Sets the calibrationHasChanged flag to true, which causes the next Update() to
  2862. /// re-apply the HMD-to-ZED offsets.
  2863. /// </summary>
  2864. private void CalibrationHasChanged()
  2865. {
  2866. calibrationHasChanged = true;
  2867. }
  2868. #endregion
  2869. #if UNITY_EDITOR
  2870. /// <summary>
  2871. /// Handles changes to tracking or graphics settings changed from the Inspector.
  2872. /// </summary>
  2873. void OnValidate()
  2874. {
  2875. if (zedCamera != null)
  2876. {
  2877. // If tracking has been switched on
  2878. if (zedCamera.IsCameraReady && !isTrackingEnable && enableTracking)
  2879. {
  2880. //Enables tracking and initializes the first position of the camera.
  2881. if (!(enableTracking = (zedCamera.EnableTracking(ref zedOrientation, ref zedPosition, enableSpatialMemory, enablePoseSmoothing, estimateInitialPosition, trackingIsStatic,
  2882. enableIMUFusion, pathSpatialMemory) == sl.ERROR_CODE.SUCCESS)))
  2883. {
  2884. isZEDTracked = false;
  2885. throw new Exception(ZEDLogMessage.Error2Str(ZEDLogMessage.ERROR.TRACKING_NOT_INITIALIZED));
  2886. }
  2887. else
  2888. {
  2889. isZEDTracked = true;
  2890. isTrackingEnable = true;
  2891. }
  2892. }
  2893. // If tracking has been switched off
  2894. if (isTrackingEnable && !enableTracking)
  2895. {
  2896. isZEDTracked = false;
  2897. lock (zedCamera.grabLock)
  2898. {
  2899. zedCamera.DisableTracking();
  2900. }
  2901. isTrackingEnable = false;
  2902. }
  2903. // If streaming has been switched on
  2904. if (enableStreaming && !isStreamingEnable)
  2905. {
  2906. lock (zedCamera.grabLock)
  2907. {
  2908. sl.ERROR_CODE err = zedCamera.EnableStreaming(streamingCodec, (uint)bitrate, (ushort)streamingPort, gopSize, adaptativeBitrate, chunkSize, streamingTargetFramerate);
  2909. if (err == sl.ERROR_CODE.SUCCESS)
  2910. {
  2911. isStreamingEnable = true;
  2912. }
  2913. else
  2914. {
  2915. enableStreaming = false;
  2916. isStreamingEnable = false;
  2917. }
  2918. }
  2919. }
  2920. // If streaming has been switched off
  2921. if (!enableStreaming && isStreamingEnable)
  2922. {
  2923. lock (zedCamera.grabLock)
  2924. {
  2925. zedCamera.DisableStreaming();
  2926. isStreamingEnable = false;
  2927. }
  2928. }
  2929. //Reapplies graphics settings based on current values.
  2930. setRenderingSettings();
  2931. }
  2932. }
  2933. #endif
  2934. }